Estructura general para Aprendizaje Automático¶
El aprendizaje automático o estadístico consiste en una serie de técnicas que se basan en el principio general de aprendizaje: decimos que el sistema aprende si mejora su rendimiento en una tarea a partir de la experiencia. Esta definición de aprendizaje incorpora 3 elementos básicos:
- La
tarea que responde al objetivo que el agente busca alcanzar o el problema que se quiere solucionar. Por ejemplo, la tarea puede ser la clasificación de e-mails, el reconocimiento de imágenes, etc. - El rendimiento que requiere de una medida cuantitativa para determinar qué tan bien resuelve la tarea nuestro sistema.
- La experiencia; es decir, aquel material que enriquecerá los conocimientos (estados de creencia) de nuestro agente. En este caso la experiencia refiere a los datos con los que aprendemos.
Siempre que se aplique un algoritmo de aprendizaje automático, es importante seguir una metodología que nos permita determinar qué tan bien el modelo de aprendizaje generaliza. Esta metodología consistirá en los siguientes pasos:
- Determinar el conjunto de datos (experiencia) con el que se va a trabajar. Este conjunto de datos debe ser idealmente representativo del problema, sea este supervisado o no supervisado (o de otro tipo). El conjunto de datos debe separarse en varios conjuntos:
- Datos de entrenamiento: Corresponden a aquellos datos con los que se aprenderá el modelo. Estos datos corresponden a la experiencia propiamente dicha, pues son aquellos datos que nuestro agente de aprendizaje verá y a partir de los cuales aprenderá. Generalmente se toma un 70% del conjunto de datos original para el entrenamiento.
- Datos de validación: Son datos que pueden servir para ajustar hiperparámetros. No siempre son necesarios.
- Datos de evaluación: Son los datos con los que se determinará el rendimiento del agente de aprendizaje. Es importante que los datos de evaluación no deben haber sido vistos por el agente previamente (durante el entrenamiento), pues de otra forma no podremos decir que el agente está aprendiendo (si no memorizando). Generalmente, se usa un 30% para los datos de evaluación.
- Selección de los modelos: Después de que tenemos el problema a tratar, podemos pasar a hacer una selección de un modelo para que resuelva este problema. En primer lugar debemos determinar qué tipo de problemas estamos enfrentado; podemos pensar en los siguientes tipos de problemas:
- Supervisados: Cuando tenemos un indicador de la clase que deseamos de salida: $\mathcal{S} = \{x,y) : x \in \mathbb{R}^d. y \in Y\}$
- No-supervisados: Cuando sólo contamos con los datos del problema, pero no con una supervisión; es decir, el conjunto es de la forma $\mathcal{U} = \{x \in \mathbb{R}\}$
- Podemos hablar de otros tipos de aprendizaje; como el aprendizaje por refuerzo, donde el agente busca resolver una tarea con una función de recompensa; aprendizaje auto-supervisado donde el agente genera su propia supervisión; o aprendizaje semi-supervisado.
- Entrenamiento del modelo: Una vez que se cuenta con los datos y se ha seleccionado un modelo adecuado para el problema, se procederá a entrenar el modelo. Este proceso es lo que se puede llamar aprendizaje propiamente dicho, pues es aquí donde el agente, a partir de la observación de los datos, aprende a resolver el problema. En este paso se podrán seleccionar hiperparámetros (valores del modelo que son elegidos por el programador) por lo que se puede usar una parte del dataset original (generalmente el 10%) para poder determinar esos valores; a esto corresponde el paso de validación.
- Evaluación del modelo: Este último paso es de suma importancia, pues determina la capacidad que el agente de aprendizaje tiene para generalizar. La evaluación del modelo consiste en determinar una medida numérica que nos indique qué tan bien el agente resuelve el problema para datos que no ha visto (de los que no ha aprendido). Según el tipo de problema se pueden utilizar diferentes métricas de evaluación.
1. Conjunto de datos¶
El conjunto de datos determina el problema que queremos resolver. Dentro del aprendizaje automático es importante contar con un conjunto de datos. Si tenemos un problema que no cuenta con uno, tendremos que conformar un conjunto de datos que represente adecuadamente al problema.
En este caso, utilizaremos un conjunto de datos ya disponible. Utilizaremos el dataset de cáncer de mama de Wisconsin, disponible en https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+(Diagnostic). Este dataset cuenta con las siguientes características:
Características | Tipo de rasgos | Núm. rasgos | Núm. instancias --- | --- | --- | --- Multivariable | Valores reales | 32 | 569
Tomaremos el dataset desde la paqueterías de sklearn.
from sklearn.datasets import load_breast_cancer
import pandas as pd
#Carga del dataset
data = load_breast_cancer()
#Entradas
x = data.data
#Salidas esperadas
y = data.target
El dataset cuenta con diferentes rasgos que describen características del tumor. Un total de 52 rasgos, entre ellos tenemos:
- mean radius: radio promedio del tumor.
- mean texture: textura del tumor en promedio.
- worst radius: el radio más alto del tumor.
En general cada rasgo describe características del tumor como radio, textura, perímetro, suavidad, concavidad, etc. Se toman varios valores, el valor medio, el mejor y el peor valor. La tabla siguiente describe estos rasgos:
data_descr = pd.DataFrame(data=x, columns=data.feature_names)
data_descr
mean radius | mean texture | mean perimeter | mean area | mean smoothness | mean compactness | mean concavity | mean concave points | mean symmetry | mean fractal dimension | ... | worst radius | worst texture | worst perimeter | worst area | worst smoothness | worst compactness | worst concavity | worst concave points | worst symmetry | worst fractal dimension | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 17.99 | 10.38 | 122.80 | 1001.0 | 0.11840 | 0.27760 | 0.30010 | 0.14710 | 0.2419 | 0.07871 | ... | 25.380 | 17.33 | 184.60 | 2019.0 | 0.16220 | 0.66560 | 0.7119 | 0.2654 | 0.4601 | 0.11890 |
1 | 20.57 | 17.77 | 132.90 | 1326.0 | 0.08474 | 0.07864 | 0.08690 | 0.07017 | 0.1812 | 0.05667 | ... | 24.990 | 23.41 | 158.80 | 1956.0 | 0.12380 | 0.18660 | 0.2416 | 0.1860 | 0.2750 | 0.08902 |
2 | 19.69 | 21.25 | 130.00 | 1203.0 | 0.10960 | 0.15990 | 0.19740 | 0.12790 | 0.2069 | 0.05999 | ... | 23.570 | 25.53 | 152.50 | 1709.0 | 0.14440 | 0.42450 | 0.4504 | 0.2430 | 0.3613 | 0.08758 |
3 | 11.42 | 20.38 | 77.58 | 386.1 | 0.14250 | 0.28390 | 0.24140 | 0.10520 | 0.2597 | 0.09744 | ... | 14.910 | 26.50 | 98.87 | 567.7 | 0.20980 | 0.86630 | 0.6869 | 0.2575 | 0.6638 | 0.17300 |
4 | 20.29 | 14.34 | 135.10 | 1297.0 | 0.10030 | 0.13280 | 0.19800 | 0.10430 | 0.1809 | 0.05883 | ... | 22.540 | 16.67 | 152.20 | 1575.0 | 0.13740 | 0.20500 | 0.4000 | 0.1625 | 0.2364 | 0.07678 |
... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
564 | 21.56 | 22.39 | 142.00 | 1479.0 | 0.11100 | 0.11590 | 0.24390 | 0.13890 | 0.1726 | 0.05623 | ... | 25.450 | 26.40 | 166.10 | 2027.0 | 0.14100 | 0.21130 | 0.4107 | 0.2216 | 0.2060 | 0.07115 |
565 | 20.13 | 28.25 | 131.20 | 1261.0 | 0.09780 | 0.10340 | 0.14400 | 0.09791 | 0.1752 | 0.05533 | ... | 23.690 | 38.25 | 155.00 | 1731.0 | 0.11660 | 0.19220 | 0.3215 | 0.1628 | 0.2572 | 0.06637 |
566 | 16.60 | 28.08 | 108.30 | 858.1 | 0.08455 | 0.10230 | 0.09251 | 0.05302 | 0.1590 | 0.05648 | ... | 18.980 | 34.12 | 126.70 | 1124.0 | 0.11390 | 0.30940 | 0.3403 | 0.1418 | 0.2218 | 0.07820 |
567 | 20.60 | 29.33 | 140.10 | 1265.0 | 0.11780 | 0.27700 | 0.35140 | 0.15200 | 0.2397 | 0.07016 | ... | 25.740 | 39.42 | 184.60 | 1821.0 | 0.16500 | 0.86810 | 0.9387 | 0.2650 | 0.4087 | 0.12400 |
568 | 7.76 | 24.54 | 47.92 | 181.0 | 0.05263 | 0.04362 | 0.00000 | 0.00000 | 0.1587 | 0.05884 | ... | 9.456 | 30.37 | 59.16 | 268.6 | 0.08996 | 0.06444 | 0.0000 | 0.0000 | 0.2871 | 0.07039 |
569 rows × 30 columns
Las estadísticas de los datos se ponen a continuación. En estas podemos ver los valores medios para cada rasgo, su desviación estándar.
#Datos estadísticos de los rasgos
data_descr.describe()
mean radius | mean texture | mean perimeter | mean area | mean smoothness | mean compactness | mean concavity | mean concave points | mean symmetry | mean fractal dimension | ... | worst radius | worst texture | worst perimeter | worst area | worst smoothness | worst compactness | worst concavity | worst concave points | worst symmetry | worst fractal dimension | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
count | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | ... | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 | 569.000000 |
mean | 14.127292 | 19.289649 | 91.969033 | 654.889104 | 0.096360 | 0.104341 | 0.088799 | 0.048919 | 0.181162 | 0.062798 | ... | 16.269190 | 25.677223 | 107.261213 | 880.583128 | 0.132369 | 0.254265 | 0.272188 | 0.114606 | 0.290076 | 0.083946 |
std | 3.524049 | 4.301036 | 24.298981 | 351.914129 | 0.014064 | 0.052813 | 0.079720 | 0.038803 | 0.027414 | 0.007060 | ... | 4.833242 | 6.146258 | 33.602542 | 569.356993 | 0.022832 | 0.157336 | 0.208624 | 0.065732 | 0.061867 | 0.018061 |
min | 6.981000 | 9.710000 | 43.790000 | 143.500000 | 0.052630 | 0.019380 | 0.000000 | 0.000000 | 0.106000 | 0.049960 | ... | 7.930000 | 12.020000 | 50.410000 | 185.200000 | 0.071170 | 0.027290 | 0.000000 | 0.000000 | 0.156500 | 0.055040 |
25% | 11.700000 | 16.170000 | 75.170000 | 420.300000 | 0.086370 | 0.064920 | 0.029560 | 0.020310 | 0.161900 | 0.057700 | ... | 13.010000 | 21.080000 | 84.110000 | 515.300000 | 0.116600 | 0.147200 | 0.114500 | 0.064930 | 0.250400 | 0.071460 |
50% | 13.370000 | 18.840000 | 86.240000 | 551.100000 | 0.095870 | 0.092630 | 0.061540 | 0.033500 | 0.179200 | 0.061540 | ... | 14.970000 | 25.410000 | 97.660000 | 686.500000 | 0.131300 | 0.211900 | 0.226700 | 0.099930 | 0.282200 | 0.080040 |
75% | 15.780000 | 21.800000 | 104.100000 | 782.700000 | 0.105300 | 0.130400 | 0.130700 | 0.074000 | 0.195700 | 0.066120 | ... | 18.790000 | 29.720000 | 125.400000 | 1084.000000 | 0.146000 | 0.339100 | 0.382900 | 0.161400 | 0.317900 | 0.092080 |
max | 28.110000 | 39.280000 | 188.500000 | 2501.000000 | 0.163400 | 0.345400 | 0.426800 | 0.201200 | 0.304000 | 0.097440 | ... | 36.040000 | 49.540000 | 251.200000 | 4254.000000 | 0.222600 | 1.058000 | 1.252000 | 0.291000 | 0.663800 | 0.207500 |
8 rows × 30 columns
Para terminar de preparar los datos, separamos estos en el conjunto de entrenamiento y de evaluación. Para esto utilizamos el 70% de los datos en entrenamiento y el 30% para la evaluación:
from sklearn.model_selection import train_test_split
# Separación de los datos en entrenamiento y evaluación
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.3, random_state=123)
print('Instancias en\nEntrenamiento: {}\nEvaluación: {}'.format(len(x_train), len(x_test)))
Instancias en Entrenamiento: 398 Evaluación: 171
2. Selección de algoritmos¶
Ya que tenemos un problema que cuenta con un conjunto de datos supervisados (en donde teneos muestras de las salidas que deseamos obtener), se propone el uso de tres algoritmos supervisados. Cada uno de estos algoritmos pertenece a una familia específica en la que se enfoca en la clasificación supervisada:
Algoritmos paramétricos: Los algoritmos paramétricos dependen de un grupo de parámetros que describen una distribución probabilística. En este caso, tomamos dos algoritmos paramétricos:
1.1. Bayes Naïve: El algoritmo de Bayes Naïve se basa en una red bayesiana simple. Se trata de un modelo gráfico dirigido y, por tanto, generativo cuyo modelo se describe como: $$\hat{y} = \arg\max_y p(y,x_1,x_2,...,x_d; \theta) = \arg\max_y \prod_{i=1}^d p(x_i|y)p(y)$$ Es decir, estima una distribución conjunta que se factoriza asumiendo que los rasgos $x_i$ son generados por una clase $y$. En este caso, se estima un conjunto de parámetros que responde a los factores $p(x_i|y)$ y $p(y)$; por tanto, se trata de un algoritmo paramétrico.
1.2. Regresión logística: La regresión logística es un modelo gráfico no dirigido y, por tanto, discriminativo en donde la clase se puede obtener como: $$\hat{y} = \arg\max_y p(y|x_1,...,x_d; \theta) = \arg\max_y \frac{1}{1+exp\{-\sum_{i=1}^d \theta_i x_i + \theta_0\}}$$. En este caso se estiman los parámetros $\theta_i$, $i=0,1,...,d$ que definen los factores de la distribución. Por tanto, es también un algoritmo paramétrico.
Algoritmo no-paramétrico: Para contrastar con los algoritmos paramétricos, tomamos un algoritmo no paramétrico: árboles de decisión, se trata de un algoritmo que construye un árbol binario donde cada nodo representa a un rasgo que se ramifica en dos casos: el dato contiene al rasgo o no lo contiene, o bien si son datos numéricos si el rasgo es mayor o no a un umbral. Para obtener el árbol de decisión minimizamos la impureza de Gini definida como: $$Gini = 1 - \sum_{i=1}^c p_i^2$$
Más adelante revisaremos los algoritmos y su implementación con más detalles; por ahora, simplemente cargamos estos algoritmos desde la paquetería de sklearn.
from sklearn.naive_bayes import GaussianNB
from sklearn.linear_model import LogisticRegression
from sklearn.tree import DecisionTreeClassifier
#Modelo de bayes naive
bayes_model = GaussianNB()
#Modelo de regresión con hiperparámetro de máximas iteraciones = 10000
logit_model = LogisticRegression(max_iter=10000)
#Modelo de árbol de decisión con impureza de gini
tree_model = DecisionTreeClassifier(criterion="gini")
3. Entrenamiento de los algoritmos¶
El entrenamiento es la parte central de todo el proceso de aprendizaje. Aquí es donde el agente aprenderá a partir de los datos de entrenamiento que ya hemos obtenido. En general, el problema de aprendizaje se convierte en un problema de optimización: se busca optimizar una función que determine qué tan bien realiza la tarea el agente. Esta función suele llamarse función objetivo. Cada algoritmo de aprendizaje tiene particularidades de su función objetivo y la forma de optimizarla. Posteriormente profundizaremos en esto.
La implementación de los algoritmos al problema se hará por medio del dataset de entrenamiento, que corresponde al 70% del conjunto original. En cada caso se hará uso de los métodos de entrenamiento:
- Cálculo de probabilidades condicionales con estimación gaussiana para el modelo de bayes ingenuo.
- Estimación de valores $\theta_i$ en regresión logística con algoritmo de gradiente descendiente con un número máximo de 10000 iteraciones.
- Construcción de árbol de decisión con algoritmo ID3 usando impureza de Gini.
#Entrenamiento de bayes naïve
bayes_model.fit(x_train, y_train)
#Entrenamiento de regresión logística
logit_model.fit(x_train, y_train)
#Entrenamiento de árbol de decisión
tree_model.fit(x_train, y_train)
DecisionTreeClassifier()In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook.
On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.
DecisionTreeClassifier()
El modelo de aprendizaje se almacena en la clase del modelo. Procedemos entonces a evaluar.
4. Evaluación de resultados¶
La evaluación consiste en determinar qué tan bien generaliza el modelo en datos nuevos. Podemos distinguir diferentes tipos de evaluación según el tipo de problema; en este caso, usaremos una evaluación supervisada: es decir, ya que contamos con las clases o salidas que esperamos del algoritmo, comparamos estos valores con los valores arrojados por el modelo. En este caso, usamos 3 de las métricas más populares para hacer evaluación supervisada (basadas en matriz de confusión). Para evaluar los resultados utilizamos, entonces, las métricas usuales:
- Precisión: $$Prec = \frac{TP}{TP+TN}$$
- Exhaustividad: $$Rec = \frac{TP}{TP+FN}$$
- Métrica F1: $$F_1 = \frac{2 Prec*Rec}{Prec + Rec}$$
Donde $TP$ son los verdaderos positivos y $TN$ los verdaderos negativos. Además, reportamos los promedios macro y pesado.
- Macro-Promedio: $\frac{1}{|C|}\sum_{c\in C} m(y, \hat{y})$
- Promedio ponderado: $\sum_{c \in C} p(c) m(y_c, \hat{y})$
Donde $m$ es una métrica (precisión, recall, $F_1$) y $C$ es el conjunto de clases y $p(c)$ es la probabilidad de la clase $c$.
bayes_pred = bayes_model.predict(x_test)
logit_pred = logit_model.predict(x_test)
tree_pred = tree_model.predict(x_test)
Para el modelo de bayes ingenuo tenemos los siguientes resultados:
from sklearn.metrics import classification_report
print('\t Resultados del modelo de Bayes Naïve')
print(classification_report(y_test, bayes_pred))
Resultados del modelo de Bayes Naïve precision recall f1-score support 0 0.98 0.91 0.95 68 1 0.94 0.99 0.97 103 accuracy 0.96 171 macro avg 0.96 0.95 0.96 171 weighted avg 0.96 0.96 0.96 171
Para el modelo de regresión logística los resultados son:
print('\t Resultados del modelo de Regresión logística')
print(classification_report(y_test, logit_pred))
Resultados del modelo de Regresión logística precision recall f1-score support 0 0.98 0.94 0.96 68 1 0.96 0.99 0.98 103 accuracy 0.97 171 macro avg 0.97 0.97 0.97 171 weighted avg 0.97 0.97 0.97 171
Finalmente para el modelo de árboles de decisión tenemos:
print('\t Resultados del modelo de Árbol de decisión')
print(classification_report(y_test, tree_pred))
Resultados del modelo de Árbol de decisión precision recall f1-score support 0 0.95 0.93 0.94 68 1 0.95 0.97 0.96 103 accuracy 0.95 171 macro avg 0.95 0.95 0.95 171 weighted avg 0.95 0.95 0.95 171
A partir de la evaluación realizada se pueden tener los siguientes resultados donde se comparan los tres modelos que se usaron. Las evaluaciones que se muestran son para la clase 1:
|Modelo | Accuracy |Precisión |Recall |F1 |---- |---- |---- |---- |---- |Bayes Naïve | 0.88| 0.90 | 0.92 | 0.91 |Regresión logística | 0.94 | 0.94 | 0.96 | 0.95 |Árboles de decisión | 0.89 | 0.92 | 0.91 | 0.92
Como se puede observar, en las evaluaciones se puede observar que el algoritmo con mejor desempeño es el de regresión logística.
5. Conclusiones¶
Los tres modelos comparados muestran diferencias. El modelo de bayes naïve y el de regresión logística son modelos paramétricos, pero que se diferencian en que el primero es generativo y el segundo discriminativo. El modelo de regresión logística se puede interpretar por los parámetros o pesos que asigna a cada rasgo. Estos son los siguientes:
logit_weights = pd.DataFrame(data=logit_model.coef_, index=['Peso'], columns=data.feature_names)
logit_weights.T
Peso | |
---|---|
mean radius | 0.603120 |
mean texture | 0.258638 |
mean perimeter | -0.269741 |
mean area | 0.021981 |
mean smoothness | -0.137305 |
mean compactness | -0.186978 |
mean concavity | -0.404731 |
mean concave points | -0.224105 |
mean symmetry | -0.250691 |
mean fractal dimension | -0.023903 |
radius error | -0.042581 |
texture error | 1.325039 |
perimeter error | 0.158698 |
area error | -0.106092 |
smoothness error | -0.020261 |
compactness error | 0.053716 |
concavity error | -0.030658 |
concave points error | -0.032026 |
symmetry error | -0.030462 |
fractal dimension error | 0.013386 |
worst radius | -0.282157 |
worst texture | -0.496638 |
worst perimeter | -0.114059 |
worst area | -0.005621 |
worst smoothness | -0.286519 |
worst compactness | -0.647771 |
worst concavity | -1.186630 |
worst concave points | -0.535546 |
worst symmetry | -0.688642 |
worst fractal dimension | -0.073242 |
Como se observa, el rasgo más resaltante para la clase cáncer es el de el error de textura radio promedio, así como la textura promedio o el peor radio.
En el caso de bayes naïve, como usamos un modelo gaussiano, obtenemos que los parámetros responden a la media y la varianza de cada uno de los rasgos:
bayes_weights = pd.DataFrame(data=bayes_model.theta_, index=['Media 0','Media 1'], columns=data.feature_names)
bayes_weights.T
Media 0 | Media 1 | |
---|---|---|
mean radius | 17.584931 | 12.194425 |
mean texture | 21.874931 | 18.002520 |
mean perimeter | 116.108819 | 78.454646 |
mean area | 988.871528 | 466.992520 |
mean smoothness | 0.101711 | 0.092745 |
mean compactness | 0.143611 | 0.082364 |
mean concavity | 0.159166 | 0.049430 |
mean concave points | 0.087917 | 0.027063 |
mean symmetry | 0.193123 | 0.174372 |
mean fractal dimension | 0.062312 | 0.063073 |
radius error | 0.620454 | 0.292748 |
texture error | 1.253738 | 1.233121 |
perimeter error | 4.419903 | 2.061406 |
area error | 74.055694 | 21.780244 |
smoothness error | 0.006814 | 0.007238 |
compactness error | 0.032312 | 0.022603 |
concavity error | 0.042059 | 0.027995 |
concave points error | 0.015451 | 0.010350 |
symmetry error | 0.020840 | 0.020749 |
fractal dimension error | 0.004071 | 0.003795 |
worst radius | 21.238264 | 13.431772 |
worst texture | 29.506319 | 23.515118 |
worst perimeter | 142.053750 | 87.470000 |
worst area | 1432.950694 | 563.537795 |
worst smoothness | 0.142171 | 0.124468 |
worst compactness | 0.360839 | 0.186753 |
worst concavity | 0.436403 | 0.172370 |
worst concave points | 0.181059 | 0.076066 |
worst symmetry | 0.320149 | 0.268840 |
worst fractal dimension | 0.089200 | 0.079726 |
bayes_sigma = pd.DataFrame(data=bayes_model.var_, index=['Sigma 0','Sigma 1'], columns=data.feature_names)
bayes_sigma.T
Sigma 0 | Sigma 1 | |
---|---|---|
mean radius | 9.243838 | 3.354453 |
mean texture | 15.792803 | 16.686035 |
mean perimeter | 428.289779 | 147.513752 |
mean area | 119870.958049 | 19335.944947 |
mean smoothness | 0.000487 | 0.000493 |
mean compactness | 0.003446 | 0.001499 |
mean concavity | 0.006256 | 0.002603 |
mean concave points | 0.001537 | 0.000587 |
mean symmetry | 0.001221 | 0.000991 |
mean fractal dimension | 0.000383 | 0.000367 |
radius error | 0.105774 | 0.014956 |
texture error | 0.272527 | 0.326160 |
perimeter error | 5.812521 | 0.665053 |
area error | 3284.796505 | 88.735027 |
smoothness error | 0.000328 | 0.000328 |
compactness error | 0.000622 | 0.000622 |
concavity error | 0.000813 | 0.001697 |
concave points error | 0.000353 | 0.000355 |
symmetry error | 0.000424 | 0.000365 |
fractal dimension error | 0.000323 | 0.000329 |
worst radius | 17.608547 | 4.084838 |
worst texture | 31.879489 | 30.198517 |
worst perimeter | 835.636961 | 189.919082 |
worst area | 347501.956984 | 28274.913772 |
worst smoothness | 0.000838 | 0.000684 |
worst compactness | 0.025017 | 0.009289 |
worst concavity | 0.031426 | 0.023017 |
worst concave points | 0.002480 | 0.001581 |
worst symmetry | 0.006146 | 0.002135 |
worst fractal dimension | 0.000706 | 0.000514 |
Finalmente, los árboles de decisión generan un árbol binario donde cada nodo representa una característica y cada hijo responde a si cumple $x \leq f$ o no. De esta forma, el algoritmo decide al llegar a una hoja que corresponde a alguna de las clases.
from sklearn.tree import plot_tree
import matplotlib.pyplot as plt
plt.figure(figsize=(20,20))
plot_tree(tree_model)
plt.show()
En conclusión, para el problema planteado que consiste en la detección de cáncer a partir de la descripción de los tumores, el algoritmo que tuvo mejor desempeño fue la regresión logística. Esto se puede deber a que las descripciones son numéricas (radio, perímetro, textura) y la regresión logística maneja bien este tipo de datos, pues pondera los valores numéricos al multiplicarlos por pesos. Mientras que los árboles de decisión, por ejemplo, manejan mejor datos categóricos de respuesta sí o no. Asimismo, el modelo de Bayes Naïve controla los datos por medio de la media y la varianza. Parece entonces que ponderar estos datos multiplicándolos por un valor real tienen mejores resultados que otros métodos.