Skip to content

Instantly share code, notes, and snippets.

@dyerrington
Created April 18, 2018 03:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save dyerrington/e6871e7f2338fa57ec197a99c10b9138 to your computer and use it in GitHub Desktop.
Save dyerrington/e6871e7f2338fa57ec197a99c10b9138 to your computer and use it in GitHub Desktop.
Display the source blob
Display the rendered blob
Raw
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<img src=\"http://imgur.com/1ZcRyrc.png\" style=\"float: left; margin: 20px; height: 55px\">\n",
"\n",
"\n",
"# Recommender Systems: Item to Item\n",
"\n",
"_Authors: David Yerrington(SF) _\n",
"\n",
"This is a brief demonstration of how to take the concept of recommendation with an active \"item\" rather than an active \"user\". A populat example would be a UI when you're looking at details of a given item/product/movie, you see **\"People who liked this [item] also liked these [items]\"**.\n",
"\n",
"This is a great technique to use when you don't know preferences a user has, but you have user preferences for an item in context. This item -> items like this. Otherwise, the method we deep dive in with the lesson is more like \"show me items from other people that are like me\"."
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.metrics.pairwise import cosine_similarity\n",
"import matplotlib.pyplot as plt, seaborn as sns\n",
"import pandas as pd\n",
"\n",
"from IPython.display import display\n",
"\n",
"%matplotlib inline"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Friday the 13th</th>\n",
" <th>Nightmare on Elm St</th>\n",
" <th>Dawn of the Dead</th>\n",
" <th>Hiro Dreams of Sushi</th>\n",
" <th>180 South</th>\n",
" <th>Exit Through the Giftshop</th>\n",
" </tr>\n",
" <tr>\n",
" <th>user</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Chuck</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Nancy</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Divya</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Pat</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Friday the 13th Nightmare on Elm St Dawn of the Dead \\\n",
"user \n",
"Chuck 1 1 0 \n",
"Nancy 1 0 0 \n",
"Divya 0 0 0 \n",
"Pat 0 0 1 \n",
"\n",
" Hiro Dreams of Sushi 180 South Exit Through the Giftshop \n",
"user \n",
"Chuck 0 0 0 \n",
"Nancy 0 1 0 \n",
"Divya 1 1 1 \n",
"Pat 0 1 1 "
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"users = [\n",
" (\"Chuck\", 1, 1, 0, 0, 0, 0),\n",
" (\"Nancy\", 1, 0, 0, 0, 1, 0),\n",
" (\"Divya\", 0, 0, 0, 1, 1, 1),\n",
" (\"Pat\", 0, 0, 1, 0, 1, 1),\n",
"]\n",
"\n",
"users = pd.DataFrame(users, columns=[\"user\", \"Friday the 13th\", \"Nightmare on Elm St\", \"Dawn of the Dead\", \"Hiro Dreams of Sushi\", \"180 South\", \"Exit Through the Giftshop\"])\n",
"users = users.set_index(\"user\")\n",
"users"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th>user</th>\n",
" <th>Chuck</th>\n",
" <th>Nancy</th>\n",
" <th>Divya</th>\n",
" <th>Pat</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Friday the 13th</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Nightmare on Elm St</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Dawn of the Dead</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hiro Dreams of Sushi</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>180 South</th>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Exit Through the Giftshop</th>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
"user Chuck Nancy Divya Pat\n",
"Friday the 13th 1 1 0 0\n",
"Nightmare on Elm St 1 0 0 0\n",
"Dawn of the Dead 0 0 0 1\n",
"Hiro Dreams of Sushi 0 0 1 0\n",
"180 South 0 1 1 1\n",
"Exit Through the Giftshop 0 0 1 1"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"items = users.T\n",
"items"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### The Item Similarity Matrix\n",
"\n",
"This matrix shows us similarity of items based on how users have rated them. The quality if these relationships is as good as the data you have. It's also a great point of investigation to see if similar items end up generally together.\n",
"\n",
"Potential non-recommendation tasks on this type of data include:\n",
"- Dimensionality reduction\n",
"- Unsupervised clustering"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"<matplotlib.axes._subplots.AxesSubplot at 0x1103c87f0>"
]
},
"execution_count": 18,
"metadata": {},
"output_type": "execute_result"
},
{
"data": {
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAcMAAAFkCAYAAABcn1CIAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3Xm8rXPd//HXPscUGYoyNEh3eqPQQCFzhojSbPglMkSp\n1K2kiKJRGtRd5twqpIEiQ5MhU5OIG28kIo4yE85xnP3743utrLM7e++1z17Wda293k+P9djXuq61\nvuuz19nWZ33noeHhYSIiIgbZtLoDiIiIqFuSYUREDLwkw4iIGHhJhhERMfCSDCMiYuAlGUZExMBL\nMoyIiL4l6dWSLpjH+W0l/V7SZZL2GK+cJMOIiOhLkj4KHAcsMuL8gsBXgC2AjYA9JS03VllJhhER\n0a/+Arx5HudXBW6yfZ/tWcDFwAZjFZRkGBERfcn2j4DH53FpCeCBtvsPAUuOVdYCXYwr+tAaK27U\nV+vxvW31DesOYcL2P3nfukOY8q466sy6Q5iwNffatu4QJmyhJZYemmwZnX7m/PnWCyfzWg8Ci7fd\nXxy4f6wnJBlGRETPDA1NOp924jpgZUnPBB4GNgS+NNYTkgwjIqJnhoaeut45STsCT7d9jKQPA+dR\nugNPsP33sZ6bZBgREX3L9i3AOtXxyW3nzwQ6bj9PMoyIiJ6Z/hTWDCcjyTAiInpmWpJhREQMuh4N\noJmwZqboiIiIHkrNMCIiemaIZtYMkwwjIqJnpk+bXncI85RkGBERPTMtfYYRERHNlJphRET0zFBD\n62BJhhER0TNNnVoxZZOhpBcAfwauaDv9a9ufHvG4U4Gdqz2vWudeB2xve5f5fO3nA2vaPrPagXkv\n29fPRzmLAr8AdrN9vaTpwLGAgCeAXW3/RdLqwDNsXyTpFmAV24/NT+wREU+lpvYZTtlkWLnW9sZj\nPcD29k/B624KrMIE1sUbSdJawFHAc9tObwtg+zWSNga+DLwReAswA7hofl8vIqIXMrWiIaok8gVg\nFnAMcCglca0EnAD8q7rdVz1+H8pOygtSNot8M3Ai8D3bP5O0KvAl26+vHj8d+BiwqKRLq5c9WNKy\nwGLADrZvlvQ5yrYi04Av2/7BiFAXBt4EfKd1wvYZks6q7q4I3CXpOcAuwCxJrVrwtyStVB2/yfZ9\n8/l2RUR0VVOXY2tmVN2zmqQL2m7Pqc4vYnsD299pe+yhwCdtbwZcCiBpGrA0sJntDSgJcW1KU+W7\nque9Gzi+VYjtJ4DPAyfb/ml1+me2NwXOAd4qaStgJduvATYBPiFpqfbAbV9i+7aRv5Dt2ZL+F/g6\n8MNqW5ITKQn1d9XDjq9qxLcAm0/kDYuIeCoNDQ11dOu1qV4z/I9mUkkrA57HY18CtJLJJcCqtudI\nmgWcIulhSpPlgsAFwJGSng1sAXx8nDj+WP2cASwHrA68supPpCpzRcbZibnF9rsk7Q/8VtJq47ze\nop2UGRHRC03tM5zqNcPRzJnHueuBdavjtQEkrQFsZ/sdwPsp79eQ7WHgu8DXgJ/bfnwe5be/t8Pz\neK3zq0S9KXAacPN4QUt6p6QDqruPVK/zRAevFxHRCEMd/tdrU71mOBHvBb4v6SPAP4HHgJuAf0n6\nAzATuBNYoXr8icBtwBrzKOtqStPnFfO4BmVgzcaSfgM8HTjd9kMdxPhj4NuSLqLUJve1/ZikPwKH\nS7qugzIiImrT1D7DoeHhVCLmR9X/eJLt19Ydy2SsseJGffUH8LbVN6w7hAnb/+R96w5hyrvqqPke\nuF2bNffatu4QJmyhJZaedJVt6zV26Ogz5+w/n9LT6mFqhvNB0luAQ4Ddag4lIqKvNLXPMMlwPtj+\nEfCjuuOIiOg3TZ1n2MzG24iIiB5KzTAiInoma5NGRMTAm97Q0aRJhhER0TNNnVrRzKgiIiJ6KDXD\niIjomfQZRkTEwMs8w4iIGHhNnWeYZBgRET2TmmFERAy89BlGRMTAS80wIiIGXvoMo5H6bUukH1x9\nUd0hTNj+ZAunp1o/boc0qFIzjIiIgZc+w4iIGHipGUZExMBLn2FERAy8btUMJU0DvgmsCcwEdrd9\nU9v1/YAdgDnAZ22fPmZcXYkqIiKit7YDFrG9LvAx4IjWBUlLAR8A1gW2AL46XmFJhhER0TNDQ0Md\n3TqwPnAugO3LgbXarv0LuBVYrLrNGa+wJMOIiOiZ6dOmdXTrwBLAA233n5DU3vV3G3AtcAVw5HiF\nJRlGRETPDHX4XwceBBZvuz/N9uzqeCtgeWAl4PnAdpJeNVZhSYYREdGPLgG2BpC0DnB127X7gEeB\nmbYfA+4HlhqrsIwmjYiInpnWvZkVpwObS7oUGAJ2lfRh4CbbP5W0GXC5pDnAxcAvxiosyTAiInqm\nWyvQ2J4D7DXi9PVt1w8GDu60vCTDiIjomaxAExERAy9rk0ZExMCbluXYCkkbA2cAq9u+rTr3eUpb\n77nAJ22/d4zn7mV7+xHnVweeYbvR+/tIegHwZ8q8l3avBY4HTrV97gTLfBfwLuAJSifyF23/XNLz\ngTVtnznpwCMiuiQ1w7nNAr4taXPbw62TtmcA80yE43gLMANodDKsXGt745EnJU24IElLAgcBq9me\nJWkF4HdVItwUWAVIMoyIxkif4dx+TZnj+D7gG62TVc3pVNvrSNoG+DRlhYH7KDWqC4CVJZ0DPJvy\nQX8ssAswS9IVlBrWRcDqgIG7gA0pC7luDSwLfAtYBFga+LTtMyRdA9xQPW6vqpylq9A+YLt9DguS\njqAsBwRwsu2vSTqxev4LKBM+d7E9shY4Jkm7ANsCT6vK+BrwRuClwH62f9L28Icp/4Z7SzrL9l8k\n/RelhvgxYFFJl9r+6URiiIh4qjQ0F9Y66X5v4EOSVh55QdJ0yvI5W9nehDJ5smURygKtGwD72P47\ncCLwZdu/o6xIcLLtDavHXFodLwS8hFJbOsL25sA+lIQM8HTgUNs7AB8HflW99p6U5Nke3zaUlQ3W\noSTEHaumWoBbbW8JfL167kirSbqg7XbEPB6zuO2tgS9U79Obq7J2bX+Q7SeAzYCVgXMl3Qq8uzr/\n+ep9SCKMiMaYNjTU0a3XahtAY/seSftSEtklIy4/C3jQ9l3V/d8Ay1XH19ieCSBpNvPWqo3dT1mb\nDkrtchHgTuBASbsBw8CC7WFVP1cHNpX0jur+M0aUvyrwm6qJ93FJlwOrVdf+VP28DXjNPGKbZzPp\nCK0y7geusz0sqRX/v1XNok+zvU91/8WUpHjxOOVHRNSiqfsZ1rocWzW4w5Rmznb/ABaX9Kzq/jpt\n14b5T3OY+3eZ12NaDgVOsv1O4HyY61+mtbL59cBXqqT1duB7I8q4jqqJVNKCwHrAjR28dqc6LWM5\n4HuSWsn6VuBuSp/syPckIqJ2Xdy1oquaMLViX8poyn+zPUfSPsDZkh6gfKjfOK8nV/4IHC7pug5e\n7wfAkZJmUGpvy8zjMZ8Bjpe0J2Vl9ENGxHeWpI0lXUZpfj3N9hUdDoJZTdIFI87tOq8Hjqd6zSOB\nX0t6hPLveZxtS1oU+ISkK2yfOj/lR0R0W1MH0AwND3ejItN9kg6g9APOlPRd4Oe2T6o7rqnm0G0O\nauYfwCh+cHU/DBie2x+u/nHdIUR0xUJLLD3pTHbQVh/v6DPn0HM+29Os2YSa4Wgeoiyy+ghwC/D9\nesOJiIipqrHJ0PY3aJt2ERER/W/6UDOHMjQ2GUZExNTT1D7DJMOIiOiZhubCDL2PiIhIzTAiInom\nC3VHRMTAS59hREQMvOnTmpkM02cYEREDLzXDiIjomaYu1J1kGBERPZMBNBERMfAa2mWYZBgREb2T\nmmFERAy8JMNopP1P3rfuECZkf/orXoC1Vn9z3SFMSD9uOfXj/fpvd7cb77i37hAm7KCzDp10GWkm\njYiIgZeaYUREDLyG5sJMuo+IiEjNMCIieiab+0ZExMBrajNpkmFERPRMU3etaGZ9NSIioodSM4yI\niJ7J1IqIiBh40xo66z7JMCIieqZbuVDSNOCbwJrATGB32ze1Xd8KOLi6ewXwPtvDo8bVnbAiIiJ6\najtgEdvrAh8DjmhdkLQ4cDiwje11gFuAZcYqLMkwIiJ6ZmhoqKNbB9YHzgWwfTmwVtu19YCrgSMk\n/Qa4y/Y/xyosyTAiInpmaKizWweWAB5ou/+EpFbX3zLAJsD+wFbAvpJePFZhfdFnKGlj4DTgWmAI\nWBD4qu3TehzHdOBsYDFgW9v3VedXB55h+yJJtwCr2H5sgmXPAi6t7j4NOA84xPacScT7eeB62yfO\nbxkREd3UxXmGDwKLtxdte3Z1fA/we9szACRdBLwMuGG0wvoiGVZ+bXt7AElPBy6UdIPtK3sYw/LA\nMrZfOeL8W4AZwEWTKPte2xsDSBoCjgLeB3x9EmVGRDRKF6dWXAJsC5wmaR1Ks2jLH4GXSloGuB9Y\nBzh2rML6KRn+m+2HJR0NvFXS1cDRwPOApYFzgK8Cv7L9MknrAj8DnkVJZscDpwBbA4sC/wV8YWTt\nSdJOwL6UUUo3AnsCxwArSzra9nuqxz0H2AWYJemK6unfkrRSdfwm4GFKcluZ0jR9oO0Lxvj9hiUd\nAZwAfF3S24APA08AF9v+mKTnAt8CFql+70/bPkPSW4ADgX8CCwHXd/zGRkQ8xbo4zfB0YHNJl1Ja\nDHeV9GHgJts/lXQApYUN4DTb14xVWF8mw8pdwCsoSfBy27tLWgS43fZBku6R9DzgdcBtwCspHayn\nV89f0vaWklYGzgRObBUsaWngU8DLbT8k6SvAe4D3Aqe2EiGA7b9LOhGYYft3kgCOt31xdX5zSrK6\n2/ZuVdkXAS/p4PdbRtIzq1jWsv2IpO9I2hwYBo6wfYGk9arHnAF8EXgVcC/lS0BERGN0q2ZYdSHt\nNeL09W3XTwVO7bS8fk6GKwK3Uz7015a0CaUNeeHq+umU2t96wBcoSWk9YDdKgmw1r95GqV21eyHw\nf7Yfqu5fBGwBnNVhbH+sfs6g1D5XBzaQ9Orq/AKSlrZ9Twe/34sotdqzq0S7eBXfxcCBknajJMYF\nJS0LPNgqt/rGFBHRGA1dgKY/R5NWc0j2AH5AaaK83/ZOlHkmi1Z9bmcAO1IS5DmUOSkLtzpUKQlk\nNH8FVpO0WHV/I8boeAXmMPd7ObLs64FTqj7Braq47xvj95sG7Ef5VvNXSsLevHr+14HfAocCJ9l+\nJ3A+pZngHmBJSc+qilp7jJgjInpu2tBQR7de66ea4aaSLqD0my0AHGzb1VDaUyVtAPyL0r+3gu3b\nq2bTX9m+T9JsOmw2tH23pIOB8yXNAW6iTOpcbpSn/BE4XNJ1o1w/GjhW0oWU4cDfnMco0WdWv98c\nymjZX1CaW4clfZkyYGg6ZfLoaZSEeqSkGZRkuYzt2ZJ2Bc6TdC/weCe/b0TEoBsaHh6rghRT3awH\n78kfwFNsrdXfXHcIE/KHq39cdwgT9uP9Tqo7hAm78Y576w5hwg4669BJV9lO2+urHX3mvP2ofXta\nPeynmmFERPS5pvYZJhlGRETPNHULp74cQBMREdFNqRlGRETPNLRimGQYERG9Mz2b+0ZExKBLn2FE\nRERDpWYYERE909CKYZJhRET0TlObSZMMIyKiZxqaC5MMIyKid1IzjIiIgdfQXJhkGBERvZOaYURE\nDLyG5sIkw4inWr9tidRvW04BfHzL7eoOITpUx8a9nUgyjIiInmloLkwyjIiI3kmfYUREDLyG5sIk\nw4iI6J2h7FoRERGDrqk1w+xaERERAy81w4iI6JlpaSaNiIhBl9GkEREx8BqaC9NnGBERkZphRET0\nTkOrhkmGERHRM+kzjIiIgTdt+oAnQ0kbA3vZ3r7t3OeB64ErgTfY/vQEy3wB8GfgCmAIWBj4ru1v\ndCnsrpL0KuDbwE9tH9B2fitgP2AOMB043vb3Jlj2BZT39/q2cy9jPt7XiIhB04iaoe0rKQlxflxr\ne2MASQsCZ0i61faZ3Yqvi7YAjrL99RHnjwLWtH2/pMWBqyT9wvY/JvNik3xfIyK6rqGtpM1Ihu21\nRkm3UmqL1wFfBY4HFgSGgQ/Yvmq0cmw/LulrwM6SrgbOBO4BzgbOAY6k1CDvAd4NPAwcDTwPWBo4\nx/ZBkk4EHgdWpNQ2TwW2BZ4PvBF4EPg+ZTTuglXsV7f9PgsCJwD/RanpfRn4K7A7MEvS7bZPbwv9\nLuCDkn4IXAusanumpEOAGbaPkrQKJZFuLOkzwKbV659i+6tVOQdLWhZYDNihineu2nhERJ2a2mfY\n66kVm0q6oHUDdpzHY54H7Gh7X+BLwJG2NwQ+SEmM47kLWKY6Xg7YwvYXgWOB91W1yLOBj1avdbnt\nLYH1gb3byrnF9haUpLyS7a2BH1GS4quAB4CtgA8AS4yI4T3A3bbXAzYDDgNuBk4EvjwiEQK8AVgU\nOAW4EzhA0lh/MTtT3rsNgUfbzv/M9qaUxP/WMZ4fEVGLoaHObr3W65rhr+fRZzjS3bbvqY5XBS6C\n0uQn6XkdvMaKwO3V8V9tz2or65uSoNTmbgDuBdaWtAmltrdwWzlXVD/vp9RUAe4DFqEkm5WBn1Bq\nkIeNiGFV4JdV3A9JupZSS/wPkp4BrGh7f2B/Sc+hJN0/jnho+5/H9sDnKMn+nLbzrefMqK5FRDRK\nt2qGkqYB3wTWBGYCu9u+aR6P+RnwE9tHjVVeEyfdz2k7vg7YAP49GGTGWE+UtDClBnnqPMoysHNV\nM/wo5Q3aBbjf9k7AEcCibTWy4TFeamPgzqrmeBjw2RHX2+NeHFid0kw6LwsDp7Ul+jspv+dM4DFg\n+er8K9p+x7dRmkE3BXaRtGIHMUdE1K6LNcPtgEVsrwt8jPIZPtJhwDM7KawRfYZj2A84VtJ+lNrc\nbvN4zGpVk+uc6jHfs/3LaqRpu72BkyRNr+7vRklap0raAPgXcCOwQgdxXQV8X9K+wBPAyNGax1Rx\nXww8DfiU7X9UtdK52J4h6f3AjyXNpvQxnmX755JupCTKDalqfVVf4r2UgTH3AT8H/tZBzBERteti\nn+H6wLkAti+XtFb7RUlvpeSFc+bx3P+Ma3g4lYlBNuvBe/IHEHNZa/U31x3ChH18y+3qDmHCbrzj\n3rpDmLCDzjp00pnsD0f8b0efOWv997vGfC1JxwE/sn1Odf9vwAttz5b0Ukol5a3AJ6kGIo5VXtNr\nhhERMYV0sWb4ILB42/1ptmdXxzsDzwF+DbyAMor/FtvnjlZYkmFERPSjSyij+0+TtA7w7+lttj/a\nOm6bojZqIoQkw4iI6KEubu57OrC5pEspo+13lfRh4CbbP51oYUmGERHRM91qJbU9B9hrxOnr5/G4\nQzopL8kwIiJ6JyvQRERENFNqhhER0TND3esz7Kokw4iI6JmGtpImGUZERO90cTRpV6XPMCIiBl5q\nhhER0TsNbSdNMoyIiJ7JAJqIiBh4Da0YJhlGREQPNTQbJhkOuKuOOrPuECZkzb22rTuECfvxfifV\nHcKE9ON2SJ8974y6Q5iwtZ/z0rpDqEVDc2GSYURE9E76DCMiYuB1cT/DrkoyjIiI3mlmLsyk+4iI\niNQMIyKiZ6ZNa2YdLMkwIiJ6p5m5MMkwIiJ6p6kDaBqaoyMiInonNcOIiOiZptYMkwwjIqJ3mpkL\nkwwjIqJ3hqY3s3eumVFFRET0UGqGERHRMw3tMkwynB+SXg18wfbG1f2XAUcBs4EbgN1tz5G0B/Ce\n6vxhts8aUc6LgK9R/h0WAP4AHGB7zgTjeRPwW2Ah4FTb60zi14uIeMo0dQBNmkknSNJHgeOARdpO\nHwx82vb6wMLA6yUtB3wAeA2wJfA5SQuPKO6zwNdtbwlsBrwYeON8hPVBYIn5eF5ERG9NG+rs1mOp\nGU7cX4A3A99pO/cn4JmShoDFgceBVwGX2J4JzJR0E7AG8Pu2590K7CLpIeB3wNsptUgkHQGsXz3u\nZNtfk3QipeZ3rqTXAdsDPwBeBpwE/D/gWZLOAJYH/mx7j26/ARER8ys1wynC9o8oya7djcCRwHXA\nssAFlJraA22PeQhYcsTzDgQuBz4H/AP4NrCkpG2AlYB1KAlxR0mrjxLPz4ArgZ2BWdXr7gqsC7xW\n0rPn5/eMiHhKDHV467Ekw+74GrCB7VUoNbQjgAcptcSWxYH7RzxvE9tftb0h8DzgYeAgYFXgN7aH\nbT9OSZirjXjuaH8uN9u+r+p3/Aew6CR+r4iIrhoaGuro1mtJht1xLyX5AdwBPIPS7LmBpEUkLUlJ\ncNeMeN4XJW0OYPthyuCbmZQa5voAkhYE1qPUPh+jNH8CvKKtnDk8+W853L1fKyKiu4amDXV067X0\nGXbH7sCpkmZTmir3sD1D0pHAbyiJ6hO2HxvxvHcAR0r6XPW8m4G9bT8kaWNJl1FGiJ5m+wpJxwEn\nSNqJkjhbLqXUSPd8Kn/JiIhJa2if4dDwcCoSg+z3Xzyxr/4A1txr27pDmLAf73dS3SFMeZ8974y6\nQ5iwtZ/z0rpDmLDjL/2fSWey288+t6PPnOdu/bqeZs3UDCMioneaWTFMMoyIiN6poz+wE0mGERHR\nOw3tM0wyjIiInunWtAlJ04BvAmtSRuHvbvumtusfoixMAnC27U+NVV6mVkRERD/aDljE9rrAxyjz\nuwGQ9EJgJ8q0tHWBLSStMVZhSYYREdE73VubdH3gXADblwNrtV27DXid7SeqBUgWpMzTHlWaSSMi\nome6OIBm5JKXT0hawPbsauWuu6v1og8H/mT7hnmWUkkyjIiInuniUmsjl7ycZnt2646kRYATKOtC\nv3e8wtJMGhER/egSYGsASesAV7cuVDXCnwBX2X6P7SfGKyw1w4iI6J3uNZOeDmwu6VLKVP5dJX0Y\nuAmYDmwELCxpq+rxB9i+bLTCkgwjIqJnutVMWg2M2WvE6evbjhdhApIMIyKiZ4amNbN3rplRRURE\n9FBqhhER0TtZmzSaqB+3ROo3N95xb90hTHn9uB3S7/8+cq/vwVDHLvadSDKMiIjeSTKMiIhBly2c\nIiIiUjOMiIhBlz7DiIiIJMOIiBh0Te0zzKT7iIgYeKkZRkRE76SZNCIiBl1T1yZNMoyIiN5Jn2FE\nREQzpWYYERE9MzTUzDpYkmFERPROBtBERMSgG5rehzVDSRsDpwHXtp3+p+23jfL4rwJfBh4GXmf7\n5LZrqwNfr+6uA/wOmAMcDnwE2Mv29fP3a3RG0gzby41xfXXgGbYvknQLsIrtxyb4GosBnwHWBR4F\nhoEjbZ8u6XXA820fI+kzwJbAfsBLbX9jlPI2prw3208kjoiI6FwnNcNfd/pBbHtf+PcH+BuAk9uu\nXQ1sXF2/BdiilWgkfWQCMT+V3gLMAC6aRBknAJe0vRfPAs6TdKHtc9se9w7g5bYfknQqMM9kGBEx\nlUyptUklLUBJGJ8CrgR+DbwO+A6wF/AJYE1Je9o+psNiD5a0LLAYsAPwfOALwCzgGEqSOgx4DLgH\neDfwMtpqTa2an6QXAScCjwO3Ai+wvTGwsKSTq7LvAd5q+/Hquc8BdgFmSbqiiulbklaqjt9EqfEe\nBaxMGYl7oO0L2t6X5QDZfkfrnO1/Snql7WFJuwCrAI8AzwV+Juk84JmSvgl8tS3u2cDOVTErSzoH\neDZwpu1DJL2cUtN+onpP9qhi+gFwZ1X+ObY/0eH7HxHx1GtoMuyk8XZTSRe03T5iezawI3AE8F1g\nP9u3tT3nM5QaZaeJEOBntjcFzgHeWp1bxPYG1WscA7zZ9kbAhcCBY5R1OPBZ25sAl7Sdfzrwcdvr\nA0sCL29dsP13SiL6su3fVaePr5LoLcDmwO7A3bY3BN4I/M+I130BcHPrjqRPSboAuFJS63fC9qcp\nyX0L258B7rX93uo1/ghsRnkPn9F6H4DtgA2AfapzxwL7VO/HNynN060YdgHWpvzbvWKM9ykioreG\npnV267FOXvHXtjduux0OYPsW4GJKbeXcsQro0B+rnzOARatjVz+XAR6sEhaUWulL5lFG6yvHqsCl\n1fFv2q7fW8U98nU6jWl1YOsqwf0IWEDS0m2Pv52SjErw9sFVMj2HkojHczxwN+X93IdSOwS4xvZM\n24+0nVvB9pXVcfv7cZXte20/AfwWUAevGxHRE0PThjq69dp8p19J6wAvpXwQ//eIy3Pmo+zheZyb\nU/28G1hC0vLV/Y2AGyjNg8tX8awIPLO6fg1lAAuUwTpjvcbI12uPe+TjrwdOqRLcVpQmyftaF23f\nDvxV0ntb5yS1aqBjvXbrX/6NwG9sv7Yqe/8x4r5D0hrVcev9AFhV0qKSpgOvZu7BTxER9Roa6uzW\nY530GW5a1YTavZFSi3kT8DfgtyMe8xdgdUn72v7qZIOs+tv2AH4saQ4lAe0C3A/cL+m3wHXAX6un\n7A+cIGk/4AFKH1wn/ggcLum6Ua4fDRwr6UJgCeCbtueMeMzOwCGSLqb05y0G/C9lMNFOo5R7raTv\nAgcD35U0m5KYP1S9zrzsAXxD0hCltrhbdX4WJZEuC/zQ9lVj/cIREb3U1AE0Q8PD41WW+o+knYDf\n2r5J0u7AerbfXXdcTzVJLwBOtb3OeI9tmfXgPVPvD6BhvrDjpL8PxjhuuffeukOYsN///Zq6Q5iw\nP9964aQz2cN/u6mjz5ynP/9FPc2aU3XS/W3AqZIeodTOdhvn8RER0QNN3dx3SiZD2xcBa9UdR69V\ng4M6rhVGREQxJZNhREQ0VEP7DJMMIyKiZ4amTa87hHlKMoyIiN5paJ9hM5cPj4iI6KHUDCMiomea\nOs8wyTAiInonO91HRMSga+oAmmam6IiIiB5KzTAiInqmWyvQSJpG2b5uTWAmsLvtm9qu7wG8h7J2\n82G2zxqrvNQMIyKid7q3a8V2lD1v1wU+RtlfF/j3RusfAF4DbAl8TtLCYxWWZBgRET0zNDSto1sH\n1qfaS9f25cy9BOergEuqfWAfAG4C1vjPIp6UZtIBt9ASSzdznPMUctBZh9YdQkRjLLTkMt36zFmC\nskVfyxOSFrA9ex7XHgKWHKuw1AwjIqIfPQgs3nZ/WpUI53Vtccr+t6NKMoyIiH50CbA1gKR1gKvb\nrv0O2EClTQuLAAAZvUlEQVTSIpKWBFYFxtxAckpu7hsREVNb22jSNYAhYFdKcrzJ9k+r0aR7Uip9\nn7X9o7HKSzKMiIiBl2bSiIgYeEmGEREx8JIMIyJi4GWeYXRNNWprc2DR1jnbJ9UX0dgkbdO+RJOk\nt9s+rc6YRiNp59GuNfk97leSlmHuv+O/1RhORyS9DBBwre2rx3t8zC3JMLrpdOBWYEZ1v5GjsyRt\nQ1mmaQdJ61WnpwNvABqZDClDwwHWAR4BLgXWBhYEGpkMJR1o+zBJpzDib8H2jjWFNS5JxwCvBe6i\njFIcBtYb80k1k3QYsCnwW+CDkk63fXjNYfWVJMPopiHbu9YdRAeuApYBHgVcnZsDnFJbROOwfQCA\npHNtv751XtLP64tqXGdWP4+qNYqJWwN4ke1GfpkbxeuAV9meI2k6cBmQZDgBSYYxaZIWqg5vlrQu\ncAVVTcD2rNoCG4Xt24ATJZ1UfXi8BJhl+8a6Y+vAsyUtZft+SUsDS9cd0GhsX1Ud3gq8lbZmR+DC\n3kfUsTsoK5Y8WHcgE3A7JeYHKK0Fd9UbTv9JMoxuMCX5DVGaalqGgRfWEtEYJG0OHA/8l6Q9gY8A\n/5R0nO3j6o1uXJ8B/iDpQcr6i++uOZ5OnEJZUHnGeA+sk6TLKH+zzwZulHRzdWnYdqObSYEVgBsk\nXQWsBsySdClAH8TeCEmGMWm2VwKQtLbt37fOS9q4tqDG9hHg1bYfl7Q/ZdDPbcAFQKOTYbWKxo8k\nPRu4x/YTdcfUgUdsf6ruIDqwffVzIaC9ReOZNcQyUW+rfra+lMYEJRnGpElan/Jt9MOSvlydngbs\nA7y0tsBGN2z7TkkvBB5vbQgqafY4z6udpDcA76M0hQ1JWsb26jWHNU+SXlwd3iVpB+ZuPr+htsBG\nN5NS2z4JeCclqUwDjqZsCdRkTwBfofx/eAPwIdu31BpRn0kyjG64H1geWLj6CWVAykdri2hsC0ha\nAHg9cB6ApKWAxWqNqjOfBN4P7AWcD2xWbzhjOrrteM+242Hmbk5vinWAD1KmJxxTnZtD9TfScMcC\n3wIuAjamdAO8ts6A+k2SYUya7WuAayQda/sOSU8Dnmji4JnK/wLXUaZTbCbppcD3gK/VGlVn7rF9\nmaS9bJ8oqbGjd21vMvKcpOdVA5gax/YZwBmStrZ9dt3xTNAitn9aHZ8h6cO1RtOHkgxj0iStRGmi\nmSHph5R+tyckfbB9UntT2D5J0hnAw9Vo0uWBXWz/qe7YOjBT0obAgpK25MmaeGNJ+gBlGstSwK7V\n9JAmf1i/TdJb20/YbvpApQUkrW77akmr09A5vk2WZBjd8G3gYOAFwA+BFwOPAecAjUuGALYfbDu+\nE7izxnAmYm9gFeAw4FBKs2nT7QBsRBlR+hLgV/WGM65Tq59DwCsoIzWb7gPACZJWAP7O3M3S0YEk\nw+iGBWxfCFwoaRPb/4D+GJDSb2z/XdIqlBV0PkUZLNF0w5Qa7F22hyU1enSm7fY+wnMbvrABAFWr\nxtp1x9HPkgyjGyzpOGBP27sASPoYDZ9X1o8kfRZ4LmV5tlnAAZSaV5OdTxnYsYOkrwBjbrJaN0lb\ntN1dHli2rlg6Jelgyijjf38Btd0PNdrGSDKMbtgD2Nb2nLZztwNH1hRPRyRtS5m0vnDrnO2t64uo\nI+vb3lDS+bb/V9LedQc0HtufAD4BIOn3th+vOaTxtH+5eIz+WNhgG2BF24/WHUi/SjKMSauS4E9G\nnPtuTeFMxJeA9wD31R3IBCwgaRFguFqDsvGT7iWdT9uADknYbuLUCgBs71qNMF4NuMH2lXXH1IF/\nAE3/ktFoSYYxaW2Tq/9DQydXt/yf7QvqDmKCvgL8EXgWZYeCL4/98EbYq/o5BLwSWLPGWMYl6f3A\njpT3dz9Jp9n+Us1hzVPbjiDLAn+SdE11abjJO4M0UZJhdMMJlDVIr2fupaCaOrm65SfVepTXtU40\nfQi97R9I+iXwIuCvtu+uO6bx2Hbb3eslNfo9piTCDWzPlrQgZbusRiZD+m9HkMZKMoxu2IKyC8E7\nbf+97mAm4APAFykr6DSepH2Ad1B2qridsgD2t2sNqgPVYugtK1B2V2iyIduzAar1axvb/FiN4qaa\nK/sMSrP5R4Gv1xlXP0oyjEmz/YikvYDnU+Y49YsZtr9fdxCdkHQIsBxlMMddwIqUJrzn2D6sztg6\n0L4wwKPA2+sKpEMXV4tH/AbYALik5ng6cRLwWcqI0h9SmtP/YwWgGN3Q8HAWKojBVH3gPR34E08u\nIP3xWoMahaTLbK874tw04HzbG9UU1riqhcTvro5fD8y0/cuawxpXFeuqwLX9sDRbNUhpM+A825tJ\nusj2hnXH1U+m1R1ARI3OpDQ1Xk/Zk9FjP7xWj408UY3ibezCBpJ2BC6XtKCkTwIHAu+VdGDNoY1K\n0hurw4spNfH1JPXDAu4LUQZTXSRpE9LqN2FJhjFwJG1RTay+cx63phqtCafJe9e9G1izmle4F/Bm\nyo7329Qa1SgkfR7YudrR5OuUXUzuoewG0XS7UL7MfYEy0ninWqPpQ/n2EF0laQlKf9bNtv9Vdzyj\nGG3FlmGgqUtvrS/pjhHnhiiDJprqCdv/krQa8M9qDVgkNXVu5Cttb14lw22A51b94RfXHVgHPmh7\nn+r4NEknATvXGVC/STKMrqlW+v8E5e/qNEnDDR3c8W7b/1HTkrRiHcF0wvZCdccwH6ZXX47eSlm0\nHUnPpWxM3EStJudXAVfbfqS639j3XtL7KM3Pz5T0Zp5sKbi2vqj6U5pJo5s+RNkg9W7Krgpvqjec\nUf171wRJh7edb/w0hT5zBPBnYGvgy5JeRemL+3StUY3uiar5fB+q9VMlbUazp95cbXt54FO2V7C9\nfHXLxr4TlJphdNMc2zOrGuGwpKY2k7b3s71ylPMxSbbPoWzrBYCkWcCrbd9VW1Bj+yBlesItwLeq\n/SK/SLOngnypGjCzRfXF7t9/ww3eXLuRkgyjm35TLQ/1XElHAb+vO6AOjFwxpy9IeobtflpTFdtN\nrmFh+y+URQ1azqtuTfYL4ErKTibtSx8OU1aFig4lGUbX2P64pNcBVwDXNXGX+8rwKMeNJ2kj4H8o\n/XE/AG61fXzNYUVNWjuCSDrI9qF1x9PPMuk+ukbSCyiDJRZtnbPduP4hSQ8A/0epFa7Wdryq7aXq\njG08ki4CtqP0aW0FXGL7lWM/qx6SPmP7E5LeaPsn4z8jJkrS7raPk/Q5Rnyxa+oCEk2VmmF00ynA\nuTR/U9816g5gEubYvrfql31M0kN1BzSGN1bTQd4vaa4Ncm0fU1NMY6oW5l4DWJIycOaahve93Vb9\nvL7WKKaAJMPopkdsf6ruIMZj+9a6Y5iEm6pawNKSPgY0+XfZlbKI+8LMvT5pI1VLsH0OuBF4mLKg\n+CqSPm77jFqDG4Xt8yQtVW30/GbK8oLDwMk1h9Z3kgxj0tr2M7xL0g6UPsPWWp9N3s+wH+0F7E6Z\novBwddxItn8P/F7Sz4G/AP9Fs7ed+gSwvu0HWyckLQn8EmhkMpS0HWWe4VrAJynzOV9OSeTfrDG0\nvpN5htENR1e35YE9KXusHU32WnsqLEaZx/lb4EFGX02nSVYCLqckm8sl/b+a4xnNgsAjI849SrMH\nWb0f2LI6vs/2AZQRsbvUFlGfSs0wJs32JgCStmkfQSqpyfOzkPQySvJepHWu6Zv7AqdT5sG15uo1\n+YO65UPAK2w/LGlx4NfAd2uOaV6OAa6oll97AFgCWB84staoxjbN9j3V8YUAth+QNDKpxziSDGPS\nJG0DrAfsKGm96vQ04I3AabUFNr4TgW/w5CCEfjDUBwl7pDm2Hwaw/ZCk/9iBowlsHyvpp5Tl2Jag\nJMRPN3iRAICntQ5sH9J2fnrvQ+lvSYbRDVdRdl9/lCe3QZoDnFpbRJ2ZYfu4uoPohKTW+pg3S1qX\nuftlmzzaEeAvko4ALgI2pPQfNtVawEzgB5QtkbavBtD8rd6wRnWZpH1sf6N1otpo+7IaY+pLmWcY\nXSNpWrXHXl+oVsm5hbk3923krhWS/kqJceSSccO2G73SSLULxHsom+VeBxxTbevUKJKOozSZLw48\nG/gOcAewt+0tx3puXSQtCpwAvBi4mdI/ezOws+1H64yt3yQZxsCSNHJh7uGmN0FKWrsapdm6v7Ht\nC2oMacpo7Q4vaQj4P9urVefPb/WLN1U1j/MFwO22/15zOH0pyTAGmqSXUlahucH2lXXHMxpJ61Pi\n/DCl+Q5Kv+w+tl9aW2BTiKTLgEOAZSiDZl4DPAR83/b6NYYWPZCpFdE1ks6StJ2kvui8l/R+4FjK\n4J9jJO1Xc0hjuZ8ydaU1gX15yo7mH60zqClmL0pz7krA+yijM39B3uOBkJphdI2kVYB3U1YdOQ84\nzvaN9UY1uqomsIHt2dUyXJfaXrvuuMYiaQXbI3e8bzRJL6GMzpxD2SLps7Z/NfazYn70424mTZGa\nYXSN7ettfxTYHHgecI2kX0haq+bQRjNkezZANaCjcYM6Ruq3RFg5ijJC80DKxPuD6w1n6pG0kaRr\ngEslfVrSbnXH1G8ytSK6RtJWlJUvVqFMqt6XsqrH2cCa9UU2qosl/RD4DWVy9SU1xzMqSUvafqDu\nOObT45SdQRayfXk1urRxJJ1PaYZuN0QZWLXePJ7SJIdSpq38iFL7vgTI1l4T0Mg/yuhb/w/4pu0L\n209KauTi3bb3qxZnXhU40fbP6o5pDGcCG0r6lu296w5mgloLR59drUr0r5rjGc3HKH3IbwJm1xzL\nRPXTbiaNlD7D6Jqq320tSm1wCFjB9in1RjU1SDoPeCawMnBtdbovai2SlgFeZftsSZsAVza1X0vS\nR4CbbJ9edywTUc2R/CewNWUrtVVtv6veqPpLaobRTT8CFgKeQ1kO6g7K/5gxeVsBK1AWQN+b/5x8\n32SLAy+S1BqVuTbwxRrjGZXtw+uOYT71zW4mTZUBNNFNS9p+HWVHhVfStgB2TI7tObZvp6z3ug1l\nuP92wJ21BtaZn1BqtTPbbtFd/bibSaOkZhjd1BqNuZjtR9vW02ykasL9t4ClgO9RdjU/a+xn1e5o\nygLSvwA2Ao4Ddq41ovHdNmIR6ei+ftzNpFGSDKObTpf0SeAqSZdTvqE22dcou7EfSxl5dw7Q9GS4\nsu0Nq+MzJF1aazSdOVPS53myrxPbJ9UYz1TUj7uZNEqSYXSN7f9pHUv6GdDYCfcttm+qRuD9s09G\n4C0iaVHbj0h6Gv2xVc/2lAW6V63up9bSJX2+m0mjJBnGpFULXo/2Adfkb6v3SnoPsJik7SlLnjXd\n1yg172soa5X2wwT2mX04HaRfmCd3M9m07fww0OjdTJomyTC6obVv4d7ApZQJv2tTNkltst2Aj1MG\nHqxV3W8029+TdA7lg+6vbbucN9mtkg5g7lpLI7fK6je2V4J572ZSW1B9KskwJs32eQCS/tt2a8j8\nJZJ+UWNYnfiW7Z3qDmKibN8L3Ft3HBOwIGW/vRdX94eBJMMuaN/NRNJcu5kA2c1kApIMo5ueLmlT\n4PeUnSAaPZqU0v+2BnADZRHp9LM8BWzv2n5f0vJ1xTIFjdzNBMrfcnbamKAkw+imd1PWSPwGZcDE\nO+oNZ1wvpsyBa0k/y1OgWo7vvZQvR4tSvny8pNagpgjb11AWxD+2Txdxb4wkw5g0SQtUuz/cDOxE\ntUxYvVGNz/bqdccwUZJ2Bg6g1ARay7E1PYFvBTwX+AplY+Jv1hvO1JNEOHlJhtENJwE78uTINngy\nITb2g1rSGyibuLbWUl3a9hr1RjWu/YFtgdvqDmQC7rE9U9Li1VSWResOKGKkJMOYNNs7VocH2f5u\nrcFMzCeB91PWdTyfsg9j091s+6a6g5ig2yW9G/iXpM9RNvqNLpI0HXg5pRkaANsX1RdR/0kyjG7a\ng7KPYb+4x/ZlkvayfaKkXcd/Su0eqaZWXMmT0xQ+Xm9I43oPpZn0B5T9LrevNZqp6YeUZQVnVPeH\ngSTDCUgyjG5aWNKfKM2lrdGZO479lFrNlLQhsKCkLXlyNF6TnV13APNhMWBPyvv7MyAjdrtvGdsb\n1B1EP0syjG7av+4AJmhvYBXgMMoo2IPqDacjOwA/Bs6w/Y+6g+nQCZR1XzeirAF7fHUc3XOrpOfZ\n7qe+5EbJFk4xaZIOBKh2uL/B9oWtW82hjWcGZUPUp1P21/trveF0ZDfKeqTHS/q5pA/UHVAHlrZ9\nAvC47Uvpr70YG03SnZLuoGzq+xdJM9rOxQSkZhjdsCmldgVlK6RNx3hsk5xNmfvWWpN0GHhzfeF0\n5A7KogbPoOxn+A7gyFoj6oCkVaqfzwWeqDmcKcN2PzTt94Ukw+iGoVGOm24R2/3WXHc38DfgC8Dm\nth+oOZ5OfAD4NmXXih9SJuBHF0n69YhTj1Om3xxm+5beR9R/kgyjG4ZHOW66i6qBM9e1Ttj+W43x\ndGIbYEvKaj9vkfRL20fXHNN4Xmd73bqDmOJupSyQ/xtgXcpc1Mso/bOvrTGuvpFkGN3wymqT2SFg\ntbbjYdvr1RvamJYFvsrczaRNjpdqKsjfKM2lO1KmKjQ9GW4t6Su20zz61Hl+2xqwlrST7eOrFYui\nA0mG0Q1NX7VlNLK96vgPa45q6srdwOnATrb/XnNInXgWcIekv1K+cDT9S1I/Wqhq5biM8oVuQUkv\npG0SfowtyTAmzfatdccwn66WtA7wJ/pnd/DXVls4AWUHCNt31hlQB7apO4ABsAtwOKWl42pKM/o6\nwIdrjKmvJBnGINsQeH3b/UavpVr5oKS9KQt1LwrcSNnPrpEkvZ4y4nUZ4HbgVNsjB3vEJNn+C/85\nEvrmOmLpV0mGMch268PdwbcCnkcf7AAh6X2UeL8G3AWsCHxc0otsH1NrcFOMpDspX+aGgGdS1rDt\nqy6AuiUZxsCRtAGlNvWhPtwdvJ92gNgJ2KBt4MyfJf2csst9kmEXtc83lLQicEh90fSnrEATg+g+\nYDme3B18ecogj37YHbyfdoCYNXIEqe2ZwOya4hkIVR/+KnXH0W9SM4yB0+e7g/fTDhBzRjnfTwsz\n9AVJp/DkHN8VKM3SMQFJhjHIdpf0fspqHa15kSvUHNOoJK0BvJUnB6P8wPaN9UY1ptb803ZDlJVo\noruOajt+DPhDXYH0qyTDGGTbUiYrP1p3IOOR9DbKriBHUz7oVgR+KOmTtn9Sa3Cj69f5p/3oT5Rd\nV1YDbqCMMr53zGfEXJIMY5D9g1Ir7AcfBDay/a/WCUknAj8FGpkM+3j+aT86AbiQslD+RsCJwBvq\nDKjfJBnGwGnrX1kW+JOka6pLww3ejHh2eyIEsP2QpCxxFlC2yfp6dXylpLfWGk0fSjKMQXTU+A9p\nnNEGo2REeAA8TdJytmdIWpay52VMwNDwcD9tMhDRPZI+OeJUa9ub79tuVPOppLuAX404PQRsYnu5\nGkLqWDXw53jKYgF3UhY7uKLeqKYWSZtR5m4+QJlus0dW+pmY1AxjkK0JPErZ9mYdnvyw3hJ4Z41x\nzcvbRznfD7XcrwG7275K0suA/wFeU3NMU82ytl8oaRnbd9cdTD9KMoxBtpTtt1THR0v6ue13Srq4\n1qjmwfaFdccwCdNsXwVg+0pJmXTffXsC30sinH9JhjHIlmp9k5a0NLCkpAXJtjfd9rikbSg18A2B\nmTXHMxUtXG3vZZ7cJqupg8EaKckwBtnBwG8lPQg8HXg/8N+U/q3ont2ALwGfB64F9qg3nClp/7oD\n6HdJhjGwbJ8l6WzKuqT/sD0MnFtzWFPRB22/re4gprhbKasTtbdq9HPTes9lWHYMHEnfqH5eBlxM\n2TX+knksHRbdsaqkpeoOYoo7BViMsiZp6xYTkJphDKJDq59NXuR6KlkNuEfSP3myP6uxa8D2qUds\nf6ruIPpZ5hnGwJG082jXbJ/Uy1giJkPSi6vDQ4AzgSuodq+wfUNNYfWl1AxjEI3cNWEI2BV4BEgy\n7BJJB9o+bMT2QgBkpGPXHN12vGfb8TCwaY9j6WtJhjFwbB/QOpb0IsqixmcB+9YV0xR1ZvWzHxYG\n6FeH2z677iCmgiTDGFiS3kdJgB+yfVbd8UxBa0pas+4gprj9gCTDLkgyjIEj6TnAtyn7vb3K9n01\nhzRVtTdH7wCcTLWJcj3hTEnTqoUihkZesD2rhnj6VgbQxMCRdB8wC/g16cvqCUnn296k7jimGkmP\nUtbTbf+SMUQZsfvC2gLrQ6kZxiDaru4ABlC+dT81Ls+XjO5IMoyB0+eLXkfEUyDJMCKeEm1TKoaA\nl0g6uXUtzdFd8/66A5gq0mcYEU8JSRuNdi2182iaJMOIiBh4Wag7IqLPSdp9xP0P1BVLv0rNMCKi\nT0naAXgDsAllqhDAdOCltl9SW2B9KANoIiL617mUeYZL8+Q6pXOAv9QWUZ9KMoyI6F+L2b5A0h0j\nzj+9lmj6WJJhRET/+nB1O3rE+exaMUHpM4yI6HOSnmP77233X2H7ijpj6jcZTRoR0f/Ok7QFgKT/\nBo6vOZ6+k2QYEdH/XgvsJ+lPwPOBdWqOp+8kGUZE9L81gOWBy4GXA8+tN5z+k2QYEdH/DgFeb3tv\n4KPAGfWG03+SDCMi+t+Gtv8GYPty4DU1x9N3kgwjIvqUpO8D2H6iGjjTkprhBCUZRkT0r2e3Hb++\n7Xio14H0uyTDiIipoT0BZgL5BCUZRkT0r+FRjmOCshxbRET/eomkkym1wvbj1eoNq/8kGUZE9K+3\ntx0fNcpxdCBrk0ZExMBLn2FERAy8JMOIiBh4SYYRETHwkgwjImLgJRlGRMTA+/+zsS5VWcMH9AAA\nAABJRU5ErkJggg==\n",
"text/plain": [
"<matplotlib.figure.Figure at 0x112535c88>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"item_user_sim = pd.DataFrame( \n",
" cosine_similarity(items, items), \n",
" index = items.index, \n",
" columns = items.index \n",
")\n",
"sns.heatmap(item_user_dist)"
]
},
{
"cell_type": "code",
"execution_count": 33,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'Top Similar Titles (based on user sim)'"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Friday the 13th</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Friday the 13th</th>\n",
" <td>1.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Nightmare on Elm St</th>\n",
" <td>0.707107</td>\n",
" </tr>\n",
" <tr>\n",
" <th>180 South</th>\n",
" <td>0.408248</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Dawn of the Dead</th>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Hiro Dreams of Sushi</th>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Exit Through the Giftshop</th>\n",
" <td>0.000000</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Friday the 13th\n",
"Friday the 13th 1.000000\n",
"Nightmare on Elm St 0.707107\n",
"180 South 0.408248\n",
"Dawn of the Dead 0.000000\n",
"Hiro Dreams of Sushi 0.000000\n",
"Exit Through the Giftshop 0.000000"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"'Common Users'"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>Friday the 13th</th>\n",
" <th>Nightmare on Elm St</th>\n",
" <th>Dawn of the Dead</th>\n",
" <th>Hiro Dreams of Sushi</th>\n",
" <th>180 South</th>\n",
" <th>Exit Through the Giftshop</th>\n",
" </tr>\n",
" <tr>\n",
" <th>user</th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" <th></th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <th>Chuck</th>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" </tr>\n",
" <tr>\n",
" <th>Nancy</th>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>1</td>\n",
" <td>0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"</div>"
],
"text/plain": [
" Friday the 13th Nightmare on Elm St Dawn of the Dead \\\n",
"user \n",
"Chuck 1 1 0 \n",
"Nancy 1 0 0 \n",
"\n",
" Hiro Dreams of Sushi 180 South Exit Through the Giftshop \n",
"user \n",
"Chuck 0 0 0 \n",
"Nancy 0 1 0 "
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"top_n_items = lambda title: item_user_sim.query(\"index == '%s'\" % title).T.sort_values(title, ascending=False)\n",
"display(\"Top Similar Titles (based on user sim)\", top_n_items(\"Friday the 13th\"))\n",
"display(\"Common Users\", items.T[items.query(\"index == 'Friday the 13th'\").any(0)])"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python [conda env:dsi-plus]",
"language": "python",
"name": "conda-env-dsi-plus-py"
},
"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.6.2"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment