<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="3.9.3">Jekyll</generator><link href="https://improve.ai/feed.xml" rel="self" type="application/atom+xml" /><link href="https://improve.ai/" rel="alternate" type="text/html" /><updated>2023-07-28T21:12:22+00:00</updated><id>https://improve.ai/feed.xml</id><title type="html">Improve AI - Contextual Multi-Armed Bandit Platform for Scoring, Ranking &amp;amp; Decisions</title><subtitle>Easily score and rank lists of items with machine learning.</subtitle><entry><title type="html"></title><link href="https://improve.ai/2023/07/28/2023-03-21-thompson-sampling.html" rel="alternate" type="text/html" title="" /><published>2023-07-28T21:12:22+00:00</published><updated>2023-07-28T21:12:22+00:00</updated><id>https://improve.ai/2023/07/28/2023-03-21-thompson-sampling</id><content type="html" xml:base="https://improve.ai/2023/07/28/2023-03-21-thompson-sampling.html">&lt;h2 id=&quot;introduction&quot;&gt;Introduction&lt;/h2&gt;

&lt;p&gt;Thompson Sampling is a highly effective algorithm used for solving the multi-armed bandit problem, an optimization challenge often encountered in online advertising, clinical trials, and recommendation systems. The crux of the problem is to balance exploration (trying out new options) and exploitation (choosing the best-known option) in order to maximize rewards over time. In this blog post, we will take a deep dive into Thompson Sampling, understanding its mechanics and benefits, and discussing real-world applications.&lt;/p&gt;

&lt;h2 id=&quot;what-is-the-multi-armed-bandit-problem&quot;&gt;What is the Multi-Armed Bandit Problem?&lt;/h2&gt;

&lt;p&gt;Imagine a gambler at a casino, faced with multiple slot machines, each with its own unknown probability of winning. The gambler’s goal is to maximize their earnings by playing the machine with the highest win probability. However, they must first determine which machine that is, without wasting too much time and money on inferior options. This is the essence of the multi-armed bandit problem: making optimal decisions under uncertainty.&lt;/p&gt;

&lt;h2 id=&quot;thompson-sampling-a-bayesian-approach&quot;&gt;Thompson Sampling: A Bayesian Approach&lt;/h2&gt;

&lt;p&gt;Thompson Sampling is a Bayesian approach to solving the multi-armed bandit problem. It involves maintaining a probability distribution for each arm (option) based on observed rewards and using those distributions to make decisions. The algorithm follows these steps:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;For each arm, maintain a prior distribution representing our belief about its expected reward.&lt;/li&gt;
  &lt;li&gt;At each time step, draw a random sample from each arm’s distribution.&lt;/li&gt;
  &lt;li&gt;Choose the arm with the highest sampled value and play it, then observe the reward.&lt;/li&gt;
  &lt;li&gt;Update the chosen arm’s distribution with the observed reward, incorporating the new information.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This approach is both exploratory and exploitative: by drawing random samples from each arm’s distribution, the algorithm is likely to choose arms with higher expected rewards more frequently, but it will still explore other arms occasionally.&lt;/p&gt;

&lt;h2 id=&quot;benefits-of-thompson-sampling&quot;&gt;Benefits of Thompson Sampling&lt;/h2&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Simple and efficient&lt;/strong&gt;: Thompson Sampling is computationally efficient and relatively easy to implement. It only requires maintaining a distribution for each arm and updating them as new information becomes available.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Convergence to optimal arm&lt;/strong&gt;: Over time, Thompson Sampling converges to the optimal arm, as the distributions become more accurate and the best arm is chosen more frequently.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Adaptability&lt;/strong&gt;: Thompson Sampling can easily adapt to changes in the reward distribution or to dynamic environments, making it well-suited for online applications.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Incorporation of prior knowledge&lt;/strong&gt;: By using a Bayesian approach, Thompson Sampling allows for the inclusion of prior knowledge or domain expertise through the choice of initial prior distributions.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;real-world-applications&quot;&gt;Real-World Applications&lt;/h2&gt;

&lt;p&gt;Thompson Sampling has been successfully applied to various real-world scenarios, including:&lt;/p&gt;

&lt;ol&gt;
  &lt;li&gt;&lt;strong&gt;Online advertising&lt;/strong&gt;: In digital advertising, Thompson Sampling can be used to optimize ad placements, maximizing click-through rates or conversion rates by intelligently allocating resources to the most effective ads.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Clinical trials&lt;/strong&gt;: In adaptive clinical trials, Thompson Sampling can be employed to assign patients to the most effective treatments while minimizing the number of patients exposed to inferior treatments.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;Recommendation systems&lt;/strong&gt;: Thompson Sampling can be used to recommend items or content to users, balancing the need to explore new options while exploiting the best-known recommendations.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Thompson Sampling is a powerful, elegant algorithm that addresses the multi-armed bandit problem by balancing exploration and exploitation in a principled, probabilistic manner. Its simplicity, adaptability, and ability to converge to the optimal solution make it a valuable tool in various fields, from online advertising to clinical trials. With its growing popularity and ongoing research, Thompson Sampling is poised to remain a cornerstone in decision-making under uncertainty.&lt;/p&gt;</content><author><name></name></author></entry><entry><title type="html">Improve AI 8.0 - Contextual Multi-Armed Bandit Platform for Scoring, Ranking &amp;amp; Decisions</title><link href="https://improve.ai/2023/06/08/contextual-bandit.html" rel="alternate" type="text/html" title="Improve AI 8.0 - Contextual Multi-Armed Bandit Platform for Scoring, Ranking &amp;amp; Decisions" /><published>2023-06-08T00:00:00+00:00</published><updated>2023-06-08T00:00:00+00:00</updated><id>https://improve.ai/2023/06/08/contextual-bandit</id><content type="html" xml:base="https://improve.ai/2023/06/08/contextual-bandit.html">&lt;p&gt;We’re thrilled to introduce Improve AI 8.0, a modern, free, production-ready &lt;em&gt;contextual multi-armed bandit&lt;/em&gt; platform that quickly scores and ranks items using intuitive reward-based training.&lt;/p&gt;

