/// <summary>
        /// Simplify learning of examples with action dependent features.
        /// </summary>
        /// <typeparam name="TExample">The type of the user example.</typeparam>
        /// <typeparam name="TActionDependentFeature">The type of the user action dependent features.</typeparam>
        /// <param name="vw">The vw instance.</param>
        /// <param name="serializer">The serializer for <typeparamref name="TExample"/>.</param>
        /// <param name="actionDependentFeatureSerializer">The serializer for <typeparamref name="TActionDependentFeature"/>.</param>
        /// <param name="example">The user example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <param name="index">The index of action dependent feature to label.</param>
        /// <param name="label">The label for the selected action dependent feature.</param>
        /// <returns>An ranked subset of predicted actions.</returns>
        public static TActionDependentFeature[] LearnAndPredict <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IEnumerable <TActionDependentFeature> actionDependentFeatures,
            int index,
            ILabel label)
        {
            Contract.Requires(vw != null);
            Contract.Requires(serializer != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);
            Contract.Requires(index >= 0);
            Contract.Requires(label != null);

#if DEBUG
            // only in debug, since it's a hot path
            if (actionDependentFeatureSerializer.CachesExamples)
            {
                throw new NotSupportedException("Cached examples cannot be used for learning");
            }
#endif

            var multiLabelPredictions = LearnAndPredictIndex(vw, serializer, actionDependentFeatureSerializer, example, actionDependentFeatures, index, label);
            return(actionDependentFeatures.Subset(multiLabelPredictions));
        }
        /// <summary>
        /// Simplify learning of examples with action dependent features.
        /// </summary>
        public static void Learn <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IReadOnlyCollection <TActionDependentFeature> actionDependentFeatures,
            int index,
            ILabel label)
        {
            Contract.Requires(vw != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);
            Contract.Requires(index >= 0);
            Contract.Requires(label != null);

            Execute(
                vw,
                serializer,
                actionDependentFeatureSerializer,
                example,
                actionDependentFeatures,
                (examples, _, __) =>
            {
                foreach (var ex in examples)
                {
                    vw.Learn(ex);
                }
            },
                index,
                label);
        }
예제 #3
0
        public VowpalWabbit(string arguments, VowpalWabbitSerializerSettings settings = null)
            : base(arguments)
        {
            var visitor = new VowpalWabbitInterfaceVisitor(this);

            this.serializer = VowpalWabbitSerializerFactory.CreateSerializer <TExample>(visitor, settings);
        }
예제 #4
0
        public VowpalWabbit(VowpalWabbitModel model, VowpalWabbitSerializerSettings settings = null)
            : base(model)
        {
            var visitor = new VowpalWabbitInterfaceVisitor(this);

            this.serializer = VowpalWabbitSerializerFactory.CreateSerializer <TExample>(visitor, settings);
        }
예제 #5
0
        internal VowpalWabbitExampleValidator(VowpalWabbitSettings settings)
        {
            this.vw         = new VowpalWabbit <TExample>(settings.ShallowCopy(enableStringExampleGeneration: true));
            this.serializer = this.vw.Serializer.Func(this.vw.Native);

            this.vwNative         = new VowpalWabbit <TExample>(settings);
            this.serializerNative = this.vwNative.Serializer.Func(this.vwNative.Native);

            this.factorySerializer = VowpalWabbitSerializerFactory.CreateSerializer <TExample>(settings.ShallowCopy(enableStringExampleGeneration: true)).Create(this.vw.Native);
        }
예제 #6
0
        /// <summary>
        /// Initializes a new instance of the <see cref="VowpalWabbit{TExample}"/> class.
        /// </summary>
        /// <param name="vw">The native instance to wrap.</param>
        /// <remarks>This instance takes ownership of <paramref name="vw"/> instance and disposes it.</remarks>
        public VowpalWabbit(VowpalWabbit vw)
        {
            if (vw == null)
            {
                throw new ArgumentNullException("vw");
            }
            Contract.Ensures(this.serializer != null);
            Contract.EndContractBlock();

            this.vw         = vw;
            this.serializer = VowpalWabbitSerializerFactory.CreateSerializer <TExample>(vw.Settings);

            // have a 2nd member to throw NullReferenceException in release instead of silently producing wrong results.
            this.learnSerializer = this.serializer.CachesExamples ? null : this.serializer;
        }
예제 #7
0
        protected override void Dispose(bool isDiposing)
        {
            if (isDiposing)
            {
                if (this.serializer != null)
                {
                    // free cached examples
                    this.serializer.Dispose();
                    this.serializer = null;
                }
            }

            // don't dispose VW before we can dispose all cached examples
            base.Dispose(isDiposing);
        }
