public void SetObservedVariables(double[][][] featureValues, GaussianArray priorWeightMeans, GammaArray priorWeightPrecisions, bool[][] labels = null) { #if !USE_PRECOMPILED_ALGORITHM numberOfResidents.ObservedValue = featureValues.Length; numberOfExamples.ObservedValue = featureValues.Select(ia => ia.Length).ToArray(); numberOfFeatures.ObservedValue = featureValues[0][0].Length; noisePrecision.ObservedValue = 1; if (labels != null) { activities.ObservedValue = labels; } this.featureValues.ObservedValue = featureValues; weightPriorMeans.ObservedValue = DistributionArrayHelpers.Copy(priorWeightMeans); weightPriorPrecisions.ObservedValue = DistributionArrayHelpers.Copy(priorWeightPrecisions); #else algorithm.SetObservedValue(numberOfResidents.Name, featureValues.Length); algorithm.SetObservedValue(numberOfExamples.Name, featureValues[0].Length); algorithm.SetObservedValue(numberOfFeatures.Name, featureValues[0][0].Length); algorithm.SetObservedValue(noisePrecision.Name, 1.0); algorithm.SetObservedValue(this.featureValues.Name, featureValues); algorithm.SetObservedValue(weightPriorMeans.Name, DistributionArrayHelpers.Copy(priorWeightMeans)); algorithm.SetObservedValue(weightPriorPrecisions.Name, DistributionArrayHelpers.Copy(priorWeightPrecisions)); if (labels != null) { algorithm.SetObservedValue(activities.Name, labels); } #endif }
/// <summary> /// Sets the observed values. /// </summary> /// <param name="instances">The instances.</param> /// <param name="featureSet">The feature buckets.</param> /// <param name="mode">The mode.</param> /// <param name="priors">The priors.</param> /// <exception cref="System.InvalidOperationException">Data is null</exception> /// <exception cref="System.ArgumentNullException">parameters;@Mode expected in parameters</exception> /// <exception cref="System.ArgumentException"></exception> public override void SetObservedValues(IList <Inputs.Instance> instances, FeatureSet featureSet, InputMode mode, Priors priors) { if (instances == null) { throw new InvalidOperationException("Data is null"); } this.NumberOfMessages.ObservedValue = instances.Count; this.NumberOfFeatures.ObservedValue = featureSet.FeatureVectorLength; this.NoiseVariance.ObservedValue = priors.NoiseVariance; if (mode == InputMode.Training) { this.RepliedTo.ObservedValue = instances.Select(ia => ia.Label).ToArray(); this.WeightPriors.ObservedValue = DistributionArrayHelpers.DistributionArray(priors.Weights.Values); } else { // This is testing, don't set isRepliedTo observed values this.WeightPriors.ObservedValue = DistributionArrayHelpers.Copy(priors.Weights.Values); } var featureIndices = featureSet.FeatureBuckets.Select((ia, i) => new { ia, i }).ToDictionary(anon => anon.ia, anon => anon.i); this.FeatureIndices.ObservedValue = instances.Select(ia => ia.FeatureValues.Select(fbv => featureIndices[fbv.Key]).ToArray()).ToArray(); this.FeatureValue.ObservedValue = instances.Select(ia => ia.FeatureValues.Select(fbv => fbv.Value).ToArray()).ToArray(); this.FeatureCounts.ObservedValue = this.FeatureIndices.ObservedValue.Select(ia => ia.Length).ToArray(); }
public void Test(int numberOfActivities, double[][][] featureValues, Gaussian[] priorWeightMeans, Gamma[] priorWeightPrecisions, out Discrete[][] posteriorActivities) { SetObservedVariables(numberOfActivities, featureValues); weightPriorMeans.ObservedValue = DistributionArrayHelpers.Copy(priorWeightMeans); weightPriorPrecisions.ObservedValue = DistributionArrayHelpers.Copy(priorWeightPrecisions); posteriorActivities = engine.Infer <Discrete[][]>(activities); }
public Bernoulli ComputeEvidence(DataSet dataSet, Marginals priors) { SetObservedVariables( dataSet.Features, DistributionArrayHelpers.Copy(priors.WeightMeans), DistributionArrayHelpers.Copy(priors.WeightPrecisions), dataSet.Labels); engine.Algorithm.DefaultNumberOfIterations = 1; return(engine.Infer <Bernoulli>(evidence)); }
/// <summary> /// Test the specified dataSet and priors. /// </summary> /// <param name="dataSet">Data set.</param> /// <param name="priors">Priors.</param> public Bernoulli[][] Test(DataSet dataSet, Marginals priors) { SetObservedVariables( dataSet.Features, DistributionArrayHelpers.Copy(priors.WeightMeans), DistributionArrayHelpers.Copy(priors.WeightPrecisions)); #if !USE_PRECOMPILED_ALGORITHM var posteriorActivities = engine.Infer <Bernoulli[][]>(activities); #else algorithm.Execute(1); var posteriorActivities = algorithm.Marginal <Bernoulli[][]>(activities.Name); #endif return(posteriorActivities); }
/// <summary> /// Sets the observed values. /// </summary> /// <param name="instances">The instances.</param> /// <param name="featureSet">The feature set.</param> /// <param name="mode">The mode.</param> /// <param name="priors">The priors.</param> /// <exception cref="System.InvalidOperationException">Data is null</exception> public override void SetObservedValues(IList <Inputs.Instance> instances, FeatureSet featureSet, InputMode mode, Priors priors) { if (instances == null) { throw new InvalidOperationException("Data is null"); } this.NumberOfMessages.ObservedValue = instances.Count; this.NumberOfFeatures.ObservedValue = featureSet.FeatureVectorLength; this.NoiseVariance.ObservedValue = priors.NoiseVariance; if (mode == InputMode.Training) { this.RepliedTo.ObservedValue = instances.Select(ia => ia.Label).ToArray(); this.WeightPriors.ObservedValue = DistributionArrayHelpers.DistributionArray(priors.Weights.Values); this.ThresholdPrior.ObservedValue = priors.Threshold; } else { // This is testing, don't set isRepliedTo observed values this.RepliedTo.ClearObservedValue(); this.WeightPriors.ObservedValue = DistributionArrayHelpers.Copy(priors.Weights.Values); this.ThresholdPrior.ObservedValue = priors.Threshold; } // Convert feature values to dense jagged array var featureValues = new double[instances.Count][]; for (int i = 0; i < instances.Count; i++) { featureValues[i] = new double[featureSet.FeatureVectorLength]; foreach (var featureBucketValue in instances[i].FeatureValues) { int index = instances[i].FeatureSet.FeatureBuckets.IndexOf(featureBucketValue.Key); if (index < 0) { throw new InvalidOperationException("Bucket index not found"); } featureValues[i][index] = featureBucketValue.Value; } } this.FeatureValue.ObservedValue = featureValues; }
/// <summary> /// Sets the observed values. /// </summary> /// <param name="instances">The instances.</param> /// <param name="featureSet">The feature set.</param> /// <param name="mode">The mode.</param> /// <param name="communityPriors">The community priors.</param> /// <exception cref="System.InvalidOperationException">Data is null</exception> public override void SetObservedValues(IList <IList <Inputs.Instance> > instances, FeatureSet featureSet, InputMode mode, CommunityPriors communityPriors) { // This is for personalisation training and testing if (instances == null) { throw new InvalidOperationException("Data is null"); } this.NumberOfPeople.ObservedValue = instances.Count; this.NumberOfMessages.ObservedValue = instances.Select(ia => ia.Count).ToArray(); this.NumberOfFeatures.ObservedValue = mode == InputMode.CommunityTraining ? featureSet.SharedFeatureVectorLength : featureSet.FeatureVectorLength; this.NoiseVariance.ObservedValue = communityPriors.NoiseVariance; if (mode == InputMode.CommunityTraining || mode == InputMode.Training) { this.RepliedTo.ObservedValue = instances.Select(inner => inner.Select(ia => ia.Label).ToArray()).ToArray(); } this.WeightMeanPriors.ObservedValue = DistributionArrayHelpers.Copy(communityPriors.WeightMeans.Values); this.WeightPrecisionPriors.ObservedValue = DistributionArrayHelpers.Copy(communityPriors.WeightPrecisions.Values); // If this is community training, we only want shared features Func <KeyValuePair <FeatureBucket, double>, bool> predicate = fbv => mode != InputMode.CommunityTraining || fbv.Key.Feature.IsShared; this.FeatureIndices.ObservedValue = instances.Select( inner => inner.Select( ia => ia.FeatureValues.Where(predicate).Select(fbv => featureSet.FeatureBuckets.IndexOf(fbv.Key)).ToArray()) .ToArray()).ToArray(); this.FeatureValue.ObservedValue = instances.Select( inner => inner.Select(ia => ia.FeatureValues.Where(predicate).Select(fbv => fbv.Value).ToArray()).ToArray()).ToArray(); this.FeatureCounts.ObservedValue = this.FeatureValue.ObservedValue.Select(inner => inner.Select(ia => ia.Length).ToArray()).ToArray(); }
public void Train(int numberOfActivities, double[][][] featureValues, int[][] labels, out Gaussian[][][] posteriorWeights, out Gaussian[] posteriorWeightMeans, out Gamma[] posteriorWeightPrecisions) { SetObservedVariables(numberOfActivities, featureValues); activities.ObservedValue = labels; var priorWeightMeans = new Gaussian[numberOfActivities]; var priorWeightPrecisions = new Gamma[numberOfActivities]; for (int i = 0; i < numberOfActivities; i++) { priorWeightMeans[i] = new Gaussian(0, 1); priorWeightPrecisions[i] = new Gamma(4, 0.5); } weightPriorMeans.ObservedValue = DistributionArrayHelpers.Copy(priorWeightMeans); weightPriorPrecisions.ObservedValue = DistributionArrayHelpers.Copy(priorWeightPrecisions); posteriorWeights = engine.Infer <Gaussian[][][]>(weights); posteriorWeightMeans = engine.Infer <Gaussian[]>(weightMeans); posteriorWeightPrecisions = engine.Infer <Gamma[]>(weightPrecisions); }
/// <summary> /// Train the specified dataSet and priors for the specified number of iterations. /// </summary> /// <param name="dataSet">Data set.</param> /// <param name="priors">Priors.</param> /// <param name="numberOfIterations">Number of iterations.</param> public Marginals Train(DataSet dataSet, Marginals priors, int numberOfIterations = 10) { SetObservedVariables( dataSet.Features, DistributionArrayHelpers.Copy(priors.WeightMeans), DistributionArrayHelpers.Copy(priors.WeightPrecisions), dataSet.Labels); #if !USE_PRECOMPILED_ALGORITHM engine.Algorithm.DefaultNumberOfIterations = numberOfIterations; var posteriorWeights = engine.Infer <Gaussian[][]>(weights); var posteriorWeightMeans = engine.Infer <Gaussian[]>(weightMeans); var posteriorWeightPrecisions = engine.Infer <Gamma[]>(weightPrecisions); #else algorithm.Execute(numberOfIterations); var posteriorWeights = algorithm.Marginal <Gaussian[][]>(weights.Name); var posteriorWeightMeans = algorithm.Marginal <Gaussian[]>(weightMeans.Name); var posteriorWeightPrecisions = algorithm.Marginal <Gamma[]>(weightPrecisions.Name); #endif return(new Marginals { Weights = posteriorWeights, WeightMeans = posteriorWeightMeans, WeightPrecisions = posteriorWeightPrecisions }); }
/// <summary> /// Initializes a new instance of the <see cref="Marginals"/> class. /// </summary> /// <param name="marginals">Marginals.</param> public Marginals(Marginals marginals) { Weights = marginals.Weights == null ? null : marginals.Weights.Select(ia => DistributionArrayHelpers.Copy(ia).ToArray()).ToArray(); WeightMeans = marginals.WeightMeans == null ? null : DistributionArrayHelpers.Copy(marginals.WeightMeans).ToArray(); WeightPrecisions = marginals.WeightPrecisions == null ? null : DistributionArrayHelpers.Copy(marginals.WeightPrecisions).ToArray(); }
/// <summary> /// Initializes a new instance of the <see cref="ToyDataRunner"/> class. /// </summary> /// <param name="trainModel">Train model.</param> /// <param name="testModel">Test model.</param> public static void Run(BinaryModel trainModel, BinaryModel testModel, bool testTransfer, bool testActive, bool testActiveTransfer) { var phase1PriorMean = new Gaussian(4, 1); var phase1PriorPrecision = new Gamma(1, 1); var phase2PriorMean = new Gaussian(4, 1); var phase2PriorPrecision = new Gamma(1, 1); // Generate data for 5 individuals var data = new List <ToyData>(); for (int i = 0; i < 3; i++) { var toy = new ToyData { // NumberOfInstances = 200, // NumberOfHoldoutInstances = i == 0 ? 0 : 1000, NumberOfResidents = 5, NumberOfFeatures = NumberOfFeatures, NumberOfActivities = 2, UseBias = false, TruePriorMean = i == 0 ? phase1PriorMean : phase2PriorMean, TruePriorPrecision = i == 0 ? phase1PriorPrecision : phase2PriorPrecision }; toy.Generate(i == 2 ? NoisyExampleProportion : 0.0, 200); if (i != 0) { // no need for holdout data in training set toy.Generate(0.0, 1000, true); } data.Add(toy); } var priors = new Marginals { WeightMeans = DistributionArrayHelpers.CreateGaussianArray(NumberOfFeatures, 0, 1).ToArray(), WeightPrecisions = DistributionArrayHelpers.CreateGammaArray(NumberOfFeatures, 1, 1).ToArray() }; Console.WriteLine("Data Generated"); // TODO: Create meta-features that allow us to do the first form of transfer learning // Train the community model Console.WriteLine("Training Community Model"); var communityExperiment = new Experiment { TrainModel = trainModel, TestModel = testModel, Name = "Community" }; communityExperiment.RunBatch(data[0].DataSet, priors); // PrintWeightPriors(communityExperiment.Posteriors, trainData.CommunityWeights); // Utils.PlotPosteriors(communityExperiment.Posteriors.Weights, data[0].Weights); // Utils.PlotPosteriors(communityExperiment.Posteriors.WeightMeans, communityExperiment.Posteriors.WeightPrecisions, null, "Community weights", "Feature"); // return; if (testTransfer) { // Do online learning // Console.WriteLine("Testing Online Model"); var onlineExperiment = new Experiment { TrainModel = trainModel, TestModel = testModel, Name = "Online" }; onlineExperiment.RunOnline(data[1].DataSet, data[1].HoldoutSet, priors); // Do transfer learning // Console.WriteLine("Testing Community Model"); var personalisationExperiment = new Experiment { TrainModel = trainModel, TestModel = testModel, Name = "Community" }; personalisationExperiment.RunOnline(data[1].DataSet, data[1].HoldoutSet, communityExperiment.Posteriors); // Plot cumulative metrics Utils.PlotCumulativeMetrics(new[] { onlineExperiment, personalisationExperiment }, "Toy Transfer"); } else { Console.WriteLine("Skipping Transfer Learning"); } // ACTIVE MODEL if (testActive) { ActiveTransfer(trainModel, testModel, data, "Toy Active", priors); } else { Console.WriteLine("Skipping Active Learning"); } if (testActiveTransfer) { Console.WriteLine("Note that the transfer learning is very effective here, so the active learning doesn't add much"); ActiveTransfer(trainModel, testModel, data, "Toy Active Transfer", communityExperiment.Posteriors); } else { Console.WriteLine("Skipping Active Transfer Learning"); } // Now create different costs for acquiring labels - want to demonstrate that we choose from all 3 possible labels }
/// <summary> /// Initializes a new instance of the <see cref="ActiveTransfer.ToyDataRunner"/> class. /// </summary> /// <param name="trainModel">Train model.</param> /// <param name="testModel">Test model.</param> public void Run(BinaryModel trainModel, BinaryModel testModel, BinaryModel evidenceModel, bool testVOI, bool testActiveEvidence) { const int NumberOfResidents = 7; const double KeepProportion = 1.0; var selectedFeatures = new HashSet <int>(Enumerable.Range(0, 48)); var ted = Source.GetDataSet(Enumerable.Range(1, 14), AddBias, selectedFeatures, KeepProportion); var trd = Target.GetDataSet(Enumerable.Range(1, 25), AddBias, selectedFeatures, KeepProportion); // var ted = Source.GetDataSet( Enumerable.Range( 1, 1 ), AddBias, selectedFeatures, KeepProportion ); // var trd = Target.GetDataSet( Enumerable.Range( 1, 20 ), AddBias, selectedFeatures, KeepProportion ); // var hod = Target.GetDataSet( Enumerable.Range( 1 + NumberOfResidents * 1, NumberOfResidents ) ); DataSet testSet; DataSet holdoutSet; ted.SplitTrainTest(0.5, out testSet, out holdoutSet); var NumFeatures = trd.Features.First().First().Count(); var trainData = new ToyData { NumberOfResidents = trd.NumberOfResidents, NumberOfFeatures = NumFeatures, NumberOfActivities = 2, UseBias = false, DataSet = trd }; var testData = new ToyData { NumberOfResidents = NumberOfResidents, NumberOfFeatures = NumFeatures, NumberOfActivities = 2, UseBias = false, DataSet = testSet, HoldoutSet = holdoutSet }; var priors = new Marginals { WeightMeans = DistributionArrayHelpers.CreateGaussianArray(trainData.NumberOfFeatures, 0.0, 1.0).ToArray(), WeightPrecisions = DistributionArrayHelpers.CreateGammaArray(trainData.NumberOfFeatures, 1.0, 1.0).ToArray() }; // TODO: Create meta-features that allow us to do the first form of transfer learning // Train the community model var communityExperiment = new Experiment { TrainModel = trainModel, TestModel = testModel, EvidenceModel = evidenceModel, Name = "Community" }; communityExperiment.RunBatch(trainData.DataSet, priors); // communityExperiment.Posteriors.WeightPrecisions = priors.WeightPrecisions; // if (false) // { // Utils.PlotPosteriors(communityExperiment.Posteriors.WeightMeans, communityExperiment.Posteriors.WeightPrecisions, null, "Community weights", "Feature", ShowPlots); // Utils.PlotPosteriors(communityExperiment.Posteriors.WeightMeans, communityExperiment.Posteriors.WeightPrecisions, null, "Community weights (prior precision)", "Feature", ShowPlots); // } // Print top features // var topWeights = communityExperiment.Posteriors.WeightMeans.Zip(communityExperiment.Posteriors.WeightPrecisions, (m, p) => new { m, p }).Select((ia, i) => new { ia, i }) // .OrderByDescending(x => Math.Abs(x.ia.m.GetMean())).ToList(); // Console.WriteLine("Top 20 weights:\n {0}", string.Join("\n", topWeights.Take(20).Select(pair => string.Format("{0}: {1}", pair.i, new Gaussian(pair.ia.m.GetMean(), pair.ia.p.GetMean()))))); // //communityExperiment.Posteriors.WeightPrecisions = DistributionArrayHelpers.Copy( priors.WeightPrecisions ).ToArray(); var sourcePosteriors = new Marginals { WeightMeans = communityExperiment.Posteriors.WeightMeans, WeightPrecisions = priors.WeightPrecisions, //communityExperiment.Posteriors.WeightMeans, Weights = null }; // Select half the features /* * trainData.DataSet.Features = trainData.DataSet.Features.Select( * ia => ia.Select( * ib => topWeights.Take(topWeights.Count / 2).Select(pair => ib[pair.i]).ToArray()) * .ToArray()) * .ToArray(); * * // Retrain using these weights */ // if (false) // { // // Do online learning // var onlineExperiment = new Experiment // { // TrainModel = trainModel, // TestModel = testModel, // Name = "Online" // }; // onlineExperiment.RunOnline(testData.DataSet, testData.HoldoutSet, priors); // // Do transfer learning // var personalisationExperiment = new Experiment // { // TrainModel = trainModel, // TestModel = testModel, // Name = "Community" // }; // personalisationExperiment.RunOnline(testData.DataSet, testData.HoldoutSet, communityExperiment.Posteriors); // // Plot cumulative metrics // Utils.PlotCumulativeMetrics(new [] { onlineExperiment, personalisationExperiment }, "Active", ShowPlots); // } // ACTIVE MODEL foreach (var doTransfer in new[] { false, true }) { var experiments = new List <Experiment>(); var learners = CreateLearners(trainModel, testModel, evidenceModel, testData, testVOI, testActiveEvidence); foreach (var learner in learners) { Console.WriteLine("Testing Active{0} Learning ({1})", doTransfer ? " Real Transfer" : "Real Online", learner.Key); var experiment = new Experiment { TrainModel = trainModel, TestModel = testModel, Name = learner.Key, ActiveLearners = learner.Value }; experiment.RunActive(testData.DataSet, testData.HoldoutSet, ActiveSteps, doTransfer ? sourcePosteriors : priors); experiments.Add(experiment); if (false) { Utils.PlotPosteriors( experiment.IndividualPosteriors[0].WeightMeans, experiment.IndividualPosteriors[0].WeightPrecisions, null, "Posterior weights for " + learner.Key + " " + (doTransfer ? " (transfer)" : ""), "Feature", ShowPlots); } } Utils.PlotHoldoutMetrics(experiments, doTransfer ? "Real Active Transfer" : "Real Active", "", ShowPlots); } }