0% encontró este documento útil (0 votos)
5 vistas14 páginas

Clasificación de Compras con Árboles de Decisión

El documento describe la aplicación de modelos de árboles de decisión y bosques aleatorios para predecir compras basadas en un conjunto de datos ficticio con características demográficas. Se detalla el proceso de preprocesamiento, entrenamiento, evaluación y visualización de los modelos, incluyendo la validación cruzada y la importancia de las características. Finalmente, se comparan los resultados de ambos modelos en términos de precisión y se visualizan las características más importantes.

Cargado por

leonardo
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd
0% encontró este documento útil (0 votos)
5 vistas14 páginas

Clasificación de Compras con Árboles de Decisión

El documento describe la aplicación de modelos de árboles de decisión y bosques aleatorios para predecir compras basadas en un conjunto de datos ficticio con características demográficas. Se detalla el proceso de preprocesamiento, entrenamiento, evaluación y visualización de los modelos, incluyendo la validación cruzada y la importancia de las características. Finalmente, se comparan los resultados de ambos modelos en términos de precisión y se visualizan las características más importantes.

Cargado por

leonardo
Derechos de autor
© All Rights Reserved
Nos tomamos en serio los derechos de los contenidos. Si sospechas que se trata de tu contenido, reclámalo aquí.
Formatos disponibles
Descarga como PDF, TXT o lee en línea desde Scribd

tree_rf_classifier

September 23, 2025

1 Aplicación de los modelos de árboles de decisión (Decision Tree)


y bosques aleatorios (Random Forest)
El dataset ficticio utilizado cuenta con características (edad, salario, nivel educativo, etc) el cual
determinan que personas realizan compras.
[5]: # funciones generales
import pandas as pd
import numpy as np
import [Link] as plt

# creación y entrenamiento del modelo


from [Link] import DecisionTreeClassifier
from sklearn.model_selection import train_test_split
from [Link] import OneHotEncoder, StandardScaler
from [Link] import ColumnTransformer
from [Link] import Pipeline

# evaluación del modelo


from [Link] import accuracy_score, confusion_matrix,␣
↪classification_report, ConfusionMatrixDisplay

[6]: df = pd.read_csv('../datas/[Link]')
[Link]()

[6]: Edad Salario NivelEducativo Genero Ciudad Hijos TipoEmpleo \


0 58 34592 Primaria Mujer North Judithbury 1 Autónomo
1 65 33434 Primaria Mujer East Jill 0 Empleado
2 31 50495 Primaria Hombre New Roberttown 4 Empresario
3 46 97236 Universitario Hombre East Jessetown 1 Empresario
4 39 56421 Secundaria Hombre Lake Debra 2 Empleado

Compra
0 0
1 0
2 0
3 1

1
4 0

[7]: # revisando el balance de los valores de la variable objetivo


[Link].value_counts()

[7]: Compra
1 3764
0 1236
Name: count, dtype: int64

[8]: # definiendo las caracteristicas categoricas y numericas y las variables␣


↪independientes y dependientes

categorical_features = ['NivelEducativo','Genero','TipoEmpleo']
numeric_features = [Link](columns=['Compra','Ciudad'] + categorical_features).
↪columns.to_list()

X = [Link](columns=['Compra','Ciudad'], axis=1)
y = df['Compra']

balanceo de los datos con respecto de la clase minoritaria


[9]: # balanceo de los datos con respecto de la variable objetivo
from imblearn.under_sampling import RandomUnderSampler

ros = RandomUnderSampler(random_state=42)
X_under, y_under = ros.fit_resample(X, y)

X_under.shape, y_under.shape

[9]: ((2472, 6), (2472,))

[10]: # separación de los datos de entrenamiento y de prueba


# El parámetro stratify se utiliza para asegurar que las proporciones de las␣
↪clases en los

# conjuntos de entrenamiento y prueba sean las mismas que en el conjunto de␣


↪datos original.

X_train, X_test, y_train, y_test = train_test_split(X_under, y_under,


test_size=0.3,
random_state=42,
stratify=y_under)

# Imprimir tamaños resultantes


