Пример #1
0
        /// <summary>
        /// Sample code simulating a news recommendation scenario. In this simple example,
        /// the rendering server has to pick 1 out of 4 news topics to show to users (e.g. as featured article).
        /// </summary>
        /// <remarks>
        /// NOTE: For this sample to work, the proper settings must be set at deployment time:
        /// Vowpal Wabbit Switches = --cb_explore_adf --epsilon 0.2 --cb_type dr
        /// </remarks>
        public static async Task NewsRecommendation()
        {
            if (String.IsNullOrWhiteSpace(SettingsBlobUri))
            {
                Console.WriteLine("Please specify a valid settings URL.");
                return;
            }

            // Create configuration for the decision service
            var serviceConfig = new DecisionServiceConfiguration(settingsBlobUri: SettingsBlobUri);

            // Enable development mode to easily debug / diagnose data flow and system properties
            // This should be turned off in production deployment
            serviceConfig.DevelopmentMode = true;

            using (var service = DecisionService.Create <UserContextADF>(serviceConfig))
            {
                var random             = new Random();
                int user               = 0;                 // user id
                int maxDecisionHistory = 100;               // max number of past decisions to record
                var correctDecisions   = new Queue <int>(); // keeps track of past decisions

                Console.WriteLine("Press Ctrl + C at any time to cancel the process.");

                // Each topic has its own set of features
                var topicFeatures = Enumerable.Range(1, 10)
                                    .Select(_ => new TopicFeature
                {
                    Features = Enumerable.Range(1, 10).Select(f => (float)random.NextDouble()).ToArray()
                })
                                    .ToArray();

                while (true)
                {
                    user++;

                    string uniqueKey = Guid.NewGuid().ToString();

                    var userContext = new UserContextADF
                    {
                        Gender        = random.NextDouble() > 0.5 ? "male" : "female",
                        TopicFeatures = topicFeatures.Take(random.Next(5, topicFeatures.Length)).ToArray()
                    };
                    int[] topicRanking = await service.ChooseRankingAsync(uniqueKey, userContext);

                    int topicId = topicRanking[0];

                    // Display the news topic chosen by exploration process.
                    Console.WriteLine("Topic {0} was chosen for user {1}.", topicId, user + 1);

                    // Report {0,1} reward as a simple float.
                    // In a real scenario, one could associated a reward of 1 if user
                    // clicks on the article and 0 otherwise.
                    float reward = 0;
                    if (userContext.Gender == "male" && topicId == 3)
                    {
                        reward = 1;
                    }
                    else if (userContext.Gender == "female" && topicId == 8)
                    {
                        reward = 1;
                    }
                    service.ReportReward(reward, uniqueKey);

                    correctDecisions.Enqueue((int)reward);
                    if (correctDecisions.Count == maxDecisionHistory)
                    {
                        correctDecisions.Dequeue();
                    }
                    if (user % 50 == 0)
                    {
                        Console.WriteLine("Correct decisions out of last {0} interactions: {1}", maxDecisionHistory, correctDecisions.Sum());
                    }
                    System.Threading.Thread.Sleep(TimeSpan.FromMilliseconds(50));
                }
            }
        }
Пример #2
0
 public static IReadOnlyCollection <TopicFeature> GetFeaturesFromContext(UserContextADF context)
 {
     return(context.TopicFeatures);
 }