&lt;p&gt;Multi-armed bandits and contextual bandits are corner-stone machine learning algorithms that power a myriad of applications including recommendation systems, personalization, &lt;a href=&quot;/2023/03/19/scorer-query-reranking.html&quot;&gt;query re-ranking&lt;/a&gt;, &lt;a href=&quot;/2023/03/19/making-decisions.html&quot;&gt;automated decisions&lt;/a&gt;, and multi-variate optimization.&lt;/p&gt;

&lt;p&gt;With version 8, we’ve fully delivered on our original vision - providing a high performance, simple to use, low cost contextual multi-armed bandit platform.&lt;/p&gt;

&lt;p&gt;Key features of v8.0 include:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Simplified APIs&lt;/li&gt;
  &lt;li&gt;90% more memory efficient XGBoost models&lt;/li&gt;
  &lt;li&gt;The reward tracker &amp;amp; trainer is now free for most uses&lt;/li&gt;
  &lt;li&gt;On-device scoring, ranking, and decisions for iOS and Android apps&lt;/li&gt;
  &lt;li&gt;Native Swift SDK that can rank or score any Encodable&lt;/li&gt;
  &lt;li&gt;&lt;em&gt;Ranked Value Encoding&lt;/em&gt; for accurate scoring of String properties&lt;/li&gt;
  &lt;li&gt;Compact hash tables for reduced model sizes when encoding large numbers of string values&lt;/li&gt;
  &lt;li&gt;Balanced exploration vs exploitation using Thompson Sampling&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;simple-apis&quot;&gt;Simple APIs&lt;/h2&gt;

&lt;p&gt;With Swift, Python, or Java, create a list of JSON encodable items and simply call &lt;em&gt;Ranker.rank(items)&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;For instance, in an iOS bedtime story app, you may have a list of &lt;em&gt;Story&lt;/em&gt; objects:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Codable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;author&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;pageCount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Int&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To obtain a ranked list of stories, use just one line of code:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rankedStories&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;try&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;modelUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;stories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The expected best story will be the first element in the ranked list:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;bestStory&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rankedStories&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;first&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;simple-training&quot;&gt;Simple Training&lt;/h2&gt;

&lt;p&gt;Easily train your rankers using &lt;a href=&quot;/reinforcement-learning/&quot;&gt;reinforcement learning&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;First, track when an item is used:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;tracker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;RewardTracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;stories&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;trackUrl&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;let&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;rewardId&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;story&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rankedStories&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Later, if a positive outcome occurs, provide a reward:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;purchased&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addReward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;profit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;rewardId&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Reinforcement learning uses positive rewards for favorable outcomes (a “carrot”) and negative rewards for undesirable outcomes (a “stick”). By assigning rewards based on business metrics, such as revenue or conversions, the system optimizes these metrics over time.&lt;/p&gt;

&lt;h2 id=&quot;contextual-ranking--scoring&quot;&gt;Contextual Ranking &amp;amp; Scoring&lt;/h2&gt;

&lt;p&gt;Improve AI turns XGBoost into a &lt;em&gt;contextual multi-armed bandit&lt;/em&gt;, meaning that context is considered when making ranking or scoring decisions.&lt;/p&gt;

&lt;p&gt;Often, the choice of the best variant depends on the context that the decision is made within. Let’s take the example of greetings for different times of the day:&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;greetings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Good Morning&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
             &lt;span class=&quot;s&quot;&gt;&quot;Good Afternoon&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
             &lt;span class=&quot;s&quot;&gt;&quot;Good Evening&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
             &lt;span class=&quot;s&quot;&gt;&quot;Buenos Días&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
             &lt;span class=&quot;s&quot;&gt;&quot;Buenas Tardes&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
             &lt;span class=&quot;s&quot;&gt;&quot;Buenas Noches&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;rank()&lt;/em&gt; also considers the &lt;em&gt;context&lt;/em&gt; of each decision. The context can be any JSON-encodable data structure.&lt;/p&gt;

&lt;div class=&quot;language-py highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;ranked&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;items&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;greetings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; 
                     &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;day_time&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;12.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
                               &lt;span class=&quot;s&quot;&gt;&quot;language&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;en&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranked&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Trained with appropriate rewards, Improve AI would learn from scratch which greeting is best for each time of day and language.&lt;/p&gt;

&lt;h2 id=&quot;xgboost-model-improvements&quot;&gt;XGBoost Model Improvements&lt;/h2&gt;

&lt;p&gt;Improve AI v8.0 is 90%+ more memory efficient for most use cases. &lt;em&gt;Feature hashing&lt;/em&gt; has been replaced with a feature encoding approach that only uses a single feature per item property, substantially improving both training performance as well as ranking / scoring.&lt;/p&gt;

&lt;h2 id=&quot;ranked-value-encoding&quot;&gt;Ranked Value Encoding&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;Ranked Value Encoding&lt;/em&gt; is our novel approach to encoding string values in a manner that is extremely space efficient, accurate, and helps approximate Thompson Sampling for balanced exploration vs exploitation. The concept of Ranked Value Encoding is similar to commonly used Target Value Encoding for encoding string or categorical features.&lt;/p&gt;

&lt;p&gt;With Target Value Encoding, each string or categorical feature is replaced with the mean of the target values for that string or category. Target Value Encoding tends to provide good results for regression.&lt;/p&gt;

&lt;p&gt;However, multi-armed bandits are less concerned with the absolute accuracy of the scores and more concerned with the relative scores between items. Since we don’t need the exact target value, we can simply store the relative ranking of the string values, which saves space in the resulting model, increasing performance and lowering distribution costs.&lt;/p&gt;

&lt;h2 id=&quot;compact-string-encoding&quot;&gt;Compact String Encoding&lt;/h2&gt;

&lt;p&gt;In conjunction with &lt;em&gt;Ranked Value Encoding&lt;/em&gt;, rather than store entire strings, which could be arbitrarily long, Improve AI v8 models only store compact string hashes, resulting in only ~4 bytes per string for typical models.&lt;/p&gt;

&lt;h2 id=&quot;proven-performance&quot;&gt;Proven Performance&lt;/h2&gt;

&lt;p&gt;Improve AI is a production ready implementation of a &lt;em&gt;contextual multi-armed bandit&lt;/em&gt; algorithm, honed through years of iterative development. By merging Thompson Sampling with XGBoost, it provides a learning system that is both fast and flexible. Thompson Sampling maintains equilibrium between exploring novel possibilities and capitalizing on established options, while XGBoost ensures cost-effective, high-performance training for updated models.&lt;/p&gt;