print('Tamaño del set de entrenamiento: ', X_train.shape, y_train.shape)
print('Tamaño del set de prueba: ', X_test.shape, y_test.shape)

# Distribución de categorías

2
print('Distribución de las categorías dataset original: ', y.
↪value_counts(normalize=True))

print('Distribución de las categorías dataset de entrenamiento: ', y_train.


↪value_counts(normalize=True))

print('Distribución de las categorías dataset de prueba: ', y_test.


↪value_counts(normalize=True))

Tamaño del set de entrenamiento: (1730, 6) (1730,)


Tamaño del set de prueba: (742, 6) (742,)
Distribución de las categorías dataset original: Compra
1 0.7528
0 0.2472
Name: proportion, dtype: float64
Distribución de las categorías dataset de entrenamiento: Compra
0 0.5
1 0.5
Name: proportion, dtype: float64
Distribución de las categorías dataset de prueba: Compra
0 0.5
1 0.5
Name: proportion, dtype: float64

2 Construcción del pipeline que incluye un codificador de variables


categóricas (OneHotEncoder), un escalador de características
numéricas (StandardScaler) y el modelo de árbol de decisión.
[11]: # se aplicar diferentes transformaciones a diferentes columnas de un conjunto␣
↪de datos.

preprocessor = ColumnTransformer(
transformers=[
('cat', OneHotEncoder(), categorical_features),
('num', StandardScaler(), numeric_features)
]
)

preprocessor

[11]: ColumnTransformer(transformers=[('cat', OneHotEncoder(),


['NivelEducativo', 'Genero', 'TipoEmpleo']),
('num', StandardScaler(),
['Edad', 'Salario', 'Hijos'])])

[12]: # creacion del pipeline con el preprocesamiento y modelo


# max_depth: profundidad máxima del árbol.
# min_samples_leaf: número mínimo de muestras que debe tener un nodo hoja.

3
pipeline = Pipeline([
('preprocessor', preprocessor),
('clf', DecisionTreeClassifier(max_depth=5,
min_samples_leaf=4,
random_state=42))
])

pipeline

[12]: Pipeline(steps=[('preprocessor',
ColumnTransformer(transformers=[('cat', OneHotEncoder(),
['NivelEducativo', 'Genero',
'TipoEmpleo']),
('num', StandardScaler(),
['Edad', 'Salario',
'Hijos'])])),
('clf',
DecisionTreeClassifier(max_depth=5, min_samples_leaf=4,
random_state=42))])

[13]: # ajustar el pipeline a los datos de entrenamiento


[Link](X_train, y_train)

[13]: Pipeline(steps=[('preprocessor',
ColumnTransformer(transformers=[('cat', OneHotEncoder(),
['NivelEducativo', 'Genero',
'TipoEmpleo']),
('num', StandardScaler(),
['Edad', 'Salario',
'Hijos'])])),
('clf',
DecisionTreeClassifier(max_depth=5, min_samples_leaf=4,
random_state=42))])

demostración de la transformacion de los datos de entrenamiento


[14]: # nombres de las columnas categóricas transformadas
cat_columns = preprocessor.named_transformers_['cat'].
↪get_feature_names_out(categorical_features)

X_train_transformed = preprocessor.fit_transform(X_train)
feature_names = [Link]([cat_columns, numeric_features])
X_train_transformed_df = [Link](X_train_transformed,␣
↪columns=feature_names)

X_train_transformed_df.head()

4
[14]: NivelEducativo_Postgrado NivelEducativo_Primaria \
0 1.0 0.0
1 0.0 0.0
2 1.0 0.0
3 0.0 0.0
4 0.0 1.0

NivelEducativo_Secundaria NivelEducativo_Universitario Genero_Hombre \


0 0.0 0.0 1.0
1 0.0 1.0 0.0
2 0.0 0.0 0.0
3 1.0 0.0 1.0
4 0.0 0.0 0.0

Genero_Mujer TipoEmpleo_Autónomo TipoEmpleo_Desempleado \


