Ejemplo de Mineria de Datos.

 

Preparación de datos

A lo largo de esta práctica veremos como aplicar diferentes tecnicas para la carga y preparación de datos:

  1. Carga de un conjunto de datos
  2. Análisis de los datos
    2.1 Análisis estadístico básico
    2.2 Análisis expxloratorio de los datos
  3. Reducción de la dimensionalidad
  4. Entrenamiento y test

Para eso necesitaremos las siguientes librerías:

In [1]:
import numpy as np
import pandas as pd
import seaborn as sns
from sklearn import datasets
from sklearn.manifold import TSNE
from sklearn.decomposition import PCA
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, confusion_matrix
from sklearn.model_selection import train_test_split, cross_val_score

import matplotlib.pyplot as plt
import ssl

ssl._create_default_https_context = ssl._create_unverified_context


pd.set_option('display.max_columns', None)

%matplotlib inline

1. Carga del conjunto de datos

En primer lugar, debéis cargar el conjunto de datos Wine recognition (más información en el enlace https://archive.ics.uci.edu/ml/datasets/Wine). Se puede descargar de internet o se puede cargar directamente desde la librería "scikit-learn", que incorpora un conjunto de datasets muy conocidos y usados para la minería de datos y machine learning http://scikit-learn.org/stable/datasets/index.html.

Ejercicio: Cargad el conjunto de datos "Wine Recognition" y mostrad:
- el número y nombre de los atributos (variables que podrían ser usadas para predecir la respuesta "wine_class")
- el número de filas del conjunto de datos
- verificad si hay o no "missing values" y en que columnas
Sugerencia: Si usáis sklearn (sklearn.datasets.load_wine), explorad las diferents 'keys' del objecto obtenido. Sugerencia: Igual os resulta útil pasar los datos (atributos + target) a un dataframe de pandas.
In [2]:
from sklearn.datasets import load_wine
data = load_wine()
df = pd.DataFrame(data.data, columns=data.feature_names)
df['classes'] = pd.Categorical.from_codes(data.target, data.target_names)
print("Primer análisis de los datos")
df.head()
Primer análisis de los datos
Out[2]:
alcoholmalic_acidashalcalinity_of_ashmagnesiumtotal_phenolsflavanoidsnonflavanoid_phenolsproanthocyaninscolor_intensityhueod280/od315_of_diluted_winesprolineclasses
014.231.712.4315.6127.02.803.060.282.295.641.043.921065.0class_0
113.201.782.1411.2100.02.652.760.261.284.381.053.401050.0class_0
213.162.362.6718.6101.02.803.240.302.815.681.033.171185.0class_0
314.371.952.5016.8113.03.853.490.242.187.800.863.451480.0class_0
413.242.592.8721.0118.02.802.690.391.824.321.042.93735.0class_0
In [3]:
print("Descripción de los datos")
df.describe()
Descripción de los datos
Out[3]:
alcoholmalic_acidashalcalinity_of_ashmagnesiumtotal_phenolsflavanoidsnonflavanoid_phenolsproanthocyaninscolor_intensityhueod280/od315_of_diluted_winesproline
count178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000
mean13.0006182.3363482.36651719.49494499.7415732.2951122.0292700.3618541.5908995.0580900.9574492.611685746.893258
std0.8118271.1171460.2743443.33956414.2824840.6258510.9988590.1244530.5723592.3182860.2285720.709990314.907474
min11.0300000.7400001.36000010.60000070.0000000.9800000.3400000.1300000.4100001.2800000.4800001.270000278.000000
25%12.3625001.6025002.21000017.20000088.0000001.7425001.2050000.2700001.2500003.2200000.7825001.937500500.500000
50%13.0500001.8650002.36000019.50000098.0000002.3550002.1350000.3400001.5550004.6900000.9650002.780000673.500000
75%13.6775003.0825002.55750021.500000107.0000002.8000002.8750000.4375001.9500006.2000001.1200003.170000985.000000
max14.8300005.8000003.23000030.000000162.0000003.8800005.0800000.6600003.58000013.0000001.7100004.0000001680.000000
In [4]:
print("El número de líneas es: " + str(df.shape[0]) + " y el número de columnas: "+ str(df.shape[1]))
El número de líneas es: 178 y el número de columnas: 14
In [5]:
print("No existe ningún null")

df.isnull().sum()
No existe ningún null
Out[5]:
alcohol                         0
malic_acid                      0
ash                             0
alcalinity_of_ash               0
magnesium                       0
total_phenols                   0
flavanoids                      0
nonflavanoid_phenols            0
proanthocyanins                 0
color_intensity                 0
hue                             0
od280/od315_of_diluted_wines    0
proline                         0
classes                         0
dtype: int64

2. Análisis de los datos

2.1 Análisis estadístico básico

Ejercicio: Realizad un análisis estadístico básico:
- Variables categóricas: - Calculad la frecuencia. - Haced un gráfico de barras.
- Variables numéricas: - Calculad estadísticos descriptivos básicos: media, mediana, desviación estandard, ... - Haced un histograma de las variables: alcohol, magnesium y color_intensity
Sugerencia: podéis usar la librería 'pandas' y sus funciones 'describe' y 'value_counts'
In [6]:
print('Cálculo de la frecuéncia')
cols = df.columns
num_cols_no_categoric = df._get_numeric_data().columns

col_categoric=list(set(cols) - set(num_cols_no_categoric))
print("Frecuéncia")
print( pd.value_counts(df[col_categoric].values.flatten()))
frecuencia_data =pd.value_counts(df[col_categoric].values.flatten())

sns.catplot(x="classes", kind="count", palette="ch:.25", data=df);
Cálculo de la frecuéncia
Frecuéncia
class_1    71
class_0    59
class_2    48
dtype: int64
In [7]:
print("Estadísticos descriptivos básicos:")
df[num_cols_no_categoric].describe()
Estadísticos descriptivos básicos:
Out[7]:
alcoholmalic_acidashalcalinity_of_ashmagnesiumtotal_phenolsflavanoidsnonflavanoid_phenolsproanthocyaninscolor_intensityhueod280/od315_of_diluted_winesproline
count178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000178.000000
mean13.0006182.3363482.36651719.49494499.7415732.2951122.0292700.3618541.5908995.0580900.9574492.611685746.893258
std0.8118271.1171460.2743443.33956414.2824840.6258510.9988590.1244530.5723592.3182860.2285720.709990314.907474
min11.0300000.7400001.36000010.60000070.0000000.9800000.3400000.1300000.4100001.2800000.4800001.270000278.000000
25%12.3625001.6025002.21000017.20000088.0000001.7425001.2050000.2700001.2500003.2200000.7825001.937500500.500000
50%13.0500001.8650002.36000019.50000098.0000002.3550002.1350000.3400001.5550004.6900000.9650002.780000673.500000
75%13.6775003.0825002.55750021.500000107.0000002.8000002.8750000.4375001.9500006.2000001.1200003.170000985.000000
max14.8300005.8000003.23000030.000000162.0000003.8800005.0800000.6600003.58000013.0000001.7100004.0000001680.000000
In [8]:
print("Histograma de las variables: alcohol")

graf1  = sns.distplot(df['alcohol'],kde=0)
Histograma de las variables: alcohol
In [9]:
print("Histograma de las variables: color_intensity")
graf3  = sns.distplot(df['color_intensity'],kde=0,color="red")
Histograma de las variables: color_intensity
In [10]:
print("Histograma de las variables: magnesium")
graf2  = sns.distplot(df['magnesium'],kde=0,color="green")
Histograma de las variables: magnesium
Análisis: Comentad los resultados.

Respecto al target, la clase de vino, cabe destacar que el número de elementos está distribuido equitativamente entre los 3 tipos de vino, es decir, no tenemos una gran cantidad del tipo1 y muy poca del resto que complicaria las tareas de clasificación.

También es posible analizar como el alcohol es el elemento más distribuido de las tres gráficas, es decir, tenemos una gran cantidad de muestras diferentes lo que me hace deducir que será una variable dificil de utilizar para la clasificación. En otro sentido, el color de la intensidad se agrupa más y el magnesio esta muy agrupado alrededor de 90.

2.2 Análisis exploratorio de los datos

En este ejercicio exploraremos la relación de algunos de los atributos numéricos con la variable respuesta ("wine_class"), tanto gráficamente como cualitativamente, y analizaremos las diferentes correlaciones. Para empezar, seleccionaremos solo 3 atributos para explorar: alcohol, magnesium y color_intensity.

In [11]:
feats_to_explore = ['alcohol', 'magnesium', 'color_intensity']
Ejercicio: Usando una librería gráfica, como por ejemplo "matplotlib", realizad un gráfico del histograma de valores para cada uno de los atributos seleccionados, separados por los valores de la clase respuesta. Los tres gráficos tienen que estar sobrepuestos, es decir, por ejemplo, en el histograma de la feature "alcohol" tienen que haber en un solo gráfico tres histogramas, uno por cada clase de vino. Añadid una leyenda para saber a que clase corresponde cada histograma. La finalidad es observar como se distribuye cada uno de los atributos en función de la clase que tengan, para poder identificar de manera visual y rápida si algunos atributos permiten diferenciar de forma clara las diferentes clases de vinos.
Sugerencia: podéis usar el parámetro "alpha" en los gráficos para que se aprecien los tres histogramas.
In [12]:
for i in [0,1,2]:
    sns.distplot(df['alcohol'][data.target==i],
                 kde=False,label='{
                }'.format(i))

plt.legend()
Out[12]:
<matplotlib.legend.Legend at 0x1246dcf98>
In [13]:
for i in [0,1,2]:
    sns.distplot(df['color_intensity'][data.target==i],kde=False,label='{}'.format(i))

plt.legend()
Out[13]:
<matplotlib.legend.Legend at 0x105b58898>
In [14]:
for i in [0,1,2]:
    sns.distplot(df['magnesium'][data.target==i],kde=False,
                 label='{
                }'.format(i))

plt.legend()
Out[14]:
<matplotlib.legend.Legend at 0x105b6bfd0>
Análisis:
Mirando los histogramas, ¿que atributo parece tener más peso a la hora de clasificar un vino? ¿Cual parece tener menos peso?

La intensidad del color, mientras qeu el de menor peso el magnesium. Realmente el color esta más agrupado y diferenciado que el resto.

Ejercicio: Usando los histogramas anteriores, añadid una linia vertical indicando la media de cada uno de los histogramas (tres por gráfico). Pintad las linias del mismo color que el histograma para que quede claro a cual hacen referencia. Añadid a la leyenda, la clase de vino y la desviación estandard en cuestión. La finalidad es verificar numéricamente las diferencias identificadas anteriormente de forma visual.
Sugerencia: podeis usar "axvline", de matplotlib axis, para las linias verticales.
In [15]:
for i in [0,1,2]:
    std = round(df["alcohol"][data.target==i].std(),3)
    sns.distplot(df['alcohol'][data.target==i],
                 kde=1,label='{} con std {}'.format(i,std))

plt.legend()
Out[15]:
<matplotlib.legend.Legend at 0x125295dd8>
In [16]:
for i in [0,1,2]:
    std = round(df["color_intensity"][data.target==i].std(),3)
    sns.distplot(df['color_intensity'][data.target==i],
                 kde=1,label='{} con std {}'.format(i,std))

plt.legend()
Out[16]:
<matplotlib.legend.Legend at 0x1274e4048>
In [17]:
for i in [0,1,2]:
    std = round(df["magnesium"][data.target==i].std(),3)
    sns.distplot(df['magnesium'][data.target==i],
                 kde=1,label='{} con std {}'.format(i,std))

plt.legend()
Out[17]:
<matplotlib.legend.Legend at 0x127615748>
Ejercicio: Calculad y mostrad la correlación entre las tres variables que estamos analizando.
In [18]:
fig, (ax) = plt.subplots(1, 1, figsize=(10,6))
corr = df[feats_to_explore].corr()

hm = sns.heatmap(corr,
                 ax=ax,           # Axes in which to draw the plot, otherwise use the currently-active Axes.
                 cmap="coolwarm", # Color Map.
                 #square=True,    # If True, set the Axes aspect to “equal” so each cell will be square-shaped.
                 annot=True,
                 fmt='.2f',       # String formatting code to use when adding annotations.
                 #annot_kws={"size": 14},
                 linewidths=.05)

fig.subplots_adjust(top=0.93)
fig.suptitle('Wine Attributes Correlation Heatmap',
              fontsize=14,
              fontweight='bold')
Out[18]:
Text(0.5, 0.98, 'Wine Attributes Correlation Heatmap')
Ejercicio: Representad gráficamente las relaciones entre estas variables (scatterplots). Diferenciad con colores diferentes las diferentes clases. La finalidad es poder observar y analizar las correlaciones de manera gráfica entre algunas de las variables.
Sugerencia: podéis usar la función "pairplot" de la librería 'seaborn' con el parámetro "hue".
In [19]:
feats_to_explore.append("classes")
sns.pairplot( hue="classes", data= df[feats_to_explore])
Out[19]:
<seaborn.axisgrid.PairGrid at 0x1277a1198>
Análisis:
Observando las correlaciones, que variables son las que tienen una correlación más fuerte? Cuadra el resultado numérico con el gráfico obtenido?

Sip, cuadra que el color y el alcohol tiene una dsitribución de los datos mucho más clara que el resto (tercer nivel izquierda). También en el gráfico de correlación aparecia el valor más elevado lo que confirma la información visualizada.

3. Reducción de la dimensionalidad

En este ejercicio se aplicarán métodos de reducción de la dimensionalidad al conjunto original de datos. El objetivo es reducir el conjunto de atributos a un nuevo conjunto con menos dimensiones. Así en vez de trabajar con 3 variables elegidas al azahar, usaremos la información de todos los atributos.

Ejercicio: Aplicad el método de reducción de la dimensionalidad Principal Component Analysis (PCA) para reducir a 2 dimensiones (el dataset entero con todas las features). Generad un gráfico (en 2D) con el resultado del PCA usando colores diferentes para cada una de las clases de la respuesta (wine_class), con el objetivo de visualizar si es posible separar eficientemente las clases con este método. NOTA: Vigilad de no incluir la variable objetivo "wine class" a la reducción de dimensionalidad. Queremos poder explicar la variable objetivo en funcion del resto de variables reducidas a dos dimensiones.
Sugerencia: No es necesario que programéis el algoritmo, podéis usar la implementación disponible en la librería de "scikit-learn".
In [20]:
from sklearn.preprocessing import StandardScaler

features = data.feature_names
# Separating out the features
x = df.loc[:, features].values
# Separating out the target
y = df.loc[:,['classes']].values
# Standardizing the features
x = StandardScaler().fit_transform(x)

from sklearn.decomposition import PCA
pca = PCA(n_components=2)
principalComponents = pca.fit_transform(x)
principalDf = pd.DataFrame(data = principalComponents
             , columns = ['principal component 1', 'principal component 2'])
principalDf
Out[20]:
principal component 1principal component 2
03.316751-1.443463
12.2094650.333393
22.516740-1.031151
33.757066-2.756372
41.008908-0.869831
.........
173-3.370524-2.216289
174-2.601956-1.757229
175-2.677839-2.760899
176-2.387017-2.297347
177-3.208758-2.768920

178 rows × 2 columns

In [21]:
finalDf = pd.concat([principalDf, df[['classes']]], axis = 1)
finalDf
Out[21]:
principal component 1principal component 2classes
03.316751-1.443463class_0
12.2094650.333393class_0
22.516740-1.031151class_0
33.757066-2.756372class_0
41.008908-0.869831class_0
............
173-3.370524-2.216289class_2
174-2.601956-1.757229class_2
175-2.677839-2.760899class_2
176-2.387017-2.297347class_2
177-3.208758-2.768920class_2

178 rows × 3 columns

In [22]:
fig = plt.figure(figsize = (8,8))
ax = fig.add_subplot(1,1,1)
ax.set_xlabel('Principal Component 1', fontsize = 15)
ax.set_ylabel('Principal Component 2', fontsize = 15)
ax.set_title('2 component PCA', fontsize = 20)
targets = ['class_0', 'class_1', 'class_2']
colors = ['r', 'g', 'b']
for target, color in zip(targets,colors):
    indicesToKeep = finalDf['classes'] == target
    ax.scatter(finalDf.loc[indicesToKeep, 'principal component 1']
               , finalDf.loc[indicesToKeep, 'principal component 2']
               , c = color
               , s = 50)
ax.legend(targets)
ax.grid()
Ejercicio: Repetid la reducción de dimensionalidad, pero en este caso usando TSNE. Podeis encontrar más información sobre este algoritmo al link: [https://distill.pub/2016/misread-tsne/](https://distill.pub/2016/misread-tsne/) Igual que antes, generad un gráfico (en 2D) con el resultado del PCA usando colores diferentes para cada una de las clases de la respuesta (wine_class), con el objetivo de visualizar si es posible separar eficientemente las clases con este método.
Sugerencia: No es necesario que programéis el algoritmo, podéis usar la implementación disponible en la librería de "scikit-learn". Sugerencia: A parte de especificar el número de componentes, probad de usar el parámetro "perplexity".
In [23]:
features = data.feature_names
# Separating out the features
x = df.loc[:, features].values
y=data.target
from sklearn.manifold import TSNE

tsne_results = TSNE(n_components=2).fit_transform(x)

target_ids = range(len([0,1,2]))


from matplotlib import pyplot as plt
colors = 'r', 'g', 'b', 'c', 'm', 'y', 'k', 'w', 'orange', 'purple'
for i, c, label in zip(target_ids, colors, [0,1,2]):
    plt.scatter(tsne_results[y == i, 0], tsne_results[y == i, 1], c=c, label=label)
plt.legend()
plt.show()


sns.scatterplot(tsne_results[:,0], tsne_results[:,1], hue=y, legend='full')
Out[23]:
<matplotlib.axes._subplots.AxesSubplot at 0x127690780>
Análisis:
Observando los dos gráficos, ¿crees que ha funcionado bien la reducción de dimensionalidad? ¿Ha conseguido separar las clases correctamente? ¿Cual de los dos métodos ha funcionado mejor? ¿Por que obtenemos resultados tan diferentes?

Si, creo que ha funcionado correctamente en el primer caso. Utilizando el PCA he conseguido observar de forma nítida la distribución del dataset en 3 clases de vinos mientras que en el segundo se entremezclan más y cuesta más diferenciarlos.

Los resultados son diferentes ya que los algoritmos están optimizados para diferentes dataset. Mientras que el PCA es muy útil para dataset con caracteristicas similares entre clases el TSNE es para todo lo contrario.

4. Entrenamiento y test

En este último ejercicio se trata de aplicar un método de aprendizaje supervisado, concretamente el clasificador Random Forest, para predecir la clase a la que pertenece cada vino y evaluar la precisión obtenida con el modelo. Para eso usaremos:

- El conjunto de datos original con todos los atributos
- El conjunto de datos reducido a solo 2 atributos con PCA
- El conjunto de datos reducido a solo 2 atributos con TSNE
Ejercicio: Usando el conjunto de datos original: - Dividid el dataset en train y test. - Definid un modelo Random Forest (fijando n_estimators=10 para mantener el modelo simple). - Aplicad validación cruzada con el modelo definido y el dataset de train (con cv=5 ya es suficiente). - Calculad la media y la desviación standard de la validación cruzada.
Sugerencia: Para separar entre train y test podéis usar train_test_split de sklearn. Sugerencia: Para entrenar un modelo random forest podéis usar 'RandomForestClassifier' de sklearn. Sugerencia: Para aplicar validación cruzada podéis usar 'cross_val_score' de sklearn.
Ejercicio: Repetid el mismo procedimiento que en el ejercicio anterior con el dataset reducido a 2 dimensiones con PCA.
Ejercicio: Repetid el mismo procedimiento que en el ejercicio anterior con el dataset reducido a 2 dimensiones con TSNE.
In [26]:
# Spot Check Algorithms
train_data = []

from sklearn.ensemble import RandomForestClassifier



features = data.feature_names
# Separating out the features
x = df.loc[:, features].values
from sklearn.manifold import TSNE

tsne_results = TSNE(n_components=2).fit_transform(x)

from sklearn.model_selection import train_test_split

# Separating out the features

train_data.append(('Completo',df.loc[:, features].values))
train_data.append((' 2 dimensiones con PCA.',principalDf))
train_data.append(('2 dimensiones con TSNE.',tsne_results))


# Separating out the target
df['classes'] = data.target

y = df['classes']


from sklearn import preprocessing
y = preprocessing.label_binarize(y, classes=[0,1, 2])

# Split the data into training and testing sets



# evaluate each model in turn
names = []
for name, x in train_data:
    print('*******')
    print(name)
    train_features, test_features, train_labels, test_labels = train_test_split(x, y, test_size = 0.25, random_state = 42)
    print('Training Features Shape:', train_features.shape)
    print('Training Labels Shape:', train_labels.shape)
    print('Testing Features Shape:', test_features.shape)
    print('Testing Labels Shape:', test_labels.shape)
    rf = RandomForestClassifier(n_estimators = 10)
    cv_results = cross_val_score(rf, train_features, train_labels, cv=5, scoring='roc_auc')
    names.append(name)
    msg = "%s:  %f (%f)" % (name, cv_results.mean(), cv_results.std())
    print(msg)
*******
Completo
Training Features Shape: (133, 13)
Training Labels Shape: (133, 3)
Testing Features Shape: (45, 13)
Testing Labels Shape: (45, 3)
Completo:  0.992782 (0.007549)
*******
 2 dimensiones con PCA.
Training Features Shape: (133, 2)
Training Labels Shape: (133, 3)
Testing Features Shape: (45, 2)
Testing Labels Shape: (45, 3)
 2 dimensiones con PCA.:  0.992468 (0.005299)
*******
2 dimensiones con TSNE.
Training Features Shape: (133, 2)
Training Labels Shape: (133, 3)
Testing Features Shape: (45, 2)
Testing Labels Shape: (45, 3)
2 dimensiones con TSNE.:  0.842401 (0.031264)
Análisis: ¿Con que datos ha funcionado mejor? ¿Tiene sentido? ¿Cuadra con los resultados que hemos visto en el ejercicio 3?
MedidasCompletoPCATSNE
Media0.9924680.9927820.809156
Std0.0143360.0110730.036769

Ha funcionado mejor con PCA, aunque con el completo también tiene muy buen resultdo. Cuadra con los resultados del ejercicio anterior y por lo tanto tiene sentido.

Ejercicio: Con el mejor modelo que hayáis obtenido: - Generad predicciones sobre el dataset de test. - Calculad la precisión de las predicciones obtenidas y la matriz de confusión asociada.
Sugerencia: Para calcular la precisión y la matriz de confusión podéis usar las funciones dentro del módulo "metrics" de sklearn.
In [27]:
x=df.loc[:, features].values

x=principalDf

y = preprocessing.label_binarize(y, classes=[0,1, 2])
train_features, test_features, train_labels, test_labels = train_test_split(x, y, test_size = 0.25, random_state = 42)

# Import the model we are using
from sklearn.ensemble import RandomForestClassifier
# Instantiate model with 1000 decision trees
rf = RandomForestClassifier(n_estimators = 10)
# Train the model on training data
rf.fit(train_features, train_labels);

# Use the forest's predict method on the test data
predictions = rf.predict(test_features)


import matplotlib.pyplot as plt

from sklearn.metrics import confusion_matrix
CM =  confusion_matrix( test_labels.argmax(axis=1), predictions.argmax(axis=1))


# Visualize it as a heatmap
import seaborn
seaborn.heatmap(CM, annot=True, fmt="d")
plt.show()
Ejercicio: El modelo random forest depende de muchos parámetros. En este ejercicio solo hemos especificado el número de estimadores (n_estimators) y hemos dejado que usara el resto de parámetros por defecto. Dos parámetros muy útiles en los random forest (y en cualquier modelo que use árboles) son el max_depth y el min_samples_split. Estos parámetros ayudan a controlar el overfitting. Entrenad los modelos anteriores usando diferentes combinaciones de los parámetros: - n_estimators - max_depth - min_samples_split ¿Has conseguido mejorar el modelo? ¿Como ha ayudado cada parámetro a mejorarlo, es decir, cuál es la finalidad de cada uno de ellos?
  • n_estimators: Número de árboles generados.
  • max_depth: Profundidad de los árboles.
  • min_samples_split: Número de casos necesarios para dividir un nodo.
In [41]:
test = [10,50,100,200]
conf = ['n_estimators','max_depth','min_samples_split']

x=df.loc[:, features].values

x=principalDf

y = preprocessing.label_binarize(y, classes=[0,1, 2])
train_features, test_features, train_labels, test_labels = train_test_split(x, y, test_size = 0.25, random_state = 42)

# Import the model we are using
from sklearn.ensemble import RandomForestClassifier
# Instantiate model with 1000 decision trees

for num in test:
        print('*******')
        print('n_estimators' + str(num))
        rf = RandomForestClassifier(n_estimators = num)
        cv_results = cross_val_score(rf, train_features, train_labels, cv=5, scoring='roc_auc')
        names.append(name)
        msg = "%s:  %f (%f)" % (name, cv_results.mean(), cv_results.std())
        print(msg)



for num in test:
        print('*******')
        print('max_depth' + str(num))
        rf = RandomForestClassifier(max_depth = num)
        cv_results = cross_val_score(rf, train_features, train_labels, cv=5, scoring='roc_auc')
        names.append(name)
        msg = "%s:  %f (%f)" % (name, cv_results.mean(), cv_results.std())
        print(msg)



for num in test:
        print('*******')
        print('min_samples_split' + str(num))
        rf = RandomForestClassifier(min_samples_split = num)
        cv_results = cross_val_score(rf, train_features, train_labels, cv=5, scoring='roc_auc')
        names.append(name)
        msg = "%s:  %f (%f)" % (name, cv_results.mean(), cv_results.std())
        print(msg)
*******
n_estimators10
min_samples_split:  0.989470 (0.012881)
*******
n_estimators50
min_samples_split:  0.987855 (0.014393)
*******
n_estimators100
min_samples_split:  0.990644 (0.009293)
*******
n_estimators200
min_samples_split:  0.991977 (0.007641)
*******
max_depth10
min_samples_split:  0.992803 (0.005915)
*******
max_depth50
min_samples_split:  0.993425 (0.005470)
*******
max_depth100
min_samples_split:  0.994343 (0.004828)
*******
max_depth200
min_samples_split:  0.992940 (0.007179)
*******
min_samples_split10
min_samples_split:  0.989566 (0.006284)
*******
min_samples_split50
min_samples_split:  0.978533 (0.010368)
*******
min_samples_split100
min_samples_split:  0.500000 (0.000000)
*******
min_samples_split200
min_samples_split:  0.500000 (0.000000)

Por una parte se observa que el aumento de valor de las variables n_estimators y max_depth generán más precisión a costa de mayor coste computacional. Por el contrario, el aumento de min_samples_split supone una disminución de la eficacia del algoritmo y mayor rapidez de ejecución.