{"id":1143,"date":"2020-06-19T15:18:32","date_gmt":"2020-06-19T15:18:32","guid":{"rendered":"https:\/\/apachedigital.io\/?post_type=insight&#038;p=1143"},"modified":"2021-05-31T14:53:11","modified_gmt":"2021-05-31T14:53:11","slug":"machine-learning-para-mejorar-la-captacion-de-leads","status":"publish","type":"insight","link":"https:\/\/apachedigital.io\/en\/insight\/machine-learning-para-mejorar-la-captacion-de-leads\/","title":{"rendered":"Machine Learning para mejorar la captaci\u00f3n de Leads"},"content":{"rendered":"\n<p>La democratizaci\u00f3n tecnol\u00f3gica, sobre todo en el \u00e1mbito de la Ciencia de Datos, ha puesto al alcance de muchos profesionales las herramientas necesarias para realizar&nbsp;<strong>una manipulaci\u00f3n \u00f3ptima de los datos que permita extraer ideas y patrones<\/strong>&nbsp;necesarios para la mejora de procesos empresariales en las \u00e1reas de Marketing, Log\u00edstica, RRHH, Comercial\u2026<\/p>\n\n\n\n<p>Pero bien es cierto que, aunque estas tecnolog\u00edas sean accesibles,&nbsp;<strong>se debe de tener un elevado conocimiento de todo su entorno tecnol\u00f3gico y matem\u00e1tico para que las conclusiones extra\u00eddas sean fieles a la realidad y no sean err\u00f3neas<\/strong>.<\/p>\n\n\n\n<p>Para demostrar lo anteriormente expuesto, me gustar\u00eda detallar un proyecto basado en Ciencia de Datos que realizamos para una reconocida empresa del sector de los seguros.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HCPkcObX6B5LbaRd.png\" alt=\"\" class=\"wp-image-1144\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HCPkcObX6B5LbaRd.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HCPkcObX6B5LbaRd-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<p>Dicha empresa contaba con una base de datos de clientes y otra de posibles clientes. La base de datos de clientes representaba en tama\u00f1o el 2% de la de posibles clientes.<\/p>\n\n\n\n<p>La estrategia de captaci\u00f3n consist\u00eda en un Call Center que iba focalizando los esfuerzos de captaci\u00f3n seg\u00fan una investigaci\u00f3n previa de cada una de las empresas a la que iban a contactar. Contando con el tama\u00f1o tan grande que ten\u00eda la base de datos de posibles clientes, esta estrategia era poco efectiva y supon\u00eda un gasto de recursos muy elevados.<\/p>\n\n\n\n<p>Por eso mismo, en APACHE ofrecimos a esta empresa realizar una Clusterizaci\u00f3n de la base de datos y un Lead Scoring, donde utilizamos t\u00e9cnicas de Machine Learning para ayudar al Call Center a focalizar los esfuerzos seg\u00fan el Cluster realizado y la nota arrojada por los diferentes algoritmos que utilizamos.<\/p>\n\n\n\n<p>Adem\u00e1s, la base de datos cuenta con una gran cantidad de valores nulos, por lo que se utilizaron tambi\u00e9n t\u00e9cnicas de Machine Learning para completar esos datos, realizando inferencia estad\u00edstica y consiguiendo entregar al cliente un conjunto de datos enriquecido donde los valores nulos ser\u00edan completados.<\/p>\n\n\n\n<p>\u00bfC\u00f3mo lo hicimos? Aqu\u00ed abajo os lo explicamos:<\/p>\n\n\n\n<h1 id=\"4f91\"><strong>Proceso<\/strong><\/h1>\n\n\n\n<p><em>Antes de comenzar, tengo que aclarar que el proyecto fue mucho m\u00e1s largo, se utiliz\u00f3 una gran cantidad de procesos y se verific\u00f3 los resultados para asegurar que estos se acercaran a la realidad, por lo que habr\u00e1 pasos que no especifiquemos completamente y \u00fanicamente aportamos una aproximaci\u00f3n como ejemplo de lo que fue el proyecto completo.<\/em><\/p>\n\n\n\n<p>Para la realizaci\u00f3n del ejemplo, vamos a utilizar una base de datos artificial que creamos a trav\u00e9s de datos sint\u00e9ticos, pero desarrollada de una forma muy precisa para que los datos se asemejara lo m\u00e1ximo posible a la realidad.<\/p>\n\n\n\n<p><strong>Importaci\u00f3n de datos y an\u00e1lisis de variables<\/strong><\/p>\n\n\n\n<p>En primer lugar, importamos las librer\u00edas necesarias para realizar el proyecto.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">import pandas as pd<br>import numpy as np<br>import missingno as msno<br>import matplotlib.pyplot as plt<br>%pylab<br>%matplotlib inline<br>import seaborn as sns<br>from sklearn.preprocessing import OrdinalEncoder<br>from fancyimpute import KNN<br>from sklearn.cluster import KMeans<br>from sklearn.metrics import silhouette_score<br>from sklearn.preprocessing import StandardScaler<br>from sklearn.model_selection import train_test_split<br>from sklearn.ensemble import RandomForestClassifier<br>from sklearn.metrics import accuracy_score, auc, confusion_matrix, f1_score, precision_score, recall_score, roc_curve<br>from sklearn.ensemble import RandomForestClassifier<\/pre>\n\n\n\n<p>Como podemos ver, importamos librer\u00edas para limpieza de datos, visualizaci\u00f3n de datos y Machine Learning.<\/p>\n\n\n\n<p>En segundo lugar, el cliente nos envi\u00f3 mediante un SFTP los datos anonimizados donde la informaci\u00f3n ten\u00eda la siguiente apariencia:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df = pd.read_csv(\"ruta\")<br>df.head()<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"168\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_-Q67If8S_vwzgSLV.png\" alt=\"Image for post\" class=\"wp-image-1146\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_-Q67If8S_vwzgSLV.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_-Q67If8S_vwzgSLV-300x72.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>En el proyecto real, los datos eran bastante m\u00e1s complejos, tuvimos que realizar una gran labor de limpieza para poder aportar uniformidad, pero para este art\u00edculo nos ahorraremos esa parte.<\/p>\n\n\n\n<p>Al revisar la forma de los datos nos encontramos con lo siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df.shape<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/miro.medium.com\/max\/60\/0*B6co8x9xoioCywSK?q=20\" alt=\"Image for post\"\/><\/figure>\n\n\n\n<p>Contamos con 19983 registros divididos en 10 columnas, las columnas son las siguientes:<\/p>\n\n\n\n<ul><li><strong>id<\/strong>: Identificador que utiliza el cliente para identificar a la empresa, que adem\u00e1s permitir\u00e1 m\u00e1s adelante relacionar los resultados con las bases de datos, debido a que no se nos proporcion\u00f3 ni el CIF ni el nombre de la empresa.<\/li><li><strong>n_empleados<\/strong>: Variable categ\u00f3rica que especifica diferentes grupos relacionados con el n\u00famero de empleados de cada empresa.<\/li><li><strong>facturacion<\/strong>: Variable categ\u00f3rica que especifica los intervalos de facturaci\u00f3n.<\/li><li><strong>forma_juridica<\/strong>: Variable categ\u00f3rica donde, como el mismo nombre indica, se trata de la forma jur\u00eddica de la empresa.<\/li><li><strong>sector_empresa<\/strong>: Variable categ\u00f3rica, aqu\u00ed nos encontramos con el sector dentro del que opera cada empresa.<\/li><li><strong>TAMA\u00d1O<\/strong>: Variable categ\u00f3rica donde se especifica en grupos el tama\u00f1o de la empresa.<\/li><li><strong>ACTIVIDAD<\/strong>: Variable categ\u00f3rica que indica la actividad que realiza cada empresa.<\/li><li><strong>Capital<\/strong>: Variable categ\u00f3rica que muestra el intervalo de Capital de cada empresa.<\/li><li><strong>Score<\/strong>: Variable num\u00e9rica, nota que le aplicaba nuestro cliente al crear el Lead dentro del CRM. Se basa en criterios internos.<\/li><li><strong>Client<\/strong>: Variable binaria. Aqu\u00ed nos encontraremos un 1 para las empresas que son cliente, un 0 para las empresas que han dejado de ser cliente y un NaN para las empresas que son prospects, es decir, que todav\u00eda ni son cliente ni han dejado de ser cliente. En este ejemplo contaremos con 3600 registros que son 0 o 1 y 16383 que son NaN.<\/li><\/ul>\n\n\n\n<p><strong>Limpieza de valores nulos (enriquecimiento de la base de datos)<\/strong><\/p>\n\n\n\n<p>A continuaci\u00f3n, os mostramos la t\u00e9cnica utilizada para realizar la limpieza de valores nulos.<\/p>\n\n\n\n<p>En primer lugar, utilizamos una de mis librer\u00edas favoritas de limpieza de datos: missingno, para poder ver de forma visual en qu\u00e9 columnas faltan datos.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">msno.matrix(df)<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"310\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_qG-hXFw4rWjnyTMj.png\" alt=\"Image for post\" class=\"wp-image-1148\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_qG-hXFw4rWjnyTMj.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_qG-hXFw4rWjnyTMj-300x133.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>Como vemos, las columnas n_empleados, facturaci\u00f3n, ACTIVIDAD y Capital cuentan con valores nulos, esto lo remediamos a continuaci\u00f3n. Client tambi\u00e9n tiene valores nulos, pero se debe a que los NaN son posibles clientes, por lo que de momento separaremos esa columna del DataFrame.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df = df.drop(columns = \"Client\")<\/pre>\n\n\n\n<p>En este caso, para la creaci\u00f3n del modelo necesitamos tener todas las empresas, por lo que no podemos eliminar ning\u00fan registro. Al ser empresas diferentes, tampoco podemos utilizar t\u00e9cnicas cl\u00e1sicas como el backfill, bfill, ffill\u2026<\/p>\n\n\n\n<p>Por ello, para solventar esta problem\u00e1tica, decidimos aplicar el primer modelo de Machine Learning:&nbsp;<strong>KNN K-Nearest Neighbors<\/strong>. Con este m\u00e9todo de clasificaci\u00f3n supervisado, pudimos estimar, gracias a una funci\u00f3n de densidad de probabilidades, los valores que faltaban en funci\u00f3n de sus \u201cvecinos\u201d del espacio vectorial, es decir, este algoritmo&nbsp;<strong>buscaba similaridades entre diferentes registros y rellenaba los valores nulos en funci\u00f3n de una inferencia basada en registros similares.<\/strong><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"609\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_bs-uOnLs9QIDGF2m.png\" alt=\"Image for post\" class=\"wp-image-1150\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_bs-uOnLs9QIDGF2m.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_bs-uOnLs9QIDGF2m-300x261.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>Por lo que aplicaremos lo siguiente:<\/p>\n\n\n\n<p><em>Encoder<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ordinal_enc_dict = {}for col_name in df:<br>    ordinal_enc_dict[col_name] = OrdinalEncoder()<br>    col = df[col_name]<br>    col_not_null = col[col.notnull()]<br>    reshaped_vals = col_not_null.values.reshape(-1, 1)<br>    encoded_vals = ordinal_enc_dict[col_name].<br>    fit_transform(reshaped_vals)<br>    df.loc[col.notnull(), col_name] = np.squeeze(encoded_vals)<\/pre>\n\n\n\n<p><em>KNN_imputer<\/em><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">KNN_imputer = KNN()df.iloc[:, :] = np.round(KNN_imputer.fit_transform(df))<br>for col_name in df:<br>    reshaped = df[col_name].values.reshape(-1, 1)<br>    df[col_name] = ordinal_enc_dict[col_name].<br>    inverse_transform(reshaped)<\/pre>\n\n\n\n<p>Con esto, se realiza una inferencia con la que se rellenar\u00e1n los datos y conseguiremos el siguiente resultado.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"301\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_1Tz5Bsc8LqbnQsiF-1.png\" alt=\"Image for post\" class=\"wp-image-1156\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_1Tz5Bsc8LqbnQsiF-1.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_1Tz5Bsc8LqbnQsiF-1-300x129.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>Como podemos ver,&nbsp;<strong>los datos han sido imputados en su totalidad,<\/strong>&nbsp;consiguiendo una base de datos completa.<\/p>\n\n\n\n<p><strong>Clustering<\/strong><\/p>\n\n\n\n<p>Ahora que tenemos los datos completos en su 100%, se procede a aplicar la segmentaci\u00f3n de los datos.<\/p>\n\n\n\n<p>Debemos tener en cuenta que la mayor\u00eda de los datos son categ\u00f3ricos, esto complica bastante el desarrollo de los diferentes algoritmos. Los datos originales contienen tambi\u00e9n columnas num\u00e9ricas, por lo que&nbsp;<strong>optamos por utilizar el algoritmo K-Means, creando variables dummies<\/strong>; otra alternativa que tambi\u00e9n valoramos fue la utilizaci\u00f3n del modelo K-Medoids, pero los tiempos de procesamiento eran muy elevados y no notamos que los resultados fueran muy diferentes.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"700\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HKusaucYEXMW34iq.png\" alt=\"Image for post\" class=\"wp-image-1152\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HKusaucYEXMW34iq.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HKusaucYEXMW34iq-300x300.png 300w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_HKusaucYEXMW34iq-150x150.png 150w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>En primer lugar, deberemos de averiguar el n\u00famero \u00f3ptimo de Clusters, y para ello emplearemos la&nbsp;<strong>t\u00e9cnica de Silhouette<\/strong>.<\/p>\n\n\n\n<p>Para ello, antes generamos las variables dummies.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df_dummies = pd.get_dummies(df, columns    [\"n_empleados\",\"facturacion\",\"forma_juridica\",<br>\"sector_empresa\",  \"TAMA\u00d1O\",\"ACTIVIDAD\",\"Capital\"])<\/pre>\n\n\n\n<p>Y a continuaci\u00f3n aplicamos la t\u00e9cnica de Silhouette.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def plot_sillhouette(blobs, figure_name, max_k = 10, n_init = 15):<br>    sillhouette_avgs = []<br>    <br>    for k in range(2, max_k):<br>        kmean = KMeans(n_clusters = k, n_init = n_init).fit(blobs)<br>        sillhouette_avgs.append(silhouette_score(blobs,<br>        kmean.labels_))<br>        <br>    plot(range(2, max_k), sillhouette_avgs)<br>    title(figure_name)plot_sillhouette(df_dummies, 'Sillhouette')<\/pre>\n\n\n\n<p>Obteniendo los siguientes resultados:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_vA-hdDAW6ijgSuiE.png\" alt=\"Image for post\" class=\"wp-image-1154\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_vA-hdDAW6ijgSuiE.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_vA-hdDAW6ijgSuiE-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>Como podemos ver,&nbsp;<strong>el n\u00famero \u00f3ptimo de Clusters es 2<\/strong>. Podr\u00edamos ahondar un poco m\u00e1s y realizar Sub-Clusters dentro de cada Cluster, pero en este caso lo dejaremos as\u00ed.<\/p>\n\n\n\n<p>Como sabemos que el n\u00famero \u00f3ptimo es 2,&nbsp;<strong>procederemos a aplicar el algoritmo K-Means para obtener los Clusters<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">kmeans = KMeans(n_clusters = 2, init=\"k-means++\", max_iter = 300, n_init = 10)<br>y_kmeans = kmeans.fit_predict(df_dummies)<br>y_kmeans<\/pre>\n\n\n\n<figure class=\"wp-block-image\"><img src=\"https:\/\/miro.medium.com\/max\/60\/0*Fo2iM8qAvVVaHwvJ?q=20\" alt=\"Image for post\"\/><\/figure>\n\n\n\n<p>Finalmente, insertamos el array obtenido dentro de nuestro DataFrame imputado.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df.insert(0, 'Cluster', y_kmeans)<\/pre>\n\n\n\n<p>Veamos la distribuci\u00f3n de los datos:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">ax = sns.countplot(x=\"Cluster\", data=df, order = df['Cluster'].value_counts().index)<br>plt.ylabel(\"N\u00aa Empresas\")<\/pre>\n\n\n\n<figure class=\"wp-block-image size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_vR7XLBtdp1Rp7-V.png\" alt=\"Image for post\" class=\"wp-image-1158\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_vR7XLBtdp1Rp7-V.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_vR7XLBtdp1Rp7-V-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure>\n\n\n\n<p>Hemos obtenido el siguiente n\u00famero de datos por Cluster:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df.groupby('Cluster').count()<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"116\" height=\"121\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0__qQebwp8h4HA_Jxy.png\" alt=\"Image for post\" class=\"wp-image-1160\"\/><\/figure><\/div>\n\n\n\n<p><strong>Entrenamiento del modelo de Clasificaci\u00f3n para el Lead Scoring<\/strong><\/p>\n\n\n\n<p>Una vez que contamos con los Clusters,&nbsp;<strong>la siguiente fase es la del Lead Scoring, donde aplicaremos modelos de clasificaci\u00f3n para generar notas por cada empresa<\/strong>&nbsp;y as\u00ed facilitar la labor del Call Center, para que se centren en los usuarios m\u00e1s proclives a convertirse en clientes.<\/p>\n\n\n\n<p>Para la creaci\u00f3n del modelo utilizaremos los primeros 3600 registros, ya que estos son los que tienen los datos de si la empresa es cliente o no, para ello simplemente aplicaremos lo siguiente:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">df = df[df_prueba['Client'].notnull()]<\/pre>\n\n\n\n<p>En segundo lugar, volveremos a generar variables dummies y crearemos la siguiente funci\u00f3n para medir los resultados de los modelos:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">def metricas_modelos(y_true, y_pred):<br>    # Obtenci\u00f3n de matriz de confusi\u00f3n<br>    confusion_matrix = confusion_matrix(y_true, y_pred)print('La matriz de confusi\u00f3n es ')<br>    print(confusion_matrix)print('Precisi\u00f3n:', accuracy_score(y_true, y_pred))<br>    print('Exactitud:', precision_score(y_true, y_pred))<br>    print('Exhaustividad:', recall_score(y_true, y_pred))<br>    print('F1:', f1_score(y_true, y_pred))false_positive_rate, recall, thresholds = roc_curve(y_true, y_pred)<br>    roc_auc = auc(false_positive_rate, recall)print('AUC:', auc(false_positive_rate, recall))plot(false_positive_rate, recall, 'b')<br>    plot([0, 1], [0, 1], 'r--')<br>    title('AUC = %0.2f' % roc_auc)<\/pre>\n\n\n\n<p>Dividimos los datos en conjunto de entrenamiento y test:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">X = df.drop(columns=[\"id\",\"Client\"])<br>y = df.pop(\"Client\")<br>X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 3)<\/pre>\n\n\n\n<p>Y comenzamos a aplicar los algoritmos de clasificaci\u00f3n para ver cu\u00e1les nos devuelven los mejores resultados.<\/p>\n\n\n\n<p>Finalmente, damos con el RandomForestClassifier, donde con sus par\u00e1metros ajustados obtenemos resultados muy interesantes.<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">rf_classifier = RandomForestClassifier(criterion = 'entropy',<br>n_estimators = 18,random_state = 1).fit(X_train, y_train)y_pred = rf_classifier.predict(X_train)print('Precisi\u00f3n:', accuracy_score(y_train, y_pred))<br>print('Exactitud:', precision_score(y_train, y_pred))<br>print('Exhaustividad:', recall_score(y_train, y_pred))<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"351\" height=\"59\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_Wm2kElZLq9T5d9DQ.png\" alt=\"Image for post\" class=\"wp-image-1162\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_Wm2kElZLq9T5d9DQ.png 351w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_Wm2kElZLq9T5d9DQ-300x50.png 300w\" sizes=\"(max-width: 351px) 100vw, 351px\" \/><\/figure><\/div>\n\n\n\n<p>Las tres m\u00e9tricas est\u00e1n por encima del 86%, generando una precisi\u00f3n y especificidad muy buenas.<\/p>\n\n\n\n<p>Adem\u00e1s, analizamos la curva ROC:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">false_positive_rate, recall, thresholds = roc_curve(y_train, y_pred)<br>roc_auc = auc(false_positive_rate, recall)print('AUC:', auc(false_positive_rate, recall))<br>plot(false_positive_rate, recall, 'b')<br>plot([0, 1], [0, 1], 'r--')<br>title('AUC = %0.2f' % roc_auc)<\/pre>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_6PDqv3x_Hmm7Tvwv.png\" alt=\"Image for post\" class=\"wp-image-1164\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_6PDqv3x_Hmm7Tvwv.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_6PDqv3x_Hmm7Tvwv-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>A continuaci\u00f3n, se toma el DataFrame total, separ\u00e1ndolo en conjunto X e y para aplicar el modelo en el conjunto total y conseguir los Score que queremos tener:<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">parameters = {'n_estimators' : 18, 'random_state' : 1, 'criterion' : 'entropy'}<br>model = RandomForestClassifier(**parameters)<br>model.fit(X, y)DefaultProba = model.predict_proba(df)<br>DefaultProba = DefaultProba[:,1]<\/pre>\n\n\n\n<p>Aplicando esto, el modelo nos devolver\u00e1 un array con n\u00fameros entre 0 y 1, que b\u00e1sicamente son la probabilidad de que una empresa se convierta en cliente.<\/p>\n\n\n\n<p>Con los resultados por empresa, estos datos se a\u00f1aden al dataframe y se representan visualmente para ver la distribuci\u00f3n de los datos:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_40RpH1RkvunnVVgT.png\" alt=\"Image for post\" class=\"wp-image-1166\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_40RpH1RkvunnVVgT.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_40RpH1RkvunnVVgT-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<p>Como vemos, los datos se acumulan entre 0.5 y 0.7, pero los m\u00e1s interesantes ser\u00e1n aquellos que est\u00e1n m\u00e1s cerca de 1 es decir 0.8 y 0.9.<\/p>\n\n\n\n<p>Para que la visualizaci\u00f3n sea m\u00e1s friendly,&nbsp;<strong>generamos Chunks y States, que b\u00e1sicamente lo que har\u00e1n ser\u00e1 agrupar a estas empresas seg\u00fan los resultados en notas del 0 al 10 y estados (Cold, Warm y Hot) para ayudar al Call Center a seleccionar a qu\u00e9 empresas llamar consiguiendo los siguientes resultados<\/strong>:<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_pj6df0VX3uEgIhi6.png\" alt=\"Image for post\" class=\"wp-image-1168\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_pj6df0VX3uEgIhi6.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_pj6df0VX3uEgIhi6-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" width=\"700\" height=\"429\" src=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_M1vUy25i5_GjKSzc.png\" alt=\"Image for post\" class=\"wp-image-1170\" srcset=\"https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_M1vUy25i5_GjKSzc.png 700w, https:\/\/apachedigital.io\/wp-content\/uploads\/2020\/10\/0_M1vUy25i5_GjKSzc-300x184.png 300w\" sizes=\"(max-width: 700px) 100vw, 700px\" \/><\/figure><\/div>\n\n\n\n<h1 id=\"d5cf\"><strong>Conclusiones<\/strong><\/h1>\n\n\n\n<p>Finalmente, devolvemos el mismo DataFrame al cliente donde cuenta con 4 columnas adicionales: Clusters, Scoring, Chunks y State.<\/p>\n\n\n\n<p><strong>Con los Clusters ser\u00e1n capaces de analizar cada segmento<\/strong>&nbsp;resultante y focalizarse en ellos en funci\u00f3n de las necesidades.<\/p>\n\n\n\n<p><strong>Con las columnas de Scoring, Chunks y State el Call Center podr\u00e1n comenzar a captar a aquellas empresas que tengan una mejor nota y sean m\u00e1s proclives a convertirse en clientes,<\/strong>&nbsp;sin necesidad de realizar una investigaci\u00f3n exhaustiva, por lo que se ahorrar\u00e1 muchos recursos.<\/p>\n\n\n\n<p>Adem\u00e1s,&nbsp;<strong>con la combinaci\u00f3n de Clusters y Scoring contar\u00e1n con la posibilidad de seleccionar a las empresas con mejores notas, excluyendo o a\u00f1adiendo los segmentos pertinentes<\/strong>, por ejemplo, en \u00e9poca de crisis inmobiliaria podr\u00e1n excluir los segmentos del sector de la construcci\u00f3n y similares centr\u00e1ndose en los restantes segmentos por nota.<\/p>\n\n\n\n<p>Por \u00faltimo y no menos importante,&nbsp;<strong>se entrega al cliente una base de datos completa que en principio contaba con una gran cantidad de valores nulos<\/strong>. Esta inferencia realizada con el algoritmo KNN ayudar\u00e1 a nuestro cliente a hacerse una idea de las caracter\u00edsticas de las empresas donde faltaban datos y podr\u00e1 as\u00ed focalizar su captaci\u00f3n hac\u00eda Leads con caracter\u00edsticas similares.<\/p>\n\n\n\n<p>Todas estas posibilidades&nbsp;<strong>generar\u00e1n una optimizaci\u00f3n de recursos donde la captaci\u00f3n de Leads se ver\u00e1 enormemente acelerada<\/strong>&nbsp;y la reducci\u00f3n de costes tambi\u00e9n marcar\u00e1 la diferencia, pudiendo reorientar esos gastos.<\/p>\n\n\n\n<p>En APACHE luchamos d\u00eda a d\u00eda para ofrecer los mejores servicios y diferenciarnos de la competencia.<\/p>\n\n\n\n<p>Es por ello por lo que nos encanta realizar soluciones disruptivas de la mano de las \u00faltimas tecnolog\u00edas, utilizadas de forma creativa e inteligente.<\/p>\n","protected":false},"author":5,"featured_media":1144,"template":"","category_insight":[57],"_links":{"self":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/insight\/1143"}],"collection":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/insight"}],"about":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/types\/insight"}],"author":[{"embeddable":true,"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/users\/5"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/media\/1144"}],"wp:attachment":[{"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/media?parent=1143"}],"wp:term":[{"taxonomy":"category_insight","embeddable":true,"href":"https:\/\/apachedigital.io\/en\/wp-json\/wp\/v2\/category_insight?post=1143"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}