{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"pygments_lexer":"ipython3","nbconvert_exporter":"python","version":"3.6.4","file_extension":".py","codemirror_mode":{"name":"ipython","version":3},"name":"python","mimetype":"text/x-python"}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"## This experiment was performed using LightFM which a very popular recommender module and it has support to take in different data modalities such as text, image, graphical, etc. Please check out their official documentation in the link mentioned below:  \n\nThe objective of this experiment is to find the best parameters which give the best precision@12 for the problem at hand.\n\nPlease refer to notebooks where you will be able to visualize different experimentations based on light FM:  \n1. Light FM with only customer article interactions:  \nLink: https://www.kaggle.com/rickykonwar/h-m-lightfm-nofeatures  \n\n2. Light FM with customer article interaction + 1 article feature (product group name)  \nLink: https://www.kaggle.com/rickykonwar/h-m-lightfm-1articlefeature  \n\n3. Light FM with customer article interaction + 1 article feature (product group name) + article description embeddings  \nLink: https://www.kaggle.com/rickykonwar/h-m-lightfm-2articlefeatures  \n\nLink to LightFM documentation\nmaking.lyst.com/lightfm/docs/home.html  \n\nIt incorporates Hyper Parameter tuning for the problem statement\n\nHope you like this notebook, please feel free to vote for this notebook","metadata":{}},{"cell_type":"markdown","source":"## Importing Required Libraries","metadata":{}},{"cell_type":"code","source":"# Importing Libraries\nimport sys, os\nimport re\nimport tqdm\nimport time\nimport pickle\nimport random\nimport datetime\nimport itertools\n\nimport pandas as pd\nimport numpy as np\nimport scipy.sparse as sparse\n%matplotlib inline\nimport matplotlib.pyplot as plt\n\n# lightfm \nfrom lightfm import LightFM # model\nfrom lightfm.evaluation import precision_at_k\nfrom lightfm.cross_validation import random_train_test_split\n\n# multiprocessing for inferencing\nfrom multiprocessing import Pool","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:00.473648Z","iopub.execute_input":"2022-03-17T05:16:00.474025Z","iopub.status.idle":"2022-03-17T05:16:00.488463Z","shell.execute_reply.started":"2022-03-17T05:16:00.473989Z","shell.execute_reply":"2022-03-17T05:16:00.487278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"os.environ[\"openblas_set_num_threads\"] = \"1\"\ndata_path = r'../input/h-and-m-personalized-fashion-recommendations/transactions_train.csv'\ncustomer_data_path = r'../input/h-and-m-personalized-fashion-recommendations/customers.csv'\narticle_data_path = r'../input/h-and-m-personalized-fashion-recommendations/articles.csv'\nsubmission_data_path = r'../input/h-and-m-personalized-fashion-recommendations/sample_submission.csv'","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:13:20.299523Z","iopub.execute_input":"2022-03-17T05:13:20.299823Z","iopub.status.idle":"2022-03-17T05:13:20.306285Z","shell.execute_reply.started":"2022-03-17T05:13:20.299792Z","shell.execute_reply":"2022-03-17T05:13:20.305189Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Data Extraction\ndef create_data(datapath, data_type=None):\n    if data_type is None:\n        df = pd.read_csv(datapath)\n    elif data_type == 'transaction':\n        df = pd.read_csv(datapath, dtype={'article_id': str}, parse_dates=['t_dat'])\n    elif data_type == 'article':\n        df = pd.read_csv(datapath, dtype={'article_id': str})\n    return df","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:13:21.174388Z","iopub.execute_input":"2022-03-17T05:13:21.175286Z","iopub.status.idle":"2022-03-17T05:13:21.183306Z","shell.execute_reply.started":"2022-03-17T05:13:21.175227Z","shell.execute_reply":"2022-03-17T05:13:21.181443Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#%%time\n\n# Load all sales data (for 3 years starting from 2018 to 2020)\n# ALso, article_id is treated as a string column otherwise it \n# would drop the leading zeros while reading the specific column values\ntransactions_data=create_data(data_path, data_type='transaction')\nprint(transactions_data.shape)\n\n# # Unique Attributes\nprint(str(len(transactions_data['t_dat'].drop_duplicates())) + \"-total No of unique transactions dates in data sheet\")\nprint(str(len(transactions_data['customer_id'].drop_duplicates())) + \"-total No of unique customers ids in data sheet\")\nprint(str(len(transactions_data['article_id'].drop_duplicates())) + \"-total No of unique article ids courses names in data sheet\")\nprint(str(len(transactions_data['sales_channel_id'].drop_duplicates())) + \"-total No of unique sales channels in data sheet\")","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:13:21.841563Z","iopub.execute_input":"2022-03-17T05:13:21.84237Z","iopub.status.idle":"2022-03-17T05:15:09.165307Z","shell.execute_reply.started":"2022-03-17T05:13:21.842336Z","shell.execute_reply":"2022-03-17T05:15:09.163478Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:09.168938Z","iopub.execute_input":"2022-03-17T05:15:09.169405Z","iopub.status.idle":"2022-03-17T05:15:09.20945Z","shell.execute_reply.started":"2022-03-17T05:15:09.169369Z","shell.execute_reply":"2022-03-17T05:15:09.208646Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions_data.info()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:09.210887Z","iopub.execute_input":"2022-03-17T05:15:09.211342Z","iopub.status.idle":"2022-03-17T05:15:09.237283Z","shell.execute_reply.started":"2022-03-17T05:15:09.211301Z","shell.execute_reply":"2022-03-17T05:15:09.236187Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\n# Load all Customers\ncustomer_data=create_data(customer_data_path)\nprint(customer_data.shape)\n\nprint(str(len(customer_data['customer_id'].drop_duplicates())) + \"-total No of unique customers ids in customer data sheet\")","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:09.241088Z","iopub.execute_input":"2022-03-17T05:15:09.241704Z","iopub.status.idle":"2022-03-17T05:15:16.157608Z","shell.execute_reply.started":"2022-03-17T05:15:09.241661Z","shell.execute_reply":"2022-03-17T05:15:16.156594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customer_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:16.159017Z","iopub.execute_input":"2022-03-17T05:15:16.159328Z","iopub.status.idle":"2022-03-17T05:15:16.180147Z","shell.execute_reply.started":"2022-03-17T05:15:16.159285Z","shell.execute_reply":"2022-03-17T05:15:16.178317Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customer_data.info()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:16.181976Z","iopub.execute_input":"2022-03-17T05:15:16.182324Z","iopub.status.idle":"2022-03-17T05:15:16.80101Z","shell.execute_reply.started":"2022-03-17T05:15:16.182291Z","shell.execute_reply":"2022-03-17T05:15:16.799763Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\n\n# Load all Customers\narticle_data=create_data(article_data_path, data_type='article')\nprint(article_data.shape)\n\nprint(str(len(article_data['article_id'].drop_duplicates())) + \"-total No of unique article ids in article data sheet\")","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:16.802309Z","iopub.execute_input":"2022-03-17T05:15:16.80253Z","iopub.status.idle":"2022-03-17T05:15:18.049286Z","shell.execute_reply.started":"2022-03-17T05:15:16.802502Z","shell.execute_reply":"2022-03-17T05:15:18.04866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"article_data.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:18.050621Z","iopub.execute_input":"2022-03-17T05:15:18.051856Z","iopub.status.idle":"2022-03-17T05:15:18.084409Z","shell.execute_reply.started":"2022-03-17T05:15:18.051792Z","shell.execute_reply":"2022-03-17T05:15:18.083006Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"article_data.info()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:18.086381Z","iopub.execute_input":"2022-03-17T05:15:18.087159Z","iopub.status.idle":"2022-03-17T05:15:18.265709Z","shell.execute_reply.started":"2022-03-17T05:15:18.087114Z","shell.execute_reply":"2022-03-17T05:15:18.2641Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Capturing Seasonal Effect by Limiting the transaction date\nBased on notebook with link: https://www.kaggle.com/tomooinubushi/folk-of-time-is-our-best-friend/notebook","metadata":{}},{"cell_type":"code","source":"transactions_data = transactions_data[transactions_data['t_dat'] > '2020-08-21']\ntransactions_data.shape","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:15:18.26795Z","iopub.execute_input":"2022-03-17T05:15:18.268471Z","iopub.status.idle":"2022-03-17T05:15:18.479033Z","shell.execute_reply.started":"2022-03-17T05:15:18.26844Z","shell.execute_reply":"2022-03-17T05:15:18.47736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Splitting transaction data to training and validation set","metadata":{}},{"cell_type":"code","source":"train_start_date = transactions_data.t_dat.min()\nsplit_date = transactions_data.t_dat.max() - datetime.timedelta(days = 7)\ntrain_transaction_data = transactions_data[(transactions_data.t_dat <= split_date) & (transactions_data.t_dat >= train_start_date)].copy()\ntest_transaction_data = transactions_data[transactions_data.t_dat > split_date].copy()\n\nprint(train_transaction_data.shape)\nprint(test_transaction_data.shape)","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:08.164401Z","iopub.execute_input":"2022-03-17T05:16:08.1649Z","iopub.status.idle":"2022-03-17T05:16:08.309375Z","shell.execute_reply.started":"2022-03-17T05:16:08.164869Z","shell.execute_reply":"2022-03-17T05:16:08.307982Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Aggregating Customers and Articles irrespective of transaction dates","metadata":{}},{"cell_type":"code","source":"transactions_data = transactions_data.groupby(['customer_id','article_id']).agg({'price':'sum','t_dat':'count'}).reset_index()\ntransactions_data = transactions_data[['customer_id','article_id','price','t_dat']]","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:10.945141Z","iopub.execute_input":"2022-03-17T05:16:10.945418Z","iopub.status.idle":"2022-03-17T05:16:10.94969Z","shell.execute_reply.started":"2022-03-17T05:16:10.94539Z","shell.execute_reply":"2022-03-17T05:16:10.948635Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generating user and article index mapping dictionaries","metadata":{}},{"cell_type":"code","source":"def get_customers_list():\n    # Creating a list of users\n    return np.sort(customer_data['customer_id'].unique())\n\ndef get_articles_list():\n    # Creating a list of courses \n    item_list = article_data['article_id'].unique()\n    return item_list\n\ndef id_mappings(customers_list, articles_list):\n    \"\"\"\n    \n    Create id mappings to convert user_id, item_id, and feature_id\n    \n    \"\"\"\n    customer_to_index_mapping = {}\n    index_to_customer_mapping = {}\n    for customer_index, customer_id in enumerate(customers_list):\n        customer_to_index_mapping[customer_id] = customer_index\n        index_to_customer_mapping[customer_index] = customer_id\n        \n    article_to_index_mapping = {}\n    index_to_article_mapping = {}\n    for article_index, article_id in enumerate(articles_list):\n        article_to_index_mapping[article_id] = article_index\n        index_to_article_mapping[article_index] = article_id\n        \n    return customer_to_index_mapping, index_to_customer_mapping, \\\n           article_to_index_mapping, index_to_article_mapping","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:19.027432Z","iopub.execute_input":"2022-03-17T05:16:19.028977Z","iopub.status.idle":"2022-03-17T05:16:19.037744Z","shell.execute_reply.started":"2022-03-17T05:16:19.028915Z","shell.execute_reply":"2022-03-17T05:16:19.036785Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customers = get_customers_list()\narticles = get_articles_list()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:19.615421Z","iopub.execute_input":"2022-03-17T05:16:19.615713Z","iopub.status.idle":"2022-03-17T05:16:21.665437Z","shell.execute_reply.started":"2022-03-17T05:16:19.615683Z","shell.execute_reply":"2022-03-17T05:16:21.664412Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customers","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:21.66747Z","iopub.execute_input":"2022-03-17T05:16:21.667903Z","iopub.status.idle":"2022-03-17T05:16:21.675196Z","shell.execute_reply.started":"2022-03-17T05:16:21.66787Z","shell.execute_reply":"2022-03-17T05:16:21.673556Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articles","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:21.676621Z","iopub.execute_input":"2022-03-17T05:16:21.677822Z","iopub.status.idle":"2022-03-17T05:16:21.694517Z","shell.execute_reply.started":"2022-03-17T05:16:21.677729Z","shell.execute_reply":"2022-03-17T05:16:21.693702Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate mapping, LightFM library can't read other than (integer) index\ncustomer_to_index_mapping, index_to_customer_mapping, \\\narticle_to_index_mapping, index_to_article_mapping = id_mappings(customers, articles)","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:21.696148Z","iopub.execute_input":"2022-03-17T05:16:21.696482Z","iopub.status.idle":"2022-03-17T05:16:22.243291Z","shell.execute_reply.started":"2022-03-17T05:16:21.696456Z","shell.execute_reply":"2022-03-17T05:16:22.242779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Generate Customer Article Interaction Matrix","metadata":{}},{"cell_type":"code","source":"def get_customer_article_interaction(customer_article_amt_df, agg_col_name='price'):\n    #start indexing\n    customer_article_amt_df[\"customer_id\"] = customer_article_amt_df[\"customer_id\"]\n    customer_article_amt_df[\"article_id\"] = customer_article_amt_df[\"article_id\"]\n    customer_article_amt_df[agg_col_name] = customer_article_amt_df[agg_col_name]\n\n    # Preprocessing dataframe created\n    customer_article_amt_df = customer_article_amt_df.rename(columns = {'price':'total_amount_spent', 't_dat': 'total_no_of_transactions'})\n\n    # Replace Amount Column with category codes \n    if agg_col_name.__eq__('price'):\n        customer_article_amt_df['total_amount_spent'] = customer_article_amt_df['total_amount_spent'].astype('category')\n        customer_article_amt_df['total_amount_spent'] = customer_article_amt_df['total_amount_spent'].cat.codes\n    elif agg_col_name.__eq__('t_dat'):\n        customer_article_amt_df['total_no_of_transactions'] = customer_article_amt_df['total_no_of_transactions'].astype('category')\n        customer_article_amt_df['total_no_of_transactions'] = customer_article_amt_df['total_no_of_transactions'].cat.codes\n\n    return customer_article_amt_df\n\ndef get_interaction_matrix(df, df_column_as_row, df_column_as_col, \n                        df_column_as_value, row_indexing_map, col_indexing_map):\n    \n    row = df[df_column_as_row].apply(lambda x: row_indexing_map[x]).values\n    col = df[df_column_as_col].apply(lambda x: col_indexing_map[x]).values\n    value = df[df_column_as_value].values\n    \n    return sparse.coo_matrix((value, (row, col)), shape = (len(row_indexing_map), len(col_indexing_map)))\n","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:25.896446Z","iopub.execute_input":"2022-03-17T05:16:25.896816Z","iopub.status.idle":"2022-03-17T05:16:25.909557Z","shell.execute_reply.started":"2022-03-17T05:16:25.896791Z","shell.execute_reply":"2022-03-17T05:16:25.90819Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Customer Article Interaction based on Amount Spent","metadata":{}},{"cell_type":"code","source":"# Create customer and article interaction dataframe based on total amount spent\ncustomer_to_article_amt = get_customer_article_interaction(customer_article_amt_df = transactions_data[['customer_id','article_id','price']])\nprint(customer_to_article_amt.shape)                                                  ","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:27.844924Z","iopub.execute_input":"2022-03-17T05:16:27.845256Z","iopub.status.idle":"2022-03-17T05:16:28.045749Z","shell.execute_reply.started":"2022-03-17T05:16:27.845226Z","shell.execute_reply":"2022-03-17T05:16:28.044764Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customer_to_article_amt.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:29.876443Z","iopub.execute_input":"2022-03-17T05:16:29.876741Z","iopub.status.idle":"2022-03-17T05:16:29.881509Z","shell.execute_reply.started":"2022-03-17T05:16:29.876712Z","shell.execute_reply":"2022-03-17T05:16:29.880801Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate customer_article_interaction_matrix for train data\ncustomer_to_article_interaction_amt = get_interaction_matrix(customer_to_article_amt, \"customer_id\", \"article_id\", \"total_amount_spent\", \\\n                                                            customer_to_index_mapping, article_to_index_mapping)","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:33.862293Z","iopub.execute_input":"2022-03-17T05:16:33.86269Z","iopub.status.idle":"2022-03-17T05:16:35.802662Z","shell.execute_reply.started":"2022-03-17T05:16:33.86266Z","shell.execute_reply":"2022-03-17T05:16:35.801752Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customer_to_article_interaction_amt","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:16:37.269564Z","iopub.execute_input":"2022-03-17T05:16:37.270134Z","iopub.status.idle":"2022-03-17T05:16:37.273379Z","shell.execute_reply.started":"2022-03-17T05:16:37.270102Z","shell.execute_reply":"2022-03-17T05:16:37.272433Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Customer Article Interaction based on Transaction Counts","metadata":{}},{"cell_type":"code","source":"# Create customer and article interaction dataframe based on total number of transactions made\ncustomer_to_article_tdate = get_customer_article_interaction(customer_article_amt_df = transactions_data[['customer_id','article_id','t_dat']],\n                                                            agg_col_name='t_dat')\nprint(customer_to_article_tdate.shape)     ","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:17:03.005801Z","iopub.execute_input":"2022-03-17T05:17:03.006145Z","iopub.status.idle":"2022-03-17T05:17:03.011539Z","shell.execute_reply.started":"2022-03-17T05:17:03.00611Z","shell.execute_reply":"2022-03-17T05:17:03.010607Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customer_to_article_tdate.head()","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:17:06.405325Z","iopub.execute_input":"2022-03-17T05:17:06.405933Z","iopub.status.idle":"2022-03-17T05:17:06.41044Z","shell.execute_reply.started":"2022-03-17T05:17:06.405901Z","shell.execute_reply":"2022-03-17T05:17:06.409017Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Generate customer_article_interaction_matrix for train data\ncustomer_to_article_interaction_tdat = get_interaction_matrix(customer_to_article_tdate, \"customer_id\", \"article_id\", \"total_no_of_transactions\", \\\n                                                            customer_to_index_mapping, article_to_index_mapping)","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:17:06.788081Z","iopub.execute_input":"2022-03-17T05:17:06.788402Z","iopub.status.idle":"2022-03-17T05:17:06.793344Z","shell.execute_reply.started":"2022-03-17T05:17:06.788365Z","shell.execute_reply":"2022-03-17T05:17:06.792208Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customer_to_article_interaction_tdat","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:17:07.243945Z","iopub.execute_input":"2022-03-17T05:17:07.245212Z","iopub.status.idle":"2022-03-17T05:17:07.249736Z","shell.execute_reply.started":"2022-03-17T05:17:07.24514Z","shell.execute_reply":"2022-03-17T05:17:07.248958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Hyperparameter Tuning using Random Search","metadata":{}},{"cell_type":"code","source":"def sample_hyperparameters():\n    while True:\n        yield {\n            \"no_components\": np.random.randint(16, 64),\n            \"learning_schedule\": np.random.choice([\"adagrad\", \"adadelta\"]),\n            \"loss\": np.random.choice([\"bpr\", \"warp\", \"warp-kos\"]),\n            \"learning_rate\": np.random.exponential(0.05),\n            \"item_alpha\": np.random.exponential(1e-8),\n            \"user_alpha\": np.random.exponential(1e-8),\n            \"max_sampled\": np.random.randint(5, 15),\n            \"num_epochs\": np.random.randint(5, 50),\n        }","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:19:19.009024Z","iopub.execute_input":"2022-03-17T05:19:19.009359Z","iopub.status.idle":"2022-03-17T05:19:19.019566Z","shell.execute_reply.started":"2022-03-17T05:19:19.009327Z","shell.execute_reply":"2022-03-17T05:19:19.018403Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Sampling Hyperparmeters Function","metadata":{}},{"cell_type":"markdown","source":"### Perform Random Search\n\nTrain and Test Interactions are provided as input parameters to the function including the random samples to generate and number of threads to use to perform model training.  \n\nOutput would be the precision score, set of hyperprameters and the model","metadata":{}},{"cell_type":"code","source":"def random_search(train_interactions, test_interactions, num_samples=50, num_threads=1):\n    for hyperparams in itertools.islice(sample_hyperparameters(), num_samples):\n        num_epochs = hyperparams.pop(\"num_epochs\")\n\n        model = LightFM(**hyperparams)\n        model.fit(train_interactions, epochs=num_epochs, num_threads=num_threads)\n\n        score = precision_at_k(model, test_interactions, train_interactions=train_interactions, k=12, num_threads=num_threads).mean()\n        \n        print(score)\n\n        hyperparams[\"num_epochs\"] = num_epochs\n\n        yield (score, hyperparams, model)","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:26:43.845894Z","iopub.execute_input":"2022-03-17T05:26:43.846243Z","iopub.status.idle":"2022-03-17T05:26:43.854791Z","shell.execute_reply.started":"2022-03-17T05:26:43.846212Z","shell.execute_reply":"2022-03-17T05:26:43.853958Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Initiating Storage Dictionary","metadata":{}},{"cell_type":"code","source":"optimized_dict={}","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:26:44.633621Z","iopub.execute_input":"2022-03-17T05:26:44.634665Z","iopub.status.idle":"2022-03-17T05:26:44.639841Z","shell.execute_reply.started":"2022-03-17T05:26:44.634626Z","shell.execute_reply":"2022-03-17T05:26:44.63836Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Splitting the primary dataset into train and test sets based on amount spent","metadata":{}},{"cell_type":"code","source":"sparse_customer_article_train, sparse_customer_article_test = random_train_test_split(customer_to_article_interaction_amt, test_percentage=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:26:45.786048Z","iopub.execute_input":"2022-03-17T05:26:45.78663Z","iopub.status.idle":"2022-03-17T05:26:45.791956Z","shell.execute_reply.started":"2022-03-17T05:26:45.786585Z","shell.execute_reply":"2022-03-17T05:26:45.790668Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(score, hyperparams, model) = max(random_search(train_interactions = sparse_customer_article_train, \n                                                test_interactions = sparse_customer_article_test, \n                                                num_threads = 4), key=lambda x: x[0])","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:26:47.712224Z","iopub.execute_input":"2022-03-17T05:26:47.712478Z","iopub.status.idle":"2022-03-17T05:59:24.672073Z","shell.execute_reply.started":"2022-03-17T05:26:47.712454Z","shell.execute_reply":"2022-03-17T05:59:24.670678Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Best score {} at {}\".format(score, hyperparams))","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:59:24.674209Z","iopub.execute_input":"2022-03-17T05:59:24.674466Z","iopub.status.idle":"2022-03-17T05:59:24.68114Z","shell.execute_reply.started":"2022-03-17T05:59:24.674433Z","shell.execute_reply":"2022-03-17T05:59:24.679659Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimized_dict['Amount_Spent'] = {'score': score, \n                                  'params': hyperparams}","metadata":{"execution":{"iopub.status.busy":"2022-03-17T05:59:24.683157Z","iopub.execute_input":"2022-03-17T05:59:24.683501Z","iopub.status.idle":"2022-03-17T05:59:24.706563Z","shell.execute_reply.started":"2022-03-17T05:59:24.683462Z","shell.execute_reply":"2022-03-17T05:59:24.705618Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Splitting the primary dataset into train and test sets based on transaction count","metadata":{}},{"cell_type":"code","source":"sparse_customer_article_train, sparse_customer_article_test = random_train_test_split(customer_to_article_interaction_tdat, test_percentage=0.2, random_state=42)","metadata":{"execution":{"iopub.status.busy":"2022-03-16T04:39:47.654556Z","iopub.execute_input":"2022-03-16T04:39:47.655423Z","iopub.status.idle":"2022-03-16T04:39:47.722153Z","shell.execute_reply.started":"2022-03-16T04:39:47.655385Z","shell.execute_reply":"2022-03-16T04:39:47.721278Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sparse_customer_article_train","metadata":{"execution":{"iopub.status.busy":"2022-03-16T04:39:47.723735Z","iopub.execute_input":"2022-03-16T04:39:47.723999Z","iopub.status.idle":"2022-03-16T04:39:47.729635Z","shell.execute_reply.started":"2022-03-16T04:39:47.723961Z","shell.execute_reply":"2022-03-16T04:39:47.729059Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sparse_customer_article_test","metadata":{"execution":{"iopub.status.busy":"2022-03-16T04:39:47.730746Z","iopub.execute_input":"2022-03-16T04:39:47.731479Z","iopub.status.idle":"2022-03-16T04:39:47.745775Z","shell.execute_reply.started":"2022-03-16T04:39:47.731441Z","shell.execute_reply":"2022-03-16T04:39:47.744839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"(score, hyperparams, model) = max(random_search(train_interactions = sparse_customer_article_train, \n                                                test_interactions = sparse_customer_article_test, \n                                                num_threads = 4), key=lambda x: x[0])","metadata":{"execution":{"iopub.status.busy":"2022-03-16T04:39:47.750447Z","iopub.execute_input":"2022-03-16T04:39:47.75113Z","iopub.status.idle":"2022-03-16T05:28:47.709435Z","shell.execute_reply.started":"2022-03-16T04:39:47.751094Z","shell.execute_reply":"2022-03-16T05:28:47.708552Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(\"Best score {} at {}\".format(score, hyperparams))","metadata":{"execution":{"iopub.status.busy":"2022-03-16T05:28:47.710846Z","iopub.execute_input":"2022-03-16T05:28:47.711083Z","iopub.status.idle":"2022-03-16T05:28:47.715958Z","shell.execute_reply.started":"2022-03-16T05:28:47.711054Z","shell.execute_reply":"2022-03-16T05:28:47.715413Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"optimized_dict['Transaction_Counts'] = {'score': score, \n                                       'params': hyperparams}","metadata":{"execution":{"iopub.status.busy":"2022-03-16T05:28:47.716962Z","iopub.execute_input":"2022-03-16T05:28:47.717543Z","iopub.status.idle":"2022-03-16T05:28:47.731363Z","shell.execute_reply.started":"2022-03-16T05:28:47.717508Z","shell.execute_reply":"2022-03-16T05:28:47.730245Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(optimized_dict)","metadata":{"execution":{"iopub.status.busy":"2022-03-16T05:28:47.732849Z","iopub.execute_input":"2022-03-16T05:28:47.733293Z","iopub.status.idle":"2022-03-16T05:28:47.745068Z","shell.execute_reply.started":"2022-03-16T05:28:47.733223Z","shell.execute_reply":"2022-03-16T05:28:47.744075Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Saving the Optimized Params","metadata":{}},{"cell_type":"code","source":"with open('optimized_dict.pkl', 'wb') as f:\n    pickle.dump(optimized_dict, f)","metadata":{"execution":{"iopub.status.busy":"2022-03-16T05:28:47.74676Z","iopub.execute_input":"2022-03-16T05:28:47.747097Z","iopub.status.idle":"2022-03-16T05:28:47.763279Z","shell.execute_reply.started":"2022-03-16T05:28:47.747053Z","shell.execute_reply":"2022-03-16T05:28:47.762276Z"},"trusted":true},"execution_count":null,"outputs":[]}]}