{"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 datetime\nfrom tqdm import tqdm","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2022-06-18T03:49:19.314526Z","iopub.execute_input":"2022-06-18T03:49:19.314945Z","iopub.status.idle":"2022-06-18T03:49:19.320727Z","shell.execute_reply.started":"2022-06-18T03:49:19.314913Z","shell.execute_reply":"2022-06-18T03:49:19.319886Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/transactions_train.csv\",usecols=['t_dat','customer_id','article_id'])\nsubmission = pd.read_csv('../input/h-and-m-personalized-fashion-recommendations/sample_submission.csv')\n\ntransactions['t_dat'] = pd.to_datetime(transactions['t_dat'])\ntransactions = transactions.loc[transactions['t_dat'] > pd.to_datetime('2020-09-01')]\n\n#only choose customers who bought more than 4 times.\nMINIMUM_PURCHASES = 4\ndfh = transactions.groupby(\"customer_id\")['article_id'].apply(lambda items: list(items))\ndfh = dfh[dfh.str.len() > MINIMUM_PURCHASES]\ntransactions = transactions.loc[transactions['customer_id'].isin(dfh.index)]\n\n#only choose articles which were bought more than 10 times\narticle_bought_count = transactions[['article_id', 't_dat']].groupby('article_id').count().reset_index().rename(columns={'t_dat': 'count'})\nmost_bought_articles = article_bought_count[article_bought_count['count']>10]['article_id'].values\ntransactions = transactions[transactions['article_id'].isin(most_bought_articles)]\n","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:49:27.860714Z","iopub.execute_input":"2022-06-18T03:49:27.861167Z","iopub.status.idle":"2022-06-18T03:50:50.775634Z","shell.execute_reply.started":"2022-06-18T03:49:27.861133Z","shell.execute_reply":"2022-06-18T03:50:50.774528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print('The number of customers: ',transactions['customer_id'].nunique())\nprint('The number of articles: ',transactions['article_id'].nunique())","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:50:56.947082Z","iopub.execute_input":"2022-06-18T03:50:56.947546Z","iopub.status.idle":"2022-06-18T03:50:57.057566Z","shell.execute_reply.started":"2022-06-18T03:50:56.947512Z","shell.execute_reply":"2022-06-18T03:50:57.056326Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#mapping\ncustomers_toindex = {c:n for n,c in enumerate(np.unique(transactions['customer_id'].values))}\narticles_toindex = {c:n for n,c in enumerate(np.unique(transactions['article_id'].values))}\n\n#convert into integer index.\ntransactions['customer_id'] = transactions['customer_id'].map(customers_toindex)\n","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:03.332378Z","iopub.execute_input":"2022-06-18T03:51:03.332854Z","iopub.status.idle":"2022-06-18T03:51:04.161496Z","shell.execute_reply.started":"2022-06-18T03:51:03.332819Z","shell.execute_reply":"2022-06-18T03:51:04.160329Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#article_customer: article is the index, customers is the values for comparing part.\narticle_customer = transactions.groupby(\"article_id\")['customer_id'].apply(lambda customer: list(set(customer)))\n\n#customer_article: to find article bought the most times by one customer without the limitation of purchase times.\ncustomer_article = transactions.groupby([\"customer_id\",\"article_id\"])['t_dat'].count()\ncustomer_article = customer_article.reset_index().sort_values(by = ['customer_id','t_dat'],ascending = [True,False])","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:06.909345Z","iopub.execute_input":"2022-06-18T03:51:06.909791Z","iopub.status.idle":"2022-06-18T03:51:07.461835Z","shell.execute_reply.started":"2022-06-18T03:51:06.909742Z","shell.execute_reply":"2022-06-18T03:51:07.460703Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(article_customer.head())\nprint(customer_article.head())","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:09.474157Z","iopub.execute_input":"2022-06-18T03:51:09.474626Z","iopub.status.idle":"2022-06-18T03:51:09.489694Z","shell.execute_reply.started":"2022-06-18T03:51:09.474592Z","shell.execute_reply":"2022-06-18T03:51:09.488231Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#The most popular articles to make up for the absent positions.\ndefault_transactions = transactions.loc[transactions['t_dat']> pd.to_datetime('2020-09-14')]\ndefault_top12 = default_transactions.groupby('article_id')['t_dat'].count().reset_index().sort_values(by='t_dat', ascending=False)['article_id'][:12]\ndefault_top12 =  ['0'+str(i) for i in default_top12]","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:15.672510Z","iopub.execute_input":"2022-06-18T03:51:15.672929Z","iopub.status.idle":"2022-06-18T03:51:15.698138Z","shell.execute_reply.started":"2022-06-18T03:51:15.672897Z","shell.execute_reply":"2022-06-18T03:51:15.696998Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"print(default_top12)","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:18.331554Z","iopub.execute_input":"2022-06-18T03:51:18.331990Z","iopub.status.idle":"2022-06-18T03:51:18.338687Z","shell.execute_reply.started":"2022-06-18T03:51:18.331956Z","shell.execute_reply":"2022-06-18T03:51:18.337521Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"class ItemtoItem:\n    def __init__(self,transactions,submission,customers_toindex,articles_toindex,article_customer,customer_article,default_top12):\n        \"\"\"\n        Constructor\n        \"\"\"\n        self.transactions = transactions\n        self.submission = submission\n        self.customers_toindex = customers_toindex\n        self.articles_toindex = articles_toindex\n        self.article_customer = article_customer\n        self.customer_article = customer_article\n        self.default_top12 = default_top12\n\n\n    def compare_vectors(self,v1, v2):\n        \"\"\"\n        Compare the two customer vectors. get a similarity score.\n\n        \"\"\"\n        intersection = len(set(v1) & set(v2))\n        denominator = np.sqrt(len(v1) * len(v2))\n        return intersection / denominator\n\n\n    def get_similar_items_for_target_article(self,u, v):\n        \"\"\"\n        Using target article to compare in other article_customer.\n\n        Arguments:\n            u:  the article bought before\n            v:  the \"vector\" representation of the article (list of customer_id)\n\n        Returns:\n            the three most similar article to target article\n            tuple of list ([similar article_id])\n        \"\"\"\n        similar_articles = self.article_customer.apply(lambda v_other: self.compare_vectors(v, v_other)).sort_values(ascending=False).index[:3]\n\n        return similar_articles\n\n    def get_target_article(self,user):\n        \"\"\"\n        Using customer_article dataframe to find the article this customer bought before. Find the\n        similar three articles to target article.\n\n        Arguments:\n                user: customer_id\n        \n        Return: Find the most similar item based on previous purchase.\n\n        \"\"\"\n        target_articles = self.customer_article.loc[self.customer_article['customer_id']== user][\"article_id\"].values[:3].tolist()\n        single_customer_similar_articles = []\n        for target_article in target_articles:\n            v = self.article_customer.loc[self.article_customer.index == target_article].tolist()[0]\n            similar_items = self.get_similar_items_for_target_article(target_article, v)\n            single_customer_similar_articles += similar_items.tolist()\n\n        return single_customer_similar_articles\n    \n\n    def get_recommendation(self):\n        \"\"\"\n        Main functions\n        \"\"\"\n        recommendations = []\n        customers = self.submission['customer_id']\n        for customer in tqdm(customers):\n                if customer in self.customers_toindex:\n                    rec_aux1 = []\n                    rec_aux2 = []\n                    aux = []\n                    # Return the similar items found for this customer.\n                    rec_aux1 = self.get_target_article(self.customers_toindex[customer])\n                    # Return the default recommendation.\n                    rec_aux2 = self.default_top12\n                    # Merge both recommendation lists.\n                    aux = rec_aux1 + rec_aux2\n                    aux = aux[:12]\n                    aux = ['0'+str(i) for i in aux]\n                    recommendations.append(' '.join(aux))\n                else:# if couldn't find the customer in the map.\n                    # Return the default recommendation\n                    recommendations.append(' '.join(self.default_top12))\n\n        return pd.DataFrame({\n                'customer_id': customers,\n                'prediction': recommendations,\n            })\n\n    \n    ","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:20.730170Z","iopub.execute_input":"2022-06-18T03:51:20.730604Z","iopub.status.idle":"2022-06-18T03:51:20.763849Z","shell.execute_reply.started":"2022-06-18T03:51:20.730571Z","shell.execute_reply":"2022-06-18T03:51:20.762672Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"rec = ItemtoItem(transactions,submission,customers_toindex,articles_toindex,article_customer,customer_article,default_top12)\nsub = rec.get_recommendation()","metadata":{"execution":{"iopub.status.busy":"2022-06-18T03:51:24.857491Z","iopub.execute_input":"2022-06-18T03:51:24.857919Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sub.to_csv('submission.csv', index=False)","metadata":{},"execution_count":null,"outputs":[]}]}