Utility class analyzing compile-time JsonPropertyAttribute annotation.
            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();
            }
Beispiel #2
0
        /// <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);
        }
Beispiel #3
0
        /// <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);
        }