{"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":"Thanks https://www.kaggle.com/cdeotte","metadata":{}},{"cell_type":"code","source":"import numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\nfrom sklearn.preprocessing import LabelEncoder\nle = LabelEncoder()\nimport matplotlib.pyplot as plt\npath = '/kaggle/input/h-and-m-personalized-fashion-recommendations/'\nimpath = '/kaggle/input/h-and-m-personalized-fashion-recommendations/images/0'\nfrom tqdm import tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-04-23T10:56:13.364756Z","iopub.execute_input":"2022-04-23T10:56:13.365137Z","iopub.status.idle":"2022-04-23T10:56:14.432862Z","shell.execute_reply.started":"2022-04-23T10:56:13.365041Z","shell.execute_reply":"2022-04-23T10:56:14.432037Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"relation = pd.read_csv(f'{path}transactions_train.csv')\nrelation = relation[['customer_id','article_id','t_dat','sales_channel_id']]\nprint(relation.shape)","metadata":{"execution":{"iopub.status.busy":"2022-04-23T10:56:14.434408Z","iopub.execute_input":"2022-04-23T10:56:14.434681Z","iopub.status.idle":"2022-04-23T10:57:21.740924Z","shell.execute_reply.started":"2022-04-23T10:56:14.434651Z","shell.execute_reply":"2022-04-23T10:57:21.739023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"channel = relation.groupby('customer_id')['sales_channel_id'].mean().apply(lambda x: 1 if(x<1.5) else 2)\nchannel.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:00:46.808597Z","iopub.execute_input":"2022-04-23T11:00:46.809082Z","iopub.status.idle":"2022-04-23T11:01:03.531621Z","shell.execute_reply.started":"2022-04-23T11:00:46.809046Z","shell.execute_reply":"2022-04-23T11:01:03.530724Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Clustering Users into 310 Groups","metadata":{}},{"cell_type":"code","source":"users = pd.read_csv(f'{path}customers.csv')\nusers = users[['customer_id', 'FN', 'Active', 'club_member_status',\n       'fashion_news_frequency','age']]\nusers = users.merge(channel,on='customer_id',how='left')\nprint(users.shape)","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:03:35.872252Z","iopub.execute_input":"2022-04-23T11:03:35.872627Z","iopub.status.idle":"2022-04-23T11:03:42.256642Z","shell.execute_reply.started":"2022-04-23T11:03:35.872589Z","shell.execute_reply":"2022-04-23T11:03:42.255645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"bin_list = [0, 10,15,18,22,25,30,35,40,45,50,55,60,65,100]\nusers['age_bins'] = pd.cut(users['age'], bin_list)\nusers['FN'] = users['FN'].replace(np.nan,0)\nusers['Active'] = users['Active'].replace(np.nan,0)\nusers.club_member_status = users.club_member_status.replace(['PRE-CREATE','LEFT CLUB',np.nan],'PASSIVE')\nusers.fashion_news_frequency = users.fashion_news_frequency.replace(['None',np.nan],'NONE')\nusers.fashion_news_frequency = users.fashion_news_frequency.replace('Monthly','Regularly')\nusers.drop(columns='age',inplace=True)\nusers['age_bins'] = users['age_bins'].replace(np.nan,'popular')\nusers['sales_channel_id'] = users['sales_channel_id'].replace(np.nan,3)\nfor i in ['club_member_status','fashion_news_frequency','age_bins'] :\n    users[i] = le.fit_transform(users[i])\nusers['cluster'] = users[['FN','Active','club_member_status','fashion_news_frequency','age_bins','sales_channel_id']].apply(tuple,axis=1)\nusers['cluster']=users['cluster'].astype(str)\nusers['cluster'] = le.fit_transform(users['cluster'])\nusers.drop(columns=['FN','Active','club_member_status','fashion_news_frequency','age_bins','sales_channel_id'],inplace=True)\nusers","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:05:54.402468Z","iopub.execute_input":"2022-04-23T11:05:54.402908Z","iopub.status.idle":"2022-04-23T11:06:23.667554Z","shell.execute_reply.started":"2022-04-23T11:05:54.402867Z","shell.execute_reply":"2022-04-23T11:06:23.666632Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Clustering Items into 3398 Groups","metadata":{}},{"cell_type":"code","source":"items = pd.read_csv(f'{path}articles.csv')\nitems = items[['article_id','product_type_name', 'perceived_colour_master_name', 'index_group_name']]\nprint(items.shape)","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:06:46.503691Z","iopub.execute_input":"2022-04-23T11:06:46.504057Z","iopub.status.idle":"2022-04-23T11:06:47.422713Z","shell.execute_reply.started":"2022-04-23T11:06:46.50402Z","shell.execute_reply":"2022-04-23T11:06:47.421658Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"for i in items.columns[1:] :\n    items[i] = le.fit_transform(items[i])\nitems['clusteri'] = items[['product_type_name','perceived_colour_master_name','index_group_name']].apply(tuple,axis=1)\nitems['clusteri']= items['clusteri'].astype(str)\nitems['clusteri'] = le.fit_transform(items['clusteri'])\n#items.drop(columns=['product_type_name','perceived_colour_master_name','index_group_name'],inplace=True)\nitems","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:06:47.424383Z","iopub.execute_input":"2022-04-23T11:06:47.425094Z","iopub.status.idle":"2022-04-23T11:06:48.908971Z","shell.execute_reply.started":"2022-04-23T11:06:47.425043Z","shell.execute_reply":"2022-04-23T11:06:48.908414Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Merging to Relation","metadata":{}},{"cell_type":"code","source":"relation = relation.merge(users,how='left',on='customer_id')\nrelation = relation.merge(items.drop(columns=['product_type_name','perceived_colour_master_name','index_group_name']),how='left',on='article_id')\nrelation","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:06:53.695877Z","iopub.execute_input":"2022-04-23T11:06:53.696525Z","iopub.status.idle":"2022-04-23T11:07:19.513957Z","shell.execute_reply.started":"2022-04-23T11:06:53.69647Z","shell.execute_reply":"2022-04-23T11:07:19.512967Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Popular Items - TimeWise","metadata":{}},{"cell_type":"code","source":"#newusers = [706016001,751471001,924243001,372860001,915529003,918522001,\n#            610776002,923758001,918292001, 915526001,730683050, 448509014]\nnewusers = [909370001, 924243001, 918522001, 865799006, 751471001, 915529003,\n            918292001, 915526001, 706016001, 751471043, 372860002, 372860001]","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:07:19.515541Z","iopub.execute_input":"2022-04-23T11:07:19.515787Z","iopub.status.idle":"2022-04-23T11:07:19.52095Z","shell.execute_reply.started":"2022-04-23T11:07:19.51576Z","shell.execute_reply":"2022-04-23T11:07:19.520009Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Each clusters 6 popular item","metadata":{}},{"cell_type":"code","source":"week = relation[(relation['t_dat'] > '2020-09-08')]\nmonth = relation[(relation['t_dat'] > '2020-08-22')]\nquarter = relation[(relation['t_dat'] > '2020-06-22')]\n\nusergroup = dict()\nfor i in tqdm (range(311), desc=\"Loading...\"):\n    top6all = list(relation[(relation['cluster']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    top6week = list(week[(week['cluster']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    top6month = list(month[(month['cluster']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    top6quarter = list(quarter[(quarter['cluster']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    \n    cnt = 8\n    ls = []\n    for j in top6week:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==6):\n                break\n    for j in top6month:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==4):\n                break\n    for j in top6quarter:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==2):\n                break\n    for j in top6all:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==0):\n                break\n    usergroup[i]=ls\n\n\nitemgroup = dict()\nfor i in tqdm (range(3398), desc=\"Loading...\"):\n    top6all = list(relation[(relation['clusteri']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    top6week = list(week[(week['clusteri']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    top6month = list(month[(month['clusteri']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n    top6quarter = list(quarter[(quarter['clusteri']==i)].groupby('article_id')['customer_id'].nunique().sort_values(ascending=False).head(6).index.astype(int))\n\n    cnt = 8\n    ls = []\n    for j in top6week:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==6):\n                break\n    for j in top6month:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==4):\n                break\n    for j in top6quarter:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==2):\n                break\n    for j in top6all:\n        if(j not in ls):\n            ls.append(j)\n            cnt=cnt-1\n            if(cnt==0):\n                break\n    itemgroup[i]=ls","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:08:24.728671Z","iopub.execute_input":"2022-04-23T11:08:24.729036Z","iopub.status.idle":"2022-04-23T11:12:12.783262Z","shell.execute_reply.started":"2022-04-23T11:08:24.728997Z","shell.execute_reply":"2022-04-23T11:12:12.78183Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#usergroup = np.load('/kaggle/input/hm-data/usergroup.npy',allow_pickle=True).item()\n#itemgroup = np.load('/kaggle/input/hm-data/itemgroup.npy',allow_pickle=True).item()","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Items Purchased Together","metadata":{}},{"cell_type":"code","source":"pairs = np.load('/kaggle/input/hm-data/pairs_cudf.npy',allow_pickle=True).item()","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:12:12.786784Z","iopub.execute_input":"2022-04-23T11:12:12.78718Z","iopub.status.idle":"2022-04-23T11:12:12.95227Z","shell.execute_reply.started":"2022-04-23T11:12:12.787135Z","shell.execute_reply":"2022-04-23T11:12:12.951237Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# User's Most Bought","metadata":{}},{"cell_type":"code","source":"tmp = relation.groupby(['customer_id','article_id'])['t_dat'].agg('count').reset_index()\ntmp.columns = ['customer_id','article_id','ct']\ntmp = relation.merge(tmp,on=['customer_id','article_id'],how='left')\ntmp = tmp.sort_values(['ct','t_dat'],ascending=False)\ntmp = tmp.drop_duplicates('customer_id',keep='first')\ntmp = tmp[['customer_id', 'article_id', 'clusteri']]\ntmp.columns = ['customer_id', 'farticle_id', 'fclusteri']\ntmp.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:12:12.953737Z","iopub.execute_input":"2022-04-23T11:12:12.95437Z","iopub.status.idle":"2022-04-23T11:13:50.167533Z","shell.execute_reply.started":"2022-04-23T11:12:12.95433Z","shell.execute_reply":"2022-04-23T11:13:50.16661Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# User Latest Purchase","metadata":{}},{"cell_type":"code","source":"relation = relation.drop_duplicates(subset='customer_id',keep='last')\nrelation = relation.reset_index(drop=True)\nrelation.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:13:50.169528Z","iopub.execute_input":"2022-04-23T11:13:50.170151Z","iopub.status.idle":"2022-04-23T11:14:00.654337Z","shell.execute_reply.started":"2022-04-23T11:13:50.170114Z","shell.execute_reply":"2022-04-23T11:14:00.653481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Merge","metadata":{}},{"cell_type":"code","source":"relation = relation.merge(tmp,on='customer_id')\nrelation.head()","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:14:00.655897Z","iopub.execute_input":"2022-04-23T11:14:00.656149Z","iopub.status.idle":"2022-04-23T11:14:02.695672Z","shell.execute_reply.started":"2022-04-23T11:14:00.656117Z","shell.execute_reply":"2022-04-23T11:14:02.694787Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Recommendations","metadata":{}},{"cell_type":"markdown","source":"### Picking 12 Items\n#### 1. Last Purchase and it's pair - 2\n#### 2. Frequent Purchase and it's pair - 2  \n#### 3. User Group - 4  \n#### 4. Item Group Last - 2 \n#### 5. Item Group Frequent - 2\n\n#### Incase less than 12 then from New Users List","metadata":{}},{"cell_type":"code","source":"rec = dict()\nfor i in tqdm (range(relation.shape[0]), desc=\"Loading...\"):\n    flag=0\n    cnt = 12\n    # Last purchase\n    ls = []\n    lastpur= relation.iloc[i]['article_id']\n    ls.append(lastpur)\n    rec[i] = '0' +str(lastpur)\n    cnt=11\n    # It's pair\n    try:\n        if(lastpur!=pairs[relation.iloc[i]['article_id']]):\n            ls.append(pairs[relation.iloc[i]['article_id']])\n            rec[i] += ' 0'+str(pairs[relation.iloc[i]['article_id']])\n            cnt-=1\n        else:\n            flag+=1 \n    except:\n        flag+=1\n    # Most Frequent\n    lastpur = relation.iloc[i]['farticle_id']\n    if(relation.iloc[i]['farticle_id'] not in ls):\n        rec[i]+= ' 0'+str(j)\n        ls.append(lastpur)\n        cnt-=1\n    else:\n        flag+=1 \n    # It's pair\n    try:\n        if((lastpur!=pairs[relation.iloc[i]['farticle_id']]) & (lastpur not in ls)):\n            ls.append(pairs[relation.iloc[i]['farticle_id']])\n            rec[i] += ' 0'+str(pairs[relation.iloc[i]['farticle_id']])\n            cnt-=1\n        else:\n            flag+=1 \n    except:\n        flag+=1\n    # 4 items from the same user group \n    for j in usergroup[relation.iloc[i]['cluster']]:\n        if(j not in ls):\n            rec[i]+= ' 0'+str(j)\n            ls.append(j)\n            cnt-=1\n        else:\n            flag+=1\n        if(cnt==4+flag):\n            break\n    for j in itemgroup[relation.iloc[i]['clusteri']]:\n        if(j not in ls):\n            rec[i]+= ' 0'+str(j)\n            ls.append(j)\n            cnt-=1\n        else:\n            flag+=1\n        if(cnt==2+flag):\n            break  \n    for j in itemgroup[relation.iloc[i]['fclusteri']]:\n        if(j not in ls):\n            rec[i]+= ' 0'+str(j)\n            ls.append(j)\n            cnt-=1\n        else:\n            flag+=1\n        if(cnt==flag):\n            break  \n    if(flag!=0):\n        for j in newusers:\n            if(j not in ls):\n                rec[i]+= ' 0'+str(j)\n                ls.append(j)\n                flag-=1\n            if(flag==0):\n                break  ","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:16:11.461947Z","iopub.execute_input":"2022-04-23T11:16:11.462427Z","iopub.status.idle":"2022-04-23T11:48:32.214793Z","shell.execute_reply.started":"2022-04-23T11:16:11.462383Z","shell.execute_reply":"2022-04-23T11:48:32.213772Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"relation = relation['customer_id']\nrelation = pd.concat([relation,pd.Series(rec)],axis=1,ignore_index=True)\nrelation.columns =['customer_id','prediction']\nfinal = pd.merge(users,relation, on='customer_id',how='left').drop(columns='cluster')","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:48:43.164504Z","iopub.execute_input":"2022-04-23T11:48:43.164899Z","iopub.status.idle":"2022-04-23T11:48:47.442475Z","shell.execute_reply.started":"2022-04-23T11:48:43.164856Z","shell.execute_reply":"2022-04-23T11:48:47.441611Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"newusers = '0909370001 0924243001 0918522001 0865799006 0751471001 0915529003 0918292001 0915526001 0706016001 0751471043 0372860002 0372860001'","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:48:47.444989Z","iopub.execute_input":"2022-04-23T11:48:47.445246Z","iopub.status.idle":"2022-04-23T11:48:47.450043Z","shell.execute_reply.started":"2022-04-23T11:48:47.445217Z","shell.execute_reply":"2022-04-23T11:48:47.449169Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final = final.replace(np.nan,newusers)","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:48:47.734783Z","iopub.execute_input":"2022-04-23T11:48:47.735757Z","iopub.status.idle":"2022-04-23T11:48:48.25701Z","shell.execute_reply.started":"2022-04-23T11:48:47.735718Z","shell.execute_reply":"2022-04-23T11:48:48.256258Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"final.to_csv('submission.csv',index=False)","metadata":{"execution":{"iopub.status.busy":"2022-04-23T11:48:50.34776Z","iopub.execute_input":"2022-04-23T11:48:50.348398Z","iopub.status.idle":"2022-04-23T11:49:03.650531Z","shell.execute_reply.started":"2022-04-23T11:48:50.348359Z","shell.execute_reply":"2022-04-23T11:49:03.649645Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}