&lt;h2 id=&quot;get-started-today&quot;&gt;Get Started Today&lt;/h2&gt;

&lt;p&gt;Improve AI is available now for &lt;a href=&quot;https://github.com/improve-ai/python-sdk/&quot;&gt;Python&lt;/a&gt;, &lt;a href=&quot;https://github.com/improve-ai/ios-sdk/&quot;&gt;Swift&lt;/a&gt;, and &lt;a href=&quot;https://github.com/improve-ai/android-sdk/&quot;&gt;Java&lt;/a&gt;. Check out the &lt;a href=&quot;/quick-start/&quot;&gt;Quick-Start Guide&lt;/a&gt; for more information.&lt;/p&gt;

&lt;p&gt;Thank you for your efforts to improve the world a little bit today.&lt;/p&gt;</content><author><name></name></author><summary type="html">We’re thrilled to introduce Improve AI 8.0, a modern, free, production-ready contextual multi-armed bandit platform that quickly scores and ranks items using intuitive reward-based training. Multi-armed bandits and contextual bandits are corner-stone machine learning algorithms that power a myriad of applications including recommendation systems, personalization, query re-ranking, automated decisions, and multi-variate optimization. With version 8, we’ve fully delivered on our original vision - providing a high performance, simple to use, low cost contextual multi-armed bandit platform. Key features of v8.0 include: Simplified APIs 90% more memory efficient XGBoost models The reward tracker &amp;amp; trainer is now free for most uses On-device scoring, ranking, and decisions for iOS and Android apps Native Swift SDK that can rank or score any Encodable Ranked Value Encoding for accurate scoring of String properties Compact hash tables for reduced model sizes when encoding large numbers of string values Balanced exploration vs exploitation using Thompson Sampling Simple APIs With Swift, Python, or Java, create a list of JSON encodable items and simply call Ranker.rank(items). For instance, in an iOS bedtime story app, you may have a list of Story objects: struct Story: Codable { var title: String var author: String var pageCount: Int } To obtain a ranked list of stories, use just one line of code: let rankedStories = try Ranker(modelUrl).rank(stories) The expected best story will be the first element in the ranked list: let bestStory = rankedStories.first Simple Training Easily train your rankers using reinforcement learning. First, track when an item is used: let tracker = RewardTracker(&quot;stories&quot;, trackUrl) let rewardId = tracker.track(story, from: rankedStories) Later, if a positive outcome occurs, provide a reward: if (purchased) { tracker.addReward(profit, rewardId) } Reinforcement learning uses positive rewards for favorable outcomes (a “carrot”) and negative rewards for undesirable outcomes (a “stick”). By assigning rewards based on business metrics, such as revenue or conversions, the system optimizes these metrics over time. Contextual Ranking &amp;amp; Scoring Improve AI turns XGBoost into a contextual multi-armed bandit, meaning that context is considered when making ranking or scoring decisions. Often, the choice of the best variant depends on the context that the decision is made within. Let’s take the example of greetings for different times of the day: greetings = [&quot;Good Morning&quot;, &quot;Good Afternoon&quot;, &quot;Good Evening&quot;, &quot;Buenos Días&quot;, &quot;Buenas Tardes&quot;, &quot;Buenas Noches&quot;] rank() also considers the context of each decision. The context can be any JSON-encodable data structure. ranked = ranker.rank(items=greetings, context={ &quot;day_time&quot;: 12.0, &quot;language&quot;: &quot;en&quot; }) greeting = ranked[0] Trained with appropriate rewards, Improve AI would learn from scratch which greeting is best for each time of day and language. XGBoost Model Improvements Improve AI v8.0 is 90%+ more memory efficient for most use cases. Feature hashing has been replaced with a feature encoding approach that only uses a single feature per item property, substantially improving both training performance as well as ranking / scoring. Ranked Value Encoding Ranked Value Encoding is our novel approach to encoding string values in a manner that is extremely space efficient, accurate, and helps approximate Thompson Sampling for balanced exploration vs exploitation. The concept of Ranked Value Encoding is similar to commonly used Target Value Encoding for encoding string or categorical features. With Target Value Encoding, each string or categorical feature is replaced with the mean of the target values for that string or category. Target Value Encoding tends to provide good results for regression. However, multi-armed bandits are less concerned with the absolute accuracy of the scores and more concerned with the relative scores between items. Since we don’t need the exact target value, we can simply store the relative ranking of the string values, which saves space in the resulting model, increasing performance and lowering distribution costs. Compact String Encoding In conjunction with Ranked Value Encoding, rather than store entire strings, which could be arbitrarily long, Improve AI v8 models only store compact string hashes, resulting in only ~4 bytes per string for typical models. Proven Performance Improve AI is a production ready implementation of a contextual multi-armed bandit algorithm, honed through years of iterative development. By merging Thompson Sampling with XGBoost, it provides a learning system that is both fast and flexible. Thompson Sampling maintains equilibrium between exploring novel possibilities and capitalizing on established options, while XGBoost ensures cost-effective, high-performance training for updated models. Get Started Today Improve AI is available now for Python, Swift, and Java. Check out the Quick-Start Guide for more information. Thank you for your efforts to improve the world a little bit today.</summary></entry><entry><title type="html">Making Decisions with *Ranker*</title><link href="https://improve.ai/2023/03/19/making-decisions.html" rel="alternate" type="text/html" title="Making Decisions with *Ranker*" /><published>2023-03-19T00:00:00+00:00</published><updated>2023-03-19T00:00:00+00:00</updated><id>https://improve.ai/2023/03/19/making-decisions</id><content type="html" xml:base="https://improve.ai/2023/03/19/making-decisions.html">&lt;p&gt;In this tutorial, we’ll walk through how to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ranker&lt;/code&gt; class to make decisions, specifically choosing a discount to offer from a list of discounts. We’ll also need to track the decision with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; and reward it for the amount of profit if a purchase is made. In this way, the Ranker will learn to rank the most profitable discount first.&lt;/p&gt;

&lt;h2 id=&quot;using-the-ranker-class&quot;&gt;Using the Ranker class&lt;/h2&gt;

&lt;p&gt;First, let’s create an instance of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ranker&lt;/code&gt; class.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;improveai&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ranker&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ranker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;ranking-items&quot;&gt;Ranking items&lt;/h3&gt;

