{"metadata":{"kernelspec":{"language":"python","display_name":"Python 3","name":"python3"},"language_info":{"name":"python","version":"3.7.12","mimetype":"text/x-python","codemirror_mode":{"name":"ipython","version":3},"pygments_lexer":"ipython3","nbconvert_exporter":"python","file_extension":".py"},"kaggle":{"accelerator":"none","dataSources":[{"sourceId":31254,"databundleVersionId":3103714,"sourceType":"competition"}],"dockerImageVersionId":30157,"isInternetEnabled":true,"language":"python","sourceType":"notebook","isGpuEnabled":false}},"nbformat_minor":4,"nbformat":4,"cells":[{"cell_type":"markdown","source":"# Содержание\n1. Импорт и чтение\n2. Articles\n3. Customers\n4. Transactions  \n5. Images with description and price\n","metadata":{}},{"cell_type":"markdown","source":"## Введение\n\nВ датасете представлены различные виды данных, которые помогают создавать хорошие рекомендации для H&M:\n\n`images` - изображения для каждого article_id\n\n`articles`  - подробная метадата для каждого article_id\n\n`customers`  - подробная метадата для каждого customer_id\n\n`transactions_train`  - покупки с деталями\n\n","metadata":{}},{"cell_type":"markdown","source":"## 1. Импорт и чтение\n","metadata":{}},{"cell_type":"code","source":"import numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib import pyplot as plt\nfrom tqdm.notebook import tqdm","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:08:28.441766Z","iopub.execute_input":"2024-06-29T20:08:28.442205Z","iopub.status.idle":"2024-06-29T20:08:29.686852Z","shell.execute_reply.started":"2024-06-29T20:08:28.442083Z","shell.execute_reply":"2024-06-29T20:08:29.685733Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articles = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/articles.csv\")\ncustomers = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/customers.csv\")\ntransactions = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/transactions_train.csv\")\nsample_submission = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/sample_submission.csv\")","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:08:29.688751Z","iopub.execute_input":"2024-06-29T20:08:29.689057Z","iopub.status.idle":"2024-06-29T20:09:58.621709Z","shell.execute_reply.started":"2024-06-29T20:08:29.689020Z","shell.execute_reply":"2024-06-29T20:09:58.620524Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 2. Articles (таблица с товарами) \n","metadata":{}},{"cell_type":"code","source":"articles.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:09:58.644491Z","iopub.execute_input":"2024-06-29T20:09:58.645132Z","iopub.status.idle":"2024-06-29T20:09:58.706949Z","shell.execute_reply.started":"2024-06-29T20:09:58.645085Z","shell.execute_reply":"2024-06-29T20:09:58.705619Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Доля одежды для женщин занимает значительную часть всех платьев. Спортивная одежда имеет наименьшую долю.\n\n","metadata":{}},{"cell_type":"code","source":"f, ax = plt.subplots(figsize=(15, 7))\nax = sns.histplot(data=articles, y='index_name', color='blue')\nax.set_xlabel('count by index name')\nax.set_ylabel('index name')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:09:58.710345Z","iopub.execute_input":"2024-06-29T20:09:58.711100Z","iopub.status.idle":"2024-06-29T20:09:59.270943Z","shell.execute_reply.started":"2024-06-29T20:09:58.711039Z","shell.execute_reply":"2024-06-29T20:09:59.269706Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Одежда, сгруппированная по индексам: самая частая одежда - футболки, особенно для женщин и детей. Следующим по числу идет аксессуары, много различных аксессуаров с низкой ценой.\n\n","metadata":{}},{"cell_type":"code","source":"f, ax = plt.subplots(figsize=(15, 7))\nax = sns.histplot(data=articles, y='garment_group_name',  hue='index_group_name', multiple=\"stack\")\nax.set_xlabel('count by garment group')\nax.set_ylabel('garment group')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:09:59.273171Z","iopub.execute_input":"2024-06-29T20:09:59.273682Z","iopub.status.idle":"2024-06-29T20:10:00.554527Z","shell.execute_reply.started":"2024-06-29T20:09:59.273603Z","shell.execute_reply":"2024-06-29T20:10:00.553308Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Женская одежда и детская/младенческая имеют подгруппы.","metadata":{}},{"cell_type":"code","source":"articles.groupby(['index_group_name', 'index_name']).count()['article_id']","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:00.556294Z","iopub.execute_input":"2024-06-29T20:10:00.556688Z","iopub.status.idle":"2024-06-29T20:10:00.815135Z","shell.execute_reply.started":"2024-06-29T20:10:00.556639Z","shell.execute_reply":"2024-06-29T20:10:00.813953Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Аксессуары действительно разнообразны, самых многочисленных: сумки, серьги и головные уборы. Однако преобладают брюки","metadata":{}},{"cell_type":"code","source":"pd.options.display.max_rows = None\narticles.groupby(['product_group_name', 'product_type_name']).count()['article_id']","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:00.816961Z","iopub.execute_input":"2024-06-29T20:10:00.817370Z","iopub.status.idle":"2024-06-29T20:10:01.066838Z","shell.execute_reply.started":"2024-06-29T20:10:00.817311Z","shell.execute_reply":"2024-06-29T20:10:01.065599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"И таблица с количеством уникальных значений в столбцах","metadata":{}},{"cell_type":"code","source":"for col in articles.columns:\n    if not 'no' in col and not 'code' in col and not 'id' in col:\n        un_n = articles[col].nunique()\n        print(f'n of unique {col}: {un_n}')","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:01.068469Z","iopub.execute_input":"2024-06-29T20:10:01.068845Z","iopub.status.idle":"2024-06-29T20:10:01.264868Z","shell.execute_reply.started":"2024-06-29T20:10:01.068801Z","shell.execute_reply":"2024-06-29T20:10:01.263422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 3. Customers (таблица с клиентами)","metadata":{}},{"cell_type":"code","source":"pd.options.display.max_rows = 50\ncustomers.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:01.268944Z","iopub.execute_input":"2024-06-29T20:10:01.269633Z","iopub.status.idle":"2024-06-29T20:10:01.294191Z","shell.execute_reply.started":"2024-06-29T20:10:01.269571Z","shell.execute_reply":"2024-06-29T20:10:01.292774Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Здесь нет дубликатов","metadata":{}},{"cell_type":"code","source":"customers.shape[0] - customers['customer_id'].nunique()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:01.299462Z","iopub.execute_input":"2024-06-29T20:10:01.299906Z","iopub.status.idle":"2024-06-29T20:10:02.263053Z","shell.execute_reply.started":"2024-06-29T20:10:01.299854Z","shell.execute_reply":"2024-06-29T20:10:02.261855Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Здесь аномальное количество клиентов с одним почтовым индексом. Один из них имеет 120303, это может быть закодированный адрес nan или что-то вроде крупного дистрибуционного центра или пункта выдачи.","metadata":{}},{"cell_type":"code","source":"data_postal = customers.groupby('postal_code', as_index=False).count().sort_values('customer_id', ascending=False)\ndata_postal.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:02.265150Z","iopub.execute_input":"2024-06-29T20:10:02.265589Z","iopub.status.idle":"2024-06-29T20:10:04.837669Z","shell.execute_reply.started":"2024-06-29T20:10:02.265532Z","shell.execute_reply":"2024-06-29T20:10:04.836437Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Возрасты, статусы участников клуба разные, как и идентификаторы клиентов.\n\n","metadata":{}},{"cell_type":"code","source":"customers[customers['postal_code']=='2c29ae653a9282cce4151bd87643c907644e09541abc28ae87dea0d1f6603b1c'].head(5)","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:04.839174Z","iopub.execute_input":"2024-06-29T20:10:04.839612Z","iopub.status.idle":"2024-06-29T20:10:05.203782Z","shell.execute_reply.started":"2024-06-29T20:10:04.839558Z","shell.execute_reply":"2024-06-29T20:10:05.202643Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Самый распространенный возраст около 21-23 лет.\n\n","metadata":{}},{"cell_type":"code","source":"import seaborn as sns\nfrom matplotlib import pyplot as plt\nsns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(10,5))\nax = sns.histplot(data=customers, x='age', bins=50, color='blue')\nax.set_xlabel('Распределение возраста клиентов')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:05.205179Z","iopub.execute_input":"2024-06-29T20:10:05.205521Z","iopub.status.idle":"2024-06-29T20:10:05.910447Z","shell.execute_reply.started":"2024-06-29T20:10:05.205468Z","shell.execute_reply":"2024-06-29T20:10:05.909303Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Статус в клубе H&M. Почти у каждого клиента есть активный статус в клубе, некоторые из них начинают активировать его (предварительно создавать). Малая часть клиентов отказалась от клуба.","metadata":{}},{"cell_type":"code","source":"sns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(10,5))\nax = sns.histplot(data=customers, x='club_member_status', color='blue')\nax.set_xlabel('Распределение статуса участника клуба')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:05.912022Z","iopub.execute_input":"2024-06-29T20:10:05.912400Z","iopub.status.idle":"2024-06-29T20:10:08.420850Z","shell.execute_reply.started":"2024-06-29T20:10:05.912360Z","shell.execute_reply":"2024-06-29T20:10:08.419663Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Здесь есть три типа для NO DATA. Давайте объединим эти значения.\n","metadata":{}},{"cell_type":"code","source":"customers['fashion_news_frequency'].unique()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:08.422611Z","iopub.execute_input":"2024-06-29T20:10:08.423096Z","iopub.status.idle":"2024-06-29T20:10:08.619350Z","shell.execute_reply.started":"2024-06-29T20:10:08.423040Z","shell.execute_reply":"2024-06-29T20:10:08.618230Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"customers.loc[~customers['fashion_news_frequency'].isin(['Regularly', 'Monthly']), 'fashion_news_frequency'] = 'None'\ncustomers['fashion_news_frequency'].unique()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:08.621052Z","iopub.execute_input":"2024-06-29T20:10:08.621493Z","iopub.status.idle":"2024-06-29T20:10:08.922477Z","shell.execute_reply.started":"2024-06-29T20:10:08.621416Z","shell.execute_reply":"2024-06-29T20:10:08.921318Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"pie_data = customers[['customer_id', 'fashion_news_frequency']].groupby('fashion_news_frequency').count()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:08.924961Z","iopub.execute_input":"2024-06-29T20:10:08.925304Z","iopub.status.idle":"2024-06-29T20:10:09.350856Z","shell.execute_reply.started":"2024-06-29T20:10:08.925264Z","shell.execute_reply":"2024-06-29T20:10:09.349534Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Клиенты предпочитают не получать сообщения о текущих новостях.\n\n","metadata":{}},{"cell_type":"code","source":"sns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(10,5))\ncolors = sns.color_palette('viridis')\nax.pie(pie_data.customer_id, labels=pie_data.index, colors = colors)\nax.set_facecolor('lightgrey')\nax.set_xlabel('Распределение частоты новостей о моде')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:09.352226Z","iopub.execute_input":"2024-06-29T20:10:09.352621Z","iopub.status.idle":"2024-06-29T20:10:09.519036Z","shell.execute_reply.started":"2024-06-29T20:10:09.352515Z","shell.execute_reply":"2024-06-29T20:10:09.517528Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 4. Transactions (таблица с транзакциями)","metadata":{}},{"cell_type":"code","source":"transactions.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:09.521388Z","iopub.execute_input":"2024-06-29T20:10:09.522973Z","iopub.status.idle":"2024-06-29T20:10:09.555097Z","shell.execute_reply.started":"2024-06-29T20:10:09.522893Z","shell.execute_reply":"2024-06-29T20:10:09.552025Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Здесь мы видим выбросы.\n\n","metadata":{}},{"cell_type":"code","source":"pd.set_option('display.float_format', '{:.4f}'.format)\ntransactions.describe()['price']","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:09.558184Z","iopub.execute_input":"2024-06-29T20:10:09.558810Z","iopub.status.idle":"2024-06-29T20:10:16.302697Z","shell.execute_reply.started":"2024-06-29T20:10:09.558682Z","shell.execute_reply":"2024-06-29T20:10:16.300974Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions.head()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:16.305132Z","iopub.execute_input":"2024-06-29T20:10:16.305519Z","iopub.status.idle":"2024-06-29T20:10:16.322464Z","shell.execute_reply.started":"2024-06-29T20:10:16.305471Z","shell.execute_reply":"2024-06-29T20:10:16.321157Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(10,5))\nax = sns.boxplot(data=transactions, x='price', color='blue')\nax.set_xlabel('Выбросы по цене')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:16.324723Z","iopub.execute_input":"2024-06-29T20:10:16.325153Z","iopub.status.idle":"2024-06-29T20:10:21.372960Z","shell.execute_reply.started":"2024-06-29T20:10:16.325094Z","shell.execute_reply":"2024-06-29T20:10:21.371866Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Топ-10 клиентов по количеству транзакций","metadata":{}},{"cell_type":"code","source":"transactions_byid = transactions.groupby('customer_id').count()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:21.374713Z","iopub.execute_input":"2024-06-29T20:10:21.375014Z","iopub.status.idle":"2024-06-29T20:10:42.298652Z","shell.execute_reply.started":"2024-06-29T20:10:21.374975Z","shell.execute_reply":"2024-06-29T20:10:42.297590Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"transactions_byid.sort_values(by='price', ascending=False)['price'][:10]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:42.300022Z","iopub.execute_input":"2024-06-29T20:10:42.300287Z","iopub.status.idle":"2024-06-29T20:10:42.895664Z","shell.execute_reply.started":"2024-06-29T20:10:42.300255Z","shell.execute_reply":"2024-06-29T20:10:42.894639Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Однако более точным будет сравнение цен внутри групп, поскольку цены на аксессуары и брюки могут сильно различаться","metadata":{}},{"cell_type":"markdown","source":"Получим сабсет из статей и объединим его с транзакциями\n","metadata":{}},{"cell_type":"code","source":"articles_for_merge = articles[['article_id', 'prod_name', 'product_type_name', 'product_group_name', 'index_name']]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:42.897117Z","iopub.execute_input":"2024-06-29T20:10:42.897423Z","iopub.status.idle":"2024-06-29T20:10:42.910996Z","shell.execute_reply.started":"2024-06-29T20:10:42.897383Z","shell.execute_reply":"2024-06-29T20:10:42.909776Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articles_for_merge = transactions[['customer_id', 'article_id', 'price', 't_dat']].merge(articles_for_merge, on='article_id', how='left')","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:42.912633Z","iopub.execute_input":"2024-06-29T20:10:42.912940Z","iopub.status.idle":"2024-06-29T20:10:57.669299Z","shell.execute_reply.started":"2024-06-29T20:10:42.912902Z","shell.execute_reply":"2024-06-29T20:10:57.667917Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Здесь мы видим различия в ценах на названия групп. Цены на одежду для нижней части тела (напр брюки)/ верхней/ всего тела сильно различаются. Это может быть похоже на некоторые уникальные коллекции  Некоторые дорогостоящие товары даже относятся к группе аксессуаров.","metadata":{}},{"cell_type":"code","source":"sns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(25,18))\nax = sns.boxplot(data=articles_for_merge, x='price', y='product_group_name')\nax.set_xlabel('Выбросы по ценам', fontsize=22)\nax.set_ylabel('Названия', fontsize=22)\nax.xaxis.set_tick_params(labelsize=22)\nax.yaxis.set_tick_params(labelsize=22)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:10:57.671896Z","iopub.execute_input":"2024-06-29T20:10:57.672297Z","iopub.status.idle":"2024-06-29T20:11:31.979783Z","shell.execute_reply.started":"2024-06-29T20:10:57.672245Z","shell.execute_reply":"2024-06-29T20:11:31.978599Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Затем просмотрим таблицу цен в зависимости от группы товаров \"аксессуары\" и найд причины высоких цен внутри группы.\n\nНаибольшие отклонения можно найти среди сумок, что вполне логично. Кроме того, шарфы и другие аксессуары имеют цены, резко отличающиеся от цен на остальную одежду","metadata":{}},{"cell_type":"code","source":"sns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(25,18))\n_ = articles_for_merge[articles_for_merge['product_group_name'] == 'Accessories']\nax = sns.boxplot(data=_, x='price', y='product_type_name')\nax.set_xlabel('Выбросы по ценам', fontsize=22)\nax.set_ylabel('Названия товаров', fontsize=22)\nax.xaxis.set_tick_params(labelsize=22)\nax.yaxis.set_tick_params(labelsize=22)\ndel _\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:11:31.984045Z","iopub.execute_input":"2024-06-29T20:11:31.984390Z","iopub.status.idle":"2024-06-29T20:11:49.337977Z","shell.execute_reply.started":"2024-06-29T20:11:31.984340Z","shell.execute_reply":"2024-06-29T20:11:49.336914Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Индекс с самой высокой средней ценой - это женская одежда. С самой низкой - детская.","metadata":{}},{"cell_type":"code","source":"articles_index = articles_for_merge[['index_name', 'price']].groupby('index_name').mean()\nsns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(10,5))\nax = sns.barplot(x=articles_index.price, y=articles_index.index, color='blue', alpha=0.8)\n\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:11:49.339470Z","iopub.execute_input":"2024-06-29T20:11:49.339866Z","iopub.status.idle":"2024-06-29T20:11:54.994416Z","shell.execute_reply.started":"2024-06-29T20:11:49.339825Z","shell.execute_reply":"2024-06-29T20:11:54.993401Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Самая низкая средняя цена на канцелярские товары, самая высокая - на обувь.","metadata":{}},{"cell_type":"code","source":"articles_index = articles_for_merge[['product_group_name', 'price']].groupby('product_group_name').mean()\nsns.set_style(\"darkgrid\")\nf, ax = plt.subplots(figsize=(10,5))\nax = sns.barplot(x=articles_index.price, y=articles_index.index, color='blue', alpha=0.8)\nax.set_xlabel('Цена по продуктовой группе')\nax.set_ylabel('Продуктовая группа')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:11:54.995990Z","iopub.execute_input":"2024-06-29T20:11:54.996348Z","iopub.status.idle":"2024-06-29T20:12:00.714058Z","shell.execute_reply.started":"2024-06-29T20:11:54.996281Z","shell.execute_reply":"2024-06-29T20:12:00.712794Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Теперь посмотрим среднее изменение цен во времени для 5 лучших товарных групп по средней цене:\n- Обувь\n- Одежда на все тело\n- Сумки\n- Одежда для нижней части тела\n- Нижнее белье/ночные сорочки","metadata":{}},{"cell_type":"code","source":"articles_for_merge['t_dat'] = pd.to_datetime(articles_for_merge['t_dat'])","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:12:00.715636Z","iopub.execute_input":"2024-06-29T20:12:00.715992Z","iopub.status.idle":"2024-06-29T20:12:11.019106Z","shell.execute_reply.started":"2024-06-29T20:12:00.715945Z","shell.execute_reply":"2024-06-29T20:12:11.018018Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"product_list = ['Shoes', 'Garment Full body', 'Bags', 'Garment Lower body', 'Underwear/nightwear']\ncolors = ['blue', 'blue', 'blue', 'blue', 'blue']\nk = 0\nf, ax = plt.subplots(3, 2, figsize=(20, 15))\nfor i in range(3):\n    for j in range(2):\n        try:\n            product = product_list[k]\n            articles_for_merge_product = articles_for_merge[articles_for_merge.product_group_name == product_list[k]]\n            series_mean = articles_for_merge_product[['t_dat', 'price']].groupby(pd.Grouper(key=\"t_dat\", freq='M')).mean().fillna(0)\n            series_std = articles_for_merge_product[['t_dat', 'price']].groupby(pd.Grouper(key=\"t_dat\", freq='M')).std().fillna(0)\n            ax[i, j].plot(series_mean, linewidth=4, color=colors[k])\n            ax[i, j].fill_between(series_mean.index, (series_mean.values-2*series_std.values).ravel(), \n                             (series_mean.values+2*series_std.values).ravel(), color=colors[k], alpha=.1)\n            ax[i, j].set_title(f'Mean {product_list[k]} price in time')\n            ax[i, j].set_xlabel('month')\n            ax[i, j].set_xlabel(f'{product_list[k]}')\n            k += 1\n        except IndexError:\n            ax[i, j].set_visible(False)\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:12:11.020879Z","iopub.execute_input":"2024-06-29T20:12:11.021280Z","iopub.status.idle":"2024-06-29T20:12:45.224806Z","shell.execute_reply.started":"2024-06-29T20:12:11.021227Z","shell.execute_reply":"2024-06-29T20:12:45.223594Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## 5. Картинки с описанием и ценой","metadata":{}},{"cell_type":"markdown","source":"Проверим последние покупки по максимальной и минимальной цене","metadata":{}},{"cell_type":"code","source":"import matplotlib.pyplot as plt\nimport matplotlib.image as mpimg","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:12:45.226645Z","iopub.execute_input":"2024-06-29T20:12:45.226961Z","iopub.status.idle":"2024-06-29T20:12:45.232278Z","shell.execute_reply.started":"2024-06-29T20:12:45.226918Z","shell.execute_reply":"2024-06-29T20:12:45.231436Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"max_price_ids = transactions[transactions.t_dat==transactions.t_dat.max()].sort_values('price', ascending=False).iloc[:5][['article_id', 'price']]\nmin_price_ids = transactions[transactions.t_dat==transactions.t_dat.min()].sort_values('price', ascending=True).iloc[:5][['article_id', 'price']]","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:12:45.233783Z","iopub.execute_input":"2024-06-29T20:12:45.234076Z","iopub.status.idle":"2024-06-29T20:13:06.365596Z","shell.execute_reply.started":"2024-06-29T20:12:45.234021Z","shell.execute_reply":"2024-06-29T20:13:06.364422Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Фотографии с описанием и ценой ( 5 лучших)","metadata":{}},{"cell_type":"code","source":"f, ax = plt.subplots(1, 5, figsize=(20,10))\ni = 0\nfor _, data in max_price_ids.iterrows():\n    desc = articles[articles['article_id'] == data['article_id']]['detail_desc'].iloc[0]\n    desc_list = desc.split(' ')\n    for j, elem in enumerate(desc_list):\n        if j > 0 and j % 5 == 0:\n            desc_list[j] = desc_list[j] + '\\n'\n    desc = ' '.join(desc_list)\n    img = mpimg.imread(f'../input/h-and-m-personalized-fashion-recommendations/images/0{str(data.article_id)[:2]}/0{int(data.article_id)}.jpg')\n    ax[i].imshow(img)\n    ax[i].set_title(f'price: {data.price:.2f}')\n    ax[i].set_xticks([], [])\n    ax[i].set_yticks([], [])\n    ax[i].grid(False)\n    ax[i].set_xlabel(desc, fontsize=10)\n    i += 1\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:13:06.367587Z","iopub.execute_input":"2024-06-29T20:13:06.367988Z","iopub.status.idle":"2024-06-29T20:13:08.455666Z","shell.execute_reply.started":"2024-06-29T20:13:06.367933Z","shell.execute_reply":"2024-06-29T20:13:08.454626Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Фотографии с описанием и ценой ( 5 худших)","metadata":{}},{"cell_type":"code","source":"f, ax = plt.subplots(1, 5, figsize=(20,10))\ni = 0\nfor _, data in min_price_ids.iterrows():\n    desc = articles[articles['article_id'] == data['article_id']]['detail_desc'].iloc[0]\n    desc_list = desc.split(' ')\n    for j, elem in enumerate(desc_list):\n        if j > 0 and j % 4 == 0:\n            desc_list[j] = desc_list[j] + '\\n'\n    desc = ' '.join(desc_list)\n    img = mpimg.imread(f'../input/h-and-m-personalized-fashion-recommendations/images/0{str(data.article_id)[:2]}/0{int(data.article_id)}.jpg')\n    ax[i].imshow(img)\n    ax[i].set_title(f'price: {data.price:.4f}')\n    ax[i].set_xlabel(desc, fontsize=10)\n    ax[i].set_xticks([], [])\n    ax[i].set_yticks([], [])\n    ax[i].grid(False)\n    i += 1\nplt.axis('off')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:13:08.457119Z","iopub.execute_input":"2024-06-29T20:13:08.457425Z","iopub.status.idle":"2024-06-29T20:13:10.217022Z","shell.execute_reply.started":"2024-06-29T20:13:08.457387Z","shell.execute_reply":"2024-06-29T20:13:10.215990Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Surprise\n","metadata":{}},{"cell_type":"code","source":"import pandas as pd\nfrom surprise import Dataset, Reader, SVD\nfrom surprise.model_selection import train_test_split\nfrom surprise import accuracy\nfrom surprise import dump\n\n# Загрузка данных\ntransactions = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/transactions_train.csv\")\nsample_submission = pd.read_csv(\"../input/h-and-m-personalized-fashion-recommendations/sample_submission.csv\")\n\n# Подготовка данных для Surprise\nreader = Reader(rating_scale=(transactions['price'].min(), transactions['price'].max()))\ndata = Dataset.load_from_df(transactions[['customer_id', 'article_id', 'price']], reader)\ntrainset, testset = train_test_split(data, test_size=0.2)\n\n\n\n\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:13:41.223936Z","iopub.execute_input":"2024-06-29T20:13:41.224264Z","iopub.status.idle":"2024-06-29T20:18:29.231048Z","shell.execute_reply.started":"2024-06-29T20:13:41.224230Z","shell.execute_reply":"2024-06-29T20:18:29.229867Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Обучение модели SVD\nmodel = SVD()\nmodel.fit(trainset)\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-29T20:33:06.827126Z","iopub.execute_input":"2024-06-29T20:33:06.828105Z","iopub.status.idle":"2024-06-29T21:14:45.294760Z","shell.execute_reply.started":"2024-06-29T20:33:06.828050Z","shell.execute_reply":"2024-06-29T21:14:45.291581Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Оценка модели\npredictions = model.test(testset)\naccuracy.rmse(predictions)\n\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-29T21:14:45.537206Z","iopub.execute_input":"2024-06-29T21:14:45.537554Z","iopub.status.idle":"2024-06-29T21:14:45.581345Z","shell.execute_reply.started":"2024-06-29T21:14:45.537516Z","shell.execute_reply":"2024-06-29T21:14:45.580023Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Сохранение обученной модели\ndump.dump('/kaggle/working/svd_model', algo=model)\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-29T17:28:58.335257Z","iopub.execute_input":"2024-06-29T17:28:58.337982Z","iopub.status.idle":"2024-06-29T17:28:58.346581Z","shell.execute_reply.started":"2024-06-29T17:28:58.33792Z","shell.execute_reply":"2024-06-29T17:28:58.345781Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"\n\n# Функция для получения рекомендаций\ndef get_surprise_recommendations(customer_id, model, trainset, num_recommendations=10):\n    customer_inner_id = trainset.to_inner_uid(customer_id)\n    scores = [(article_inner_id, model.predict(customer_inner_id, article_inner_id).est) for article_inner_id in trainset.all_items()]\n    top_items = sorted(scores, key=lambda x: x[1], reverse=True)[:num_recommendations]\n    return [trainset.to_raw_iid(i[0]) for i in top_items]\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-29T17:28:58.347969Z","iopub.execute_input":"2024-06-29T17:28:58.348674Z","iopub.status.idle":"2024-06-29T17:29:00.627042Z","shell.execute_reply.started":"2024-06-29T17:28:58.34864Z","shell.execute_reply":"2024-06-29T17:29:00.624352Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Генерация рекомендаций для всех пользователей\nsubset_customers = sample_submission['customer_id'].sample(n=10, random_state=42)\nsubmission_subset = sample_submission[sample_submission['customer_id'].isin(subset_customers)].copy()\n\nsubmission_subset['prediction'] = submission_subset['customer_id'].apply(lambda x: ' '.join(map(str, get_surprise_recommendations(x, model, trainset))))\n\n","metadata":{"execution":{"iopub.status.busy":"2024-06-29T17:57:32.669052Z","iopub.execute_input":"2024-06-29T17:57:32.669759Z","iopub.status.idle":"2024-06-29T17:59:37.78317Z","shell.execute_reply.started":"2024-06-29T17:57:32.669711Z","shell.execute_reply":"2024-06-29T17:59:37.782161Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Сохранение в файл\nsubmission_subset.to_csv('/kaggle/working/submission_surprise.csv', index=False)\n\n","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"# Вывод списка файлов в директории /kaggle/working\nimport os\nfor dirname, _, filenames in os.walk('/kaggle/working'):\n    for filename in filenames:\n        print(os.path.join(dirname, filename))","metadata":{},"execution_count":null,"outputs":[]}]}