Paloma Recuero de los Santos Video Post #9: Analíticas Big Data, sí, pero ¿Cuáles? Sabemos que las analíticas avanzadas Big Data son imprescindibles para no perder la comba de la innovación digital. Lo que no tenemos tan claro es qué tipo de...
LUCA Talk: La importancia de la seguridad y aspectos legales en el gobierno de los datos. FORMATO: Charla de 30 minutos + Q&A de 10 minutosCUÁNDO: 3 de marzo, 16:00 h (CET)CÓMO: Inscripción gratuita en eventbrite SOBRE QUÉ: Desde la Comisión Europea se está definiendo y escribiendo...
Sergio Sancho Azcoitia La inteligencia artificial detrás de GitHub Git es un sistema de control de versiones que se ha vuelto muy popular durante los últimos años. Eso se debe a su gran potencia y versatilidad, lo que ha...
Ismael Rihawi Tu primer proyecto IoT Cloud (I): Tutorial para solución E2E con ESP32 y AWS IoT En un anterior post a comienzos de verano exploramos en profundidad el catálogo de servicios disponibles en Amazon Web Services para la implementación de soluciones profesionales que permitan unir...
Alicia Martín Domingos Cómo optimizar la gestión de stock y almacenes ¿Alguna vez has visto cómo llega la mercancía a los almacenes de una tienda? Hace años, un operario descargaba la mercancía y con un listado en papel iba revisando...
LUCA Planificando la ubicación de un site de retail con los datos Una de las decisiones de negocio clave para cualquier marca es decidir dónde “establecer su tienda”. Esto implica la necesidad de conocer muy bien a los consumidores y su...
LUCA Deep Learning e imágenes por satélite para estimar el impacto de la COVID19 Motivados por el hecho de que la pandemia de COVID-19 ha causado conmoción mundial en un corto periodo de tiempo desde diciembre de 2019, estimamos el impacto negativo del...
Alicia Martín Domingos Cómo optimizar la gestión de stock y almacenes ¿Alguna vez has visto cómo llega la mercancía a los almacenes de una tienda? Hace años, un operario descargaba la mercancía y con un listado en papel iba revisando...
LUCA LUCATalk: LUCA Store, Digitalizando las tiendas físicas Como muchos otros sectores, el sector de Retail también esta pasando por una gran transformación. Gracias a los avances de la tecnología, hay muchas maneras de llegar a los...
Paloma Recuero de los Santos Video Post #9: Analíticas Big Data, sí, pero ¿Cuáles? Sabemos que las analíticas avanzadas Big Data son imprescindibles para no perder la comba de la innovación digital. Lo que no tenemos tan claro es qué tipo de...
Paloma Recuero de los Santos Video Post #9: Analíticas Big Data, sí, pero ¿Cuáles? Sabemos que las analíticas avanzadas Big Data son imprescindibles para no perder la comba de la innovación digital. Lo que no tenemos tan claro es qué tipo de...
LUCA Talk: La importancia de la seguridad y aspectos legales en el gobierno de los datos. FORMATO: Charla de 30 minutos + Q&A de 10 minutosCUÁNDO: 3 de marzo, 16:00 h (CET)CÓMO: Inscripción gratuita en eventbrite SOBRE QUÉ: Desde la Comisión Europea se está definiendo y escribiendo...
Predictor de infidelidad (III): Ejemplo de regresión logística en PythonPaloma Recuero de los Santos 27 febrero, 2019 Ya estamos llegando al final del nuestro experimento. Tras introducir el problema y explorar el dataset en el primer post, y aprender cómo funciona el algoritmo de regresión logística, en el segundo, ya estamos listos para crear nuestro modelo a partir de los datos y… aplicarlo. ¿Te animas a llegar hasta el final? En este tercer y último post aprenderemos lo siguiente: Como crear un predictor usando el modelo de regresión logística de scikit-learn Cómo valorar sus métricas Cómo hacer una predicción Qué conclusiones podemos extraer Retomamos pues, nuestro Python notebook, donde, ya habíamos realizado la carga y exploración de los datos y creado la variable objetivo, a la que llamamos “infidelity”. (Como hemos hecho en los post anteriores, primero, explicaremos paso a paso con imágenes cómo hacerlo, y al final del proceso, incorporamos la versión final editable de la que podéis copiar directamente el código para pegarlo en vuestro notebook ) 3. Aplicación del modelo. Para aplicar el modelo de regresión logística, vamos a usar una librería de Python, Patsy, que permite generar de forma muy cómoda el formato de matrices con el que funciona este modelo. Vamos a recordar un poco cómo era la notación matemática, para entender cuál debe ser el formato de entrada al modelo. La regresión logística era una transformación lineal (con salida no lineal) que se podía expresar de la siguiente manera: Figura 1: Fórmula de una transformación lineal. Donde Y es la variable dependiente u objetivo que queremos estimar (“infidelity”), y X son las variables dependientes o predictoras, que “condicionan” el valor de la Y (“age”, “religious”, “children” etc). Los valores de los coeficientes βi son los que el modelo va a “aprender” entrenándose con valores conocidos del dataset. Una vez entrenado el modelo, será capaz de predecir qué valor tendrá Y para un caso no recogido en los datos de entrenamiento. La fórmula también puede expresarse de esta forma, como producto escalar: Figura 2: Transformación lineal expresada como producto escalar. Si generalizamos para más de una observación Xi, necesitamos generar una matriz como esta: Figura 3: Transformación lineal expresada de forma matricial. 3.1 Formateamos los datos con Patsy La librería Patsy permite, precisamente, generar estas matrices de forma muy ágil gracias a la función dmatrices y a su notación de fórmula. Además, dmatrices añade de forma automática la columna de “1” necesaria para obtener los términos de corte (εi), conocidos como “intercept terms”. Otra de las ventajas de Patsy es que permite trabajar con datos categóricos de forma muy flexible, gracias a la función C(), que indica que los datos entre los paréntesis deben tratarse como etiquetas y no como números. En nuestro ejemplo, vamos a usarlo para que no considere como números los códigos de ocupación. Esta operación es lo que se llama, convertir datos en “dummy”. Por tanto, al aplicar la función dmatrices con esta sintaxis, obtenemos como resultado dos matrices. La primera, con los resultados o valores de la variable objetivo “y”, y la segunda, con los valores de las variables independientes X o datos predictores: Figura 4: Sintaxis de de función dmatrices de Patsy. Para nuestro ejemplo: y, X = dmatrices(‘infidelity ~ rate_marriage + age + yrs_married + children + religious+ educ + C(occupation) + C(occupation_husb) ‘, dta, return_type = ‘dataframe’) Con esta sentencia obtenemos las dos matrices que hemos mencionado antes, en las que los valores de “infidelity”(y) son iguales al producto de los valores de la matriz que representa las variables independientes (X) por unos coeficientes, más un término de corte. Al mismo tiempo indicamos que no use los valores de códigos de ocupación como numéricos sino como categóricos. Figura 5: Código para convertir la matriz de datos en el formato necesario para aplicar el modelo. Comprobamos las dimensiones de las matrices de salida, y sus índices: Figura 6: Código para comprobar las dimensiones de las matrices. 3.2 Aplicamos el modelo Ya sólo nos queda un último paso para poder aplicar el modelo de regresión logística de scikit-learn, y es convertir el vector columna y en matriz 1D. A continuación, ya podemos aplicar directamente el modelo LogisticRegression. Como resultado del entrenamiento del modelo, obtenemos la matriz de coeficientes: Figura 7: Aplicación del modelo. Podemos ver que la precisión del modelo es de un 73%: Figura 8: Estimación de la precisión. También, podemos estimar también qué porcentaje de individuos tienen alguna aventura, obteniendo un resultado de un 32% Figura 9: Porcentaje de individuos infieles. La matriz de coeficientes obtenida muestra qué peso tiene cada uno de los coeficientes. Para visualizarlo, podemos usar List(zip), que crea una matriz a partir de dos listas, la que contiene el nombre de los índices, en la primera columna, y los valores en la segunda. Figura 10: Código para obtener la matriz de coeficientes. Por ejemplo, podemos ver cómo los incrementos en rate_marrige y religiousnes disminuyen la probabilidad de infidelidad. Lo cual es consistente con el análisis de correlación de variables que hicimos en el primer post. Figura 11: Coeficientes. 3.3 Evaluamos el modelo Para evaluar el modelo, dividimos el dataset en dos partes. Dejamos un 75% de los datos como datos de entrenamiento (train), y reservamos el 25% restando como datos de prueba (test). A continuación, entrenamos el modelo de nuevo, pero ahora sólo con los datos de entrenamiento. Figura 12: Dividimos el dataset en train y test. Una vez entrenado el modelo, lo aplicamos a los datos reservados como “test”, y calculamos las métricas precisión (Accurary) y exactitud (Precision). Cuidado con los “false friends”- Hemos obtenido unos valores de un 73% para la precisión, que no es que sea muy alto, pero tampoco es un mal resultado. Indica que la dispersión de los valores es baja. Sin embargo, la exactitud, es sólo de un 62%. No es un dato muy bueno, ya que se refiere a lo cerca que está un resultado del valor verdadero. Los valores de la diagonal principal de la matriz de confusión (993, 176) indican las predicciones correctas, tanto para verdaderos positivos, como verdaderos negativos. La otra diagonal (con valores 316, 117) recoge las predicciones erróneas. Figura 13: Calculamos precisión, exactitud y matriz de confusión. Para ver la matriz de confusión de forma mucho más “visual”, podemos hacerlo en forma de mapa de calor: Figura 14: Código para ver la matriz de confusión como mapa de calor usando seaborn. Figura 15: Matriz de confusión en forma de mapa de calor. 3.4 Hacemos una predicción Por último, ya sólo nos queda hacer una predicción usando el modelo que acabamos de crear. Para que nos resulta más fácil “escribir” los datos de entrada, usaremos el indexador iloc para extraer ,como ejemplo, uno de los registros de la matriz de datos. En particular hemos elegido el registro número 4. Figura 16: Extraemos un registro del dataset como ejemplo. Como resultado, podemos ver el aspecto que tiene este registro en concreto, lo reconvertimos en el formato necesario para poder aplicar el modelo y, ya que estamos, lo probamos. En este caso, la probabilidad de infidelidad es de un 30%. Figura 17: Visualización de ese registro concreto. A continuación, lo usaremos de base para introducir en el modelo los datos concretos para los que queremos obtener una predicción mediante el método keys(). Por ejemplo: mujer de 35 años, con 3 hijos, no religiosa,nivel educativo alto, con ocupaciones (ambos) técnicos especializados y una buena valoración de su matrimonio. F.keys();F[‘age’]=35; F[‘children’]=3; F[‘yrs_married’]=10; F[‘religious’]=1; F[‘religious’]=1; F[‘C(occupation_husb)[T.3.0]’]=1 Figura 18: Cambiamos con F.keys() los valores de cada variable para introducir los que queramos Al aplicar el modelo a este caso en particular, obtenemos como resultado una probabilidad de infidelidad del 29%. Prueba con los datos que quieras, ¿qué resultados obtienes? Figura 19: Resultado obtenido al aplicar el modelo al nuevo caso. ¿Te animas a probarlo? A continuación, tienes el código completo del experimento, que puedes cortar y pegar en tu Jupyter notebook. Te recomendamos que lo vayas haciendo paso a paso, como lo hemos explicado, para poder entender qué se hace en cada momento. Incluso, puedes ir introduciendo pequeñas modificaciones para probar cosas nuevas.g #Importamos los módulos y librerías que vamos a necesitar #!/usr/bin/env python -W ignore::DeprecationWarning #!/usr/bin/env python -W ignore::FutureWarning import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.api as sm import seaborn as sns from patsy import dmatrices from scipy import stats from sklearn import metrics from sklearn.linear_model import LogisticRegression from sklearn.model_selection import train_test_split In [3]: #Cargamos los datos dta = sm.datasets.fair.load_pandas().data dta.head(10) Out[3]: rate_marriage age yrs_married children religious educ occupation occupation_husb affairs 0 3.0 32.0 9.0 3.0 3.0 17.0 2.0 5.0 0.111111 1 3.0 27.0 13.0 3.0 1.0 14.0 3.0 4.0 3.230769 2 4.0 22.0 2.5 0.0 1.0 16.0 3.0 5.0 1.400000 3 4.0 37.0 16.5 4.0 3.0 16.0 5.0 5.0 0.727273 4 5.0 27.0 9.0 1.0 1.0 14.0 3.0 4.0 4.666666 5 4.0 27.0 9.0 0.0 2.0 14.0 3.0 4.0 4.666666 6 5.0 37.0 23.0 5.5 2.0 12.0 5.0 4.0 0.852174 7 5.0 37.0 23.0 5.5 2.0 12.0 2.0 3.0 1.826086 8 3.0 22.0 2.5 0.0 2.0 12.0 3.0 3.0 4.799999 9 3.0 27.0 6.0 0.0 1.0 16.0 3.0 5.0 1.333333 In [4]: #Información sobre el dataset: descripción general, origen, #definición de variables,tipo de variables print(sm.datasets.fair.NOTE) print(sm.datasets.fair.SOURCE) print(sm.datasets.fair.DESCRLONG) dta.info() :: Number of observations: 6366 Number of variables: 9 Variable name definitions: rate_marriage : How rate marriage, 1 = very poor, 2 = poor, 3 = fair, 4 = good, 5 = very good age : Age yrs_married : No. years married. Interval approximations. See original paper for detailed explanation. children : No. children religious : How relgious, 1 = not, 2 = mildly, 3 = fairly, 4 = strongly educ : Level of education, 9 = grade school, 12 = high school, 14 = some college, 16 = college graduate, 17 = some graduate school, 20 = advanced degree occupation : 1 = student, 2 = farming, agriculture; semi-skilled, or unskilled worker; 3 = white-colloar; 4 = teacher counselor social worker, nurse; artist, writers; technician, skilled worker, 5 = managerial, administrative, business, 6 = professional with advanced degree occupation_husb : Husband's occupation. Same as occupation. affairs : measure of time spent in extramarital affairs See the original paper for more details. Fair, Ray. 1978. "A Theory of Extramarital Affairs," `Journal of Political Economy`, February, 45-61. The data is available at http://fairmodel.econ.yale.edu/rayfair/pdf/2011b.htm Extramarital affair data used to explain the allocation of an individual's time among work, time spent with a spouse, and time spent with a paramour. The data is used as an example of regression with censored data. RangeIndex: 6366 entries, 0 to 6365 Data columns (total 9 columns): rate_marriage 6366 non-null float64 age 6366 non-null float64 yrs_married 6366 non-null float64 children 6366 non-null float64 religious 6366 non-null float64 educ 6366 non-null float64 occupation 6366 non-null float64 occupation_husb 6366 non-null float64 affairs 6366 non-null float64 dtypes: float64(9) memory usage: 447.7 KB In [5]: #Comprobamos que no falten datos (Resultado booleano: true=falta dato, false=dato) #También se puede visualizar si faltan datos con los mapas de calor de seaborn. #En este caso, no hace falta. dta.isnull().head(10) Out[5]: rate_marriage age yrs_married children religious educ occupation occupation_husb affairs 0 False False False False False False False False False 1 False False False False False False False False False 2 False False False False False False False False False 3 False False False False False False False False False 4 False False False False False False False False False 5 False False False False False False False False False 6 False False False False False False False False False 7 False False False False False False False False False 8 False False False False False False False False False 9 False False False False False False False False False In [6]: # Veamos ahora la matriz de correlación. # Deberíamos eliminar las variables altamente correlacionadas >0,90 # Edad, años matrimonio-- lógica # Correlación positiva--religious/rate marriage,age/yrs_marriage # Correlación negativa: affairs/children, religious print(dta.corr()) #Edad, años matrimonio-- lógicamente no son independientes, para eliminarlos habría que hacer: #dta.drop(['age','yrs_married'],axis=1,inplace=True) #dta.head() rate_marriage age yrs_married children religious \ rate_marriage 1.000000 -0.111127 -0.128978 -0.129161 0.078794 age -0.111127 1.000000 0.894082 0.673902 0.136598 yrs_married -0.128978 0.894082 1.000000 0.772806 0.132683 children -0.129161 0.673902 0.772806 1.000000 0.141845 religious 0.078794 0.136598 0.132683 0.141845 1.000000 educ 0.079869 0.027960 -0.109058 -0.141918 0.032245 occupation 0.039528 0.106127 0.041782 -0.015068 0.035746 occupation_husb 0.027745 0.162567 0.128135 0.086660 0.004061 affairs -0.178068 -0.089964 -0.087737 -0.070278 -0.125933 educ occupation occupation_husb affairs rate_marriage 0.079869 0.039528 0.027745 -0.178068 age 0.027960 0.106127 0.162567 -0.089964 yrs_married -0.109058 0.041782 0.128135 -0.087737 children -0.141918 -0.015068 0.086660 -0.070278 religious 0.032245 0.035746 0.004061 -0.125933 educ 1.000000 0.382286 0.183932 -0.017740 occupation 0.382286 1.000000 0.201156 0.004469 occupation_husb 0.183932 0.201156 1.000000 -0.015614 affairs -0.017740 0.004469 -0.015614 1.000000 In [7]: #También podemos ver la matriz de correlación de forma gráfica #Si los coeficientes son muy bajos, significa que la influencia #de esa variable es muy pequeña y,podríamos plantearnos una "reducción" #de estas para simplifacar el modelo, pero en este ejemplo no vamos a #quitar ninguna %matplotlib inline sns.heatmap(dta.corr(), annot=True) Out[7]: In [8]: #En la fase de exploración, podemos visualizar las variables y #sus relaciones mediante histogramas #Para que muestre los gráficos en el notebook añadimos: %matplotlib inline # histograma sobre influencia del nivel educativo dta.educ.hist() plt.title('Influencia del Nivel Educativo') plt.xlabel('Nivel Académico') plt.ylabel('Frecuencia infidelidad') Out[8]: Text(0,0.5,'Frecuencia infidelidad') In [9]: # Creamos una nueva variable binaria "infidelity" para tratarlo #como un problema de clasificación 0=fiel, 1=infiel # Mostramos los 10 primeros ... infieles dta['infidelity'] = (dta.affairs > 0).astype(int) print(dta.head(10)) dta.shape rate_marriage age yrs_married children religious educ occupation \ 0 3.0 32.0 9.0 3.0 3.0 17.0 2.0 1 3.0 27.0 13.0 3.0 1.0 14.0 3.0 2 4.0 22.0 2.5 0.0 1.0 16.0 3.0 3 4.0 37.0 16.5 4.0 3.0 16.0 5.0 4 5.0 27.0 9.0 1.0 1.0 14.0 3.0 5 4.0 27.0 9.0 0.0 2.0 14.0 3.0 6 5.0 37.0 23.0 5.5 2.0 12.0 5.0 7 5.0 37.0 23.0 5.5 2.0 12.0 2.0 8 3.0 22.0 2.5 0.0 2.0 12.0 3.0 9 3.0 27.0 6.0 0.0 1.0 16.0 3.0 occupation_husb affairs infidelity 0 5.0 0.111111 1 1 4.0 3.230769 1 2 5.0 1.400000 1 3 5.0 0.727273 1 4 4.0 4.666666 1 5 4.0 4.666666 1 6 4.0 0.852174 1 7 3.0 1.826086 1 8 3.0 4.799999 1 9 5.0 1.333333 1 Out[9]: (6366, 10) In [10]: #Patsy es una librería de Python que permite convertir los datos #en el formato de matriz necesario para aplicar el modelo #También permite generar variables dummy mediante la función C() #La sintaxis es: #patsy.dmatrix(formula_like, data={}, eval_env=0, NA_action='drop', return_type='matrix') from patsy import dmatrices y, X = dmatrices('infidelity ~ rate_marriage + age + yrs_married + children + religious+ educ + C(occupation) + C(occupation_husb) ', dta, return_type = 'dataframe') #Comprobamos las dimensiones y los índices de las matrices resultado print(X.shape) print(y.shape) print (X.columns) print(y.columns) (6366, 17) (6366, 1) Index(['Intercept', 'C(occupation)[T.2.0]', 'C(occupation)[T.3.0]', 'C(occupation)[T.4.0]', 'C(occupation)[T.5.0]', 'C(occupation)[T.6.0]', 'C(occupation_husb)[T.2.0]', 'C(occupation_husb)[T.3.0]', 'C(occupation_husb)[T.4.0]', 'C(occupation_husb)[T.5.0]', 'C(occupation_husb)[T.6.0]', 'rate_marriage', 'age', 'yrs_married', 'children', 'religious', 'educ'], dtype='object') Index(['infidelity'], dtype='object') In [11]: #Para que scikit-learn entienda y como variable dependiente (target) #debemos convertirla de vector columna en matriz 1D y=np.ravel(y) print(y) # sklearn output model = LogisticRegression(fit_intercept = False, C = 1e9) mdl = model.fit(X, y) model.coef_ [ 1. 1. 1. ..., 0. 0. 0.] Out[11]: array([[ 3.02618999e+00, 3.49733210e-01, 6.61853517e-01, 4.31150708e-01, 1.01297621e+00, 1.06658685e+00, 1.60404225e-01, 2.73983554e-01, 1.32893449e-01, 1.62639164e-01, 1.73031585e-01, -7.10360913e-01, -6.13554596e-02, 1.08087003e-01, 1.55318807e-02, -3.75392191e-01, -1.96584314e-03]]) In [12]: # Veamos la precisión del modelo (sobre los datos de entrenamiento) 73% # Más adelante volveremos a entrenar el modelo, pero separando antes los # datos en train y test. Volveremos a calcular la precisión del modelo # entrenado sobre los datos train al aplicarlo a los test model.score(X,y) Out[12]: 0.72510210493245364 In [13]: #¿Qué porcentaje tiene aventuras?: 32%-- #Si predecimos siempre "no", acertaríamos el 68% de las veces, #algo mejor que el error nulo pero no mucho y.mean() Out[13]: 0.32249450204209867 In [14]: # Podemos examinar la matriz de coeficientes, para ver qué peso tiene # cada uno de los coeficientes. List(zip) permite crear una matriz # a partir de dos listas, el nombre de los índices, en la primera columna # y en la segunda, los valores #pd.DataFrame(list(zip(X.columns, np.transpose(model.coef_))) pd.DataFrame(list(zip(X.columns, np.transpose(model.coef_)))) # Por ejemplo, los incrementos en rate_marrige y religiousnes disminuyen # la probabilidad de infidelidad (coefientes negativos) Out[14]: 0 1 0 Intercept [3.02618998703] 1 C(occupation)[T.2.0] [0.349733209538] 2 C(occupation)[T.3.0] [0.661853517181] 3 C(occupation)[T.4.0] [0.431150707917] 4 C(occupation)[T.5.0] [1.01297621288] 5 C(occupation)[T.6.0] [1.06658684973] 6 C(occupation_husb)[T.2.0] [0.160404224729] 7 C(occupation_husb)[T.3.0] [0.27398355359] 8 C(occupation_husb)[T.4.0] [0.132893449067] 9 C(occupation_husb)[T.5.0] [0.162639163742] 10 C(occupation_husb)[T.6.0] [0.17303158544] 11 rate_marriage [-0.710360913438] 12 age [-0.0613554595525] 13 yrs_married [0.10808700349] 14 children [0.0155318806807] 15 religious [-0.375392191185] 16 educ [-0.00196584314225] In [15]: # Para evaluar el modelo, dividimos el dataset en dos partes # un 75% de los datos para entrenar el modelo # y el 25% restante para evaluarlo X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.25, random_state=0) # Ahora, aplicamos el modelo sobre los datos reservados para entrenamiento "train" model2 = LogisticRegression() model2.fit(X_train, y_train) Out[15]: LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True, intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1, penalty='l2', random_state=None, solver='liblinear', tol=0.0001, verbose=0, warm_start=False) In [16]: # Una vez entrenado el modelo, lo aplicamos a los datos reservados para "test" predicted = model2.predict(X_test) print (predicted) # Generamos las métricas de evaluación # Cuidado con los "false friends" # "Accuracy" es la precisión, y "Precision" es la exactitud print("Accuracy:",metrics.accuracy_score(y_test, predicted)) print("Precision:",metrics.precision_score(y_test, predicted)) # Generamos la matriz de confusión cnf_matrix = metrics.confusion_matrix(y_test, predicted) cnf_matrix [ 1. 0. 0. ..., 0. 1. 1.] Accuracy: 0.734296482412 Precision: 0.621908127208 Out[16]: array([[993, 107], [316, 176]], dtype=int64) In [17]: #Podemos visualizarla con un mapa de calor #Diagonal values represent accurate predictions, while non-diagonal elements are inaccurate predictions. #In the output, 119 and 36 are actual predictions, and 26 and 11 are incorrect predictions. #The accuracy is 73%, which is the same as we experienced when training and predicting on the same data. #We can also see the confusion matrix and a classification report with other metrics. In [18]: # Importamos los módulos necesarios class_names=[0,1] # name of classes fig, ax = plt.subplots() tick_marks = np.arange(len(class_names)) plt.xticks(tick_marks, class_names) plt.yticks(tick_marks, class_names) # Creamos un mapa de calor sns.heatmap(pd.DataFrame(cnf_matrix), annot=True, cmap="YlGnBu" ,fmt='g') ax.xaxis.set_label_position("top") plt.tight_layout() plt.title('Confusion matrix', y=1.1) plt.ylabel('Actual label') plt.xlabel('Predicted label') Out[18]: Text(0.5,257.44,'Predicted label') In [19]: # Vamos a usar el modelo para hacer una predicción # Para que nos resulta más fácil "escribir" los datos de entrada, # vamos a sacar un ejemplo de uno de los registros de la matriz de # datos, por ejemplo, el 4º, y después lo usaremos de base para # introducir en el modelo los datos que querarmos. print(X.iloc[4]) F=X.iloc[4] F.shape #Con reshape(1,-1) indicamos que lo convierta en una matriz de 1 fila y #el número de columnas que corresponda para que la nueva forma sea #compatible con la original F.values.reshape(1,-1) model.predict_proba(F.values.reshape(1, -1)) Intercept 1.0 C(occupation)[T.2.0] 0.0 C(occupation)[T.3.0] 1.0 C(occupation)[T.4.0] 0.0 C(occupation)[T.5.0] 0.0 C(occupation)[T.6.0] 0.0 C(occupation_husb)[T.2.0] 0.0 C(occupation_husb)[T.3.0] 0.0 C(occupation_husb)[T.4.0] 1.0 C(occupation_husb)[T.5.0] 0.0 C(occupation_husb)[T.6.0] 0.0 rate_marriage 5.0 age 27.0 yrs_married 9.0 children 1.0 religious 1.0 educ 14.0 Name: 4, dtype: float64 Out[19]: array([[ 0.69041584, 0.30958416]]) A partir del registro F que hemos extraído del conjunto de datos, podemos configurar un registro nuevo con los valores que queramos para que el modelo prediga la probabilidad de infidelidad. Vamos asignado los valores variable a varible, y luego le daremos la forma necesaria para poder introducirlos en el modelo. Por ejemplo, mujer de 35 años, con 3 hijos, no religiosa,nivel educativo alto, con ocupaciones (ambos) técnicos especializados y una buena valoración de su matrimonio In [23]: F.keys(); F['age']=35; F['children']=3; F['yrs_married']=10; F['religious']=1; F['religious']=1; F['C(occupation_husb)[T.3.0]']=1 print(F.values) [ 1. 0. 1. 0. 0. 0. 0. 1. 1. 0. 0. 5. 35. 10. 3. 1. 14.] In [24]: # Aplicamos el modelo a este nuevo conjunto de valores y obtenmos # la probabilidad de infidelidad que, en este caso es de un 29% F.values.reshape(1,-1) model.predict_proba(F.values.reshape(1, -1)) [[ 1. 0. 1. 0. 0. 0. 0. 1. 1. 0. 0. 5. 35. 10. 3. 1. 14.]] Out[24]: array([[ 0.70677527, 0.29322473]]) 4. Conclusiones Llegado el momento de sacar conclusiones, tenemos que pararnos a reflexionar. ¿Cuál ha sido el objetivo del experimento?. Hemos aprendido a crear un modelo de predicción basado en regresión logística. Hemos conocido y aprendido a cargar los datasets de Statsmodels. Hemos recordado un poco de álgebra de matrices para comprender mejor el modelo. Y sí, hemos aplicado el modelo a nuestros datos (¿a que no te has resistido?), pero ¿tiene algún tipo de validez el resultado?. A pesar de haber hecho un análisis serio, que, por supuesto se podría haber hecho siguiendo otros enfoques, por ejemplo, reduciendo por ejemplo el número de variables a considerar tras el análisis de correlación, o aplicando el modelo de statsmodel en lugar del del scikit learn, o incluso eligiendo otro algoritmo de clasificación; nunca debemos olvidar sobre qué estamos construyendo nuestro modelo. Nos referimos, por supuesto, a los datos. Y un dataset cuyo origen es una encuesta realizada en los años 70 por una revista femenina en EEUU no parece que pueda ser extrapolable al momento actual, ni a latitudes tan distantes como la nuestra. Si embargo, en la era de las apps “para ligar” o encontrar tu media naranja, hay que ser conscientes de lo que una buena analítica de datos podría obtener a partir de sus bases de datos que, por supuesto, están protegidas por leyes de privacidad. Pero…ahí están. Aquí puedes encontrar todos los post de este experimento: Especial San Valentin: ¿Podemos predecir la infidelidad con IA? Predictor de infidelidad (II): ¿Qué es la regresión logística? Predictor de infidelidad (III): Un ejemplo de regresión logística sobre el dataset “Affairs” (este post) Para mantenerte al día con LUCA visita nuestra página web, suscríbete a LUCA Data Speaks o síguenos en Twitter, LinkedIn y YouTube. Deep Learning, solo para pilotos profesionales¿Te atreves? ¡Lanzamos la 3ª edición del Reto de IA, Big Data y Ciberseguridad!
Paloma Recuero de los Santos Iot4All: Los desafíos que debe enfrentar la IoT Internet de las cosas, IoT, está presente en numerosos escenarios y casos de uso. No sólo está en la base de la transformación digital de la industria, y otros...
Paloma Recuero de los Santos Video Post #9: Analíticas Big Data, sí, pero ¿Cuáles? Sabemos que las analíticas avanzadas Big Data son imprescindibles para no perder la comba de la innovación digital. Lo que no tenemos tan claro es qué tipo de...
Fran Ramírez Las matemáticas del Machine Learning: Números aleatorios y dónde encontrarlos (II) En el artículo anterior mencionamos la importancia que tienen en nuestro día a día los números aleatorios, utilizados para realizar cualquier tipo de simulación y fundamentales a la hora...
LUCA Talk: La importancia de la seguridad y aspectos legales en el gobierno de los datos. FORMATO: Charla de 30 minutos + Q&A de 10 minutosCUÁNDO: 3 de marzo, 16:00 h (CET)CÓMO: Inscripción gratuita en eventbrite SOBRE QUÉ: Desde la Comisión Europea se está definiendo y escribiendo...
LUCA La teoría Gestalt en Gobierno del Dato Al igual que un dato por si sólo no vale nada si no se le dota de información, conocimiento y se usa para un propósito, “Gobernar el dato por...
Paloma Recuero de los Santos Drones e IA para detectar síntomas de COVID19 La Universidad de Australia de Sur, UniSA ha diseñado una tecnología pionera en el mundo que combina ingeniería, drones, cámaras e inteligencia artificial para monitorizar a distancia constantes vitales....