{"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":"# This Python 3 environment comes with many helpful analytics libraries installed\n# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python\n# For example, here's several helpful packages to load\n\nimport numpy as np # linear algebra\nimport pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)\n\n# Input data files are available in the read-only \"../input/\" directory\n# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory\n\nimport os\n#for dirname, _, filenames in os.walk('/kaggle/input'):\n#    for filename in filenames:\n#        print(os.path.join(dirname, filename))\n#MAPHI\n#MAPHI v2\n# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using \"Save & Run All\" \n# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session","metadata":{"_uuid":"8f2839f25d086af736a60e9eeb907d3b93b6e0e5","_cell_guid":"b1076dfc-b9ad-4769-8c92-a6c4dae69d19","execution":{"iopub.status.busy":"2023-05-18T01:56:59.482041Z","iopub.execute_input":"2023-05-18T01:56:59.482429Z","iopub.status.idle":"2023-05-18T01:56:59.488442Z","shell.execute_reply.started":"2023-05-18T01:56:59.482396Z","shell.execute_reply":"2023-05-18T01:56:59.487549Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"# Proyecto Final: Modelos avanzados de ciencia de datos\n## H&M Personalized Product Recommendations","metadata":{}},{"cell_type":"markdown","source":"**Motivación de la elección del problema**\n\nLa construcción de un modelo de predicción basado en el historial de compra de productos (en este caso, productos de las tiendas en línea del Grupo H&M) tiene un enfoque particularmente interesante al tener como resultado recomendaciones personalizadas ya que implantar la necesidad o el deseo de un producto a un cliente, resulta sumamente conveniente y de cierta manera controlador, una idea codiciada y de gran valor para todas las empresas o personas que ofrecen sus productos con el único objetivo de maximizar las ventas.\n\nEn este mismo sentido, es de igual manera motivante el lograr adelantarse al deseo o querer de alguien, predecir el gusto del cliente y ofrecer un producto antes que el cliente mismo sepa que quiere ese producto.\n\nPor último, el proyecto contiene distintos tipos de información para analizar: datos de clientes, artículos y transacciones de clientes (datos estructurados); así como textos e imágenes (datos no estructurados), lo que lo hace también atrayente para el equipo, por la diversidad de técnicas de análisis y procesamiento que se estarán aplicando.","metadata":{}},{"cell_type":"markdown","source":"**Descripción general del problema**\n\n\nGrupo H&M es una familia de marcas y negocios con 53 mercados en línea y aproximadamente 4850 tiendas. Sus tiendas en línea ofrecen a los compradores una amplia selección de productos. Pero con demasiadas opciones, es posible que los clientes no encuentren rápidamente lo que les interesa o lo que están buscando y, al final, ellos podrían no realizar una compra. Para mejorar la experiencia de compra, las recomendaciones de productos son clave. Más importante aún, ayudar a los clientes a tomar las decisiones correctas también tiene implicaciones positivas para la sostenibilidad, ya que reduce las devoluciones y, por lo tanto, minimiza las emisiones del transporte.\n \nGrupo H&M requiere desarrollar recomendaciones de productos basadas en datos de transacciones previas, así como en metadatos de clientes y productos. \n \nEl proyecto se evaluará con el estadístico Mean Average Precision @ 12 (MAP@12):\n\n\\begin{equation*}\nMAP@12=\\frac{1}{U}\\sum_{u=1}^{U}\\frac{1}{min(m,12)}\\sum_{k=1}^{min(n,12)} P(k)*rel(k)\n\\end{equation*}\n\nU = Número de clientes  \nP(k) = Precisión del corte k  \nn = Número de predicciones por cliente  \nm = Número de elementos por cliente  \nrel(k) = Función indicadora, 1 si el artículo es correcto y 0 si no  \n\n\n> Bloque con sangría\n\n\nDescripción del set de datos\n \nArchivos:\n \n* images/ - Carpeta con imágenes (.jpg) que corresponden a cada artículo. Nota: no todos los artículos tienen una imagen.\n* articles.csv – Detalle de cada artículo disponible para compra.\n* customers.csv - Datos del cliente\n* sample_submission.csv – Ejemplo del archivo de envío (formato requerido)\n* transaction_train.csv - Datos de las compras de cada cliente.\n\n","metadata":{}},{"cell_type":"code","source":"#Importar librerías\nimport pandas as pd\nimport numpy as np\n\n#Librerías para graficar\nimport matplotlib.pyplot as plt\nimport seaborn as sns\nimport plotly.express as px\nimport plotly.graph_objects as go\n\n#Para ignorar warnings\nimport warnings\nwarnings.filterwarnings(\"ignore\")\n\n#Para realizar los clúster\nfrom sklearn.cluster import KMeans\nfrom sklearn.preprocessing import MinMaxScaler\n","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:25:36.254841Z","iopub.execute_input":"2023-05-18T04:25:36.255431Z","iopub.status.idle":"2023-05-18T04:25:37.152613Z","shell.execute_reply.started":"2023-05-18T04:25:36.255387Z","shell.execute_reply":"2023-05-18T04:25:37.151325Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Preprocesamiento y limpieza de los datos","metadata":{}},{"cell_type":"markdown","source":"### Tabla de artículos","metadata":{}},{"cell_type":"code","source":"articulos=pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/articles.csv')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T01:59:41.083382Z","iopub.execute_input":"2023-05-18T01:59:41.083817Z","iopub.status.idle":"2023-05-18T01:59:42.254661Z","shell.execute_reply.started":"2023-05-18T01:59:41.083783Z","shell.execute_reply":"2023-05-18T01:59:42.253710Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articulos.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:50:38.091073Z","iopub.execute_input":"2023-05-18T02:50:38.091587Z","iopub.status.idle":"2023-05-18T02:50:38.123031Z","shell.execute_reply.started":"2023-05-18T02:50:38.091548Z","shell.execute_reply":"2023-05-18T02:50:38.121845Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Revisión de las columnas que contiene la tabla, tipo de datos y descriptivo de las variables flotantes.","metadata":{}},{"cell_type":"code","source":"articulos.columns.values","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:32:03.684990Z","iopub.execute_input":"2023-05-18T02:32:03.685396Z","iopub.status.idle":"2023-05-18T02:32:03.692960Z","shell.execute_reply.started":"2023-05-18T02:32:03.685365Z","shell.execute_reply":"2023-05-18T02:32:03.691989Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articulos.info()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:27:41.952241Z","iopub.execute_input":"2023-05-18T02:27:41.952660Z","iopub.status.idle":"2023-05-18T02:27:42.448690Z","shell.execute_reply.started":"2023-05-18T02:27:41.952628Z","shell.execute_reply":"2023-05-18T02:27:42.447553Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articulos.describe()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:28:24.179222Z","iopub.execute_input":"2023-05-18T02:28:24.179882Z","iopub.status.idle":"2023-05-18T02:28:24.275754Z","shell.execute_reply.started":"2023-05-18T02:28:24.179848Z","shell.execute_reply":"2023-05-18T02:28:24.274562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"La tabla de información de artículos contiene 105,542 datos, con 11 datos de tipo entero y 14 de tipo caráctes.\n\nEl descriptivo  no es de mucha utilidad debido a que los códigos son relacionados al artículo, es una llave para saber que producto es.","metadata":{}},{"cell_type":"markdown","source":"Para revisar la presencia de nulos se recurre a la siguiente función.","metadata":{}},{"cell_type":"code","source":"articulos.isnull().sum()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:32:54.888532Z","iopub.execute_input":"2023-05-18T02:32:54.889598Z","iopub.status.idle":"2023-05-18T02:32:55.353316Z","shell.execute_reply.started":"2023-05-18T02:32:54.889559Z","shell.execute_reply":"2023-05-18T02:32:55.352091Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"La única variable que contiene nulos es la variable detail_des, la variable contiene información descriptiva del producto y debido a que ya tenemos desglosada la información relacionada al producto para el análisis se estará omitiendo la variable detail_desc.\n\nAún así, se revisa que contiene la variable para corroborar su estructura.","metadata":{}},{"cell_type":"code","source":"def producto(x):\n    print(\"El producto es:\\n\",articulos.prod_name[x])\n    print(\"\\nTipo de producto: \\n\",articulos.product_type_name[x])\n    print(\"\\nDetalle del producto:\\n\",articulos.detail_desc[x])","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:37:25.537136Z","iopub.execute_input":"2023-05-18T02:37:25.537754Z","iopub.status.idle":"2023-05-18T02:37:25.542767Z","shell.execute_reply.started":"2023-05-18T02:37:25.537719Z","shell.execute_reply":"2023-05-18T02:37:25.541564Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"producto(13)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:37:27.362417Z","iopub.execute_input":"2023-05-18T02:37:27.362854Z","iopub.status.idle":"2023-05-18T02:37:27.368607Z","shell.execute_reply.started":"2023-05-18T02:37:27.362824Z","shell.execute_reply":"2023-05-18T02:37:27.367537Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"articulos_1=articulos.drop(['detail_desc'],axis=1)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:42:51.888478Z","iopub.execute_input":"2023-05-18T02:42:51.889413Z","iopub.status.idle":"2023-05-18T02:42:51.917125Z","shell.execute_reply.started":"2023-05-18T02:42:51.889375Z","shell.execute_reply":"2023-05-18T02:42:51.915839Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Tabla de transacciones","metadata":{}},{"cell_type":"code","source":"transactions=pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/transactions_train.csv')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:30:06.458902Z","iopub.execute_input":"2023-05-18T03:30:06.459823Z","iopub.status.idle":"2023-05-18T03:31:17.091841Z","shell.execute_reply.started":"2023-05-18T03:30:06.459781Z","shell.execute_reply":"2023-05-18T03:31:17.090773Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Se convierten las variables a formato datatime y se extrae el mes de la fecha de compra (t_dat).","metadata":{}},{"cell_type":"code","source":"#Transformzar a datetime\ntransactions['t_dat']=pd.to_datetime(transactions['t_dat'])\n#Nombre del mes\ntransactions['mes']=transactions['t_dat'].dt.month","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:37:41.521381Z","iopub.execute_input":"2023-05-18T03:37:41.523844Z","iopub.status.idle":"2023-05-18T03:37:52.446815Z","shell.execute_reply.started":"2023-05-18T03:37:41.523778Z","shell.execute_reply":"2023-05-18T03:37:52.445818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"### Tabla de clientes","metadata":{}},{"cell_type":"markdown","source":"## Análisis exploratorio de los datos","metadata":{}},{"cell_type":"markdown","source":"### Tabla de artículos","metadata":{}},{"cell_type":"markdown","source":"Se recurre a una función definida para obtener la frecuencia de alguna de las variables de la tabla de artículos.","metadata":{}},{"cell_type":"code","source":"\ndef frecuencia(grupo,leyenda):\n    #Revisar en que productos se venden más productos\n    productos= articulos_1.groupby(grupo)['article_id'].count()\n    productos=pd.DataFrame(productos).sort_values('article_id', ascending=False)\n    productos[grupo] = productos.index\n\n    #Para graficar\n    grafica=productos.head(20)\n\n    fig = go.Figure()\n\n    fig.add_trace(\n        go.Bar(\n                y=grafica['article_id'], x=grafica[grupo]\n                ,text=grafica['article_id']\n                ,textposition='outside'\n                ,textfont=dict(color='black')\n                ,textfont_size=12\n                ,textfont_color='black'\n                ,marker={\"color\": '#FF81C0'}\n                ,yaxis='y1'\n    ))\n\n    fig.update_layout(xaxis=dict(domain=[0, 1]),\n        #Crear eje primario          \n        yaxis=dict(title=leyenda),\n\n                     )\n\n    fig.update_layout(title_text='<b>Frecuencia de los artículos comprados</b>', title_x=0.5\n                 #,xaxis_title=\"Año de reporte de la información\"\n                 ,showlegend=False #Quitar la legenda del grafico\n                 ,font=dict(family=\"Montserrat (Títulos)\",size=15,color=\"black\")\n                 ,template = 'simple_white' ) #Cambiar el fondo\n\n    #Para modificar la posición: textangle=90\n    fig.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:47:57.635052Z","iopub.execute_input":"2023-05-18T02:47:57.635734Z","iopub.status.idle":"2023-05-18T02:47:57.646950Z","shell.execute_reply.started":"2023-05-18T02:47:57.635695Z","shell.execute_reply":"2023-05-18T02:47:57.645707Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"frecuencia('prod_name','Nombre del producto')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:47:59.284563Z","iopub.execute_input":"2023-05-18T02:47:59.284949Z","iopub.status.idle":"2023-05-18T02:48:01.015914Z","shell.execute_reply.started":"2023-05-18T02:47:59.284920Z","shell.execute_reply":"2023-05-18T02:48:01.014562Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"En la gráfica anterior se observa que el producto Dragonfly se encuentra 98 veces en la tabla, se revisa cuál es la diferencia den producto con nombre Dragonfly.","metadata":{}},{"cell_type":"code","source":"articulos_1[articulos_1['prod_name'] == 'Dragonfly dress']","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:55:09.032073Z","iopub.execute_input":"2023-05-18T02:55:09.032892Z","iopub.status.idle":"2023-05-18T02:55:09.090543Z","shell.execute_reply.started":"2023-05-18T02:55:09.032843Z","shell.execute_reply":"2023-05-18T02:55:09.089729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Como se observa en la tabla, aunque el nombre del producto es el mismo el id del artículo es diferente debido a que el color del producto varia.","metadata":{}},{"cell_type":"code","source":"frecuencia('colour_group_name','Nombre del color del grupo')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:02:08.108870Z","iopub.execute_input":"2023-05-18T03:02:08.109279Z","iopub.status.idle":"2023-05-18T03:02:08.173595Z","shell.execute_reply.started":"2023-05-18T03:02:08.109249Z","shell.execute_reply":"2023-05-18T03:02:08.172416Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Con la gráfica anterior podemos observar que las prendas de color negro o que predomina el negro, son las que el público más compra.","metadata":{}},{"cell_type":"code","source":"frecuencia('department_name','Nombre del departamento del artículo')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:04:16.176559Z","iopub.execute_input":"2023-05-18T03:04:16.176964Z","iopub.status.idle":"2023-05-18T03:04:16.240278Z","shell.execute_reply.started":"2023-05-18T03:04:16.176934Z","shell.execute_reply":"2023-05-18T03:04:16.239010Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"El departamento que tiene más productos es el de Jersey.","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def univariado(variable,leyenda):\n\n    plt.hist(articulos_1[variable], color='#CD1076', rwidth=0.85)\n    plt.title('Histograma de los productos comprados')\n    plt.xlabel(leyenda)\n    plt.ylabel('Frecuencia')\n\n    plt.show()\n\n    print(\"Descripción de la variable: \\n\",articulos_1[variable].describe())\n    \n    missing_values_count = articulos_1[variable].isnull().sum()\n\n    total_cells = np.product(articulos_1[variable].shape)\n    total_missing = missing_values_count.sum() \n    \n    print(\"\\nMissing en la variable: \\n\",articulos_1[variable].isnull().sum())\n    print(\"\\nPorcentaje de missing: \\n\",(total_missing/total_cells)*100)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:07:49.657220Z","iopub.execute_input":"2023-05-18T03:07:49.658462Z","iopub.status.idle":"2023-05-18T03:07:49.666929Z","shell.execute_reply.started":"2023-05-18T03:07:49.658414Z","shell.execute_reply":"2023-05-18T03:07:49.665696Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"univariado('product_code','Nombre del producto')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:07:51.400103Z","iopub.execute_input":"2023-05-18T03:07:51.401229Z","iopub.status.idle":"2023-05-18T03:07:51.678461Z","shell.execute_reply.started":"2023-05-18T03:07:51.401179Z","shell.execute_reply":"2023-05-18T03:07:51.677088Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"La variable product_code es una variable númerica y únicamente es una llave relacionada a la variable prod_name, no contiene missing y su llave indica que los existen más productos con llaves más grandes, en la grafica se ve la información más cargada a la derecha.","metadata":{}},{"cell_type":"markdown","source":"### Correlaciones","metadata":{}},{"cell_type":"markdown","source":"Se revisa la correlación y las variables articulo_id y product_code se encuentran muy correlacionas.\n\nEl articulo_id se estará utilizando para unir la tabla de articulos con la de transacciones, ya que la variable articulo_id funge como llave.","metadata":{}},{"cell_type":"code","source":"df_sincategoricas=articulos_1.select_dtypes(exclude=['object'])\ndf_sincategoricas.info()\n","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:20:30.686588Z","iopub.execute_input":"2023-05-18T03:20:30.687092Z","iopub.status.idle":"2023-05-18T03:20:30.706921Z","shell.execute_reply.started":"2023-05-18T03:20:30.687057Z","shell.execute_reply":"2023-05-18T03:20:30.705225Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"sns.set(rc = {'figure.figsize':(30,20)})\nsns.pairplot(df_sincategoricas,vars = [\"article_id\",\"product_code\", \"product_type_no\",\"colour_group_code\"])","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:20:56.388817Z","iopub.execute_input":"2023-05-18T03:20:56.389544Z","iopub.status.idle":"2023-05-18T03:21:09.483151Z","shell.execute_reply.started":"2023-05-18T03:20:56.389507Z","shell.execute_reply":"2023-05-18T03:21:09.481818Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Para las transacciones, es octubre 2019 el periodo con mayor número de transacciones.","metadata":{}},{"cell_type":"code","source":"def elementos_grafica():\n    plt.rcParams['font.family'] = 'sans-serif'\n    plt.figure(figsize=(10,5))\n    plt.xticks(rotation=90, size=8)\n    plt.grid(False)\n    #Eliminar los bordes\n    plt.gca().spines['top'].set_visible(False)\n    plt.gca().spines['right'].set_visible(False)\n    #Eje y con separadores de miles\n    plt.gca().get_yaxis().set_major_formatter(plt.FuncFormatter(lambda x, loc: \"{:,}\".format(int(x))))","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:48:20.511697Z","iopub.execute_input":"2023-05-18T03:48:20.512179Z","iopub.status.idle":"2023-05-18T03:48:20.519819Z","shell.execute_reply.started":"2023-05-18T03:48:20.512136Z","shell.execute_reply":"2023-05-18T03:48:20.518572Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"elementos_grafica()\n#gráfica de  línea de transacciones por día\ntransactions.groupby('t_dat')['t_dat'].count().plot(color='#a1d99b')\n#Média móvil de 7 días\ntransactions.groupby('t_dat')['t_dat'].count().rolling(7).mean().plot()\nplt.legend(['Transacciones','Media móvil 7 días'], frameon=False)\nplt.title('Transacciones por día', size=14, weight='bold')\n#Título ejes\nplt.xlabel('Fecha')\nplt.ylabel('Transacciones')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:48:35.127908Z","iopub.execute_input":"2023-05-18T03:48:35.128345Z","iopub.status.idle":"2023-05-18T03:48:36.810897Z","shell.execute_reply.started":"2023-05-18T03:48:35.128313Z","shell.execute_reply":"2023-05-18T03:48:36.809567Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"raw","source":"Junio es el mes que presenta mayor número de compras, mientras que febrero y diciembre son los meese con un menor número de compras.","metadata":{}},{"cell_type":"code","source":"#Gráfica de transacciones por mes para ver estacionalidad\nelementos_grafica()\ntransactions.groupby(transactions['mes'])['mes'].count().plot(kind='bar', color='#a1d99b')\nplt.title('Transacciones por mes', size=14, weight='bold')\nplt.xlabel('Mes')\nplt.ylabel('Transacciones')\n#Incorporar nombre de los meses\nplt.xticks([0,1,2,3,4,5,6,7,8,9,10,11],['Ene','Feb','Mar','Abr','May','Jun','Jul','Ago','Sep','Oct','Nov','Dic'], rotation=0)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:50:49.371696Z","iopub.execute_input":"2023-05-18T03:50:49.372123Z","iopub.status.idle":"2023-05-18T03:50:50.360028Z","shell.execute_reply.started":"2023-05-18T03:50:49.372091Z","shell.execute_reply":"2023-05-18T03:50:50.358779Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Las transaciones se realizan principalmente por el canal 2 ().","metadata":{}},{"cell_type":"code","source":"#Transacciones por channel_id\nelementos_grafica()\ntransactions.groupby('sales_channel_id')['sales_channel_id'].count().plot(kind='bar', color='#a1d99b')\nplt.title('Transacciones por canal de ventas', size=14, weight='bold')\nplt.xlabel('Canal de ventas')\nplt.ylabel('Transacciones')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:51:21.541278Z","iopub.execute_input":"2023-05-18T03:51:21.542521Z","iopub.status.idle":"2023-05-18T03:51:22.349906Z","shell.execute_reply.started":"2023-05-18T03:51:21.542456Z","shell.execute_reply":"2023-05-18T03:51:22.348729Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Transacciones por precio\nelementos_grafica()\ntransactions.groupby('price')['price'].count().plot(color='#a1d99b',label=\"Transacciones\")\n#Precio medio y mediano\nplt.axvline(transactions['price'].mean(), color='red', linestyle='--', label='Precio promedio')\nplt.axvline(transactions['price'].median(), color='green', linestyle='--', label='Precio mediano')\nplt.legend(frameon=False)\n#Título y ejes\nplt.title('Transacciones por precio', size=14, weight='bold')\nplt.xlabel('Precio')\nplt.ylabel('Transacciones')\n#Anotaciones\nplt.annotate('Precio medio: ${:.2f}'.format(transactions['price'].mean()), xy=(transactions['price'].mean(), 0.7), xytext=(transactions['price'].mean()+.2,3000000)\n             )\nplt.annotate('Precio mediano: ${:.2f}'.format(transactions['price'].median()), xy=(transactions['price'].mean(), 0.7), xytext=(transactions['price'].mean()+.2,2900000)\n             )\nplt.annotate('Precio máximo: ${:.2f}'.format(transactions['price'].max()), xy=(transactions['price'].mean(), 0.7), xytext=(transactions['price'].mean()+.2,2800000)\n             )\nplt.annotate('Precio mínimo: ${:.2f}'.format(transactions['price'].min()), xy=(transactions['price'].mean(), 0.7), xytext=(transactions['price'].mean()+.2,2700000)\n             )","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:53:01.392069Z","iopub.execute_input":"2023-05-18T03:53:01.392513Z","iopub.status.idle":"2023-05-18T03:53:05.021133Z","shell.execute_reply.started":"2023-05-18T03:53:01.392462Z","shell.execute_reply":"2023-05-18T03:53:05.019931Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Tabla con 20 productos más vendidos\ntop_products=transactions.groupby('article_id')['article_id'].count().sort_values(ascending=False).head(20)\nbottom_products=transactions.groupby('article_id')['article_id'].count().sort_values(ascending=False).tail(20)\nprint('Los 20 productos más vendidos son:')\nprint(top_products)\nprint(\"\\n\")\nprint('Los 20 productos menos vendidos son:')\nprint(bottom_products)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:53:29.616649Z","iopub.execute_input":"2023-05-18T03:53:29.617760Z","iopub.status.idle":"2023-05-18T03:53:31.092653Z","shell.execute_reply.started":"2023-05-18T03:53:29.617719Z","shell.execute_reply":"2023-05-18T03:53:31.091323Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Top 20 de customers\ntop_customers=transactions.groupby('customer_id')['customer_id'].count().sort_values(ascending=False).head(20)\nbottom_customers=transactions.groupby('customer_id')['customer_id'].count().sort_values(ascending=False).tail(20)\nprint('Los 20 clientes que más compran son:')\nprint(top_customers)\nprint(\"\\n\")\nprint('Los 20 clientes que menos compran son:')\nprint(bottom_customers)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:53:46.944974Z","iopub.execute_input":"2023-05-18T03:53:46.945364Z","iopub.status.idle":"2023-05-18T03:54:19.631627Z","shell.execute_reply.started":"2023-05-18T03:53:46.945334Z","shell.execute_reply":"2023-05-18T03:54:19.630273Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"## Selección y entrenamiento de los modelos","metadata":{}},{"cell_type":"markdown","source":"Para el presente trabjo se utilizarán dos modelos de recomendación:\n\n1. Xgboost (Extreme Gradient Boosting), el cual es de carácter no lineal y se basa en árboles de decisión. Este modelo es de tipo colaborativo, ya que utiliza la información de los usuarios y de los artículos para generar las recomendaciones. Es un modelo de tipo supervisado.\n2. x. Es un modelo de tipo no supervisado.","metadata":{}},{"cell_type":"markdown","source":"Unir las tablas en un dataframe concentrado para realizar los modelos","metadata":{}},{"cell_type":"code","source":"#Importar la tabla clientes\nclientes=pd.read_csv('/kaggle/input/h-and-m-personalized-fashion-recommendations/customers.csv')\nclientes=clientes.drop(['FN', 'Active', 'postal_code'], axis=1)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:59:16.469203Z","iopub.execute_input":"2023-05-18T03:59:16.469679Z","iopub.status.idle":"2023-05-18T03:59:20.790255Z","shell.execute_reply.started":"2023-05-18T03:59:16.469644Z","shell.execute_reply":"2023-05-18T03:59:20.789213Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#transacciones=transacciones.sample(frac = fracc)\n\n#Importar la tabla transacciones\ntransactions=(transactions.merge(articulos,on=['article_id'], how='left')\n        .merge(clientes,on=['customer_id'], how='left'))\n","metadata":{"execution":{"iopub.status.busy":"2023-05-18T03:59:37.076254Z","iopub.execute_input":"2023-05-18T03:59:37.076756Z","iopub.status.idle":"2023-05-18T04:01:05.283370Z","shell.execute_reply.started":"2023-05-18T03:59:37.076724Z","shell.execute_reply":"2023-05-18T04:01:05.282084Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Ya que tenemos una tabla que concentra las 3 tablas de los datos necesarios para el modelos, se da una revisión a la existencia de valores nulos.","metadata":{}},{"cell_type":"code","source":"#Revisión de valores nulos\nprint('Valores nulos existentes: ',(transactions['age'].isnull().sum()/(transactions['age'].count()+transactions['age'].isnull().sum()))*100)\n","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:06:53.326795Z","iopub.execute_input":"2023-05-18T04:06:53.327182Z","iopub.status.idle":"2023-05-18T04:06:53.485727Z","shell.execute_reply.started":"2023-05-18T04:06:53.327151Z","shell.execute_reply":"2023-05-18T04:06:53.484542Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Los valores nulos existentes en la tabla de datos es del 0.44%, por lo que serán eliminados para que no causen ruido en el modelo.","metadata":{}},{"cell_type":"code","source":"#Eliminar valores nulos\ntransactions=transactions.dropna()\n\n#Valores nulos despues de NA\nprint('Valores nulos existentes después de aplicar drop NA: ',(transactions['age'].isnull().sum()/(transactions['age'].count()+transactions['age'].isnull().sum()))*100)","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:08:11.387779Z","iopub.execute_input":"2023-05-18T04:08:11.388400Z","iopub.status.idle":"2023-05-18T04:11:54.295747Z","shell.execute_reply.started":"2023-05-18T04:08:11.388369Z","shell.execute_reply":"2023-05-18T04:11:54.294239Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Frecuencia de edad\nplt.hist(x=transactions['age'], color='#F2AB6D', rwidth=0.85)\nplt.title('Histograma de edades de los clientes')\nplt.xlabel('Edades')\nplt.ylabel('Frecuencia')\nplt.show()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:16:20.538724Z","iopub.execute_input":"2023-05-18T04:16:20.539396Z","iopub.status.idle":"2023-05-18T04:16:21.805991Z","shell.execute_reply.started":"2023-05-18T04:16:20.539356Z","shell.execute_reply":"2023-05-18T04:16:21.804778Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Para realizar los clúster, dejamos únicamente las variables numericas.","metadata":{}},{"cell_type":"code","source":"#Extraer únicamente las variables númericas\ndf_numericas=transactions._get_numeric_data()\ndf_numericas.head()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:24:02.316197Z","iopub.execute_input":"2023-05-18T04:24:02.317848Z","iopub.status.idle":"2023-05-18T04:24:02.344614Z","shell.execute_reply.started":"2023-05-18T04:24:02.317780Z","shell.execute_reply":"2023-05-18T04:24:02.343374Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"Se obtiene el número de clúster obtimo mediante una elbow.","metadata":{}},{"cell_type":"code","source":"#Revisión del codo para saber el número de clúster ideal\nkmeans_kwargs = {\"init\": \"random\",\"n_init\": 10,\"random_state\": 1,}\n\nsse = []\nfor k in range(1, 11):\n    kmeans = KMeans(n_clusters=k, **kmeans_kwargs)\n    kmeans.fit(df_numericas)\n    sse.append(kmeans.inertia_)\n\nplt.plot(range(1, 11), sse)\nplt.xticks(range(1, 11))\nplt.xlabel(\"Clúster\")\nplt.title('Elbow Curve')\nplt.show()","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"#Preparación de datos\ndf_numericas['edad']=df_numericas['age']\n\nescalar = MinMaxScaler()\nescalar.fit(transactions[['age']])\ndf_numericas['age'] = escalar.transform(df_numericas[['age']])\n\n#Encontrar los clúster\nkm = KMeans(n_clusters=6)\ny_predicted = km.fit_predict(df_numericas[['age','price']])\n\n#Añadir clúster a la tabla de transacciones\ntransactions['cluster']=y_predicted\ntransactions.head()\n\n#Revisar la distribución de los clúser\ntransactions.groupby(by='cluster').count()","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:32:47.440898Z","iopub.execute_input":"2023-05-18T04:32:47.441425Z","iopub.status.idle":"2023-05-18T04:37:12.534539Z","shell.execute_reply.started":"2023-05-18T04:32:47.441383Z","shell.execute_reply":"2023-05-18T04:37:12.533292Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"plt.figure(figsize=(20,8))\n\nplt.subplot(2,3,1)\nplt.hist(x=transactions[transactions['cluster'] == 0]['age'], color='#00688B', rwidth=0.85)\nplt.title('Clúster 0')\n\nplt.subplot(2,3,2)\nplt.hist(x=transactions[transactions['cluster'] == 1]['age'], color='#00688B', rwidth=0.85)\nplt.title('Clúster 1')\n\nplt.subplot(2,3,3)\nplt.hist(x=transactions[transactions['cluster'] == 2]['age'], color='#00688B', rwidth=0.85)\nplt.title('Clúster 2')\n\nplt.subplot(2,3,4)\nplt.hist(x=transactions[transactions['cluster'] == 3]['age'], color='#00688B', rwidth=0.85)\nplt.title('Clúster 3')\n\nplt.subplot(2,3,5)\nplt.hist(x=transactions[transactions['cluster'] == 4]['age'], color='#00688B', rwidth=0.85)\nplt.title('Clúster 4')\n\nplt.subplot(2,3,6)\nplt.hist(x=transactions[transactions['cluster'] == 5]['age'], color='#00688B', rwidth=0.85)\nplt.title('Clúster 5')","metadata":{"execution":{"iopub.status.busy":"2023-05-18T04:37:53.671013Z","iopub.execute_input":"2023-05-18T04:37:53.671535Z","iopub.status.idle":"2023-05-18T04:38:26.672995Z","shell.execute_reply.started":"2023-05-18T04:37:53.671470Z","shell.execute_reply":"2023-05-18T04:38:26.671736Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"def poblacion(df,n,prodctos):\n    cluster=df[transacciones['cluster'] == n]\n    cluster.t_dat = pd.to_datetime(cluster.t_dat)\n\n    #Grafica del comportamiento de compras del clúster\n    cluster[['t_dat','article_id']].groupby('t_dat').count().plot(figsize=(12,6), legend=False, fontsize=10)\n    plt.title('Productos comprados por día', fontsize=18)\n    plt.xlabel('Fecha',fontsize=14)\n\n    #Crear meses y días\n    cluster['mes']=pd.to_datetime(cluster['t_dat']).dt.month_name(locale='es_ES.utf8')\n    cluster['dia']=pd.to_datetime(cluster['t_dat']).dt.day\n\n    lista_meses = ['Enero', 'Febrero', 'Marzo', 'Abril', 'Mayo', 'Junio', 'Julio','Agosto', 'Septiembre', 'Octubre', 'Noviembre', 'Diciembre']\n    meses = pd.api.types.CategoricalDtype(categories=lista_meses)\n    cluster['mes']= cluster['mes'].astype(meses)\n\n\n    fig2 = px.density_heatmap(cluster, x=cluster['mes'].sort_values(), y=\"dia\", template=\"seaborn\")\n    fig2.show()\n    \n    color = plt.cm.rainbow(np.linspace(0, 1, prodctos))\n    cluster['prod_name'].value_counts().head(prodctos).plot.bar(color = color, figsize=(13,5))\n    plt.title('Items más comprados', fontsize = 20)\n    plt.xticks(rotation = 90 )\n    plt.grid()\n    plt.show()\n    \n    return cluster","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"cluster=poblacion(transacciones,2,40)","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"markdown","source":"cfaszXc ","metadata":{}},{"cell_type":"markdown","source":"### Tabla de transacciones","metadata":{}},{"cell_type":"markdown","source":"### Tabla de clientes","metadata":{}},{"cell_type":"code","source":"### Tabla de artículos","metadata":{"execution":{"iopub.status.busy":"2023-05-18T02:44:24.602935Z","iopub.execute_input":"2023-05-18T02:44:24.603359Z","iopub.status.idle":"2023-05-18T02:44:24.608735Z","shell.execute_reply.started":"2023-05-18T02:44:24.603327Z","shell.execute_reply":"2023-05-18T02:44:24.607555Z"},"trusted":true},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### Tabla de transacciones","metadata":{},"execution_count":null,"outputs":[]},{"cell_type":"code","source":"### Tabla de artículos","metadata":{},"execution_count":null,"outputs":[]}]}