0 0.0 1.0 0.0
1 1.0 1.0 0.0
2 1.0 0.0 0.0
3 0.0 0.0 0.0
4 1.0 0.0 0.0

TipoEmpleo_Empleado TipoEmpleo_Empresario Edad Salario Hijos


0 0.0 0.0 -1.346692 -0.760248 -0.568180
1 0.0 0.0 -0.962029 1.764131 0.127469
2 0.0 1.0 0.576624 0.451312 -1.263830
3 1.0 0.0 -0.962029 -1.289537 -0.568180
4 1.0 0.0 0.191961 1.568257 -1.263830

[15]: # acceso al clasificador de árbol de decisión entrenado


tree_clf = pipeline.named_steps['clf']
tree_clf

[15]: DecisionTreeClassifier(max_depth=5, min_samples_leaf=4, random_state=42)

3 Evaluación del modelo


[16]: # StratifiedKFold: mantiene la misma proporción de clases que el conjunto de␣
↪datos original

# cross_val_score: evaluación del rendimiento del modelo mediante validación␣


↪cruzada.

from sklearn.model_selection import StratifiedKFold, cross_val_score

# configurar StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# realizar validación cruzada utilizando el pipeline

5
scores = cross_val_score(pipeline, X_train, y_train, cv=skf, scoring='accuracy')

# resultados de la validación cruzada


print("Puntuaciones de validación cruzada:", [Link](scores, 3))
print("Media de las puntuaciones:", [Link]([Link](), 3))

# resultado con el set de prueba


print("Resultado con el set de prueba:", [Link]([Link](X_test,␣
↪y_test),3))

Puntuaciones de validación cruzada: [0.798 0.815 0.809 0.786 0.795]


Media de las puntuaciones: 0.801
Resultado con el set de prueba: 0.809

4 Gráfico del árbol de decisiones


[17]: # visualización de un árbol de decisión
from [Link] import plot_tree

[Link](figsize=(35,7))

# gráfico del árbol de decisiones


plot_tree(tree_clf,
feature_names=feature_names, # usando los nombres de las columnas␣
↪transformadas

class_names=['No compra', 'Compra'],


filled=True,
rounded=True)

[Link]()

[18]: # profundidad del árbol y el número de hojas del árbol


print('Profundidad del árbol: ', tree_clf.get_depth())
print('Número de hojas del árbol: ', tree_clf.get_n_leaves())

Profundidad del árbol: 5


Número de hojas del árbol: 23

6
5 Visualización de las características importantes del modelo
[19]: features = [Link]({'feature': feature_names, 'importance': tree_clf.
↪feature_importances_})

features = features.sort_values('importance', ascending=False)

[Link](figsize=(15,7))
[Link]([Link][:8], [Link][:8])
[Link](rotation=45)
[Link]()

6 Predicción con el set de prueba y gráfica de la matriz de con-


fusión
[20]: # realizando las predicciones con el set de prueba
y_pred = [Link](X_test)

cm = confusion_matrix(y_test, y_pred)
dist = ConfusionMatrixDisplay(cm, display_labels=['No compra', 'Compra'])
[Link](cmap='gray')
[Link]()

7
7 Aplicación del modelo de Random Forest
[21]: # creación del modelo de random forest
from [Link] import RandomForestClassifier

pipeline_rf = Pipeline([
('preprocessor', preprocessor),
('clf', RandomForestClassifier(n_estimators=8, # número de árboles de␣
↪decisión que se crearán

max_features=None,
max_depth=5,
min_samples_leaf=4,
random_state=42))
])

pipeline_rf

[21]: Pipeline(steps=[('preprocessor',
ColumnTransformer(transformers=[('cat', OneHotEncoder(),
['NivelEducativo', 'Genero',

8
'TipoEmpleo']),
('num', StandardScaler(),
['Edad', 'Salario',
'Hijos'])])),
('clf',
RandomForestClassifier(max_depth=5, max_features=None,
min_samples_leaf=4, n_estimators=8,
random_state=42))])

[22]: # entrenamiento del modelo con datos específicos


pipeline_rf.fit(X_train, y_train)

