public VowpalWabbitMultiExampleSerializerCompilerImpl(VowpalWabbitSettings settings, Schema schema, FeatureExpression multiFeature) { Contract.Requires(settings != null); Contract.Requires(schema != null); Contract.Requires(multiFeature != null); var nonMultiFeatures = schema.Features.Where(fe => fe != multiFeature).ToList(); this.sharedSerializerCompiler = nonMultiFeatures.Count == 0 ? null : new VowpalWabbitSingleExampleSerializerCompiler <TExample>( new Schema { Features = nonMultiFeatures }, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); this.adfSerializerComputer = new VowpalWabbitSingleExampleSerializerCompiler <TActionDependentFeature>( AnnotationJsonInspector.CreateSchema(typeof(TActionDependentFeature), settings.PropertyConfiguration), settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); var exampleParameter = Expression.Parameter(typeof(TExample), "example"); // CODE condition1 && condition2 && condition3 ... var condition = multiFeature.ValueValidExpressionFactories .Skip(1) .Aggregate( multiFeature.ValueValidExpressionFactories.First()(exampleParameter), (cond, factory) => Expression.AndAlso(cond, factory(exampleParameter))); var multiExpression = multiFeature.ValueExpressionFactory(exampleParameter); // CODE example => (IEnumerable<TActionDependentFeature>)(example._multi != null ? example._multi : null) var expr = Expression.Lambda <Func <TExample, IEnumerable <TActionDependentFeature> > >( Expression.Condition( condition, multiExpression, Expression.Constant(null, multiExpression.Type), typeof(IEnumerable <TActionDependentFeature>)), exampleParameter); this.adfAccessor = (Func <TExample, IEnumerable <TActionDependentFeature> >)expr.CompileToFunc(); }
/// <summary> /// Creates a serializer for the given type and settings. /// </summary> /// <typeparam name="TExample">The user type to serialize.</typeparam> /// <param name="settings"></param> /// <returns></returns> public static IVowpalWabbitSerializerCompiler <TExample> CreateSerializer <TExample>(VowpalWabbitSettings settings = null) { Schema schema = null; Type cacheKey = null; if (settings != null && settings.Schema != null) { schema = settings.Schema; } else { // only cache non-string generating serializer if (!settings.EnableStringExampleGeneration) { cacheKey = typeof(TExample); object serializer; if (SerializerCache.TryGetValue(cacheKey, out serializer)) { return((IVowpalWabbitSerializerCompiler <TExample>)serializer); } } if (settings.FeatureDiscovery == VowpalWabbitFeatureDiscovery.Json) { schema = AnnotationJsonInspector.CreateSchema(typeof(TExample), settings.PropertyConfiguration); var multiExampleSerializerCompiler = VowpalWabbitMultiExampleSerializerCompiler.TryCreate <TExample>(settings, schema); if (multiExampleSerializerCompiler != null) { return(multiExampleSerializerCompiler); } } else { // TODO: enhance caching based on feature list & featurizer set // if no feature mapping is provided, use [Feature] annotation on provided type. Func <PropertyInfo, FeatureAttribute, bool> propertyPredicate = null; Func <PropertyInfo, LabelAttribute, bool> labelPredicate = null; switch (settings.FeatureDiscovery) { case VowpalWabbitFeatureDiscovery.Default: propertyPredicate = (_, attr) => attr != null; labelPredicate = (_, attr) => attr != null; break; case VowpalWabbitFeatureDiscovery.All: propertyPredicate = (_, __) => true; labelPredicate = (_, __) => true; break; } schema = AnnotationInspector.CreateSchema(typeof(TExample), propertyPredicate, labelPredicate); } } // need at least a single feature to do something sensible if (schema == null || schema.Features.Count == 0) { return(null); } var newSerializer = new VowpalWabbitSingleExampleSerializerCompiler <TExample>( schema, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); if (cacheKey != null) { SerializerCache[cacheKey] = newSerializer; } return(newSerializer); }
/// <summary> /// Creates a serializer for the given type and settings. /// </summary> /// <typeparam name="TExample">The user type to serialize.</typeparam> /// <param name="settings"></param> /// <returns></returns> public static VowpalWabbitSerializerCompiled <TExample> CreateSerializer <TExample>(VowpalWabbitSettings settings = null) { List <FeatureExpression> allFeatures = null; Type cacheKey = null; if (settings != null && settings.AllFeatures != null) { allFeatures = settings.AllFeatures; } else { // only cache non-string generating serializer if (!settings.EnableStringExampleGeneration) { cacheKey = typeof(TExample); object serializer; if (SerializerCache.TryGetValue(cacheKey, out serializer)) { return((VowpalWabbitSerializerCompiled <TExample>)serializer); } } if (settings.FeatureDiscovery == VowpalWabbitFeatureDiscovery.Json) { allFeatures = AnnotationJsonInspector.ExtractFeatures(typeof(TExample)); } else { // TODO: enhance caching based on feature list & featurizer set // if no feature mapping is provided, use [Feature] annotation on provided type. Func <PropertyInfo, FeatureAttribute, bool> propertyPredicate = null; switch (settings.FeatureDiscovery) { case VowpalWabbitFeatureDiscovery.Default: propertyPredicate = (_, attr) => attr != null; break; case VowpalWabbitFeatureDiscovery.All: propertyPredicate = (_, __) => true; break; } allFeatures = AnnotationInspector.ExtractFeatures(typeof(TExample), propertyPredicate); } } // need at least a single feature to do something sensible if (allFeatures == null || allFeatures.Count == 0) { return(null); } var newSerializer = new VowpalWabbitSerializerCompiled <TExample>( allFeatures, settings == null ? null : settings.CustomFeaturizer, !settings.EnableStringExampleGeneration); if (cacheKey != null) { SerializerCache[cacheKey] = newSerializer; } return(newSerializer); }