<jupyter_start><jupyter_text>Personalizer*Personalizer* is a service that allows the application to chooise the best **single** content item to show to the user. Personalizer uses reinforcement learning techniques to enable the selection of the best item is based on the features about the content and the context. The selection is based on the collective behaviour and the reward score for all the users. The **Azure Personalizer** cognitive service in Microsoft Azure provides a cloud-based solution for creating personalized journeys for the users.. Create a Personalizer resourceTo use the Personalizer service, you need an Azure resource that you can use to train a model, and a resource with which you can publish it for applications to use. Unlike other congnitive services you will need to use one resource for every task you create. It would not be advisable to merge different content, or actions within the same resource. 1. In a new browser tab, open the Azure portal at [https://portal.azure.com](https://portal.azure.com), and sign in using the Microsoft account associated with your Azure subscription.2. Select the **&65291;Create a resource** button, search for *personalizer*, and create a **Personalizer** resource with the following settings:    - **Name**: *Enter a unique name*    - **Subscription**: *Your Azure subscription*    - **Location**: *Choose any available region*    - **Pricing tier**: F0    > **Note**: F0 tiers allows you about 50K transactions a month, that would be sufficient when you try out, but for all practical purposes you will need to setup a **S0** tier to be of any utility.3. Wait for deployment to complete. Then go to your cognitive services resource, and on the **Overview** page, click the link to manage the keys for the service. You will need the endpoint and keys to connect to your cognitive services resource from client applications. Get the Key and Endpoint for your Personalizer resourceTo use your cognitive services resource, client applications need its  endpoint and authentication key:1. In the Azure portal, on the **Keys and Endpoint** page for your personalizer resource, copy the **Key1** for your resource and paste it in the code below, replacing **YOUR_PER_KEY**.2. Copy the **endpoint** for your resource and and paste it in the code below, replacing **YOUR_PER_ENDPOINT**.3. Run the code in the cell below by clicking its green &9655 button.<jupyter_code>personalizer_key = 'YOUR_PER_KEY'
personalizer_endpoint = 'YOUR_PER_ENDPOINT'

print('Ready to use personalizer services at {} using key {}'.format(personalizer_endpoint, personalizer_key))
from azure.cognitiveservices.personalizer import PersonalizerClient
from azure.cognitiveservices.personalizer.models import RankableAction, RewardRequest, RankRequest
from msrest.authentication import CognitiveServicesCredentials
from random import choice
import datetime, json, os, time, uuid
# Instantiate a Personalizer client
client = PersonalizerClient(personalizer_endpoint, CognitiveServicesCredentials(personalizer_key))
#
# Actions are the content items, such as news articles, specific movies, or products that the users
# can choose from. You can also define the attributes / features for each of the action. Unlike a 
# machine learning you dont have to define all the features for every action.
#  
def get_actions():
    action1 = RankableAction(id='pasta', features=[{"taste": "salty", "spice_level": "medium"},
                                                   {"nutrition_level": 5, "cuisine": "italian"}])
    action2 = RankableAction(id='ice cream',
                             features=[{"taste": "sweet", "spice_level": "none"}, {"nutritional_level": 2}])
    action3 = RankableAction(id='juice', features=[{"taste": "sweet", 'spice_level': 'none'}, {'nutritional_level': 5},
                                                   {'drink': True}])
    action4 = RankableAction(id='salad', features=[{'taste': 'salty', 'spice_level': 'none'}, {'nutritional_level': 2}])
    return [action1, action2, action3, action4]<jupyter_output><empty_output><jupyter_text>Creating user featuresNow we will create user features for which we will make the action recommendation for.In our current case we are asking the user their choice for taste and the time of the day.<jupyter_code>#
# Create user feature: Taste Preference
def get_user_preference(rand=False):
    res = {}
    taste_features = ['salty', 'sweet']

    if not rand:
        pref = input("What type of food would you prefer? Enter number 1.salty 2.sweet\n")

        try:
            ppref = int(pref)
            if (ppref <= 0 or ppref > len(taste_features)):
                raise IndexError
            res['taste_preference'] = taste_features[ppref - 1]
        except (ValueError, IndexError):
            print("Entered value is invalid. Setting feature value to", taste_features[0] + ".")
            res['taste_preference'] = taste_features[0]
    else:
        res['taste_preference'] = choice(taste_features)
        print("Randomly picked ", res['taste_preference'] + ".")
    return res
#
# Create user feature: Time of the day
def get_user_timeofday(rand=False):
    res = {}
    time_features = ["morning", "afternoon", "evening", "night"]
    if not rand:
        time = input("What time of day is it (enter number)? 1. morning 2. afternoon 3. evening 4. night\n")
        try:
            ptime = int(time)
            if (ptime <= 0 or ptime > len(time_features)):
                raise IndexError
            res['time_of_day'] = time_features[ptime - 1]
        except (ValueError, IndexError):
            print("Entered value is invalid. Setting feature value to", time_features[0] + ".")
            res['time_of_day'] = time_features[0]
    else:
        res['time_of_day'] = choice(time_features)
        print("Randomly picked ", res['time_of_day'] + ".")
    return res<jupyter_output><empty_output><jupyter_text>Main Loop  Interactive version<jupyter_code>keep_going = True
while keep_going:

    eventid = str(uuid.uuid4())

    context = [get_user_preference(), get_user_timeofday()]
    actions = get_actions()

    # <rank>
    # We get this from the personalizer to suggest what actions can the user take. 
    # In the first few (1000s) of iterations it will random, but once it starts to 
    # understand what the choices are for the given features, the algorithm will 
    # start to make good recommendations. 
    rank_request = RankRequest(actions=actions, context_features=context, excluded_actions=['juice'], event_id=eventid)
    response = client.rank(rank_request=rank_request)
    # </rank>

    print("Personalizer service ranked the actions with the probabilities listed below:")

    rankedList = response.ranking
    for ranked in rankedList:
        print(ranked.id, ':', ranked.probability)

    print("Personalizer thinks you would like to have", response.reward_action_id + ".")
    answer = input("Is this correct?(y/n)\n")[0]

    # <reward>
    # Rewards is way to let the personalizer know whether the choice is correct or incorrect. 
    # The rewards have to be between 0 and 1, both values are inclusive. 
    reward_val = "0.0"
    if (answer.lower() == 'y'):
        reward_val = "1.0"
    elif (answer.lower() == 'n'):
        reward_val = "0.0"
    else:
        print("Entered choice is invalid. Service assumes that you didn't like the recommended food choice.")

    client.events.reward(event_id=eventid, value=reward_val)
    # </reward>

    br = input("Press Q to exit, any other key to continue: ")[0]
    if (br.lower() == 'q'):
        keep_going = False<jupyter_output><empty_output><jupyter_text>An automated version to run multiple iterations<jupyter_code>#
# Feature files with attributes
# 
# The example file defines generic user preference  depending on 
# the time of the day and taste preference
examplepath = os.path.join('data', 'foodChoices.json')
with open(examplepath) as handle:
    userpref = json.loads(handle.read())
# 
# A helper function to support the reward function
def get_reward(timeofday, tastepreference, action):
    if userpref[timeofday][tastepreference] == action:
        return 1
    else:
        return 0
num_requests = 500
i = 1

while i <= num_requests:

    eventid = str(uuid.uuid4())

    context = [get_user_preference(rand=True), 
                get_user_timeofday(rand=True)]
    actions = get_actions()

    # <rank>
    rank_request = RankRequest(actions=actions, context_features=context, event_id=eventid)
    response = client.rank(rank_request=rank_request)
    # </rank>

    print("Personalizer service ranked the actions with the probabilities listed below:")

    rankedList = response.ranking
    for ranked in rankedList:
        print(ranked.id, ':', ranked.probability)

    print("Personalizer thinks you would like to have", response.reward_action_id + ".")

    if (i % 50 == 0):
        print("Waiting for 2 minutes to allow for model update")
        time.sleep(120)

    # <reward>
    answer = get_reward(context[1]['time_of_day'], context[0]['taste_preference'], response.reward_action_id)
    print('Correct Choice' if answer == 1 else 'Incorrect Choice')
    client.events.reward(event_id=eventid, value=answer)

    print(" ")

    # </reward>
    i += 1<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.09663234663234663, 'fraction_numerical': 0.00858000858000858, 'mean_word_length': 3.7455470737913488, 'pattern_counts': {'":': 8, '<': 28, '<?xml version=': 0, '>': 28, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '4', 'dir': 'jupyter-structured-clean-dedup', 'id': '406450', 'license': 'MIT', 'n_tokens_mistral': 2626, 'n_tokens_neox': 2522, 'n_words': 974, 'path': 'Labs/decision/personalizer/foodChoices.ipynb', 'repo_name': 'hakimzulkufli/azure-cognitive-labs', 'size': '9324'}