[22]: Pipeline(steps=[('preprocessor',
ColumnTransformer(transformers=[('cat', OneHotEncoder(),
['NivelEducativo', 'Genero',
'TipoEmpleo']),
('num', StandardScaler(),
['Edad', 'Salario',
'Hijos'])])),
('clf',
RandomForestClassifier(max_depth=5, max_features=None,
min_samples_leaf=4, n_estimators=8,
random_state=42))])

[23]: # acceso al modelo de random forest entrenado


rf_clf = pipeline_rf.named_steps['clf']
rf_clf

[23]: RandomForestClassifier(max_depth=5, max_features=None, min_samples_leaf=4,


n_estimators=8, random_state=42)

8 Evaluación del modelo de random forest


[24]: # configurar StratifiedKFold
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)

# realizar validación cruzada utilizando el pipeline


scores = cross_val_score(pipeline_rf, X_train, y_train, cv=skf,␣
↪scoring='accuracy')

# resultados de la validación cruzada


print("Puntuaciones de validación cruzada:", [Link](scores, 3))
print("Media de las puntuaciones:", [Link]([Link](), 3))

# resultado con el set de prueba

9
print("Resultado con el set de prueba:", [Link](pipeline_rf.score(X_test,␣
↪y_test),3))

Puntuaciones de validación cruzada: [0.821 0.801 0.821 0.806 0.829]


Media de las puntuaciones: 0.816
Resultado con el set de prueba: 0.798

9 Visualización de las características importantes del modelo Ran-


dom Forest
[25]: features_rf = [Link]({'feature': feature_names, 'importance': rf_clf.
↪feature_importances_})

features_rf = features_rf.sort_values('importance', ascending=False)

[Link](figsize=(15,7))
[Link](features_rf.feature[:8], features_rf.importance[:8])
[Link]('Importancia', size=13)
[Link]('Características', size=13)
[Link]('Importancia de las características del modelo de Random Forest\n',␣
↪size=18)

[Link](rotation=45)
[Link]()

10
características importantes de cada árbol creado dentro del modelo de random forest
[26]: importances = [tree.feature_importances_ for tree in rf_clf.estimators_]

df_importances = [Link](importances, columns=feature_names)


df_importances_t = df_importances.T

fig, ax = [Link](len(importances), 1, figsize=(8, 40))

for i in range(len(importances)):
# creación de un dataframe con las importancias y las características
temp_df = [Link]({
'feature': df_importances_t.index,
'importance': df_importances_t.iloc[:, i]
})

# ordenar el dataframe por importancia de mayor a menor


temp_df = temp_df.sort_values(by='importance', ascending=False)

# gráfico de las importancias ordenadas


ax[i].bar(temp_df['feature'][:8], temp_df['importance'][:8])
ax[i].set_title(f'Árbol {i+1}')
ax[i].set_xlabel('Características')
ax[i].set_ylabel('Importancia')
ax[i].set_xticks(range(len(temp_df['feature'][:8])))
ax[i].set_xticklabels(temp_df['feature'][:8], rotation=70)

plt.tight_layout()
[Link]()

11
12
10 Identificación y visualización del árbol con la mayor importan-
cia de características
[27]: # calculo del promedio de la suma de las importancias de características para␣
↪cada árbol

mean_importances = [Link](importances, axis=1)

most_important_tree_index = [Link](mean_importances)
most_important_tree = rf_clf.estimators_[most_important_tree_index]
most_important_tree

[27]: DecisionTreeClassifier(max_depth=5, min_samples_leaf=4, random_state=1608637542)

[28]: # gráfico del árbol de decisión más importante


[Link](figsize=(50,10))
plot_tree(most_important_tree,
filled=True,
feature_names=feature_names,
class_names=['No compra', 'Compra'])
[Link]()

[29]: # realizando las predicciones con el set de prueba


y_pred = pipeline_rf.predict(X_test)

cm = confusion_matrix(y_test, y_pred)
dist = ConfusionMatrixDisplay(cm, display_labels=['No compra', 'Compra'])
[Link](cmap='gray')
[Link]()

13
14

También podría gustarte