예제 #8
0
        private void Initialize(VowpalWabbitSerializerSettings settings)
        {
            var visitor = new VowpalWabbitInterfaceVisitor(this);

            this.actionDependentFeatureSerializer = VowpalWabbitSerializerFactory.CreateSerializer <TActionDependentFeature>(visitor, settings);

            if (this.actionDependentFeatureSerializer == null)
            {
                throw new ArgumentException(typeof(TActionDependentFeature) + " must have a least a single [Feature] defined.");
            }

            using (var exBuilder = new VowpalWabbitExampleBuilder(this))
            {
                this.emptyExample = exBuilder.CreateExample();
            }
        }
예제 #9
0
 /// <summary>
 /// Cleanup.
 /// </summary>
 /// <param name="isDiposing">See IDiposable pattern.</param>
 protected override void Dispose(bool isDiposing)
 {
     if (isDiposing)
     {
         if (this.actionDependentFeatureSerializer != null)
         {
             this.actionDependentFeatureSerializer.Dispose();
             this.actionDependentFeatureSerializer = null;
         }
         if (this.emptyExample != null)
         {
             this.emptyExample.Dispose();
             this.emptyExample = null;
         }
     }
     base.Dispose(isDiposing);
 }
        /// <summary>
        /// Simplify prediction of examples with action dependent features.
        /// </summary>
        /// <typeparam name="TExample">The type of the user example.</typeparam>
        /// <typeparam name="TActionDependentFeature">The type of the user action dependent features.</typeparam>
        /// <param name="vw">The vw instance.</param>
        /// <param name="serializer">The serializer for <typeparamref name="TExample"/>.</param>
        /// <param name="actionDependentFeatureSerializer">The serializer for <typeparamref name="TActionDependentFeature"/>.</param>
        /// <param name="example">The user example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <returns>An ranked subset of predicted actions.</returns>
        public static TActionDependentFeature[] Predict <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IEnumerable <TActionDependentFeature> actionDependentFeatures)
        {
            Contract.Requires(vw != null);
            Contract.Requires(serializer != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);

            var multiLabelPredictions = PredictIndex(vw, serializer, actionDependentFeatureSerializer, example, actionDependentFeatures);

            return(actionDependentFeatures.Subset(multiLabelPredictions));
        }
예제 #11
0
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.serializer != null)
                {
                    this.serializer.Dispose();
                    this.serializer = null;
                }

                if (this.vw != null)
                {
                    this.vw.Dispose();
                    this.vw = null;
                }
            }
        }
        /// <summary>
        /// Simplify learning of examples with action dependent features.
        /// </summary>
        /// <typeparam name="TExample">The type of the user example.</typeparam>
        /// <typeparam name="TActionDependentFeature">The type of the user action dependent features.</typeparam>
        /// <param name="vw">The vw instance.</param>
        /// <param name="serializer">The serializer for <typeparamref name="TExample"/>.</param>
        /// <param name="actionDependentFeatureSerializer">The serializer for <typeparamref name="TActionDependentFeature"/>.</param>
        /// <param name="example">The user example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <param name="index">The index of action dependent feature to label.</param>
        /// <param name="label">The label for the selected action dependent feature.</param>
        /// <returns>An ranked subset of predicted actions.</returns>
        public static ActionDependentFeature <TActionDependentFeature>[] LearnAndPredict <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IReadOnlyCollection <TActionDependentFeature> actionDependentFeatures,
            int index,
            ILabel label)
        {
            Contract.Requires(vw != null);
            Contract.Requires(serializer != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);
            Contract.Requires(index >= 0);
            Contract.Requires(label != null);

            ActionDependentFeature <TActionDependentFeature>[] predictions = null;

            Execute(
                vw,
                serializer,
                actionDependentFeatureSerializer,
                example,
                actionDependentFeatures,
                (examples, validActionDependentFeatures, emptyActionDependentFeatures) =>
            {
                foreach (var ex in examples)
                {
                    vw.Learn(ex);
                }

                predictions = VowpalWabbitMultiLine.GetPrediction(vw, examples, validActionDependentFeatures, emptyActionDependentFeatures);
            },
                index,
                label);

            // default to the input list
            return(predictions ?? actionDependentFeatures.Select((o, i) => new ActionDependentFeature <TActionDependentFeature>(i, o)).ToArray());
        }
