{"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":"code","source":"import pandas as pd\nimport numpy as np\nimport warnings\nimport gc\nfrom tqdm import tqdm\nfrom datetime import datetime","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:06:30.003032Z","iopub.execute_input":"2023-05-01T17:06:30.003588Z","iopub.status.idle":"2023-05-01T17:06:30.043300Z","shell.execute_reply.started":"2023-05-01T17:06:30.003540Z","shell.execute_reply":"2023-05-01T17:06:30.042054Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"warnings.filterwarnings('ignore')\ntqdm.pandas()","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:06:30.045089Z","iopub.execute_input":"2023-05-01T17:06:30.046490Z","iopub.status.idle":"2023-05-01T17:06:30.053826Z","shell.execute_reply.started":"2023-05-01T17:06:30.046434Z","shell.execute_reply":"2023-05-01T17:06:30.052210Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"1. https://www.kaggle.com/code/hervind/h-m-faster-trending-products-weekly/notebook\n2. https://www.kaggle.com/code/lichtlab/do-customers-buy-the-same-products-again","metadata":{}},{"cell_type":"code","source":"%%time\ntransactions_train = pd.read_csv('../input/h-and-m-personalized-fashion-recommendations/transactions_train.csv', \n                                 usecols = ['t_dat', 'customer_id', 'article_id'], dtype={'article_id': str})\ntransactions_train['t_dat'] = pd.to_datetime(transactions_train['t_dat'])\nlastday = transactions_train['t_dat'].max()\ntransactions_train","metadata":{"scrolled":true,"execution":{"iopub.status.busy":"2023-05-01T17:06:30.055514Z","iopub.execute_input":"2023-05-01T17:06:30.056669Z","iopub.status.idle":"2023-05-01T17:08:03.237056Z","shell.execute_reply.started":"2023-05-01T17:06:30.056574Z","shell.execute_reply":"2023-05-01T17:08:03.233921Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ntransactions_train['dow'] = transactions_train['t_dat'].dt.dayofweek\ntransactions_train['ldbw'] = transactions_train['t_dat'] - pd.TimedeltaIndex(transactions_train['dow'] - 1, unit='D')\ntransactions_train.loc[transactions_train['dow'] >=2 , 'ldbw'] = \\\n                transactions_train.loc[transactions_train['dow'] >=2 , 'ldbw'] + \\\n                pd.TimedeltaIndex(np.ones(len(transactions_train.loc[transactions_train['dow'] >=2])) * 7, unit='D')\ndel transactions_train['dow']\ntransactions_train","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:08:03.241571Z","iopub.execute_input":"2023-05-01T17:08:03.242146Z","iopub.status.idle":"2023-05-01T17:08:12.922766Z","shell.execute_reply.started":"2023-05-01T17:08:03.242075Z","shell.execute_reply":"2023-05-01T17:08:12.921026Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nweekly_sales = transactions_train.drop(['customer_id'], axis=1).groupby(['ldbw', 'article_id']).count()\nweekly_sales = weekly_sales.rename(columns={'t_dat': 'count'})\ntransactions_train = pd.merge(transactions_train, weekly_sales, on=['ldbw', 'article_id'], how='left')\ntransactions_train","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:08:12.924971Z","iopub.execute_input":"2023-05-01T17:08:12.925610Z","iopub.status.idle":"2023-05-01T17:08:36.170000Z","shell.execute_reply.started":"2023-05-01T17:08:12.925548Z","shell.execute_reply":"2023-05-01T17:08:36.168651Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nweekly_sales = weekly_sales.reset_index().set_index('article_id')\nlast_day = lastday.strftime('%Y-%m-%d')\n\ntransactions_train = transactions_train.join(\n    weekly_sales.loc[weekly_sales['ldbw']==last_day, ['count']],\n    on='article_id', rsuffix=\"_targ\")\n\ntransactions_train['count_targ'].fillna(0, inplace=True)\n# The count_targ column is to check the number of products sold in the past week, \n# and NAN means that the product has not been sold in this week\ntransactions_train","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:08:36.172351Z","iopub.execute_input":"2023-05-01T17:08:36.172928Z","iopub.status.idle":"2023-05-01T17:08:46.219532Z","shell.execute_reply.started":"2023-05-01T17:08:36.172871Z","shell.execute_reply":"2023-05-01T17:08:46.218481Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"**Коэффициент** -популярность товаров, пользующихся спросом на прошлой неделе, за каждую неделю.","metadata":{}},{"cell_type":"code","source":"transactions_train['quotient'] = transactions_train['count_targ'] / transactions_train['count']\ntransactions_train","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:08:46.220860Z","iopub.execute_input":"2023-05-01T17:08:46.222111Z","iopub.status.idle":"2023-05-01T17:08:46.409829Z","shell.execute_reply.started":"2023-05-01T17:08:46.222053Z","shell.execute_reply":"2023-05-01T17:08:46.408448Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"\n**ценность** -симпатия покупателя к определенному продукту, которая включает в себя множество факторов (время покупки, количество покупок и популярность продукта (коэффициент))","metadata":{}},{"cell_type":"code","source":"%%time\ntrain_fo = transactions_train.copy()\ntrain_fo['week_x'] = ((lastday - train_fo['ldbw']) / np.timedelta64(7, 'D')).astype(int)\ntrain_fo['sup_1'] = 0.1 \ntrain_fo['week_x'] = train_fo[['week_x', 'sup_1']].max(axis=1)\n\ntrain_fo['y'] = 1.2e3 / train_fo['week_x']\ntrain_fo['sup_25'] = 25 \ntrain_fo['y'] = train_fo[[\"y\", \"sup_25\"]].max(axis=1)\ntrain_fo['value'] = train_fo['quotient'] * train_fo['y'] \n\nvalue = train_fo.groupby(['customer_id', 'article_id']).agg({'value': 'sum'})\nvalue = value.reset_index()\nvalue","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:08:46.411803Z","iopub.execute_input":"2023-05-01T17:08:46.412331Z","iopub.status.idle":"2023-05-01T17:09:51.779974Z","shell.execute_reply.started":"2023-05-01T17:08:46.412287Z","shell.execute_reply":"2023-05-01T17:09:51.778549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\ntrain_fo = train_fo.groupby(['customer_id', 'article_id']).agg({'value': 'sum'})\ntrain_fo = train_fo.reset_index()\n\ntrain_fo = train_fo.loc[train_fo['value'] > 180]\n# why 180? If an item's quotient remains at 1, users will buy it again if it has been purchased about the last 7 weeks\ntrain_fo['rank'] = train_fo.groupby(\"customer_id\")[\"value\"].rank(\"dense\", ascending=False)\ntrain_fo = train_fo.loc[train_fo['rank'] <= 12]\n\npurchase_records = train_fo.sort_values(['customer_id', 'value'], ascending = False).reset_index(drop = True)\npurchase_records['prediction'] = purchase_records['article_id'].astype(str) + ' '\npurchase_records = purchase_records.groupby('customer_id').agg({'prediction': sum}).reset_index() #str求和\npurchase_records['prediction'] = purchase_records['prediction'].str.strip()\npurchase_records","metadata":{"execution":{"iopub.status.busy":"2023-05-01T17:09:51.781868Z","iopub.execute_input":"2023-05-01T17:09:51.782452Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"","metadata":{}},{"cell_type":"markdown","source":"**Составляем пары товаров**\nhttps://www.kaggle.com/code/titericz/article-id-pairs-in-3s-using-cudf","metadata":{}},{"cell_type":"code","source":"def calc_pairs(train):\n    # Calculate all articles purchased together\n    dt = train.groupby(['customer_id','t_dat'])['article_id'].agg(list).rename('pair').reset_index()\n    df = pd.merge(train[['customer_id', 't_dat', 'article_id']], dt, on=['customer_id', 't_dat'], how='left')\n    del dt\n    gc.collect()\n\n    # baes_count\n    base_count = df.groupby(['article_id']).size().rename('base_count').reset_index()\n    gc.collect()\n    \n    # Explode the rows vs list of articles\n    df = df[['article_id', 'pair']].explode(column='pair')\n    gc.collect()\n    \n    # Discard duplicates\n    df = df.loc[df['article_id']!=df['pair']].reset_index(drop=True)\n    gc.collect()\n\n    # Count how many times each pair combination happens\n    df = df.groupby(['article_id', 'pair']).size().rename('pair_count').reset_index()\n    gc.collect()\n    \n    # Sort by frequency\n    df = df.sort_values(['article_id' ,'pair_count'], ascending=[False, False]).reset_index(drop=True)\n    df = pd.merge(df, base_count, on=['article_id'], how='left')\n    df['ratio'] = df['pair_count'] / df['base_count']\n    gc.collect()\n    \n    # Pick only top1 most frequent pair\n    df = df.groupby('article_id').head(2)\n    gc.collect()\n    \n    return df","metadata":{"execution":{"iopub.status.busy":"2023-05-03T14:15:28.022604Z","iopub.execute_input":"2023-05-03T14:15:28.023632Z","iopub.status.idle":"2023-05-03T14:15:28.068933Z","shell.execute_reply.started":"2023-05-03T14:15:28.023555Z","shell.execute_reply":"2023-05-03T14:15:28.067825Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\narticles_pair = calc_pairs(transactions_train[transactions_train['t_dat']>datetime(2020,6,22)])\narticles_pair","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articles_pair_base = articles_pair[articles_pair['ratio']>0.12]\narticles_pair_base.sort_values('ratio', ascending=False, inplace=True)\narticles_pair_base = articles_pair_base.groupby('article_id')['pair'].agg(list).reset_index()\ndel articles_pair\narticles_pair_base","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def pair_zh(train, pair_train):\n    \n    train = train.explode('prediction')\n    train = pd.merge(train, pair_train, left_on='prediction', right_on='article_id', how='left')\n    train.fillna('0', inplace=True)\n    for col in ['article_id']:\n        del train[col]\n        \n    def flat(x):\n        res = []\n        if isinstance(x, str):\n            res.append(x)\n        else:\n            res.extend(x)\n        unique_list = []\n        for i in res:\n            if i not in unique_list and i != '0':\n                unique_list.append(i)\n        re = []\n        for i in unique_list:\n            if isinstance(i, list):\n                re.extend(i)\n            else:\n                re.append(i)\n        return re\n    prediction = train.groupby('customer_id')['prediction'].apply(lambda x:flat(x))\n    pair = train.groupby('customer_id')['pair'].progress_apply(lambda x:flat(x))\n    train['prediction'] = train['customer_id'].map(prediction)\n    train['pair'] = train['customer_id'].map(pair)\n    train.drop_duplicates('customer_id', inplace=True)\n    \n    def falt(x):\n        res = []\n        for i in x:\n            res.extend(i)\n        unique_list = []\n        for i in res:\n            if i not in unique_list:\n                unique_list.append(i)\n        return unique_list[:12]\n    train['prediction'] = train[['prediction', 'pair']].apply(lambda x:falt(x.tolist()), axis='columns')\n    del train['pair']\n    \n    return train","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"purchase_records['prediction'] = purchase_records['prediction'].apply(lambda x:x.split(' '))\npurchase_records = pair_zh(purchase_records, articles_pair_base)\ndel articles_pair_base\ngc.collect()\npurchase_records","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Все, что ниже улучшили score ненамного","metadata":{}},{"cell_type":"markdown","source":"**Разделяем потребителей по возрасту и находим самые популярные товары за последнюю неделю**\n","metadata":{}},{"cell_type":"code","source":"%%time\ncustomers = pd.read_csv('../input/h-and-m-personalized-fashion-recommendations/customers.csv', \n                        usecols=['customer_id', 'age'])\nbins = list(range(16,81,4))+ [100]\nnames = list(range(len(bins)-1))\ncustomers['age_group'] = pd.cut(customers['age'], bins, labels=names, right=False)\ndel customers['age']\ncustomers['age_group'] = customers['age_group'].astype(float).fillna(99).astype(int)\n\n\nagegroup = transactions_train[['t_dat', 'customer_id', 'article_id']]\nagegroup = agegroup[agegroup['t_dat'] > datetime(2020,9,15)][['customer_id', 'article_id']]\nagegroup = pd.merge(agegroup, customers, on='customer_id', how='left')\ndel agegroup['customer_id']\nagegroup = agegroup[agegroup['age_group'] != 99]\n\ndef generate_age_top(agegroup, num11, num22):\n    \n    def hope(x, num1, num2):\n        return ' '.join(x.value_counts().index.tolist()[num1:num2])\n    age_articles = agegroup[['age_group', 'article_id']].groupby('age_group')['article_id'].\\\n                   progress_apply(lambda x:hope(x, num11, num22)).reset_index()\n    age_articles.loc[17,'age_group'] = 99\n    age_articles.loc[17,'article_id'] = ' '.join(agegroup['article_id'].value_counts().index.tolist()[num11:num22])\n    age_articles['article_id'] = age_articles['article_id'].map(lambda x:x.split(' '))\n    \n    return age_articles\n\nage_articles = generate_age_top(agegroup,0,12)\nage_articles_ = age_articles.copy()\nage_articles_['article_id'] = age_articles_['article_id'].apply(lambda x:' '.join(x))\nage_articles_","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"lastday = transactions_train['t_dat'].max()\ntransactions_train['purchaseday_to_last'] = lastday - transactions_train['t_dat'] \ntransactions_train['purchaseday_to_last'] = transactions_train.groupby(['customer_id', 'article_id'])['purchaseday_to_last'].transform(min)\ntransactions_train['purchaseday_to_last'] = transactions_train['purchaseday_to_last'].dt.days\nfor col in ['ldbw', 'count', 'count_targ', 'quotient']:\n    del transactions_train[col]\ntransactions_train","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"purchase_times = transactions_train.groupby(['customer_id', 'article_id'])['t_dat'].count().\\\n                 reset_index().rename(columns={'t_dat':'purchase_times'})\ntransactions_train_pt = pd.merge(transactions_train, purchase_times, on=['customer_id', 'article_id'], how='left')\ntransactions_train_pt.drop_duplicates(['customer_id', 'article_id'], keep='last', inplace=True)\ntransactions_train_pt = pd.merge(transactions_train_pt, value, on=['customer_id', 'article_id'], how='left')\ndel transactions_train\ntransactions_train_pt","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\narticles = pd.read_csv('../input/h-and-m-personalized-fashion-recommendations/articles.csv',\n                       usecols = ['article_id', 'detail_desc', 'index_group_no'], dtype={'article_id': str})\narticles.rename(columns={'detail_desc':'detail_feature_no', 'index_group_no':'population_no'}, inplace=True)\n# articles_sales_week = transactions_train[transactions_train['t_dat'] > datetime(2020,9,15)].\\\n#                       groupby(['article_id'])['t_dat'].count()\n# articles_sales_month = transactions_train[transactions_train['t_dat'] > datetime(2020,8,22)].\\\n#                       groupby(['article_id'])['t_dat'].count()\n# del transactions_train\n# articles = pd.merge(articles, articles_sales_week, on='article_id', how='left')\n# articles.rename(columns={'t_dat':'sales_week'}, inplace=True)\n# articles = pd.merge(articles, articles_sales_month, on='article_id', how='left')\n# articles.rename(columns={'t_dat':'sales_month'}, inplace=True)\n# articles['sales_week'].fillna(0, inplace=True)\n# articles['sales_month'].fillna(0, inplace=True)\n# articles.sort_values(by=['sales_week', 'sales_month'], ascending=[False, False], inplace=True)\narticles['detail_feature_no'] = pd.factorize(articles['detail_feature_no'])[0]\narticles","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def articles_table(data):\n    data['label_A'] = data['detail_feature_no'].astype(str)\n    data['label_B'] = data['population_no'].astype(str) \n    \n    for col in ['detail_feature_no', 'population_no']:\n        del data[col]\n    return data\n\narticles = articles_table(articles)\narticles","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions_train_pt = pd.merge(transactions_train_pt, articles, on='article_id', how='left')\ngc.collect()\ntransactions_train_pt","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# LABEL RECOMMENDATION\n1. Используйте метку A, чтобы порекомендовать аналогичные продукты топ-5 продуктов с наибольшей ценностью для каждого потребителя.\n2. Используйте две категории продуктов с меткой B с наибольшим количеством покупок из 12 продуктов с наибольшей ценностью для рекомендации.","metadata":{}},{"cell_type":"code","source":"def recommand(train, articles, label, A_num=5, B_num=60, C_num=12):\n    def get_likegroup(x,num):\n        return x.tolist()[:num]\n    recommend_A_mapgroup = articles.groupby(label)['article_id'].apply(lambda x:get_likegroup(x,A_num))\n    \n    train['article_id_recommend'] = train[label].map(recommend_A_mapgroup)\n    train.fillna('0', inplace=True)\n    for col in ['label_A', 'label_B']:\n        del train[col]\n\n    def flat(x, lnum):\n        res = []\n        for i in x:\n            res.extend(i)\n        unique_list = []\n        for i in res:\n            if i not in unique_list and i != '0':\n                unique_list.append(i)\n        return unique_list[:lnum]\n    temp = train[['customer_id', 'article_id_recommend']].\\\n                     groupby('customer_id')['article_id_recommend'].apply(lambda x:flat(x.tolist(), lnum=B_num))\n    train['prediction'] = train['customer_id'].map(temp)\n    for col in ['article_id', 'purchaseday_to_last', 'purchase_times', 't_dat', 'article_id_recommend', 'value',\n                'age_group']:\n        del train[col]\n    train.drop_duplicates('customer_id', inplace=True)\n    train['count'] = train['prediction'].apply(lambda x:len(x))\n    train = train[train['count']>0]\n    del train['count']  \n    \n    train = train.explode('prediction')\n    train = pd.merge(train, articles[['article_id', 'rank']], left_on='prediction', right_on='article_id', how='left')\n    train.sort_values('rank', ascending=True, inplace=True)\n    temp = train.groupby('customer_id')['prediction'].apply(lambda x:x.tolist()[:C_num])\n    train['prediction'] = train['customer_id'].map(temp)\n    for col in ['article_id', 'rank']:\n        del train[col]\n    train.drop_duplicates('customer_id', inplace=True)\n\n    return train","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def age_rank_rec(train, train_age, customers, articles, label_rec ,rank, num1=5, num2=70, num3=12):    \n    \n    res = pd.DataFrame()\n    train_age = pd.merge(train_age, customers, on='customer_id', how='left')\n\n    for i in tqdm(list(range(len(bins)-1)) + [99]):\n\n        train_age_temp = train_age[train_age['age_group'] == i]\n        train_temp = train[train['age_group'] == i]\n\n\n        articles_sales_week_temp = train_age_temp[train_age_temp['t_dat'] > datetime(2020,9,15)].\\\n                    groupby(['article_id'])['t_dat'].count().reset_index().rename(columns={'t_dat':'sale_week_temp'})\n        articles_sales_month_temp = train_age_temp[train_age_temp['t_dat'] > datetime(2020,8,22)].\\\n                    groupby(['article_id'])['t_dat'].count().reset_index().rename(columns={'t_dat':'sale_month_temp'})\n\n       \n        articles_temp = articles.copy()\n        articles_temp = pd.merge(articles_temp, articles_sales_week_temp, on='article_id', how='left')\n        articles_temp = pd.merge(articles_temp, articles_sales_month_temp, on='article_id', how='left')\n        articles_temp['sale_week_temp'].fillna(0, inplace=True)\n        articles_temp['sale_month_temp'].fillna(0, inplace=True)\n        articles_temp.sort_values(by=['sale_week_temp', 'sale_month_temp'], inplace=True, ascending=[False, False])\n        articles_temp = articles_temp[articles_temp['sale_week_temp']>0]\n        articles_temp['rank'] = articles_temp['sale_week_temp'].rank(method='first',ascending=False)\n        articles_temp = articles_temp[['article_id', label_rec, 'rank']][articles_temp['rank']<=rank]\n\n        rec = recommand(train_temp, articles_temp, label=label_rec, A_num=num1, B_num=num2, C_num=num3)\n        res = pd.concat([res, rec])\n        del rec\n        gc.collect()\n\n    return res","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_head5 = transactions_train_pt.copy()\ntrain_head5.sort_values(by=['value', 'purchase_times'], ascending=[False, False], inplace=True)\ntrain_head5 = train_head5.groupby('customer_id').head(5)\ntrain_head5 = pd.merge(train_head5, customers, on='customer_id', how='left')\ntrain_head5","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nrec_A = age_rank_rec(train_head5, transactions_train_pt, customers, \n                     articles, label_rec='label_A', rank=1000, num1=5, num2=20, num3=8)\ndel train_head5\ngc.collect()\nrec_A","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_B_lov1 = transactions_train_pt.copy()\ntrain_B_lov1.sort_values(by=['value', 'purchase_times'], ascending=[False, False], inplace=True)\ntrain_B_lov1 = train_B_lov1.groupby('customer_id').head(18)\ntrain_B_lov1 = pd.merge(train_B_lov1, customers, on='customer_id', how='left')\ntemp = train_B_lov1.groupby('customer_id')['label_B'].progress_apply(lambda x:x.value_counts().index.tolist()[:1])\ntrain_B_lov1['label_B'] = train_B_lov1['customer_id'].map(temp)\ntrain_B_lov1.drop_duplicates('customer_id', inplace=True)\ntrain_B_lov1 = train_B_lov1.explode('label_B')\ntrain_B_lov1","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"%%time\nrec_B = age_rank_rec(train_B_lov1, transactions_train_pt, customers, \n                     articles, label_rec='label_B', rank=800, num1=12, num2=30, num3=12)\ndel train_B_lov1\ngc.collect()\nrec_B","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = customers['customer_id']\nsub = pd.merge(sub, purchase_records, on='customer_id', how='left')\nsub = pd.merge(sub, rec_A, on='customer_id', suffixes=['_a', '_b'], how='left')\nsub = pd.merge(sub, rec_B, on='customer_id', how='left')\nsub.fillna('0', inplace=True)\ndef wash(x):\n    res = []\n    for i in x:\n        res.extend(i)\n    unique_list = []\n    for i in res:\n        if i not in unique_list and i != '0':\n            unique_list.append(i)\n    return unique_list\nsub['prediction'] = sub[['prediction_a', 'prediction_b', 'prediction']].progress_apply(lambda x:wash(x.tolist()), axis=1)\nsub['count'] = sub['prediction'].progress_apply(lambda x:len(x))\nsub = sub[sub['count'] > 0]\nfor col in ['prediction_a', 'prediction_b', 'count']:\n    del sub[col]\nsub","metadata":{"scrolled":true,"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"train_foo = sub.copy()\ntrain_foo['prediction'] = train_foo['prediction'].progress_apply(lambda x:' '.join(x))\ntrain_foo","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.read_csv('../input/h-and-m-personalized-fashion-recommendations/sample_submission.csv', usecols=['customer_id'])\nno_sub = sub[~sub['customer_id'].isin(train_foo['customer_id'])]\nno_sub = pd.merge(no_sub, customers, on='customer_id', how='left')\nno_sub = pd.merge(no_sub, age_articles, on='age_group', how='left')\nno_sub.rename(columns={'article_id':'prediction'}, inplace=True)\ndel no_sub['age_group']\nno_sub['prediction'] = no_sub['prediction'].map(lambda x:' '.join(x)[:131])\nno_sub","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.concat([train_foo, no_sub])","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub = pd.merge(sub, customers, on='customer_id', how='left')\nsub = pd.merge(sub, age_articles_, on='age_group', how='left')\ndel sub['age_group']\nsub['prediction'] = sub['prediction'] + ' '+ sub['article_id']\ndel sub['article_id']\nsub['prediction'] = sub['prediction'].map(lambda x:x.lstrip()[:131])\nsub","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"","metadata":{},"execution_count":null,"outputs":[]}]}