&lt;p&gt;To rank items, you can call the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;rank&lt;/code&gt; method of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ranker&lt;/code&gt; class. This method accepts a list of items and an optional context.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;discounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;15&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;20&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;25&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;30&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;ranked_discounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;discounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;selecting-the-highest-ranking-discount&quot;&gt;Selecting the highest-ranking discount&lt;/h3&gt;

&lt;p&gt;Now that we have the ranked discounts, we can choose the highest-ranking discount.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;best_discount&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranked_discounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;tracking-the-decision-with-rewardtracker&quot;&gt;Tracking the decision with RewardTracker&lt;/h2&gt;

&lt;p&gt;Next, we need to track our decision using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; class.&lt;/p&gt;

&lt;h3 id=&quot;creating-a-rewardtracker-instance&quot;&gt;Creating a RewardTracker instance&lt;/h3&gt;

&lt;p&gt;First, create a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; instance with the required arguments.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;improveai&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RewardTracker&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RewardTracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;discounts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;track_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;tracking-the-decision&quot;&gt;Tracking the decision&lt;/h3&gt;

&lt;p&gt;Now we can track our decision using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;track&lt;/code&gt; method of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; class. This method accepts the selected item, a list of candidates, and an optional context.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;reward_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;best_discount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;discounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;rewarding-the-decision&quot;&gt;Rewarding the decision&lt;/h3&gt;

&lt;p&gt;Once a purchase is made, we can add a reward to the decision using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;add_reward&lt;/code&gt; method of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; class. This method requires a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reward&lt;/code&gt; value and a &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;reward_id&lt;/code&gt; that was obtained when tracking the chosen discount.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;reward&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;profit_amount&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_reward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reward_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Improve AI will automatically balance exploring new discounts with doubling down on the discounts expected to be most profitable. Over time and as more decisions are made, the model will learn to choose the optimal discount.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;In this tutorial, we covered how to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Ranker&lt;/code&gt; class to make decisions, such as choosing a discount from a list of discounts. We also learned how to track the decision with the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; and reward it based on the profit.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;Improve AI is available for &lt;a href=&quot;https://github.com/improve-ai/python-ranker/&quot;&gt;Python&lt;/a&gt;, &lt;a href=&quot;https://github.com/improve-ai/swift-ranker/&quot;&gt;Swift&lt;/a&gt;, and &lt;a href=&quot;https://github.com/improve-ai/java-ranker/&quot;&gt;Java&lt;/a&gt;. See the &lt;a href=&quot;/quick-start/&quot;&gt;Quick-Start Guide&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;p&gt;Thank you for your efforts to improve the world a little bit today.&lt;/p&gt;</content><author><name>Justin Chapweske</name></author><summary type="html">In this tutorial, we’ll walk through how to use the Ranker class to make decisions, specifically choosing a discount to offer from a list of discounts. We’ll also need to track the decision with the RewardTracker and reward it for the amount of profit if a purchase is made. In this way, the Ranker will learn to rank the most profitable discount first.</summary></entry><entry><title type="html">Simple Re-Ranking of SQL Queries with Machine Learning</title><link href="https://improve.ai/2023/03/19/scorer-query-reranking.html" rel="alternate" type="text/html" title="Simple Re-Ranking of SQL Queries with Machine Learning" /><published>2023-03-19T00:00:00+00:00</published><updated>2023-03-19T00:00:00+00:00</updated><id>https://improve.ai/2023/03/19/scorer-query-reranking</id><content type="html" xml:base="https://improve.ai/2023/03/19/scorer-query-reranking.html">&lt;p&gt;In this tutorial, we will demonstrate how to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scorer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; classes to update a ‘score’ column for a number of products in a ‘products’ table. The ‘score’ column will be used to learn an optimized ranking for these products, allowing for extremely fast and simple product recommendations. By sorting the queries based on the score column, we can provide a highly efficient product recommendation system.&lt;/p&gt;

&lt;h2 id=&quot;step-1-initialize-scorer-and-rewardtracker-instances&quot;&gt;Step 1: Initialize Scorer and RewardTracker Instances&lt;/h2&gt;

&lt;p&gt;First, you need to create instances of the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scorer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; classes.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;improveai&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RewardTracker&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Initialize Scorer instance
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scorer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Scorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Initialize RewardTracker instance
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;reward_tracker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RewardTracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;products&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;track_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-2-query-products-from-database-and-score-them&quot;&gt;Step 2: Query Products from Database and Score Them&lt;/h2&gt;

&lt;p&gt;Next, you should query the products from your database and score them using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scorer&lt;/code&gt; instance. Scores are updated periodically via a CRON job.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;your_database_module&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;as&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Query products from the database
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SELECT * FROM products&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Score the products using the Scorer instance
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scorer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Update the 'score' column for each product in the products table
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;score&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;zip&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scores&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;update&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;UPDATE products SET score = %s WHERE product_id = %s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;score&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;product_id&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-3-sort-products-by-score-and-display-them&quot;&gt;Step 3: Sort Products by Score and Display Them&lt;/h2&gt;

&lt;p&gt;When querying the list of products, sort them descending by score.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Query products sorted by score
&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sorted_products&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;db&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;query&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;SELECT * FROM products ORDER BY score DESC&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# Display the sorted products
&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sorted_products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;print&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h2 id=&quot;step-4-track-product-selection-and-purchase&quot;&gt;Step 4: Track Product Selection and Purchase&lt;/h2&gt;

&lt;p&gt;When the user selects a product to browse, track the product using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt;. If the product is purchased, track a reward for the amount of profit generated.&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;on_product_selected&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selected_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Track the selected product using the RewardTracker
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;reward_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reward_tracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;selected_product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;products&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reward_id&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;on_product_purchased&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;profit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reward_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# Track a reward for the amount of profit generated
&lt;/span&gt;    &lt;span class=&quot;n&quot;&gt;reward_tracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;addReward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;profit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reward_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, you can use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;on_product_selected&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;on_product_purchased&lt;/code&gt; functions to track product selection and purchase events in your application.&lt;/p&gt;