예제 #13
0
        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                if (this.vw != null)
                {
                    this.vw.Dispose();
                    this.vw = null;
                }

                if (this.vwNative != null)
                {
                    this.vwNative.Dispose();
                    this.vwNative = null;
                }

                if (this.factorySerializer != null)
                {
                    this.factorySerializer.Dispose();
                    this.factorySerializer = null;
                }
            }
        }
        /// <summary>
        /// Simplify learning of examples with action dependent features.
        /// </summary>
        /// <typeparam name="TExample">The type of the user example.</typeparam>
        /// <typeparam name="TActionDependentFeature">The type of the user action dependent features.</typeparam>
        /// <param name="vw">The vw instance.</param>
        /// <param name="serializer">The serializer for <typeparamref name="TExample"/>.</param>
        /// <param name="actionDependentFeatureSerializer">The serializer for <typeparamref name="TActionDependentFeature"/>.</param>
        /// <param name="example">The user example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <param name="index">The index of action dependent feature to label.</param>
        /// <param name="label">The label for the selected action dependent feature.</param>
        /// <returns>An ranked subset of predicted action indexes.</returns>
        public static int[] LearnAndPredictIndex <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IEnumerable <TActionDependentFeature> actionDependentFeatures,
            int index,
            ILabel label)
        {
            Contract.Requires(vw != null);
            Contract.Requires(serializer != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);
            Contract.Requires(index >= 0);
            Contract.Requires(label != null);

#if DEBUG
            // only in debug, since it's a hot path
            if (actionDependentFeatureSerializer.CachesExamples)
            {
                throw new NotSupportedException("Cached examples cannot be used for learning");
            }
#endif

            var examples = new List <VowpalWabbitExample>();

            try
            {
                // contains prediction results
                var sharedExample = serializer.Serialize(vw, example);
                // check if we have shared features
                if (sharedExample != null)
                {
                    examples.Add(sharedExample);
                    vw.Learn(sharedExample);
                }

                // leave as loop (vs. linq) so if the serializer throws an exception, anything allocated so far can be free'd
                var i = 0;
                foreach (var actionDependentFeature in actionDependentFeatures)
                {
                    var adfExample = actionDependentFeatureSerializer.Serialize(vw, actionDependentFeature, i == index ? label : null);
                    Contract.Assert(adfExample != null);

                    examples.Add(adfExample);

                    vw.Learn(adfExample);
                    i++;
                }

                // signal we're finished using an empty example
                var empty = vw.GetOrCreateEmptyExample();
                examples.Add(empty);
                vw.Learn(empty);

                // Nasty workaround. Since the prediction result is stored in the first example
                // and we'll have to get an actual VowpalWabbitExampt
                var firstExample = examples.FirstOrDefault();
                if (firstExample == null)
                {
                    return(null);
                }

                return(firstExample.GetPrediction(vw, VowpalWabbitPredictionType.Multilabel));
            }
            finally
            {
                // dispose examples
                // Note: must not dispose examples before final example
                // as the learning algorithm (such as cbf) keeps a reference
                // to the example
                foreach (var e in examples)
                {
                    e.Dispose();
                }
            }
        }
        /// <summary>
        /// Serializes the specifed example to VW native string format.
        /// </summary>
        /// <typeparam name="TExample">The user example type.</typeparam>
        /// <typeparam name="TActionDependentFeature">The user action dependent feature type.</typeparam>
        /// <param name="vw">The VW instance.</param>
        /// <param name="example">The shared example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <param name="index">The optional index of the label example.</param>
        /// <param name="label">The optional label.</param>
        /// <param name="serializer">The example serializer.</param>
        /// <param name="actionDependentFeatureSerializer">The action dependent feature serializer.</param>
        /// <param name="dictionary">Dictionary used for dictify operation.</param>
        /// <param name="fastDictionary">Dictionary used for dictify operation.</param>
        /// <returns>The string serialized example.</returns>
        public static string SerializeToString <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            TExample example,
            IReadOnlyCollection <TActionDependentFeature> actionDependentFeatures,
            int?index    = null,
            ILabel label = null,
            VowpalWabbitSerializer <TExample> serializer = null,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer = null,
            Dictionary <string, string> dictionary     = null,
            Dictionary <object, string> fastDictionary = null)
        {
            if (vw == null)
            {
                throw new ArgumentNullException("vw");
            }

            if (serializer == null)
            {
                serializer = VowpalWabbitSerializerFactory.CreateSerializer <TExample>(new VowpalWabbitSettings(enableStringExampleGeneration: true)).Create(vw);
            }
            else if (!serializer.EnableStringExampleGeneration)
            {
                throw new ArgumentException("Serializer must be compiled using EnableStringExampleGeneration = true");
            }

            if (actionDependentFeatureSerializer == null)
            {
                actionDependentFeatureSerializer = VowpalWabbitSerializerFactory.CreateSerializer <TActionDependentFeature>(new VowpalWabbitSettings(enableStringExampleGeneration: true)).Create(vw);
            }
            else if (!actionDependentFeatureSerializer.EnableStringExampleGeneration)
            {
                throw new ArgumentException("Action dependent serializer must be compiled using EnableStringExampleGeneration = true");
            }

            var stringExample = new StringBuilder();

            var sharedExample = serializer.SerializeToString(example, SharedLabel.Instance, dictionary, fastDictionary);

            // check if we have shared features
            if (!string.IsNullOrWhiteSpace(sharedExample))
            {
                stringExample.AppendLine(sharedExample);
            }

            var i = 0;

            foreach (var actionDependentFeature in actionDependentFeatures)
            {
                var adfExample = actionDependentFeatureSerializer.SerializeToString(actionDependentFeature,
                                                                                    index != null && i == index ? label : null, dictionary, fastDictionary);

                if (!string.IsNullOrWhiteSpace(adfExample))
                {
                    stringExample.AppendLine(adfExample);
                }

                i++;
            }

            return(stringExample.ToString());
        }
        /// <summary>
        /// Simplify prediction of examples with action dependent features.
        /// </summary>
        /// <typeparam name="TExample">The type of the user example.</typeparam>
        /// <typeparam name="TActionDependentFeature">The type of the user action dependent features.</typeparam>
        /// <param name="vw">The vw instance.</param>
        /// <param name="serializer">The serializer for <typeparamref name="TExample"/>.</param>
        /// <param name="actionDependentFeatureSerializer">The serializer for <typeparamref name="TActionDependentFeature"/>.</param>
        /// <param name="example">The user example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <returns>An ranked subset of predicted action indexes.</returns>
        public static int[] PredictIndex <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IEnumerable <TActionDependentFeature> actionDependentFeatures)
        {
            Contract.Requires(vw != null);
            Contract.Requires(serializer != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);

            // shared |userlda :.1 |che a:.1
            // `doc1 |lda :.1 :.2 [1]
            // `doc2 |lda :.2 :.3 [2]
            // <new line>
            var examples = new List <VowpalWabbitExample>();

            try
            {
                // contains prediction results
                var sharedExample = serializer.Serialize(vw, example);
                // check if we have shared features
                if (sharedExample != null)
                {
                    examples.Add(sharedExample);
                    vw.Predict(sharedExample);
                }

                // leave as loop (vs. linq) so if the serializer throws an exception, anything allocated so far can be free'd
                foreach (var actionDependentFeature in actionDependentFeatures)
                {
                    var adfExample = actionDependentFeatureSerializer.Serialize(vw, actionDependentFeature);
                    Contract.Assert(adfExample != null);

                    examples.Add(adfExample);

                    vw.Predict(adfExample);
                }

                // signal we're finished using an empty example
                var empty = vw.GetOrCreateEmptyExample();
                examples.Add(empty);
                vw.Predict(empty);

                // Nasty workaround. Since the prediction result is stored in the first example
                // and we'll have to get an actual VowpalWabbitExampt
                var firstExample = examples.FirstOrDefault();
                if (firstExample == null)
                {
                    return(null);
                }

                return(firstExample.GetPrediction(vw, VowpalWabbitPredictionType.Multilabel));
            }
            finally
            {
                // dispose examples
                // Note: must not dispose examples before final example
                // as the learning algorithm (such as cbf) keeps a reference
                // to the example
                foreach (var e in examples)
                {
                    e.Dispose();
                }
            }
        }
        /// <summary>
        /// Simplify learning of examples with action dependent features.
        /// </summary>
        /// <typeparam name="TExample">User example type.</typeparam>
        /// <typeparam name="TActionDependentFeature">Action dependent feature type.</typeparam>
        /// <param name="vw">The VowpalWabbit instances.</param>
        /// <param name="serializer">The example serializer.</param>
        /// <param name="actionDependentFeatureSerializer">The action dependent feature serializer.</param>
        /// <param name="example">The example.</param>
        /// <param name="actionDependentFeatures">The action dependent features.</param>
        /// <param name="predictOrLearn">An action executed once the set of valid examples is determined. </param>
        /// <param name="index">The optional index of the action dependent feature this label belongs too.</param>
        /// <param name="label">The optional label to be used for learning or evaluation.</param>
        public static void Execute <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IReadOnlyCollection <TActionDependentFeature> actionDependentFeatures,
            LearnOrPredictAction <TActionDependentFeature> predictOrLearn,
            int?index    = null,
            ILabel label = null)
        {
            Contract.Requires(vw != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);

            var examples      = new List <VowpalWabbitExample>(actionDependentFeatures.Count + 1);
            var validExamples = new List <VowpalWabbitExample>(actionDependentFeatures.Count + 1);
            var validActionDependentFeatures = new List <ActionDependentFeature <TActionDependentFeature> >(actionDependentFeatures.Count + 1);
            var emptyActionDependentFeatures = new List <ActionDependentFeature <TActionDependentFeature> >(actionDependentFeatures.Count + 1);

            try
            {
                // contains prediction results
                if (serializer != null)
                {
                    var sharedExample = serializer.Serialize(example, SharedLabel.Instance);
                    // check if we have shared features
                    if (sharedExample != null)
                    {
                        examples.Add(sharedExample);

                        if (!sharedExample.IsNewLine)
                        {
                            validExamples.Add(sharedExample);
                        }
                    }
                }

                var i = 0;
                foreach (var actionDependentFeature in actionDependentFeatures)
                {
                    var adfExample = actionDependentFeatureSerializer.Serialize(actionDependentFeature,
                                                                                index != null && i == index ? label : null);
                    Contract.Assert(adfExample != null);

                    examples.Add(adfExample);

                    if (!adfExample.IsNewLine)
                    {
                        validExamples.Add(adfExample);
                        validActionDependentFeatures.Add(new ActionDependentFeature <TActionDependentFeature>(i, actionDependentFeature));
                    }
                    else
                    {
                        emptyActionDependentFeatures.Add(new ActionDependentFeature <TActionDependentFeature>(i, actionDependentFeature));
                    }

                    i++;
                }

                if (validActionDependentFeatures.Count == 0)
                {
                    return;
                }

                // signal we're finished using an empty example
                var empty = vw.GetOrCreateEmptyExample();
                examples.Add(empty);
                validExamples.Add(empty);

                predictOrLearn(validExamples, validActionDependentFeatures, emptyActionDependentFeatures);
            }
            finally
            {
                // dispose examples
                // Note: must not dispose examples before final example
                // as the learning algorithm (such as cbf) keeps a reference
                // to the example
                foreach (var e in examples)
                {
                    e.Dispose();
                }
            }
        }
        /// <summary>
        /// Simplify learning of examples with action dependent features.
        /// </summary>
        public static void Learn <TExample, TActionDependentFeature>(
            VowpalWabbit vw,
            VowpalWabbitSerializer <TExample> serializer,
            VowpalWabbitSerializer <TActionDependentFeature> actionDependentFeatureSerializer,
            TExample example,
            IEnumerable <TActionDependentFeature> actionDependentFeatures,
            int index,
            ILabel label)
        {
            Contract.Requires(vw != null);
            Contract.Requires(serializer != null);
            Contract.Requires(actionDependentFeatureSerializer != null);
            Contract.Requires(example != null);
            Contract.Requires(actionDependentFeatures != null);
            Contract.Requires(index >= 0);
            Contract.Requires(label != null);

#if DEBUG
            // only in debug, since it's a hot path
            if (actionDependentFeatureSerializer.CachesExamples)
            {
                throw new NotSupportedException("Cached examples cannot be used for learning");
            }
#endif

            var examples = new List <VowpalWabbitExample>();

            try
            {
                // contains prediction results
                var sharedExample = serializer.Serialize(vw, example, SharedLabel.Instance);
                // check if we have shared features
                if (sharedExample != null)
                {
                    examples.Add(sharedExample);
                    vw.Learn(sharedExample);
                }

                var i = 0;
                foreach (var actionDependentFeature in actionDependentFeatures)
                {
                    var adfExample = actionDependentFeatureSerializer.Serialize(vw, actionDependentFeature, i == index ? label : null);
                    Contract.Assert(adfExample != null);

                    examples.Add(adfExample);

                    vw.Learn(adfExample);

                    i++;
                }

                // signal we're finished using an empty example
                var empty = vw.GetOrCreateEmptyExample();
                examples.Add(empty);
                vw.Learn(empty);

                // Dump input file for command line learning
                //File.AppendAllLines(@"c:\temp\msn.txt",
                //    examples.OfType<VowpalWabbitDebugExample>()
                //        .Select(e => e.VowpalWabbitString)
                //        .Union(new[] { "" }));
            }
            finally
            {
                // dispose examples
                // Note: must not dispose examples before final example
                // as the learning algorithm (such as cbf) keeps a reference
                // to the example
                foreach (var e in examples)
                {
                    e.Dispose();
                }
            }
        }