{ "cells": [ { "cell_type": "markdown", "id": "4e938668-ce23-4bf4-8696-0b11dc95216a", "metadata": {}, "source": [ "# InformationWeightTransformer\n", "The information weight transformer is designed to improve the embeddings given by a simple Ngram Vectorizer by taking into account the amount of information that each token provides. It plays a similar role to the Term Frequency - Inverse Document Frequency transform for weighting count vectors, but by performing a calculation which is grounded in Bayesian inference and information theory.\n", "\n", "It is inspired by the paper *An information-theoretic perspective of tf–idf measures* by A. Aizawa (https://doi.org/10.1016/S0306-4573(02)00021-3)" ] }, { "cell_type": "markdown", "id": "60f1156e-082f-49dc-a8cb-eb80bbd2fb9e", "metadata": {}, "source": [ "## Example: Distinctive Ingredients from Regional Cuisines\n", "Consider a dataset of recipes, labelled by what regional cuisine they came from, and defined by a list of the ingredients used in the recipe." ] }, { "cell_type": "code", "execution_count": 2, "id": "43b05d84-91ba-45b3-8205-a98e694248b0", "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import pandas as pd\n", "from vectorizers.transformers import InformationWeightTransformer\n", "from sklearn.feature_extraction.text import CountVectorizer, TfidfTransformer\n", "from pathlib import Path\n", "import json\n", "from zipfile import ZipFile" ] }, { "cell_type": "code", "execution_count": 3, "id": "cc7b33af-a925-4fb0-8cc8-c074b5c0b284", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
idcuisineingredients
010259greek[romaine lettuce, black olives, grape tomatoes, garlic, pepper, purple onion, seasoning, garbanzo beans, feta cheese...
125693southern_us[plain flour, ground pepper, salt, tomatoes, ground black pepper, thyme, eggs, green tomatoes, yellow corn meal, mil...
220130filipino[eggs, pepper, salt, mayonaise, cooking oil, green chilies, grilled chicken breasts, garlic powder, yellow onion, so...
322213indian[water, vegetable oil, wheat, salt]
413162indian[black pepper, shallots, cornflour, cayenne pepper, onions, garlic paste, milk, butter, salt, lemon juice, water, ch...
............
3976929109irish[light brown sugar, granulated sugar, butter, warm water, large eggs, all-purpose flour, whole wheat flour, cooking ...
3977011462italian[KRAFT Zesty Italian Dressing, purple onion, broccoli florets, rotini, pitted black olives, Kraft Grated Parmesan Ch...
397712238irish[eggs, citrus fruit, raisins, sourdough starter, flour, hot tea, sugar, ground nutmeg, salt, ground cinnamon, milk, ...
3977241882chinese[boneless chicken skinless thigh, minced garlic, steamed white rice, baking powder, corn starch, dark soy sauce, kos...
397732362mexican[green chile, jalapeno chilies, onions, ground black pepper, salt, chopped cilantro fresh, green bell pepper, garlic...
\n", "

39774 rows × 3 columns

\n", "
" ], "text/plain": [ " id cuisine \\\n", "0 10259 greek \n", "1 25693 southern_us \n", "2 20130 filipino \n", "3 22213 indian \n", "4 13162 indian \n", "... ... ... \n", "39769 29109 irish \n", "39770 11462 italian \n", "39771 2238 irish \n", "39772 41882 chinese \n", "39773 2362 mexican \n", "\n", " ingredients \n", "0 [romaine lettuce, black olives, grape tomatoes, garlic, pepper, purple onion, seasoning, garbanzo beans, feta cheese... \n", "1 [plain flour, ground pepper, salt, tomatoes, ground black pepper, thyme, eggs, green tomatoes, yellow corn meal, mil... \n", "2 [eggs, pepper, salt, mayonaise, cooking oil, green chilies, grilled chicken breasts, garlic powder, yellow onion, so... \n", "3 [water, vegetable oil, wheat, salt] \n", "4 [black pepper, shallots, cornflour, cayenne pepper, onions, garlic paste, milk, butter, salt, lemon juice, water, ch... \n", "... ... \n", "39769 [light brown sugar, granulated sugar, butter, warm water, large eggs, all-purpose flour, whole wheat flour, cooking ... \n", "39770 [KRAFT Zesty Italian Dressing, purple onion, broccoli florets, rotini, pitted black olives, Kraft Grated Parmesan Ch... \n", "39771 [eggs, citrus fruit, raisins, sourdough starter, flour, hot tea, sugar, ground nutmeg, salt, ground cinnamon, milk, ... \n", "39772 [boneless chicken skinless thigh, minced garlic, steamed white rice, baking powder, corn starch, dark soy sauce, kos... \n", "39773 [green chile, jalapeno chilies, onions, ground black pepper, salt, chopped cilantro fresh, green bell pepper, garlic... \n", "\n", "[39774 rows x 3 columns]" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "path_recipes = Path(\"data/recipes.zip\")\n", "with ZipFile(path_recipes) as file_data:\n", " data = pd.DataFrame(json.loads(file_data.read(\"train.json\")))\n", "with pd.option_context(\"max_colWidth\", 120):\n", " display(data)" ] }, { "cell_type": "markdown", "id": "e0b4d769-96d4-43b3-81ad-9929974c0b05", "metadata": {}, "source": [ "We can count-vectorize the ingredients, obtaining a vector $x_i$ for each recipe, and we can get a count-vector $X_c$ for each type of cuisine by summing together the vectors corresponding to all recipes in the cuisine $c$.\n", "\n", "Let us take the convention that $X_c$ is a row vector; then it's $i$th entry represents the number of times that ingredient $i$ was used in cuisine $c$'s recipes. We can find the largest entries of $X_c$ to get the most common ingredients in a given cuisine:" ] }, { "cell_type": "code", "execution_count": 4, "id": "9c568115-2954-42f7-a1b7-efc0b04cc235", "metadata": {}, "outputs": [], "source": [ "tokens = []\n", "for i, idno in enumerate(data['id'].to_list()):\n", " tokens_i = ''.join(x.replace(\" \",\"_\").replace(\"-\",\"_\")+' ' for x in list(data['ingredients'].iloc[i]))\n", " tokens.append(tokens_i)\n", " \n", "vectorizer = CountVectorizer()\n", "vectors = vectorizer.fit_transform(tokens)" ] }, { "cell_type": "code", "execution_count": 5, "id": "59775158-16f2-4fbb-9ca5-e63135e354e5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CuisineMost Frequent
0BrazilianOlive oil, Onions, Salt,
1BritishButter, All purpose flour, Salt,
2Cajun_creoleGarlic, Onions, Salt,
3ChineseSalt, Sesame oil, Soy sauce,
4FilipinoWater, Garlic, Salt,
5FrenchAll purpose flour, Sugar, Salt,
6GreekDried oregano, Olive oil, Salt,
7IndianGaram masala, Onions, Salt,
8IrishButter, All purpose flour, Salt,
9ItalianGarlic cloves, Olive oil, Salt,
10JamaicanWater, Onions, Salt,
11JapaneseMirin, Salt, Soy sauce,
12KoreanGarlic, Sesame oil, Soy sauce,
13MexicanGround cumin, Onions, Salt,
14MoroccanGround cumin, Olive oil, Salt,
15RussianOnions, Sugar, Salt,
16Southern_usAll purpose flour, Butter, Salt,
17SpanishGarlic cloves, Olive oil, Salt,
18ThaiSalt, Garlic, Fish sauce,
19VietnameseSalt, Sugar, Fish sauce,
\n", "
" ], "text/plain": [ " Cuisine Most Frequent\n", "0 Brazilian Olive oil, Onions, Salt, \n", "1 British Butter, All purpose flour, Salt, \n", "2 Cajun_creole Garlic, Onions, Salt, \n", "3 Chinese Salt, Sesame oil, Soy sauce, \n", "4 Filipino Water, Garlic, Salt, \n", "5 French All purpose flour, Sugar, Salt, \n", "6 Greek Dried oregano, Olive oil, Salt, \n", "7 Indian Garam masala, Onions, Salt, \n", "8 Irish Butter, All purpose flour, Salt, \n", "9 Italian Garlic cloves, Olive oil, Salt, \n", "10 Jamaican Water, Onions, Salt, \n", "11 Japanese Mirin, Salt, Soy sauce, \n", "12 Korean Garlic, Sesame oil, Soy sauce, \n", "13 Mexican Ground cumin, Onions, Salt, \n", "14 Moroccan Ground cumin, Olive oil, Salt, \n", "15 Russian Onions, Sugar, Salt, \n", "16 Southern_us All purpose flour, Butter, Salt, \n", "17 Spanish Garlic cloves, Olive oil, Salt, \n", "18 Thai Salt, Garlic, Fish sauce, \n", "19 Vietnamese Salt, Sugar, Fish sauce, " ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "cuisine_array = np.array(data['cuisine'].to_list())\n", "cuisines = np.unique(cuisine_array)\n", "n_cuisines = np.size(cuisines)\n", "cookbook_vectors = np.zeros((n_cuisines, np.shape(vectors)[1]))\n", "keywords_freq = []\n", "for k, cuisine in enumerate(cuisines):\n", " idx = (cuisine_array == cuisine).nonzero()\n", " cookbook_vectors[k] = np.sum(vectors[idx], axis=0)\n", " sort_ = np.argsort(cookbook_vectors[k])\n", " cuisine_str = ''\n", " for idx in sort_[-3:]:\n", " word=vectorizer.get_feature_names_out()[idx]\n", " cuisine_str += word.capitalize().replace(\"_\",\" \") + \", \"\n", " keywords_freq.append(cuisine_str)\n", "df = pd.DataFrame()\n", "df['Cuisine'] = [x.capitalize() for x in cuisines]\n", "df['Most Frequent'] = keywords_freq\n", "df" ] }, { "cell_type": "markdown", "id": "164d6e67-2589-4ebd-b201-119eab0d4481", "metadata": {}, "source": [ "These most frequent words are not very good at distinguishing the cuisines, because there are some ingredients that are just too universally common. For example, *salt* appears in the top 3 for every cuisine except Korean! \n", "\n", "To obtain more distinctive words, we can try to weight the words according to their relative frequencies in each document. This is the working principle behind Term Frequency - Inverse Document Frequency (TF-IDF) weighting. Let's try TF-IDF and Information Weighting and see what distinguishing words we obtain:" ] }, { "cell_type": "code", "execution_count": 6, "id": "3c352bcc-41bb-4757-8753-a1cb423f65dd", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
CuisineMost FrequentTF-IDFInfo Weight
0BrazilianOlive oil, Onions, Salt,Sweetened condensed milk, Lime, Cachaca,Chocolate sprinkles, Açai, Cachaca,
1BritishButter, All purpose flour, Salt,Salt, All purpose flour, Milk,Beef drippings, Suet, Stilton cheese,
2Cajun_creoleGarlic, Onions, Salt,Onions, Green bell pepper, Cajun seasoning,Creole seasoning, Andouille sausage, Cajun sea...
3ChineseSalt, Sesame oil, Soy sauce,Corn starch, Sesame oil, Soy sauce,Shaoxing wine, Soy sauce, Sesame oil,
4FilipinoWater, Garlic, Salt,Water, Garlic, Soy sauce,Calamansi juice, Fish sauce, Soy sauce,
5FrenchAll purpose flour, Sugar, Salt,All purpose flour, Salt, Unsalted butter,Grated gruyère cheese, Cognac, Gruyere cheese,
6GreekDried oregano, Olive oil, Salt,Feta cheese, Olive oil, Feta cheese crumbles,Greek seasoning, Feta cheese, Feta cheese crum...
7IndianGaram masala, Onions, Salt,Ground turmeric, Salt, Garam masala,Cumin seed, Ground turmeric, Garam masala,
8IrishButter, All purpose flour, Salt,Salt, All purpose flour, Butter,Irish cream liqueur, Guinness beer, Irish whis...
9ItalianGarlic cloves, Olive oil, Salt,Salt, Grated parmesan cheese, Olive oil,Shredded mozzarella cheese, Ricotta cheese, Gr...
10JamaicanWater, Onions, Salt,Dried thyme, Salt, Ground allspice,Ground allspice, Jamaican jerk season, Scotch ...
11JapaneseMirin, Salt, Soy sauce,Sake, Soy sauce, Mirin,Dashi, Sake, Mirin,
12KoreanGarlic, Sesame oil, Soy sauce,Sesame seeds, Soy sauce, Sesame oil,Sesame oil, Kimchi, Gochujang base,
13MexicanGround cumin, Onions, Salt,Chili powder, Jalapeno chilies, Salt,Flour tortillas, Salsa, Corn tortillas,
14MoroccanGround cumin, Olive oil, Salt,Ground cinnamon, Olive oil, Ground cumin,Ras el hanout, Preserved lemon, Couscous,
15RussianOnions, Sugar, Salt,Sour cream, Sugar, Salt,Dill, Fresh dill, Beets,
16Southern_usAll purpose flour, Butter, Salt,All purpose flour, Butter, Salt,Bourbon whiskey, Grits, Buttermilk,
17SpanishGarlic cloves, Olive oil, Salt,Salt, Extra virgin olive oil, Olive oil,Serrano ham, Saffron threads, Spanish chorizo,
18ThaiSalt, Garlic, Fish sauce,Lemongrass, Coconut milk, Fish sauce,Thai red curry paste, Lemongrass, Fish sauce,
19VietnameseSalt, Sugar, Fish sauce,Garlic, Sugar, Fish sauce,Beansprouts, Lemongrass, Fish sauce,
\n", "
" ], "text/plain": [ " Cuisine Most Frequent \\\n", "0 Brazilian Olive oil, Onions, Salt, \n", "1 British Butter, All purpose flour, Salt, \n", "2 Cajun_creole Garlic, Onions, Salt, \n", "3 Chinese Salt, Sesame oil, Soy sauce, \n", "4 Filipino Water, Garlic, Salt, \n", "5 French All purpose flour, Sugar, Salt, \n", "6 Greek Dried oregano, Olive oil, Salt, \n", "7 Indian Garam masala, Onions, Salt, \n", "8 Irish Butter, All purpose flour, Salt, \n", "9 Italian Garlic cloves, Olive oil, Salt, \n", "10 Jamaican Water, Onions, Salt, \n", "11 Japanese Mirin, Salt, Soy sauce, \n", "12 Korean Garlic, Sesame oil, Soy sauce, \n", "13 Mexican Ground cumin, Onions, Salt, \n", "14 Moroccan Ground cumin, Olive oil, Salt, \n", "15 Russian Onions, Sugar, Salt, \n", "16 Southern_us All purpose flour, Butter, Salt, \n", "17 Spanish Garlic cloves, Olive oil, Salt, \n", "18 Thai Salt, Garlic, Fish sauce, \n", "19 Vietnamese Salt, Sugar, Fish sauce, \n", "\n", " TF-IDF \\\n", "0 Sweetened condensed milk, Lime, Cachaca, \n", "1 Salt, All purpose flour, Milk, \n", "2 Onions, Green bell pepper, Cajun seasoning, \n", "3 Corn starch, Sesame oil, Soy sauce, \n", "4 Water, Garlic, Soy sauce, \n", "5 All purpose flour, Salt, Unsalted butter, \n", "6 Feta cheese, Olive oil, Feta cheese crumbles, \n", "7 Ground turmeric, Salt, Garam masala, \n", "8 Salt, All purpose flour, Butter, \n", "9 Salt, Grated parmesan cheese, Olive oil, \n", "10 Dried thyme, Salt, Ground allspice, \n", "11 Sake, Soy sauce, Mirin, \n", "12 Sesame seeds, Soy sauce, Sesame oil, \n", "13 Chili powder, Jalapeno chilies, Salt, \n", "14 Ground cinnamon, Olive oil, Ground cumin, \n", "15 Sour cream, Sugar, Salt, \n", "16 All purpose flour, Butter, Salt, \n", "17 Salt, Extra virgin olive oil, Olive oil, \n", "18 Lemongrass, Coconut milk, Fish sauce, \n", "19 Garlic, Sugar, Fish sauce, \n", "\n", " Info Weight \n", "0 Chocolate sprinkles, Açai, Cachaca, \n", "1 Beef drippings, Suet, Stilton cheese, \n", "2 Creole seasoning, Andouille sausage, Cajun sea... \n", "3 Shaoxing wine, Soy sauce, Sesame oil, \n", "4 Calamansi juice, Fish sauce, Soy sauce, \n", "5 Grated gruyère cheese, Cognac, Gruyere cheese, \n", "6 Greek seasoning, Feta cheese, Feta cheese crum... \n", "7 Cumin seed, Ground turmeric, Garam masala, \n", "8 Irish cream liqueur, Guinness beer, Irish whis... \n", "9 Shredded mozzarella cheese, Ricotta cheese, Gr... \n", "10 Ground allspice, Jamaican jerk season, Scotch ... \n", "11 Dashi, Sake, Mirin, \n", "12 Sesame oil, Kimchi, Gochujang base, \n", "13 Flour tortillas, Salsa, Corn tortillas, \n", "14 Ras el hanout, Preserved lemon, Couscous, \n", "15 Dill, Fresh dill, Beets, \n", "16 Bourbon whiskey, Grits, Buttermilk, \n", "17 Serrano ham, Saffron threads, Spanish chorizo, \n", "18 Thai red curry paste, Lemongrass, Fish sauce, \n", "19 Beansprouts, Lemongrass, Fish sauce, " ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## Information Weighting:\n", "IWT = InformationWeightTransformer()\n", "iwt_vectors = IWT.fit_transform(vectors,y=data['cuisine'].to_list())\n", "cookbook_vectors_iwt = np.zeros((n_cuisines, np.shape(vectors)[1]))\n", "keywords_iwt = []\n", "\n", "for k, cuisine in enumerate(cuisines):\n", " idx = (cuisine_array == cuisine).nonzero()\n", " cookbook_vectors_iwt[k] = np.sum(iwt_vectors[idx], axis=0)\n", "for k, cuisine in enumerate(cuisines):\n", " sort_ = np.argsort(cookbook_vectors_iwt[k])\n", " cuisine_str = ''\n", " for idx in sort_[-3:]:\n", " word=vectorizer.get_feature_names_out()[idx]\n", " cuisine_str += word.capitalize().replace(\"_\",\" \") + \", \"\n", " keywords_iwt.append(cuisine_str)\n", "\n", "## TF-IDF Weighting:\n", "TFIDF = TfidfTransformer()\n", "tfidf_vectors = TFIDF.fit_transform(vectors)\n", "cookbook_vectors_tfidf= np.zeros((n_cuisines, np.shape(vectors)[1]))\n", "for k, cuisine in enumerate(cuisines):\n", " idx = (cuisine_array == cuisine).nonzero()\n", " cookbook_vectors_tfidf[k] = np.sum(tfidf_vectors[idx], axis=0)\n", "\n", "keywords_tfidf = []\n", "for k, cuisine in enumerate(cuisines):\n", " sort_ = np.argsort(cookbook_vectors_tfidf[k])\n", " cuisine_str = ''\n", " for idx in sort_[-3:]:\n", " word=vectorizer.get_feature_names_out()[idx]\n", " cuisine_str += word.capitalize().replace(\"_\",\" \") + \", \"\n", " keywords_tfidf.append(cuisine_str)\n", "\n", "\n", "df['TF-IDF'] = keywords_tfidf\n", "df['Info Weight'] = keywords_iwt\n", "df" ] }, { "cell_type": "markdown", "id": "d2347e74-74e9-4db9-9d5c-653705e63b12", "metadata": {}, "source": [ "Using the advanced eyeball test, we can see that the TF-IDF and IWT weighted words are much more distinctive of the various cuisines. However the TF-IDF weighting still leaves a lot of redundancy, such as salt still showing up for half of the cuisines. The information weight transform, on the other hand, has distinguished the cuisines much more, and we see some well-known associations like Kimchi in Korean cuisine or Feta in Greek cuisine." ] }, { "cell_type": "markdown", "id": "b64c812a-647a-4c5a-84c2-db9eb440212c", "metadata": {}, "source": [ "\n", "## Theoretical Explanation\n", "What is the Information Weight Transform actually doing? It is weighting each column (word) by the information that an observation of that column conveys relative to the baseline probability. Suppose you have an array of vectors $A$ so that $A[d]$ is a row vector recording the word counts of document $d$. First, a *baseline* probability distribution over the set of documents is computed by dividing the length of each document by the total number of words in the corpus.\n", "$$P_0(d) = \\left(\\sum_{i=0}^{N} A[d]_i\\right / \\left(\\sum_{i=0}^{N}\\sum_{d} A[d]_i\\right)$$\n", "If one picks a random word $w$ from the corpus, the baseline probability distribution $P_0$ is a Bayesian prior for which document the word came from. However, if we look at the word $w$, we can update to a posterior distribution $P'(d) = P(d|w)$ determined by the count data. The *information gain* from an observation of the word $w$ is the relative entropy, or Kullback-Leibler divergence,\n", "$$K(w) = K(P',P_0) = \\sum_{d} P(d|w) \\log\\left(\\frac{P(d|w)}{P_0(d)}\\right).$$\n", "The information weight transform assigns a weight of $K(w)$ to the column of the array $A$ corresponding to the count of word $w$.\n", "\n", "For example, let us first plot the baseline probability for the recipe data. We'll again aggregate along the 'Cuisine' axis." ] }, { "cell_type": "code", "execution_count": 7, "id": "8dc86ed3-7777-40e9-a8e8-15bc2ed463a9", "metadata": {}, "outputs": [ { "data": { "image/png": "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6mLw4MHi5s2bUp1Hjx6JUaNGSf/3eP3110VSUpJo2bKlyt+D3N/QmDFjBACxYMECqezrr78Wvr6+wtzcXFhZWQlvb28xZswYcePGDZ334b9CIQTvniYiIiIiKg2dO3cudup0qvh4DxMRERERUQn4559/VH5PSUnBtm3b0KpVq/LpEJUIXmEiIiIiIioBVatWRd++faVndC1evBi5ubk4duyY2mcg0ouBkz4QEREREZWAdu3a4fvvv0d6ejqUSiUCAwMxffp0JksvOF5hIiIiIiIiksF7mIiIiIiIiGQwYSIiIiIiIpLx0tzDVFBQgBs3bsDKygoKhaK8u0NE9NIQQuDBgweoVq0ajIx4nu5ZjE1EROVDl9j00iRMN27cgJubW3l3g4jopXX16lW88sor5d2NCoWxiYiofGkTm16ahMnKygrA0zfF2tq6nHtDRPTyyMrKgpubm3Qcpn8xNhERlQ9dYtNLkzAVDnWwtrZmUCIiKgccclYUYxMRUfnSJjZxMDkREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJqFTeHSB62biP26pzm9QZHUqhJ0RERBWDIkqhcxsxSZRCT4iK4hUmIiIiIiIiGUyYiIiIiIiIZDBhIiIiIiIiksGEiYiIiIiISAYTJiIiIiIiIhlMmIiIiIiIiGQwYSIiIiIiIpLBhImIiIiIiEgGEyYiIiIiIiIZeiVMCxcuhLu7O8zMzBAQEIBDhw7J1j116hS6du0Kd3d3KBQKxMbGFqlT+Nrzy9ChQ6U6rVq1KvL6Rx99pE/3iYiIiIiItKJzwrR+/XpERERg0qRJOHr0KBo3bozg4GDcunVLbf2cnBx4enpixowZcHFxUVvnzz//xM2bN6Vl586dAICQkBCVegMHDlSp9+WXX+rafSIiIiIiIq3pnDDFxMRg4MCBCAsLg5eXF+Li4mBhYYHly5errf/qq69i1qxZ6N69O5RKpdo6jo6OcHFxkZZff/0VNWvWRMuWLVXqWVhYqNSztrbWtftERERERERa0ylhysvLw5EjRxAUFPTvCoyMEBQUhKSkpBLpUF5eHr777jv069cPCoVC5bU1a9bAwcEBDRs2RGRkJHJycmTXk5ubi6ysLJWFiIioOLoMOQeA2NhY1K1bF+bm5nBzc8PIkSPx6NGjMuotERGVhUq6VL5z5w7y8/Ph7OysUu7s7IyzZ8+WSIc2b96M+/fvo2/fvirlPXv2RI0aNVCtWjWcOHECY8eOxblz57Bp0ya164mOjkZUVFSJ9ImIiP77Coecx8XFISAgALGxsQgODsa5c+fg5ORUpP7atWsxbtw4LF++HM2aNcP58+fRt29fKBQKxMTElMMeEBFRadApYSoL33zzDdq3b49q1aqplA8aNEj62dvbG1WrVkWbNm1w8eJF1KxZs8h6IiMjERERIf2elZUFNze30us4ERG90J4dcg4AcXFx2Lp1K5YvX45x48YVqX/gwAG8/vrr6NmzJ4CnExj16NEDf/zxR5n2m4iISpdOQ/IcHBxgbGyMjIwMlfKMjAzZCR10ceXKFezatQsDBgzQWDcgIAAAcOHCBbWvK5VKWFtbqyxERETq6DPkvFmzZjhy5Ig0bO/SpUvYtm0b3n77bdntcLg4EdGLR6eEydTUFL6+vkhISJDKCgoKkJCQgMDAQIM7s2LFCjg5OaFDhw4a6yYnJwMAqlatavB2iYjo5VbckPP09HS1bXr27IkpU6agefPmMDExQc2aNdGqVSt89tlnstuJjo6GjY2NtHDkAxFRxafzLHkRERFYunQpVq1ahTNnzmDIkCHIzs6WhjCEhoYiMjJSqp+Xl4fk5GQkJycjLy8P169fR3JycpErQwUFBVixYgX69OmDSpVURwpevHgRU6dOxZEjR5Camoqff/4ZoaGhaNGiBRo1aqTPfhMRERkkMTER06dPx6JFi3D06FFs2rQJW7duxdSpU2XbREZGIjMzU1quXr1ahj0mIiJ96HwPU7du3XD79m1MnDgR6enp8PHxQXx8vHRWLi0tDUZG/+ZhN27cQJMmTaTfZ8+ejdmzZ6Nly5ZITEyUynft2oW0tDT069evyDZNTU2xa9cuxMbGIjs7G25ubujatSvGjx+va/eJiIiK0GfI+YQJE/Dhhx9Kw8i9vb2RnZ2NQYMG4fPPP1eJhYWUSqXsIzaIiKhi0mvSh/DwcISHh6t97dkkCHh6E6wQQuM627ZtK1vPzc0Ne/fu1bmfRERE2nh2yHnnzp0B/DvkXC7e5eTkFEmKjI2NAUCruEdERC+GCjdLHhERUXmIiIhAnz594OfnB39/f2lUw7NDzl1dXREdHQ0A6NixI2JiYtCkSRMEBATgwoULmDBhAjp27CglTkRE9OJjwkRERATdh5yPHz8eCoUC48ePx/Xr1+Ho6IiOHTviiy++KK9dICKiUqAQL8m4gaysLNjY2CAzM5NTjFO5ch+3Vec2qTM0zxxJVFHx+CuP7w3RU4oohc5txKSX4r+wVEp0Of7qPEseERERERHRy4IJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyahU3h0gopeL+7itOrdJndGhFHpCREREpBmvMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMRERE/2/hwoVwd3eHmZkZAgICcOjQIdm6rVq1gkKhKLJ06NChDHtMRESljQkTERERgPXr1yMiIgKTJk3C0aNH0bhxYwQHB+PWrVtq62/atAk3b96UlpMnT8LY2BghISFl3HMiIipNTJiIiIgAxMTEYODAgQgLC4OXlxfi4uJgYWGB5cuXq61vb28PFxcXadm5cycsLCyYMBER/ccwYSIiopdeXl4ejhw5gqCgIKnMyMgIQUFBSEpK0mod33zzDbp3747KlSuXVjeJiKgc6JUw6TLG+9SpU+jatSvc3d2hUCgQGxtbpM7kyZOLjAGvV6+eSp1Hjx5h6NChqFKlCiwtLdG1a1dkZGTo030iIiIVd+7cQX5+PpydnVXKnZ2dkZ6errH9oUOHcPLkSQwYMKDYerm5ucjKylJZiIioYtM5YdJ1jHdOTg48PT0xY8YMuLi4yK63QYMGKmPB9+3bp/L6yJEj8csvv2DDhg3Yu3cvbty4gffee0/X7hMREZW4b775Bt7e3vD39y+2XnR0NGxsbKTFzc2tjHpIRET60jlh0nWM96uvvopZs2ahe/fuUCqVsuutVKmSylhwBwcH6bXMzEx88803iImJwZtvvglfX1+sWLECBw4cwMGDB3XdBSIiIhUODg4wNjYuMnIhIyOj2JN9AJCdnY1169ahf//+GrcTGRmJzMxMabl69apB/SYiotKnU8JUEmO85aSkpKBatWrw9PREr169kJaWJr125MgRPH78WGW79erVQ/Xq1WW3y2EPRESkLVNTU/j6+iIhIUEqKygoQEJCAgIDA4ttu2HDBuTm5qJ3794at6NUKmFtba2yEBFRxaZTwmToGG85AQEBWLlyJeLj47F48WJcvnwZb7zxBh48eAAASE9Ph6mpKWxtbbXeLoc9EBGRLiIiIrB06VKsWrUKZ86cwZAhQ5CdnY2wsDAAQGhoKCIjI4u0++abb9C5c2dUqVKlrLtMRERloFJ5dwAA2rdvL/3cqFEjBAQEoEaNGvjhhx+0GuKgTmRkJCIiIqTfs7KymDQREZGsbt264fbt25g4cSLS09Ph4+OD+Ph46SRhWloajIxUzzOeO3cO+/btw44dO8qjy0REVAZ0SpgMGeOtC1tbW9SpUwcXLlwAALi4uCAvLw/3799XucpU3HaVSmWx90wRERE9Lzw8HOHh4WpfS0xMLFJWt25dCCFKuVdERFSedBqSZ8gYb108fPgQFy9eRNWqVQEAvr6+MDExUdnuuXPnkJaWVqLbJSIiIiIiepbOQ/IiIiLQp08f+Pn5wd/fH7GxsUXGeLu6uiI6OhrA04kiTp8+Lf18/fp1JCcnw9LSErVq1QIAfPrpp+jYsSNq1KiBGzduYNKkSTA2NkaPHj0AADY2Nujfvz8iIiJgb28Pa2trDBs2DIGBgXjttddK5I0gIiIiIiJ6ns4Jk65jvG/cuIEmTZpIv8+ePRuzZ89Gy5YtpeEN165dQ48ePXD37l04OjqiefPmOHjwIBwdHaV2c+fOhZGREbp27Yrc3FwEBwdj0aJF+u43ERERERGRRgrxkgy+zsrKgo2NDTIzMzmNK5Ur93FbdW6TOqNDKfSkfLzs+/8y4vFXHt8boqcUUQqd24hJL8V/YamU6HL81fnBtURERERERC8LJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMRERE/2/hwoVwd3eHmZkZAgICcOjQoWLr379/H0OHDkXVqlWhVCpRp04dbNu2rYx6S0REZaFSeXeAiIioIli/fj0iIiIQFxeHgIAAxMbGIjg4GOfOnYOTk1OR+nl5eXjrrbfg5OSEjRs3wtXVFVeuXIGtrW3Zd56IiEoNEyYiIiIAMTExGDhwIMLCwgAAcXFx2Lp1K5YvX45x48YVqb98+XLcu3cPBw4cgImJCQDA3d29LLtMRERlgEPyiIjopZeXl4cjR44gKChIKjMyMkJQUBCSkpLUtvn5558RGBiIoUOHwtnZGQ0bNsT06dORn58vu53c3FxkZWWpLEREVLExYSIiopfenTt3kJ+fD2dnZ5VyZ2dnpKenq21z6dIlbNy4Efn5+di2bRsmTJiAOXPmYNq0abLbiY6Oho2NjbS4ubmV6H4QEVHJY8JERESkh4KCAjg5OeHrr7+Gr68vunXrhs8//xxxcXGybSIjI5GZmSktV69eLcMeExGRPngPExERvfQcHBxgbGyMjIwMlfKMjAy4uLiobVO1alWYmJjA2NhYKqtfvz7S09ORl5cHU1PTIm2USiWUSmXJdp6IiEoVrzAREdFLz9TUFL6+vkhISJDKCgoKkJCQgMDAQLVtXn/9dVy4cAEFBQVS2fnz51G1alW1yRIREb2YmDAREREBiIiIwNKlS7Fq1SqcOXMGQ4YMQXZ2tjRrXmhoKCIjI6X6Q4YMwb179zBixAicP38eW7duxfTp0zF06NDy2gUiIioFHJJHREQEoFu3brh9+zYmTpyI9PR0+Pj4ID4+XpoIIi0tDUZG/55ndHNzw/bt2zFy5Eg0atQIrq6uGDFiBMaOHVteu0BERKWACRMREdH/Cw8PR3h4uNrXEhMTi5QFBgbi4MGDpdwrIiIqT3oNyVu4cCHc3d1hZmaGgIAAHDp0SLbuqVOn0LVrV7i7u0OhUCA2NrZInejoaLz66quwsrKCk5MTOnfujHPnzqnUadWqFRQKhcry0Ucf6dN9IiIiIiIireicMK1fvx4RERGYNGkSjh49isaNGyM4OBi3bt1SWz8nJweenp6YMWOG7ExDe/fuxdChQ3Hw4EHs3LkTjx8/Rtu2bZGdna1Sb+DAgbh586a0fPnll7p2n4iIiIiISGs6D8mLiYnBwIEDpZtg4+LisHXrVixfvhzjxo0rUv/VV1/Fq6++CgBqXweA+Ph4ld9XrlwJJycnHDlyBC1atJDKLSwsZJMuIiIiIiKikqbTFaa8vDwcOXIEQUFB/67AyAhBQUFISkoqsU5lZmYCAOzt7VXK16xZAwcHBzRs2BCRkZHIycmRXUdubi6ysrJUFiIiIiIiIl3odIXpzp07yM/Pl2YMKuTs7IyzZ8+WSIcKCgrwySef4PXXX0fDhg2l8p49e6JGjRqoVq0aTpw4gbFjx+LcuXPYtGmT2vVER0cjKiqqRPpEREREREQvpwo3S97QoUNx8uRJ7Nu3T6V80KBB0s/e3t6oWrUq2rRpg4sXL6JmzZpF1hMZGYmIiAjp96ysLLi5uZVex4mIiIiI6D9Hp4TJwcEBxsbGyMjIUCnPyMgokXuLwsPD8euvv+L333/HK6+8UmzdgIAAAMCFCxfUJkxKpRJKpdLgPhERERER0ctLp3uYTE1N4evri4SEBKmsoKAACQkJCAwM1LsTQgiEh4fjp59+wu7du+Hh4aGxTXJyMgCgatWqem+XiIiIiIioODoPyYuIiECfPn3g5+cHf39/xMbGIjs7W5o1LzQ0FK6uroiOjgbwdKKI06dPSz9fv34dycnJsLS0RK1atQA8HYa3du1abNmyBVZWVkhPTwcA2NjYwNzcHBcvXsTatWvx9ttvo0qVKjhx4gRGjhyJFi1aoFGjRiXyRhARERERET1P54SpW7duuH37NiZOnIj09HT4+PggPj5emggiLS0NRkb/Xri6ceMGmjRpIv0+e/ZszJ49Gy1btpSemr548WIATx9O+6wVK1agb9++MDU1xa5du6TkzM3NDV27dsX48eN17T4REREREZHW9Jr0ITw8HOHh4WpfK0yCCrm7u0MIUez6NL3u5uaGvXv36tRHIiIiIiIiQ+l0DxMREREREdHLhAkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxERET/b+HChXB3d4eZmRkCAgJw6NAh2borV66EQqFQWczMzMqwt0REVBaYMBEREQFYv349IiIiMGnSJBw9ehSNGzdGcHAwbt26JdvG2toaN2/elJYrV66UYY+JiKgsMGEiIiICEBMTg4EDByIsLAxeXl6Ii4uDhYUFli9fLttGoVDAxcVFWpydncuwx0REVBaYMBER0UsvLy8PR44cQVBQkFRmZGSEoKAgJCUlybZ7+PAhatSoATc3N3Tq1AmnTp0qdju5ubnIyspSWYiIqGJjwkRERC+9O3fuID8/v8gVImdnZ6Snp6ttU7duXSxfvhxbtmzBd999h4KCAjRr1gzXrl2T3U50dDRsbGykxc3NrUT3g4iISh4TJiIiIj0EBgYiNDQUPj4+aNmyJTZt2gRHR0csWbJEtk1kZCQyMzOl5erVq2XYYyIi0kel8u4AERFReXNwcICxsTEyMjJUyjMyMuDi4qLVOkxMTNCkSRNcuHBBto5SqYRSqTSor0REVLZ4hYmIiF56pqam8PX1RUJCglRWUFCAhIQEBAYGarWO/Px8/PXXX6hatWppdZOIiMoBrzAREREBiIiIQJ8+feDn5wd/f3/ExsYiOzsbYWFhAIDQ0FC4uroiOjoaADBlyhS89tprqFWrFu7fv49Zs2bhypUrGDBgQHnuBhERlTAmTERERAC6deuG27dvY+LEiUhPT4ePjw/i4+OliSDS0tJgZPTvwIy///4bAwcORHp6Ouzs7ODr64sDBw7Ay8urvHaBiIhKARMmIiKi/xceHo7w8HC1ryUmJqr8PnfuXMydO7cMekVEROWJ9zARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJEOvhGnhwoVwd3eHmZkZAgICcOjQIdm6p06dQteuXeHu7g6FQoHY2Fi91vno0SMMHToUVapUgaWlJbp27YqMjAx9uk9ERERERKQVnROm9evXIyIiApMmTcLRo0fRuHFjBAcH49atW2rr5+TkwNPTEzNmzICLi4ve6xw5ciR++eUXbNiwAXv37sWNGzfw3nvv6dp9IiIiIiIiremcMMXExGDgwIEICwuDl5cX4uLiYGFhgeXLl6ut/+qrr2LWrFno3r07lEqlXuvMzMzEN998g5iYGLz55pvw9fXFihUrcODAARw8eFDXXSAiIiIiItKKTglTXl4ejhw5gqCgoH9XYGSEoKAgJCUl6dUBbdZ55MgRPH78WKVOvXr1UL16ddnt5ubmIisrS2UhIiIiIiLShU4J0507d5Cfnw9nZ2eVcmdnZ6Snp+vVAW3WmZ6eDlNTU9ja2mq93ejoaNjY2EiLm5ubXv0jIiIiIqKX1392lrzIyEhkZmZKy9WrV8u7S0RERERE9IKppEtlBwcHGBsbF5mdLiMjQ3ZCh5JYp4uLC/Ly8nD//n2Vq0zFbVepVMreM0VERERERKQNna4wmZqawtfXFwkJCVJZQUEBEhISEBgYqFcHtFmnr68vTExMVOqcO3cOaWlpem+XiIiIiIhIE52uMAFAREQE+vTpAz8/P/j7+yM2NhbZ2dkICwsDAISGhsLV1RXR0dEAnk7qcPr0aenn69evIzk5GZaWlqhVq5ZW67SxsUH//v0REREBe3t7WFtbY9iwYQgMDMRrr71WIm8EERERERHR83ROmLp164bbt29j4sSJSE9Ph4+PD+Lj46VJG9LS0mBk9O+Fqxs3bqBJkybS77Nnz8bs2bPRsmVLJCYmarVOAJg7dy6MjIzQtWtX5ObmIjg4GIsWLdJ3v4mI9OY+bqvObVJndCiFnhAREVFp0zlhAoDw8HCEh4erfa0wCSrk7u4OIYRB6wQAMzMzLFy4EAsXLtSpr0RERERERPr6z86SR0REREREZCgmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSjUnl3gKgsuY/bqnOb1BkdSqEnRFQRLVy4ELNmzUJ6ejoa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hBMnTiAsLAxhYWHYvn17GfeciIhKExMmIiIiADExMRg4cCDCwsLg5eWFuLg4WFhYYPny5Wrrt2rVCl26dEH9+vVRs2ZNjBgxAo0aNcK+ffvKuOdERFSamDAREdFLLy8vD0eOHEFQUJBUZmRkhKCgICQlJWlsL4RAQkICzp07hxYtWpRmV4mIqIxVKu8OEBERlbc7d+4gPz8fzs7OKuXOzs44e/asbLvMzEy4uroiNzcXxsbGWLRoEd566y3Z+rm5ucjNzZV+z8rKMrzzRERUqpgwERER6cnKygrJycl4+PAhEhISEBERAU9PT7Rq1Upt/ejoaERFRZVtJ4mIyCBMmIiI6KXn4OAAY2NjZGRkqJRnZGTAxcVFtp2RkRFq1aoFAPDx8cGZM2cQHR0tmzBFRkYiIiJC+j0rKwtubm6G7wAREZUa3sNEREQvPVNTU/j6+iIhIUEqKygoQEJCAgIDA7VeT0FBgcqQu+cplUpYW1urLEREVLHxChMRERGAiIgI9OnTB35+fvD390dsbCyys7MRFhYGAAgNDYWrqyuio6MBPB1e5+fnh5o1ayI3Nxfbtm3Dt99+i8WLF5fnbhARUQljwkRERASgW7duuH37NiZOnIj09HT4+PggPj5emggiLS0NRkb/DszIzs7Gxx9/jGvXrsHc3Bz16tXDd999h27dupXXLhARUSlgwkRERPT/wsPDER4erva1xMREld+nTZuGadOmlUGviIioPPEeJiIiIiIiIhlMmIiIiIiIiGQwYSIiIiIiIpLBe5ioTLmP26pzm9QZHUqhJ0REREREmvEKExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCRDr4Rp4cKFcHd3h5mZGQICAnDo0KFi62/YsAH16tWDmZkZvL29sW3bNpXX+/btC4VCobK0a9dOpc69e/fQq1cvWFtbw9bWFv3798fDhw/16T4REREREZFWdE6Y1q9fj4iICEyaNAlHjx5F48aNERwcjFu3bqmtf+DAAfTo0QP9+/fHsWPH0LlzZ3Tu3BknT55UqdeuXTvcvHlTWr7//nuV13v16oVTp05h586d+PXXX/H7779j0KBBunafiIiIiIhIazonTDExMRg4cCDCwsLg5eWFuLg4WFhYYPny5Wrrz5s3D+3atcPo0aNRv359TJ06FU2bNsWCBQtU6imVSri4uEiLnZ2d9NqZM2cQHx+PZcuWISAgAM2bN8dXX32FdevW4caNG7ruAhERERERkVZ0Spjy8vJw5MgRBAUF/bsCIyMEBQUhKSlJbZukpCSV+gAQHBxcpH5iYiKcnJxQt25dDBkyBHfv3lVZh62tLfz8/KSyoKAgGBkZ4Y8//lC73dzcXGRlZaksREREREREutApYbpz5w7y8/Ph7OysUu7s7Iz09HS1bdLT0zXWb9euHVavXo2EhATMnDkTe/fuRfv27ZGfny+tw8nJSWUdlSpVgr29vex2o6OjYWNjIy1ubm667CoREREREREqlXcHAKB79+7Sz97e3mjUqBFq1qyJxMREtGnTRq91RkZGIiIiQvo9KyuLSRMREREREelEpytMDg4OMDY2RkZGhkp5RkYGXFxc1LZxcXHRqT4AeHp6wsHBARcuXJDW8fykEk+ePMG9e/dk16NUKmFtba2yEBERERER6UKnhMnU1BS+vr5ISEiQygoKCpCQkIDAwEC1bQIDA1XqA8DOnTtl6wPAtWvXcPfuXVStWlVax/3793HkyBGpzu7du1FQUICAgABddoGIiIiIiEhrOs+SFxERgaVLl2LVqlU4c+YMhgwZguzsbISFhQEAQkNDERkZKdUfMWIE4uPjMWfOHJw9exaTJ0/G4cOHER4eDgB4+PAhRo8ejYMHDyI1NRUJCQno1KkTatWqheDgYABA/fr10a5dOwwcOBCHDh3C/v37ER4eju7du6NatWol8T4QEREREREVofM9TN26dcPt27cxceJEpKenw8fHB/Hx8dLEDmlpaTAy+jcPa9asGdauXYvx48fjs88+Q+3atbF582Y0bNgQAGBsbIwTJ05g1apVuH//PqpVq4a2bdti6tSpUCqV0nrWrFmD8PBwtGnTBkZGRujatSvmz59v6P4TERERERHJ0mvSh/DwcOkK0fMSExOLlIWEhCAkJERtfXNzc2zfvl3jNu3t7bF27Vqd+klERERERGQInYfkERERERERvSyYMBEREREREcmoEM9hIu25j9uqc5vUGR1KoSdERP89CxcuxKxZs5Ceno7GjRvjq6++gr+/v9q6S5cuxerVq3Hy5EkAgK+vL6ZPny5bn4iIXkxMmIiIXjA8cVI61q9fj4iICMTFxSEgIACxsbEIDg7GuXPn4OTkVKR+YmIievTogWbNmsHMzAwzZ85E27ZtcerUKbi6upbDHhARUWngkDwiIiIAMTExGDhwIMLCwuDl5YW4uDhYWFhg+fLlauuvWbMGH3/8MXx8fFCvXj0sW7ZMejYhERH9dzBhIiKil15eXh6OHDmCoKAgqczIyAhBQUFISkrSah05OTl4/Pgx7O3tZevk5uYiKytLZSEiooqNCRMREb307ty5g/z8fOmZgoWcnZ2Rnp6u1TrGjh2LatWqqSRdz4uOjoaNjY20uLm5GdRvIiIqfUyYiIiIDDRjxgysW7cOP/30E8zMzGTrRUZGIjMzU1quXr1ahr0kIiJ9cNIHIiJ66Tk4OMDY2BgZGRkq5RkZGXBxcSm27ezZszFjxgzs2rULjRo1KrauUqmEUqk0uL9ERFR2eIWJiIheeqampvD19VWZsKFwAofAwEDZdl9++SWmTp2K+Ph4+Pn5lUVXiYiojPEKExEREYCIiAj06dMHfn5+8Pf3R2xsLLKzsxEWFgYACA0NhaurK6KjowEAM2fOxMSJE7F27Vq4u7tL9zpZWlrC0tKy3PaDiIhKFhMmIiIiAN26dcPt27cxceJEpKenw8fHB/Hx8dJEEGlpaTAy+ndgxuLFi5GXl4f3339fZT2TJk3C5MmTy7LrRERUipgwERER/b/w8HCEh4erfS0xMVHl99TU1NLvEBERlTvew0RERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDCZMREREREREMpgwERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJqFTeHSCisuU+bqvObVJndCiFnhARERFVfLzCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJ4INr6YXCh64SERERUVnS6wrTwoUL4e7uDjMzMwQEBODQoUPF1t+wYQPq1asHMzMzeHt7Y9u2bdJrjx8/xtixY+Ht7Y3KlSujWrVqCA0NxY0bN1TW4e7uDoVCobLMmDFDn+4TERERERFpReeEaf369YiIiMCkSZNw9OhRNG7cGMHBwbh165ba+gcOHECPHj3Qv39/HDt2DJ07d0bnzp1x8uRJAEBOTg6OHj2KCRMm4OjRo9i0aRPOnTuHd999t8i6pkyZgps3b0rLsGHDdO0+ERERERGR1nROmGJiYjBw4ECEhYXBy8sLcXFxsLCwwPLly9XWnzdvHtq1a4fRo0ejfv36mDp1Kpo2bYoFCxYAAGxsbLBz50588MEHqFu3Ll577TUsWLAAR44cQVpamsq6rKys4OLiIi2VK1fWY5eJiIiIiIi0o1PClJeXhyNHjiAoKOjfFRgZISgoCElJSWrbJCUlqdQHgODgYNn6AJCZmQmFQgFbW1uV8hkzZqBKlSpo0qQJZs2ahSdPnujSfSIiIiIiIp3oNOnDnTt3kJ+fD2dnZ5VyZ2dnnD17Vm2b9PR0tfXT09PV1n/06BHGjh2LHj16wNraWiofPnw4mjZtCnt7exw4cACRkZG4efMmYmJi1K4nNzcXubm50u9ZWVla7SMREREREVGhCjVL3uPHj/HBBx9ACIHFixervBYRESH93KhRI5iammLw4MGIjo6GUqkssq7o6GhERUWVep+JqOxxtkQiIiIqKzolTA4ODjA2NkZGRoZKeUZGBlxcXNS2cXFx0ap+YbJ05coV7N69W+XqkjoBAQF48uQJUlNTUbdu3SKvR0ZGqiRZWVlZcHNzK3adRERloSIkfLr2gQknERG9rHS6h8nU1BS+vr5ISEiQygoKCpCQkIDAwEC1bQIDA1XqA8DOnTtV6hcmSykpKdi1axeqVKmisS/JyckwMjKCk5OT2teVSiWsra1VFiIiouLo8tiMU6dOoWvXrtJjL2JjY8uuo0REVGZ0niUvIiICS5cuxapVq3DmzBkMGTIE2dnZCAsLAwCEhoYiMjJSqj9ixAjEx8djzpw5OHv2LCZPnozDhw8jPDwcwNNk6f3338fhw4exZs0a5OfnIz09Henp6cjLywPwdOKI2NhYHD9+HJcuXcKaNWswcuRI9O7dG3Z2diXxPhAR0UtO18dm5OTkwNPTEzNmzJAdZUFERC8+ne9h6tatG27fvo2JEyciPT0dPj4+iI+PlyZ2SEtLg5HRv3lYs2bNsHbtWowfPx6fffYZateujc2bN6Nhw4YAgOvXr+Pnn38GAPj4+Khsa8+ePWjVqhWUSiXWrVuHyZMnIzc3Fx4eHhg5cqTKkDsiIiJDPPvYDACIi4vD1q1bsXz5cowbN65I/VdffRWvvvoqAKh9nYiI/hv0mvQhPDxcukL0vMTExCJlISEhCAkJUVvf3d0dQohit9e0aVMcPHhQ534SERFpo/CxGc+OkND02Ax9cAZXIqIXT4WaJY+IKr6KMGEBUUnT57EZ+uAMrkRELx6d72EiIiIi/URGRiIzM1Narl69Wt5dIiIiDXiFiYiIXnr6PDZDH0qlUu2zA4mIqOLiFSYiInrp6fPYDCIiejnwChMRERGePjajT58+8PPzg7+/P2JjY4s8NsPV1RXR0dEAnk4Ucfr0aenn69evIzk5GZaWlqhVq1a57QcREZUsJkxERETQ/bEZN27cQJMmTaTfZ8+ejdmzZ6Nly5ZqZ4wlIqIXExMmIiKi/6fLYzO0eSwGaaaIUujcRkzi+05EZYcJUxnidMxERERERC8WTvpAREREREQkg1eYSCe8SkZERERELxNeYSIiIiIiIpLBhImIiIiIiEgGEyYiIiIiIiIZTJiIiIiIiIhkcNIHohcMJ94gIiIiKjtMmIh0xISFiIiI6OXBIXlEREREREQymDARERERERHJYMJEREREREQkgwkTERERERGRDE76QEQvHU7cQURERNriFSYiIiIiIiIZTJiIiIiIiIhkcEieDjiMh4iIiIjo5cIrTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMTvpARERERC80RZRC5zZikiiFntB/Ea8wERERERERyWDCREREREREJIMJExERERERkQwmTERERERERDKYMBEREREREclgwkRERERERCSDCRMREREREZEMJkxEREREREQymDARERERERHJqFTeHSAiIiIiohebIkqhcxsxSZRCT0oerzARERERERHJ0CthWrhwIdzd3WFmZoaAgAAcOnSo2PobNmxAvXr1YGZmBm9vb2zbtk3ldSEEJk6ciKpVq8Lc3BxBQUFISUlRqXPv3j306tUL1tbWsLW1Rf/+/fHw4UN9uk9ERKRWScc3IiLSjiJKofNSVnQekrd+/XpEREQgLi4OAQEBiI2NRXBwMM6dOwcn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", "text/plain": [ "
" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import matplotlib.pyplot as plt\n", "baseline_counts = np.squeeze(np.array(cookbook_vectors.sum(axis=1)))\n", "baseline_probabilities = baseline_counts / baseline_counts.sum()\n", "N_data = np.shape(cookbook_vectors)[0]\n", "\n", "prior_strength = 0.1\n", "word_index = vectorizer.vocabulary_['sake']\n", "observed_counts = cookbook_vectors[:,word_index]\n", "observed_norm = observed_counts.sum() + prior_strength\n", "observed_probabilities = (\n", " observed_counts + prior_strength * baseline_probabilities\n", ") / observed_norm\n", "\n", "fig, (ax1,ax2) = plt.subplots(1,2)\n", "fig.set_size_inches(10, 5)\n", "\n", "ax1.bar(np.arange(N_data), baseline_probabilities, tick_label=cuisines)\n", "plt.sca(ax1)\n", "plt.title(\"Prior distribution\")\n", "plt.xticks(rotation='vertical')\n", "\n", "ax2.bar(np.arange(N_data), observed_probabilities, tick_label=cuisines,color='g')\n", "plt.sca(ax2)\n", "plt.title(\"Posterior after observing 'sake'\")\n", "plt.xticks(rotation='vertical')\n", "\n", "plt.show()" ] }, { "cell_type": "markdown", "id": "36beedc2-cf62-4ad2-b217-b7fd50a1e68e", "metadata": {}, "source": [ "Computing the information gain of this observation, and handling the change in support due to zero observations, we obtain the information weight for `sake`:" ] }, { "cell_type": "code", "execution_count": 8, "id": "f004c546-1a30-46df-99c2-b5e0ce7c9861", "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "The information weight of 'sake' is 2.7023532028001647\n" ] } ], "source": [ "observed_zero_constant = (prior_strength / observed_norm) * np.log(\n", " prior_strength / observed_norm\n", ")\n", "result = 0.0\n", "\n", "for i, cuisine in enumerate(cuisines):\n", " if observed_probabilities[i] > 0.0:\n", " result += observed_probabilities[i] * np.log(\n", " observed_probabilities[i] / baseline_probabilities[i]\n", " )\n", " else:\n", " result += baseline_probabilities[i] * observed_zero_constant\n", "\n", "print(\"The information weight of 'sake' is\",result)" ] }, { "cell_type": "markdown", "id": "805093ec-f1af-4dd3-a5ec-330ea096e284", "metadata": {}, "source": [ "One final note of comparison: Suppose that a) all documents have the same length, and b) if a word $w_i$ appears in a document, it does so a constant number $n_i$ of times. In this situation, TF-IDF and IWT agree exactly.\n", "\n", "In this sense, one can think of the Information Weight Transform as a TF-IDF which accounts for variability in document lengths and the information provided by relative frequency of a word in different documents." ] }, { "cell_type": "markdown", "id": "00cea5bb-a4ca-4af1-84f1-536820ea4860", "metadata": {}, "source": [ "## Parameters\n", "One benefit of the information weight transform is it's lack of hyperparameters that need to be chosen. The InformationWeightTransformer class only has three keyword arguments:\n", "\n", "`approximate_prior`- Whether to approximate weights based on the Bayesian prior or perform\n", " exact computations. Approximations are much faster especially for very\n", " large or very sparse datasets.\n", "\n", "`prior_strength` - How strongly to weight the prior when doing a Bayesian update to\n", " derive a model based on observed counts of a column.\n", "\n", "`y` - If supervised target labels are available, these can be used to define distributions\n", " over the target classes rather than over rows, allowing weights to be\n", " supervised and target based. If None then unsupervised weighting is used." ] } ], "metadata": { "kernelspec": { "display_name": "Python (sklearn)", "language": "python", "name": "myenv" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.12.3" } }, "nbformat": 4, "nbformat_minor": 5 }