&lt;p&gt;To wrap up, we have shown you how to use the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scorer&lt;/code&gt; class from the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;improveai&lt;/code&gt; module to update the ‘score’ column of a products table, sort the products descending by score, and track product selection and purchase events using the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; class. By implementing these functionalities, you can improve your product recommendation system by leveraging the &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;Scorer&lt;/code&gt; and &lt;code class=&quot;language-plaintext highlighter-rouge&quot;&gt;RewardTracker&lt;/code&gt; classes.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;Improve AI is available for &lt;a href=&quot;https://github.com/improve-ai/python-ranker/&quot;&gt;Python&lt;/a&gt;, &lt;a href=&quot;https://github.com/improve-ai/swift-ranker/&quot;&gt;Swift&lt;/a&gt;, and &lt;a href=&quot;https://github.com/improve-ai/java-ranker/&quot;&gt;Java&lt;/a&gt;. See the &lt;a href=&quot;/quick-start/&quot;&gt;Quick-Start Guide&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;p&gt;Thank you for your efforts to improve the world a little bit today.&lt;/p&gt;</content><author><name>Justin Chapweske</name></author><summary type="html">In this tutorial, we will demonstrate how to use the Scorer and RewardTracker classes to update a ‘score’ column for a number of products in a ‘products’ table. The ‘score’ column will be used to learn an optimized ranking for these products, allowing for extremely fast and simple product recommendations. By sorting the queries based on the score column, we can provide a highly efficient product recommendation system.</summary></entry><entry><title type="html">Optimize Any Python, Swift, or Java Object with Reinforcement Learning</title><link href="https://improve.ai/2022/11/14/optimize-any-object.html" rel="alternate" type="text/html" title="Optimize Any Python, Swift, or Java Object with Reinforcement Learning" /><published>2022-11-14T00:00:00+00:00</published><updated>2022-11-14T00:00:00+00:00</updated><id>https://improve.ai/2022/11/14/optimize-any-object</id><content type="html" xml:base="https://improve.ai/2022/11/14/optimize-any-object.html">&lt;p&gt;&lt;a href=&quot;https://improve.ai/&quot;&gt;Improve AI&lt;/a&gt; is a machine learning platform for making apps &lt;em&gt;self-improving&lt;/em&gt;, meaning they optimize their own data structures and variables to improve revenue and conversions.&lt;/p&gt;

&lt;p&gt;With Improve AI v7.2, you can now optimize the variables of any Java, Swift, or Python object with reinforcement learning. &lt;em&gt;It’s like an exponentially faster form of A/B testing&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;The new optimize() method finds the best combination of variable values given current conditions.&lt;/p&gt;

&lt;p&gt;Optimized objects are created immediately, on the fly, with zero network latency.&lt;/p&gt;

&lt;h2 id=&quot;optimize-any-object&quot;&gt;Optimize Any Object&lt;/h2&gt;

&lt;p&gt;Improve AI can optimize any object or JSON-encodable dictionary in Swift, Java, or Python to find the best combination of variables given current conditions.&lt;/p&gt;

&lt;p&gt;As an example, let’s optimize a pop up discount offer in an iOS app. The goal is to maximize expected revenue by assigning the best combination of variable values.&lt;/p&gt;

&lt;p&gt;First, we’ll create an &lt;em&gt;Offer&lt;/em&gt; type with four variables: &lt;em&gt;title&lt;/em&gt;, &lt;em&gt;description&lt;/em&gt;, &lt;em&gt;discount&lt;/em&gt;, and &lt;em&gt;buttonText&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;struct&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Offer&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Codable&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;description&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;discount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Float&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nv&quot;&gt;buttonText&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;String&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next we’ll create a mapping from each variable to possible values.&lt;/p&gt;

&lt;p&gt;Here the values are hardcoded but they could easily be loaded from a database or configuration file:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;titles&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Special Offer!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Limited Time!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;descriptions&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;New and improved.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Great features.&quot;&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Huge value.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;discounts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;buttonTexts&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Try Free&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Subscribe&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Continue&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;To generate an optimized &lt;em&gt;Offer&lt;/em&gt;, simply call &lt;em&gt;optimize()&lt;/em&gt; with a map of the variables and the &lt;em&gt;Offer&lt;/em&gt; type.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;offer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offersModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;titles&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;descriptions&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;discount&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;discounts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;buttonText&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;buttonTexts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; 
                             &lt;span class=&quot;kt&quot;&gt;Offer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The best combination of variables is selected by the machine learning model and the result is returned as a new &lt;em&gt;Offer&lt;/em&gt; object.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That’s like A/B testing on steroids.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;contextual-optimization&quot;&gt;Contextual Optimization&lt;/h2&gt;

&lt;p&gt;Unlike A/B testing, &lt;em&gt;optimize()&lt;/em&gt; also considers the &lt;em&gt;context&lt;/em&gt; of each variable assignment. On iOS and Android, the context automatically includes &lt;strong&gt;country&lt;/strong&gt;, &lt;strong&gt;language&lt;/strong&gt;, &lt;strong&gt;OS&lt;/strong&gt;, &lt;strong&gt;device&lt;/strong&gt;, &lt;strong&gt;time of day&lt;/strong&gt; and many other attributes. (No personally identifiable information is ever used, transmitted, or stored)&lt;/p&gt;

&lt;p&gt;With contextual optimization, different versions of the object may be returned for different contexts. This allows the object’s variables to adapt dynamically to it’s environment, enabling deep optimization, personalization, and more.&lt;/p&gt;

&lt;p&gt;Custom context can also be provided via &lt;em&gt;given()&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;offer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;offersModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;given&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;churned&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
                   &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;optimize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variableMap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kt&quot;&gt;Offer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example, given the user has churned, create an &lt;em&gt;Offer&lt;/em&gt; that will maximize expected revenue.&lt;/p&gt;

&lt;p&gt;Perhaps churned users need a larger discount? Perhaps they just need a nudge with the right message? With &lt;em&gt;optimize()&lt;/em&gt; you don’t have to guess - it will automatically learn the best &lt;em&gt;Offer&lt;/em&gt; for each context.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Contextual optimization, which is often infeasible with A/B testing, is trivial with this new capability.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;simple-training&quot;&gt;Simple Training&lt;/h2&gt;

&lt;p&gt;&lt;em&gt;optimize()&lt;/em&gt; is easily trained with &lt;a href=&quot;/reinforcement-learning/&quot;&gt;reinforcement learning&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;purchased&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;offersModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addReward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;profit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With reinforcement learning, positive rewards are assigned for positive outcomes (a “carrot”) and negative rewards are assigned for undesirable outcomes (a “stick”).&lt;/p&gt;

