/// <summary> /// Trains the classifier in an online manner /// </summary> protected override void TrainMoreBinary(IArrayView <Example> binaryExamples) { foreach (var example in binaryExamples) { this.DoTrainingStep(example, 1.0); } }
public TestProvider(IArrayView <string> presentation, RandomizedQueue <StudyTestPair> stp, TestSettings settings) { this.presentation = presentation; this.stp = stp; this.settings = settings; }
private static void CheckBounds <T>(this IArrayView <T> array, int index) { if (index < 0 || index >= array.Count) { throw new IndexOutOfRangeException(index.ToString()); } }
/// <summary> /// Invokes the listen action /// </summary> public void Listen(IArrayView <EEGDataEntry> data) { if (this.onListen != null) { this.invoker.BeginInvoke(this.onListen, new object[] { data }); } }
/// <summary> /// Adds the examples to the set of possible neighbor examples /// </summary> public void TrainMore(IArrayView<Example> labeledExamples) { if (this.IsTrained) this.neighborhood.AddRange(labeledExamples); else this.Train(labeledExamples); }
private IArrayView <int> SelectFeatures(IArrayView <Example> binaryExamples, int round) { switch (this.WeakLearnerTrainingMode) { case WeakLearnerTrainingModes.AllFeatures: return(binaryExamples[0].Features.Indices()); case WeakLearnerTrainingModes.RandomSubset: return(binaryExamples[0].Features .Indices() .Shuffled(this.rand) .SubView(0, this.rand.Next(1, binaryExamples[0].Features.Count))); case WeakLearnerTrainingModes.RandomFeature: return(this.rand.Next(binaryExamples[0].Features.Count).NCopies(1)); case WeakLearnerTrainingModes.SequentialFeature: return((round % binaryExamples[0].Features.Count).NCopies(1)); case WeakLearnerTrainingModes.RandomTimeBin: int bin = this.rand.Next(binaryExamples[0].Features.Count / Channels.Values.Count), start = Channels.Values.Count * bin, count = Channels.Values.Count; if (start + count > binaryExamples[0].Features.Count) { count = binaryExamples[0].Features.Count - start; } return(Arrays.Range(start, 1, count)); case WeakLearnerTrainingModes.SequentialTimeBin: return(Arrays.Range((Channels.Values.Count * round) % binaryExamples[0].Features.Count, 1, Channels.Values.Count)); } throw new Exception("Training mode not supported!"); }
public UserCtrlProvider(IArrayView <string> presentation, IArrayView <string> comp, IArrayView <string> class1, IArrayView <string> class2, RandomizedQueue <StudyTestPair> stp, UserCtrlSettings settings)//, IEEGDataSource dataSource) { this.presentation = presentation; this.comp = comp; this.class1 = class1; this.class2 = class2; this.stp = stp; this.settings = settings; blocks = new RandomizedQueue <string> [settings.NumBlocks * 2]; int limit = 0; for (int i = 0; i < settings.NumBlocks * 2; i += 2) { blocks[i] = new RandomizedQueue <string>(); blocks[i + 1] = new RandomizedQueue <string>(); for (int j = 0 + limit * settings.BlockSize; j < (limit + 1) * settings.BlockSize; j++) { blocks[i].Add(this.class1[j]); blocks[i + 1].Add(this.class2[j]); } limit++; } }
private Example GetExample(IArrayView <EEGDataEntry> trial) { int marker = trial.FirstItem().Marker; var means = Channels.Values.Select(ch => trial.Channel(ch).Average()).ToArray(); IArrayView <EEGDataEntry> trimmedTrial = trial.DownSample(this.Settings.BinWidthMillis); if (trial.Count > this.minFeatures) { trimmedTrial = trial.SubView(0, this.minFeatures); } else if (trial.Count < this.minFeatures) { var defaultEntry = new EEGDataEntry(marker, 0, 0, means); trimmedTrial = Arrays.FromMap(i => i < trial.Count ? trial[i] : defaultEntry, this.minFeatures); } var features = trimmedTrial .Select(this.selectedBins) .SelectMany(e => this.Settings.SelectedChannels.Select(ch => e[ch] - means[ch.ToIndex()])); if (this.Settings.IncludeChannelMeans) { features = features.Concat(this.Settings.SelectedChannels.Select(ch => means[ch.ToIndex()])); } return(new Example(marker, features)); }
public FalseAdaptProvider(RandomizedQueue <StudyTestTuple> presentation, IArrayView <string> comp, IArrayView <string> class1, IArrayView <string> class2, IArrayView <string> study, FalseAdaptSettings settings) { this.presentation = presentation; this.comp = comp; this.class1 = class1; this.class2 = class2; this.settings = settings; this.study = study; blocks = new RandomizedQueue <string> [settings.NumBlocks * 2]; int limit = 0; for (int i = 0; i < settings.NumBlocks * 2; i += 2) { blocks[i] = new RandomizedQueue <string>(); blocks[i + 1] = new RandomizedQueue <string>(); for (int j = 0 + limit * settings.BlockSize; j < (limit + 1) * settings.BlockSize; j++) { blocks[i].Add(this.class1[j]); blocks[i + 1].Add(this.class2[j]); } limit++; } }
//MATLAB REFERENCE. You must add the matlab reference via the project menu before this will work //MLApp.MLApp matlab; public AdaptiveProvider(RandomizedQueue <StudyTestPair> stp, IArrayView <string> presentation, IArrayView <string> class1, IArrayView <string> class2, AdaptiveSettings settings, IEEGDataSource dataSource, IArray <ClassificationScheme> classifiers) { this.pres = stp; this.settings = settings; this.dataSource = dataSource; this.presentation = presentation; this.class1 = class1; this.class2 = class2; this.classifiers = classifiers; //NOTE: It will always take the first classification scheme chosen //TODO: Make it so that only one classification scheme can be specified classifier = new ClassifierManager(classifiers[0]); //MATLAB REFERENCE //matlab = new MLApp.MLApp(); blocks = new RandomizedQueue <string> [settings.NumBlocks * 2]; int limit = 0; for (int i = 0; i < settings.NumBlocks * 2; i += 2) { blocks[i] = new RandomizedQueue <string>(); blocks[i + 1] = new RandomizedQueue <string>(); for (int j = 0 + limit * settings.BlockSize; j < (limit + 1) * settings.BlockSize; j++) { blocks[i].Add(this.class1[j]); blocks[i + 1].Add(this.class2[j]); } limit++; } }
private EEGDataEntry(int marker, int timeStamp, int relativeTimeStamp, IArrayView <double> channelData) : this() { this.Data = channelData; this.Marker = marker; this.TimeStamp = timeStamp; this.RelativeTimeStamp = relativeTimeStamp; }
public KRMonitorProvider(IArrayView <string> presentation, RandomizedQueue <StudyTestPair> stp, KRMonitorSettings settings, IEEGDataSource dataSource) { this.presentation = presentation; this.stp = stp; this.settings = settings; this.dataSource = dataSource; }
public void LogTrial(IArrayView <EEGDataEntry> trial) { if (this.TrialLogger != null) { try { this.TrialLogger.WriteLine(trial.ConcatToString(Environment.NewLine)); } catch (Exception) { } } }
private EEGDataEntry(int marker, int timeStamp, int relativeTimeStamp, IArrayView<double> channelData) : this() { this.Data = channelData; this.Marker = marker; this.TimeStamp = timeStamp; this.RelativeTimeStamp = relativeTimeStamp; }
/// <summary> /// Returns a view of the specified portion of the array. Does not perform copying /// </summary> public static IArrayView <T> SubView <T>(this IArrayView <T> array, int start, int count) { if (start == 0 && count == array.Count) { return(array); } return(new ShallowSubArrayView <T, IArrayView <T> >(array, start, count)); }
/// <summary> /// Enqueues a trial /// </summary> public void AddTrial(IArrayView <EEGDataEntry> trial) { if (trial.Count <= 0) { throw new Exception("At least one entry required"); } this.queuedTrials.Add(trial); }
/// <summary> /// Записывает массив в поток. /// </summary> /// <param name = "writer">Поток.</param> /// <param name = "array">Массив.</param> /// <exception cref = "ArgumentNullException"><paramref name = "writer" /> является <c>null</c>.</exception> /// <exception cref = "ArgumentNullException"><paramref name = "array" /> является <c>null</c>.</exception> public static void Write(this BinaryWriter writer, IArrayView <byte> array) { if (writer == null) throw new ArgumentNullException ("writer"); if (array == null) throw new ArgumentNullException ("array"); writer.Write (array.Base, array.Offset, array.Length); }
/// <summary> /// Adds the examples to the set of possible neighbor examples /// </summary> public void TrainMore(IArrayView <Example> labeledExamples) { if (this.IsTrained) { this.neighborhood.AddRange(labeledExamples); } else { this.Train(labeledExamples); } }
/// <summary> /// Converts the examples to binary and then calls TrainMoreBinary. /// </summary> public void TrainMore(IArrayView <Example> labeledExamples) { if (this.IsTrained) { this.TrainMoreBinary(labeledExamples.SelectArray(this.ConvertToBinaryExample)); } else { this.Train(labeledExamples); } }
/// <summary> /// Construct an experiment with the given parameters /// </summary> public ExperimentProvider(ExperimentSettings settings, StimulusClass stimulusClass1, StimulusClass stimulusClass2, IArrayView <ClassificationScheme> classificationSchemes, IEEGDataSource dataSource) { this.Settings = settings; this.StimulusClass1 = stimulusClass1; this.StimulusClass2 = stimulusClass2; this.ClassificationSchemes = classificationSchemes; this.DataSource = dataSource; }
/// <summary> /// Checks that the classifiers parameters are valid and calls TrainHelper. Sets IsTrained to true. /// </summary> public void Train(IArrayView <Example> labeledExamples) { string errorMessage; if (!this.AreParameterValuesValid(out errorMessage)) { throw new Exception("Invalid parameter value: " + errorMessage); } this.TrainHelper(labeledExamples); this.IsTrained = true; }
/// <summary> /// Construct a view with the specified classifier managers /// </summary> public TrainView(IArrayView <ClassifierManager> classifiers) : base() { var panel = this.RegisterDisposable(new Panel() { Dock = DockStyle.Fill, UseWaitCursor = true }); int count = classifiers.Count; this.DoOnDeploy(c => { c.Controls.Add(panel); foreach (int i in classifiers.Indices().Reverse()) { var classifier = classifiers[i]; var label = ("Training " + classifier.Settings.Name + "...").ToLabel(DockStyle.Top, ContentAlignment.MiddleCenter, false); label.Font = GUIUtils.Constants.DISPLAY_FONT; panel.Controls.Add(label); // perform training in a separate thread ThreadPool.QueueUserWorkItem(ignored => { classifier.Train(); this.Invoke(() => { label.Text = classifier.Settings.Name + " trained"; if (--count > 0) { return; } panel.UseWaitCursor = false; var continuePanel = new Panel() { Dock = DockStyle.Bottom }; this.DeploySubView(new ChoiceView("Continue".Enumerate()), continuePanel); panel.Controls.Add(continuePanel); }); }); } if (!string.IsNullOrWhiteSpace(this.Text)) { panel.Controls.Add(new Label() { Text = this.Text, Dock = DockStyle.Top, TextAlign = ContentAlignment.MiddleCenter, Font = GUIUtils.Constants.DISPLAY_FONT }); } }); }
/// <summary> /// Gets data from the headset /// </summary> protected override bool TryGetData(out IArrayView<EEGDataEntry> data) { Dictionary<EdkDll.EE_DataChannel_t, double[]> rawData; if (!this.headset.TryGetData(out rawData)) { data = null; return false; } data = this.CreateEntries(rawData).ToIArray(); return true; }
/// <summary> /// Transposes the 2-dimensional array in time proportional to one of the dimensions /// </summary> public static IArrayView <IArrayView <T> > Transposed <T>(this IArrayView <IArrayView <T> > array2d) { if (array2d.Count == 0) { return(Arrays.NCopies <IArrayView <T> >(null, 0)); } return(array2d[0] .Indices() .Select(i => Arrays.FromMap(j => array2d[j][i], array2d.Count)) .ToIArray()); }
static Channels() { var chanValues = Enum.GetValues(typeof(Channel)); var chanValuesArray = new Channel[chanValues.Length]; chanValues.CopyTo(chanValuesArray, 0); values = chanValuesArray.ToIArray(); channelsToIndices = values .ParallelTo(values.Indices()) .ToDictionary(d => d.Item1, d => d.Item2); }
private bool TryGetTrialData(Runtime runtime, out IArrayView <EEGDataEntry> trial) { // get rid of excess trials while (runtime.TrialDataQueue.Count > 1) { runtime.TrialDataQueue.Dequeue(); runtime.LogLine("Found extra trial data!"); } // try to get the trial return(runtime.TrialDataQueue.TryDequeue(2000, out trial)); }
/// <summary> /// Gets data from the headset /// </summary> protected override bool TryGetData(out IArrayView <EEGDataEntry> data) { Dictionary <EdkDll.EE_DataChannel_t, double[]> rawData; if (!this.headset.TryGetData(out rawData)) { data = null; return(false); } data = this.CreateEntries(rawData).ToIArray(); return(true); }
private static void TestArrayViewAccess <T>(this IArrayView <T> array) { var list = new List <T>(); for (int i = 0; i < array.Count; i++) { list.Add(array[i]); } var list2 = new List <T>(); foreach (T t in array) { list2.Add(t); } if (!list.SequenceEqual(list2)) { throw new Exception(array.GetType().Name + ": " + list.ConcatToString(',') + " != " + list2.ConcatToString(',')); } bool caught = false; T item; try { item = array[-1]; } catch (Exception) { caught = true; } if (!caught) { throw new Exception(array.GetType().Name + ": allowed -1 access"); } caught = false; try { item = array[array.Count]; } catch (Exception) { caught = true; } if (!caught) { throw new Exception(array.GetType().Name + ": allowed Count access"); } }
/// <summary> /// Attempts to get data from the data source /// </summary> protected override bool TryGetData(out IArrayView <EEGDataEntry> data) { var rand = new Random(); data = (10) .CountTo() .Select(i => new EEGDataEntry(this.Marker, (DateTime.Now - baseTime).TotalMilliseconds.Rounded(), (DateTime.Now - this.markerBaseTime).TotalMilliseconds.Rounded(), Channels.Values.Count .CountTo() .Select(j => 3000 + 50 * rand.NextDouble()))).ToIArray(); return(true); }
/// <summary> /// Converts the examples to have binary class values, then calls TrainBinary. The mappings from /// regular classes to binary classes are stored until future calls to TrainHelper. /// </summary> protected override void TrainHelper(IArrayView <Example> examples) { var classes = examples.Select(e => e.Class).Distinct().InOrder().ToIArray(); if (classes.Count > 2) { throw new ArgumentException("Training set has too many classes for binary classifier"); } this.classMap.Clear(); this.classMap[classes.FirstItem()] = this.NegativeExampleValue; this.classMap[classes.LastItem()] = this.PositiveExampleValue; this.TrainBinary(examples.SelectArray(this.ConvertToBinaryExample)); }
private double TrainWeakLearner(IArrayView <Example> binaryExamples, IArrayView <double> weights, int round, bool[] predictionResults) { this.weakLearnerFeatures[round] = this.SelectFeatures(binaryExamples, round); this.weakLearners[round].Train(binaryExamples.SelectArray(e => e.WithFeatures(this.weakLearnerFeatures[round])), weights); double trainingError = 0; for (int i = 0; i < binaryExamples.Count; i++) { if (!(predictionResults[i] = (this.weakLearners[round].Predict(binaryExamples[i].WithFeatures(this.weakLearnerFeatures[round])) == binaryExamples[i].Class))) { trainingError += weights[i]; } } return(trainingError); }
/// <summary> /// Averages together adjacent bins in values /// </summary> public static IArrayView<double> Downsample(this IArrayView<double> values, int binWidth) { if (binWidth <= 0) throw new ArgumentException("binWidth must be positive"); int div = values.Count / binWidth, mod = values.Count % binWidth; double[] downsampled = new double[div + Math.Sign(mod)]; int offset; for (int i = 0; i < div; i++) { offset = binWidth * i; for (int j = 0; j < binWidth; j++) downsampled[i] += values[offset + j]; downsampled[i] /= binWidth; } if (div < downsampled.Length) downsampled[div] = values.SubView(values.Count - mod, mod).Average(); return downsampled.AsIArray(); }
/// <summary> /// Performs the regression /// </summary> protected override void TrainBinary(IArrayView <Example> binaryExamples) { Matrix X = new Matrix(binaryExamples[0].Features.Count + 1, binaryExamples.Count), d = new Matrix(1, X.ColumnCount); int i = 0, j = 0; foreach (var example in binaryExamples) { d[0, i] = example.Class; foreach (var dataPoint in example.Features) { X[j++, i] = dataPoint; } X[j, i] = 1; // pad with 1s to incorporate b j = 0; i++; } this.weights = ComputeWeights(X, d, this.Lambda, this.MinDistance, this.MaxIterations); }
/// <summary> /// Zscores the examples, returning the calculated means and standard deviations as out parameters. /// </summary> internal static IArrayView <Example> ZScored(IArrayView <Example> examples, out IArrayView <double> means, out IArrayView <double> standardDeviations) { // compute means and standard deviations int numFeatures = examples[0].Features.Count; IArray <double> meansArray = Arrays.New <double>(numFeatures), standardDeviationsArray = Arrays.New <double>(numFeatures); double mean; for (int i = 0; i < numFeatures; i++) { standardDeviationsArray[i] = examples.Select(e => e.Features[i]).StandardDeviation(out mean); meansArray[i] = mean; } means = meansArray; standardDeviations = standardDeviationsArray; // z-score the examples return(examples.Select(e => e.ZScored(meansArray, standardDeviationsArray)).ToIArray()); }
/// <summary> /// Construct a view with the specified classifier managers /// </summary> public TrainView(IArrayView<ClassifierManager> classifiers) : base() { var panel = this.RegisterDisposable(new Panel() { Dock = DockStyle.Fill, UseWaitCursor = true }); int count = classifiers.Count; this.DoOnDeploy(c => { c.Controls.Add(panel); foreach (int i in classifiers.Indices().Reverse()) { var classifier = classifiers[i]; var label = ("Training " + classifier.Settings.Name + "...").ToLabel(DockStyle.Top, ContentAlignment.MiddleCenter, false); label.Font = GUIUtils.Constants.DISPLAY_FONT; panel.Controls.Add(label); // perform training in a separate thread ThreadPool.QueueUserWorkItem(ignored => { classifier.Train(); this.Invoke(() => { label.Text = classifier.Settings.Name + " trained"; if (--count > 0) return; panel.UseWaitCursor = false; var continuePanel = new Panel() { Dock = DockStyle.Bottom }; this.DeploySubView(new ChoiceView("Continue".Enumerate()), continuePanel); panel.Controls.Add(continuePanel); }); }); } if (!string.IsNullOrWhiteSpace(this.Text)) panel.Controls.Add(new Label() { Text = this.Text, Dock = DockStyle.Top, TextAlign = ContentAlignment.MiddleCenter, Font = GUIUtils.Constants.DISPLAY_FONT }); }); }
private void TrainBinary(IArrayView<Example> binaryExamples, IArrayView<double> weights) { int feature = this.Feature < binaryExamples[0].Features.Count ? this.Feature : 0; var sortedExamples = binaryExamples.Select((e, i) => new { Example = e, Weight = weights[i] }).ToList(); sortedExamples.Sort((e1, e2) => e1.Example.Features[feature].CompareTo(e2.Example.Features[feature])); // init the errors double negsBelowError = 0, negsAboveError = 0; foreach (var e in sortedExamples) if (e.Example.Class == this.NegativeExampleValue) negsBelowError += e.Weight; else negsAboveError += e.Weight; // determine the optimal cut point double bestError = Math.Min(negsBelowError, negsAboveError); bool bestPolicy = negsBelowError < negsAboveError; int bestCutPoint = 0; for (int cutPoint = 1; cutPoint <= sortedExamples.Count; cutPoint++) { if (sortedExamples[cutPoint - 1].Example.Class == this.NegativeExampleValue) { negsBelowError -= sortedExamples[cutPoint - 1].Weight; negsAboveError += sortedExamples[cutPoint - 1].Weight; } else { negsBelowError += sortedExamples[cutPoint - 1].Weight; negsAboveError -= sortedExamples[cutPoint - 1].Weight; } if (negsBelowError < bestError) { bestError = negsBelowError; bestPolicy = true; bestCutPoint = cutPoint; } if (negsAboveError < bestError) { bestError = negsAboveError; bestPolicy = false; bestCutPoint = cutPoint; } } // return if (bestCutPoint == sortedExamples.Count) this.cutPoint = sortedExamples.LastItem().Example.Features[feature] * 1.01 + double.Epsilon; else if (bestCutPoint == 0) this.cutPoint = sortedExamples[0].Example.Features[feature] * 0.99 - double.Epsilon; else this.cutPoint = (sortedExamples[bestCutPoint - 1].Example.Features[feature] + sortedExamples[bestCutPoint].Example.Features[feature]) / 2.0; this.negativesBelowCutPoint = bestPolicy; }
/// <summary> /// Efficiently returns an identical example except with only the features /// at the indices specified by the argument. No copying of features is performed. /// </summary> public Example WithFeatures(IArrayView<int> featureIndices) { return new Example(this.Class, this.Features.Select(featureIndices)); }
/// <summary> /// Uses the classifier to predict the class of the trial /// </summary> public int Predict(IArrayView<EEGDataEntry> trial, out double confidence) { var example = this.GetExample(trial); return this.Classifier.Predict(this.Settings.ZScoreFeatures ? example.ZScored(this.means, this.stddevs) : example, out confidence); }
/// <summary> /// Trains the classifier /// </summary> private void TrainBinary(IArrayView<Example> binaryExamples, IArrayView<double> weights) { this.mistakes.Clear(); this.perceptronWeights.Clear(); this.confidenceRange = 0; // We need padding, since the first weight refers to the zeros vector this.mistakes.Add(default(Example)); this.perceptronWeights.Add(0); this.currentPerceptron = Arrays.New<double>(binaryExamples[0].Features.Count); // in each epoch for (int i = 0; i < this.Epochs; i++) // train on each example for (int e = 0; e < binaryExamples.Count; e++) this.DoTrainingStep(binaryExamples[e], weights[e]); }
/// <summary> /// Trains the classifier in an online manner /// </summary> protected override void TrainBinary(IArrayView<Example> binaryExamples) { this.TrainBinary(binaryExamples, (1.0 / binaryExamples.Count).NCopies(binaryExamples.Count)); }
/// <summary> /// Removes the trial if it was enqueued but not yet processed /// </summary> public void RemoveTrial(IArrayView<EEGDataEntry> trial) { this.queuedTrials.Remove(trial); }
/// <summary> /// Called from the reader thread in a locked context. /// </summary> protected abstract bool TryGetData(out IArrayView<EEGDataEntry> data);
private IArrayView<int> SelectFeatures(IArrayView<Example> binaryExamples, int round) { switch (this.WeakLearnerTrainingMode) { case WeakLearnerTrainingModes.AllFeatures: return binaryExamples[0].Features.Indices(); case WeakLearnerTrainingModes.RandomSubset: return binaryExamples[0].Features .Indices() .Shuffled(this.rand) .SubView(0, this.rand.Next(1, binaryExamples[0].Features.Count)); case WeakLearnerTrainingModes.RandomFeature: return this.rand.Next(binaryExamples[0].Features.Count).NCopies(1); case WeakLearnerTrainingModes.SequentialFeature: return (round % binaryExamples[0].Features.Count).NCopies(1); case WeakLearnerTrainingModes.RandomTimeBin: int bin = this.rand.Next(binaryExamples[0].Features.Count / Channels.Values.Count), start = Channels.Values.Count * bin, count = Channels.Values.Count; if (start + count > binaryExamples[0].Features.Count) count = binaryExamples[0].Features.Count - start; return Arrays.Range(start, 1, count); case WeakLearnerTrainingModes.SequentialTimeBin: return Arrays.Range((Channels.Values.Count * round) % binaryExamples[0].Features.Count, 1, Channels.Values.Count); } throw new Exception("Training mode not supported!"); }
private double TrainWeakLearner(IArrayView<Example> binaryExamples, IArrayView<double> weights, int round, bool[] predictionResults) { this.weakLearnerFeatures[round] = this.SelectFeatures(binaryExamples, round); this.weakLearners[round].Train(binaryExamples.SelectArray(e => e.WithFeatures(this.weakLearnerFeatures[round])), weights); double trainingError = 0; for (int i = 0; i < binaryExamples.Count; i++) if (!(predictionResults[i] = (this.weakLearners[round].Predict(binaryExamples[i].WithFeatures(this.weakLearnerFeatures[round])) == binaryExamples[i].Class))) trainingError += weights[i]; return trainingError; }
/// <summary> /// ZScores the examples, returning the calculated means and standard deviations as out parameters /// </summary> public static IArrayView<Example> ZScored(this IArrayView<Example> examples, out IArrayView<double> means, out IArrayView<double> standardDeviations) { return Example.ZScored(examples, out means, out standardDeviations); }
/// <summary> /// Zscores the examples, returning the calculated means and standard deviations as out parameters. /// </summary> internal static IArrayView<Example> ZScored(IArrayView<Example> examples, out IArrayView<double> means, out IArrayView<double> standardDeviations) { // compute means and standard deviations int numFeatures = examples[0].Features.Count; IArray<double> meansArray = Arrays.New<double>(numFeatures), standardDeviationsArray = Arrays.New<double>(numFeatures); double mean; for (int i = 0; i < numFeatures; i++) { standardDeviationsArray[i] = examples.Select(e => e.Features[i]).StandardDeviation(out mean); meansArray[i] = mean; } means = meansArray; standardDeviations = standardDeviationsArray; // z-score the examples return examples.Select(e => e.ZScored(meansArray, standardDeviationsArray)).ToIArray(); }
/// <summary> /// Efficiently returns an identical example with features that have been z-scored using means and standardDeviations. /// </summary> public Example ZScored(IArrayView<double> means, IArrayView<double> standardDeviations) { var features = this.Features; return new Example(this.Class, Arrays.FromMap(i => (features[i] - means[i]) / standardDeviations[i], features.Count)); }
private Example GetExample(IArrayView<EEGDataEntry> trial) { int marker = trial.FirstItem().Marker; var means = Channels.Values.Select(ch => trial.Channel(ch).Average()).ToArray(); IArrayView<EEGDataEntry> trimmedTrial = trial.DownSample(this.Settings.BinWidthMillis); if (trial.Count > this.minFeatures) trimmedTrial = trial.SubView(0, this.minFeatures); else if (trial.Count < this.minFeatures) { var defaultEntry = new EEGDataEntry(marker, 0, 0, means); trimmedTrial = Arrays.FromMap(i => i < trial.Count ? trial[i] : defaultEntry, this.minFeatures); } var features = trimmedTrial .Select(this.selectedBins) .SelectMany(e => this.Settings.SelectedChannels.Select(ch => e[ch] - means[ch.ToIndex()])); if (this.Settings.IncludeChannelMeans) features = features.Concat(this.Settings.SelectedChannels.Select(ch => means[ch.ToIndex()])); return new Example(marker, features); }
/// <summary> /// Trains the classifier on all enqueued examples /// </summary> public void Train() { IArrayView<Example> examples; if (!this.Classifier.IsTrained) { this.minFeatures = this.queuedTrials.Select(t => t.Count).Min(); this.selectedBins = this.Settings.SelectedBins.Where(i => i < this.minFeatures).ToIArray(); examples = this.queuedTrials.Select(this.GetExample).ToIArray(); if (this.Settings.ZScoreFeatures) examples = examples.ZScored(out this.means, out this.stddevs); } else { examples = this.queuedTrials.Select(this.GetExample).ToIArray(); if (this.Settings.ZScoreFeatures) examples = examples.Select(e => e.ZScored(this.means, this.stddevs)).ToIArray(); } // train if (this.Classifier.IsTrained) this.Classifier.TrainMore(examples); else this.Classifier.Train(examples); // don't waste memory! this.queuedTrials.Clear(); }
/// <summary> /// Trains the classifier on the supplied binary examples /// </summary> protected override void TrainBinary(IArrayView<Example> binaryExamples) { this.rand = new Random(unchecked(this.Rounds * binaryExamples.Count * binaryExamples[0].Features.Count)); this.weakLearners = new IWeightedClassifier[this.Rounds]; this.weakLearnerFeatures = new IArrayView<int>[this.Rounds]; this.alphas = new double[this.Rounds]; var predictionResults = new bool[binaryExamples.Count]; var weights = (1.0 / binaryExamples.Count).NCopies(binaryExamples.Count).ToIArray(); var factory = this.WeakLearnerTemplate.GetFactory(); double trainingError; for (int i = 0; i < this.Rounds; i++) { this.weakLearners[i] = factory(); trainingError = this.TrainWeakLearner(binaryExamples, weights, i, predictionResults); this.alphas[i] = this.GetAlpha(trainingError); // update weights ( w *= exp(-alpha * y_i * h(x_i)) ) double expAlpha = Math.Exp(this.alphas[i]), normalizationFactor = 0; for (int e = 0; e < binaryExamples.Count; e++) if (predictionResults[e]) normalizationFactor += (weights[e] /= expAlpha); else normalizationFactor += (weights[e] *= expAlpha); // normalize weights for (int e = 0; e < binaryExamples.Count; e++) weights[e] /= normalizationFactor; } }
/// <summary> /// Attempts to get data from the data source /// </summary> protected override bool TryGetData(out IArrayView<EEGDataEntry> data) { var rand = new Random(); data = (10) .CountTo() .Select(i => new EEGDataEntry(this.Marker, (DateTime.Now - baseTime).TotalMilliseconds.Rounded(), (DateTime.Now - this.markerBaseTime).TotalMilliseconds.Rounded(), Channels.Values.Count .CountTo() .Select(j => 3000 + 50 * rand.NextDouble()))).ToIArray(); return true; }
/// <summary> /// Trains the classifier /// </summary> protected override void TrainHelper(IArrayView<Example> labeledExamples) { this.neighborhood.Clear(); this.neighborhood.AddRange(labeledExamples); }
/// <summary> /// Invokes the listen action /// </summary> public void Listen(IArrayView<EEGDataEntry> data) { if (this.onListen != null) this.invoker.BeginInvoke(this.onListen, new object[] { data }); }
/// <summary> /// Trains the classifier in an online manner /// </summary> protected override void TrainMoreBinary(IArrayView<Example> binaryExamples) { foreach (var example in binaryExamples) this.DoTrainingStep(example, 1.0); }
public void Init() { this.data = new Array <byte> (new byte [] { 124, 224, 0, 75 }); this.address = new IPAddress (this.data); }
/// <summary> /// Trains the classifier /// </summary> public void Train(IArrayView<Example> labeledExamples, IArrayView<double> weights) { this.TrainBinary(labeledExamples.SelectArray(this.ConvertToBinaryExample), weights); this.IsTrained = true; }
/// <summary> /// Enqueues a trial /// </summary> public void AddTrial(IArrayView<EEGDataEntry> trial) { if (trial.Count <= 0) throw new Exception("At least one entry required"); this.queuedTrials.Add(trial); }
public void Init() { this.data = new Array <byte> (new byte [] { 11, 65, 23, 198, 0, 37 }); this.address = new MACAddress (this.data); }
private Example(int cls, IArrayView<double> features) : this() { this.Class = cls; this.Features = features; }