&lt;p&gt;When rewards are business metrics, such as revenue or conversions, it will automatically optimize those metrics over time.&lt;/p&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;Object optimization is available immediately for &lt;a href=&quot;https://github.com/improve-ai/python-sdk/&quot;&gt;Python&lt;/a&gt;, &lt;a href=&quot;https://github.com/improve-ai/ios-sdk/&quot;&gt;iOS&lt;/a&gt;, and &lt;a href=&quot;https://github.com/improve-ai/android-sdk/&quot;&gt;Android/Java&lt;/a&gt;. See the &lt;a href=&quot;/quick-start/&quot;&gt;Quick-Start Guide&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;p&gt;Thank you for your efforts to improve the world a little bit today.&lt;/p&gt;</content><author><name>Justin Chapweske</name></author><summary type="html">Improve AI is a machine learning platform for making apps self-improving, meaning they optimize their own data structures and variables to improve revenue and conversions.</summary></entry><entry><title type="html">Self Improving Apps: The Origin of a Radical Idea</title><link href="https://improve.ai/2022/11/11/ai-growth-hacking.html" rel="alternate" type="text/html" title="Self Improving Apps: The Origin of a Radical Idea" /><published>2022-11-11T00:00:00+00:00</published><updated>2022-11-11T00:00:00+00:00</updated><id>https://improve.ai/2022/11/11/ai-growth-hacking</id><content type="html" xml:base="https://improve.ai/2022/11/11/ai-growth-hacking.html">&lt;p&gt;I’ve been working on Improve AI for many years, but by 2017 the idea had begun to gel enough that I was ready to talk about it.&lt;/p&gt;

&lt;p&gt;Much has changed since this original talk, but the grand vision of building apps that automatically improve their own metrics remains unchanged.&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/ptrEuJwK-XM&quot; title=&quot;YouTube video player&quot; frameborder=&quot;0&quot; allow=&quot;accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;h2 id=&quot;getting-started&quot;&gt;Getting Started&lt;/h2&gt;

&lt;p&gt;Improve AI is available now for &lt;a href=&quot;/python-sdk/&quot;&gt;Python&lt;/a&gt;, &lt;a href=&quot;/ios-sdk/&quot;&gt;iOS&lt;/a&gt;, and &lt;a href=&quot;/android-sdk/&quot;&gt;Android&lt;/a&gt;. See the &lt;a href=&quot;/quick-start/&quot;&gt;Quick-Start Guide&lt;/a&gt; to learn more.&lt;/p&gt;

&lt;p&gt;Thank you for your efforts to improve the world a little bit today.&lt;/p&gt;</content><author><name>Justin Chapweske</name></author><summary type="html">I’ve been working on Improve AI for many years, but by 2017 the idea had begun to gel enough that I was ready to talk about it.</summary></entry><entry><title type="html">The NEW 20 lines of code that will beat A/B testing every time</title><link href="https://improve.ai/2022/04/05/lines-beat-ab-testing.html" rel="alternate" type="text/html" title="The NEW 20 lines of code that will beat A/B testing every time" /><published>2022-04-05T00:00:00+00:00</published><updated>2022-04-05T00:00:00+00:00</updated><id>https://improve.ai/2022/04/05/lines-beat-ab-testing</id><content type="html" xml:base="https://improve.ai/2022/04/05/lines-beat-ab-testing.html">&lt;p&gt;In 2012, &lt;a href=&quot;http://stevehanov.ca/blog/&quot;&gt;Steve Hanov&lt;/a&gt; wrote the popular and &lt;a href=&quot;https://news.ycombinator.com/item?id=4040022&quot;&gt;controversial&lt;/a&gt; blog post &lt;a href=&quot;http://stevehanov.ca/blog/?id=132&quot;&gt;“20 lines of code that will beat A/B testing every time”&lt;/a&gt; that brought the previously academic idea of &lt;a href=&quot;https://en.wikipedia.org/wiki/Multi-armed_bandit&quot;&gt;&lt;em&gt;multi armed bandit&lt;/em&gt;&lt;/a&gt; algorithms into the awareness of the larger developer community.&lt;/p&gt;

&lt;p&gt;Here were his original 20 (actually 16) lines of “code”:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;choose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;():&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;math&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# exploration!
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# choose a random lever 10% of the time.
&lt;/span&gt;    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
        &lt;span class=&quot;c1&quot;&gt;# exploitation!
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# for each lever, 
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# calculate the expectation of reward. 
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# This is the number of trials of the lever divided by the total reward 
&lt;/span&gt;            &lt;span class=&quot;c1&quot;&gt;# given by that lever.
&lt;/span&gt;        &lt;span class=&quot;c1&quot;&gt;# choose the lever with the greatest expectation of reward.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# increment the number of times the chosen lever has been played.
&lt;/span&gt;    &lt;span class=&quot;c1&quot;&gt;# store test data in redis, choice in session key, etc..
&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;choice&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# add the reward to the total for the given lever.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;What he’s describing here is a very simple form of &lt;a href=&quot;/reinforcement-learning/&quot;&gt;&lt;em&gt;reinforcement learning&lt;/em&gt;&lt;/a&gt; known as the Epsilon Greedy algorithm. Much of the controversy surrounding this post was that it greatly oversold the simplicity of deploying such an algorithm in production.&lt;/p&gt;

&lt;p&gt;Now after years of work and many thousands of lines of code, I’m pleased to present a new &lt;em&gt;“12 lines of code that will beat A/B testing every time”&lt;/em&gt; that is robust, scalable, and proven in large scale production:&lt;/p&gt;

&lt;div class=&quot;language-python highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kn&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;improveai&lt;/span&gt; &lt;span class=&quot;kn&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RewardTracker&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;ranker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;Ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;RewardTracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model_name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;track_url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;choose&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;best&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;ranker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;rank&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;decision_id&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tracker&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;track&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;best&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;candidates&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;variants&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;best&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decision_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decision_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;):&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add_reward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;amount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;decision_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unlike Steve’s code that envisioned querying simple statistics from something like Redis, Improve AI loads a trained machine learning model locally into the process so that decisions are made immediately with zero network latency.&lt;/p&gt;

&lt;p&gt;Improve AI is also a contextual multi-armed bandit, which means it can make use of contextual data such as language, time of day, and screen resolution to make the best decision. This makes it simple to implement recommender systems, personalization, app optimization, and more.&lt;/p&gt;

&lt;p&gt;Is it finally time to stop wasting conversions and throw away A/B testing for good?&lt;/p&gt;

&lt;p&gt;Improve AI is available now for &lt;a href=&quot;https://github.com/improve-ai/ios-sdk&quot;&gt;iOS&lt;/a&gt;, &lt;a href=&quot;https://github.com/improve-ai/android-sdk&quot;&gt;Android&lt;/a&gt;, and &lt;a href=&quot;https://github.com/improve-ai/python-sdk&quot;&gt;Python&lt;/a&gt;.&lt;/p&gt;</content><author><name></name></author><summary type="html">In 2012, Steve Hanov wrote the popular and controversial blog post “20 lines of code that will beat A/B testing every time” that brought the previously academic idea of multi armed bandit algorithms into the awareness of the larger developer community.</summary></entry><entry><title type="html">Improve AI - Easily Optimize Your App with Reinforcement Learning</title><link href="https://improve.ai/2022/04/05/welcome-to-improve.html" rel="alternate" type="text/html" title="Improve AI - Easily Optimize Your App with Reinforcement Learning" /><published>2022-04-05T00:00:00+00:00</published><updated>2022-04-05T00:00:00+00:00</updated><id>https://improve.ai/2022/04/05/welcome-to-improve</id><content type="html" xml:base="https://improve.ai/2022/04/05/welcome-to-improve.html">&lt;p&gt;Optimize and personalize your apps with fast AI decisions that get smarter over time. Decisions are made immediately, on-device, with no network latency.&lt;/p&gt;

&lt;p&gt;The heart of Improve AI is the &lt;em&gt;which()&lt;/em&gt; statement. &lt;em&gt;which()&lt;/em&gt; is like an AI if/then statement.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greetingsModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Howdy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hola&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;which()&lt;/em&gt; uses logic stored in a  machine learning model to make the best choice. Models are easily trained with &lt;em&gt;reinforcement learning&lt;/em&gt;.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;success&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;greetingsModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addReward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;1.0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;With reinforcement learning, positive rewards are assigned for positive outcomes (a “carrot”) and negative rewards are assigned for undesirable outcomes (a “stick”).&lt;/p&gt;

&lt;p&gt;&lt;em&gt;which()&lt;/em&gt; chooses the option that provides the highest expected reward given the current conditions.&lt;/p&gt;

&lt;p&gt;When rewards are business metrics, such as revenue, conversions, or user retention, the decisions will optimize to automatically improve those metrics over time.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;That’s like A/B testing on steroids.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;However, unlike A/B testing, Improve AI uses context to personalize each decision.  On iOS and Android, the context automatically includes &lt;strong&gt;language&lt;/strong&gt;, &lt;strong&gt;OS&lt;/strong&gt;, &lt;strong&gt;device type&lt;/strong&gt;, &lt;strong&gt;day of week&lt;/strong&gt;, &lt;strong&gt;time of day&lt;/strong&gt;, &lt;strong&gt;app version&lt;/strong&gt;, and many other attributes. (No personally identifiable information is ever used, transmitted, or stored)&lt;/p&gt;

&lt;p&gt;With this context, for a Spanish speaker the &lt;em&gt;greetings&lt;/em&gt; model will learn to choose &lt;em&gt;Hola&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;Custom context can also be provided via &lt;em&gt;given()&lt;/em&gt;:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;greetingsModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;given&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;language&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;cowboy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
                         &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;Hello&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Howdy&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;Hola&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Given the language is &lt;em&gt;cowboy&lt;/em&gt;, the variant with the highest expected reward is &lt;em&gt;Howdy&lt;/em&gt; and the model will learn to make that choice.&lt;/p&gt;

&lt;p&gt;The combination of &lt;em&gt;given()&lt;/em&gt;, &lt;em&gt;which()&lt;/em&gt;, and &lt;em&gt;addReward()&lt;/em&gt; make it simple to implement personalization, recommendations, dynamic In App Offers, and more.&lt;/p&gt;

&lt;h2 id=&quot;example-personalizing-an-upsell-offer&quot;&gt;Example: Personalizing an Upsell Offer&lt;/h2&gt;

&lt;p&gt;Improve AI is powerful and flexible.  &lt;em&gt;which()&lt;/em&gt; accepts any JSON encodeable object including &lt;strong&gt;strings&lt;/strong&gt;, &lt;strong&gt;numbers&lt;/strong&gt;, &lt;strong&gt;booleans&lt;/strong&gt;, &lt;strong&gt;lists&lt;/strong&gt;, and &lt;strong&gt;dictionaries&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;For a dungeon crawler game, say the user is purchasing an item using an In App Purchase.  Improve AI can choose an additional product to display as an upsell offer during checkout. With a few lines of code, a model can be trained that will learn to optimize the upsell offer given the original product being purchased.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;red sword&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;4.99&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;upsellOffers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;gold&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;100&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;1.99&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;diamonds&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;quantity&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;2.99&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
                &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;red scabbard&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;price&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mf&quot;&gt;0.99&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;upsell&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;upsellModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;given&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;product&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
                    &lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upsellOffers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;The product to be purchased is the &lt;strong&gt;red sword&lt;/strong&gt;.  Notice that the variants are dictionaries with a mix of string and numeric values.&lt;/p&gt;

&lt;p&gt;The rewards in this case might be any additional revenue from the upsell.&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upsellPurchased&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;upsellModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addReward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;upsell&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;price&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While it is reasonable to hypothesize that the &lt;strong&gt;red scabbord&lt;/strong&gt; might be the best upsell offer to pair with the &lt;strong&gt;red sword&lt;/strong&gt;, it is still a guess. Any time a guess is made on the value of a variable, instead use Improve AI to decide.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Replace guesses with AI decisions.&lt;/em&gt;&lt;/p&gt;

&lt;h2 id=&quot;example-performance-tuning&quot;&gt;Example: Performance Tuning&lt;/h2&gt;

&lt;p&gt;I used to write a lot of video streaming code. The initial motivation for Improve AI came out of my frustrations with attempting to tune video streaming clients across heterogenious networks.&lt;/p&gt;

&lt;p&gt;I was forced to make guesses on performance sensitive configuration defaults through slow trial and error. My client configuration code maybe looked something like this:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;s&quot;&gt;&quot;bufferSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2048&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
           &lt;span class=&quot;s&quot;&gt;&quot;videoBitrate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;384000&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This is the code I wish I could have written:&lt;/p&gt;

&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;config&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;configModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bufferSize&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1024&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2048&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4096&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;8192&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
                            &lt;span class=&quot;s&quot;&gt;&quot;videoBitrate&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;256000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;384000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;512000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;This example decides multiple variables simultaneously.  Notice that instead of a single list of variants, a dictionary mapping keys to lists of variants is provided to &lt;em&gt;which&lt;/em&gt;. This multi-variate mode jointly optimizes all variables for the highest expected reward.&lt;/p&gt;

&lt;p&gt;The rewards in this case might be negative to penalize any stalls during video playback.&lt;/p&gt;
&lt;div class=&quot;language-swift highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;videoStalled&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;configModel&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;addReward&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mf&quot;&gt;0.001&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Improve AI frees us from having to overthink our configuration values during development. We simply give it some reasonable variants and let it learn from real world usage.&lt;/p&gt;

&lt;p&gt;This is an enormously powerful tool and I’m sure you’ll come up with some very interesting uses. Look for places where you’re relying on guesses or an executive decision and consider instead directly optimizing for the outcomes you desire.&lt;/p&gt;

&lt;p&gt;Improve AI is available now for &lt;a href=&quot;https://github.com/improve-ai/ios-sdk&quot;&gt;iOS&lt;/a&gt;, &lt;a href=&quot;https://github.com/improve-ai/android-sdk&quot;&gt;Android&lt;/a&gt;, and &lt;a href=&quot;https://github.com/improve-ai/python-sdk&quot;&gt;Python&lt;/a&gt;. See the Quick-Start Guide to learn more.&lt;/p&gt;

&lt;p&gt;Thank you for your efforts to improve the world a little bit today.&lt;/p&gt;

&lt;p&gt;– Justin Chapweske&lt;/p&gt;</content><author><name></name></author><summary type="html">Optimize and personalize your apps with fast AI decisions that get smarter over time. Decisions are made immediately, on-device, with no network latency. The heart of Improve AI is the which() statement. which() is like an AI if/then statement. greeting = greetingsModel.which(&quot;Hello&quot;, &quot;Howdy&quot;, &quot;Hola&quot;) which() uses logic stored in a machine learning model to make the best choice. Models are easily trained with reinforcement learning. if (success) { greetingsModel.addReward(1.0) } With reinforcement learning, positive rewards are assigned for positive outcomes (a “carrot”) and negative rewards are assigned for undesirable outcomes (a “stick”). which() chooses the option that provides the highest expected reward given the current conditions. When rewards are business metrics, such as revenue, conversions, or user retention, the decisions will optimize to automatically improve those metrics over time. That’s like A/B testing on steroids. However, unlike A/B testing, Improve AI uses context to personalize each decision. On iOS and Android, the context automatically includes language, OS, device type, day of week, time of day, app version, and many other attributes. (No personally identifiable information is ever used, transmitted, or stored) With this context, for a Spanish speaker the greetings model will learn to choose Hola. Custom context can also be provided via given(): greeting = greetingsModel.given({&quot;language&quot;: &quot;cowboy&quot;}) .which(&quot;Hello&quot;, &quot;Howdy&quot;, &quot;Hola&quot;) Given the language is cowboy, the variant with the highest expected reward is Howdy and the model will learn to make that choice. The combination of given(), which(), and addReward() make it simple to implement personalization, recommendations, dynamic In App Offers, and more. Example: Personalizing an Upsell Offer Improve AI is powerful and flexible. which() accepts any JSON encodeable object including strings, numbers, booleans, lists, and dictionaries. For a dungeon crawler game, say the user is purchasing an item using an In App Purchase. Improve AI can choose an additional product to display as an upsell offer during checkout. With a few lines of code, a model can be trained that will learn to optimize the upsell offer given the original product being purchased. product = { &quot;name&quot;: &quot;red sword&quot;, &quot;price&quot;: 4.99 } upsellOffers = [{ &quot;name&quot;: &quot;gold&quot;, &quot;quantity&quot;: 100, &quot;price&quot;: 1.99 }, { &quot;name&quot;: &quot;diamonds&quot;, &quot;quantity&quot;: 10, &quot;price&quot;: 2.99 }, { &quot;name&quot;: &quot;red scabbard&quot;, &quot;price&quot;: 0.99 }] upsell = upsellModel.given(product) .which(upsellOffers) The product to be purchased is the red sword. Notice that the variants are dictionaries with a mix of string and numeric values. The rewards in this case might be any additional revenue from the upsell. if (upsellPurchased) { upsellModel.addReward(upsell.price) } While it is reasonable to hypothesize that the red scabbord might be the best upsell offer to pair with the red sword, it is still a guess. Any time a guess is made on the value of a variable, instead use Improve AI to decide. Replace guesses with AI decisions. Example: Performance Tuning I used to write a lot of video streaming code. The initial motivation for Improve AI came out of my frustrations with attempting to tune video streaming clients across heterogenious networks. I was forced to make guesses on performance sensitive configuration defaults through slow trial and error. My client configuration code maybe looked something like this: config = { &quot;bufferSize&quot;: 2048, &quot;videoBitrate&quot;: 384000 } This is the code I wish I could have written: config = configModel.which({&quot;bufferSize&quot;: [1024, 2048, 4096, 8192], &quot;videoBitrate&quot;: [256000, 384000, 512000]}) This example decides multiple variables simultaneously. Notice that instead of a single list of variants, a dictionary mapping keys to lists of variants is provided to which. This multi-variate mode jointly optimizes all variables for the highest expected reward. The rewards in this case might be negative to penalize any stalls during video playback. if (videoStalled) { configModel.addReward(-0.001) } Improve AI frees us from having to overthink our configuration values during development. We simply give it some reasonable variants and let it learn from real world usage. This is an enormously powerful tool and I’m sure you’ll come up with some very interesting uses. Look for places where you’re relying on guesses or an executive decision and consider instead directly optimizing for the outcomes you desire. Improve AI is available now for iOS, Android, and Python. See the Quick-Start Guide to learn more. Thank you for your efforts to improve the world a little bit today. – Justin Chapweske</summary></entry></feed>