Si se tiene un dataset para predecir una clase, y dentro de las variables existen algunas que son discretas (como ciudad, empresa, rubro, etc), puede usarse esta variable discreta para crear nuevas variables "dummies" que agrupen los valores que mejor ajusten la clase a predecir.
En este ejemplo se transforma la variable discreta "state" para crear una matriz dispersa con valores dummies, luego se ajusta un modelo usando el algoritmo ExtraTreesClassifier para predecir la clase "churn". Después de tener el modelo se extrae la importancia de las variables para identificar (usando percentiles) las nuevas variables dummies a crear.
Nota: Para la importancia de la variable, el algoritmo ExtraTreesClassifier usa la medida "Mean Decrease Impurity Importance", también llamado "Gini importance", "Mean Decrease Gini", etc. Para detalles, ver Referencia No.1. Para detalles sobre sesgos en el calculo de la importancia, ver Referencia No.2. Para ver las imágenes, estas se pueden descargar AQUI
El proceso conceptual sigue estos pasos:
PASO 1
Cargar el dataset que contiene la variable a predecir (churn en este caso) y la variable discreta a descomponer. Seria algo así:
PASO 2
Transoformar variable discreata en matriz dispersa, usando la función get_dummies de la librería pandas, quedando así:
PASO 3
Se ajusta un modelo para predecir la variable "churn", usando a la matriz dispersa. En este ejemplo se aplica el algoritmo ExtraTreesClassifier, únicamente para extraer la importancia de las variables:
PASO 4
Se dividen las variables según su importancia usando percentiles, para luego crear los script que crean los grupos, segun el lenguaje que se este usando:
El script seria este:
import pandas as pd import numpy as np from sklearn.ensemble import ExtraTreesClassifier # FUNCIONES # --------------------------------------------------------------------- def float_to_int(df): for col in df.columns: if np.issubdtype(df[col].dtype, np.number): df[col] = df[col].fillna(0.0).astype(int) return df def discrete_to_matrix(df=None, var_name=None, class_name=None): bin_mtx = pd.get_dummies(df[var_name]) bin_class = df[class_name] return bin_mtx, bin_class def var_importance(bin_mtx=None,bin_class=None, n_tree=10): modelo = ExtraTreesClassifier(n_estimators = n_tree) modelo.fit(bin_mtx, bin_class) var_imp = pd.DataFrame({ 'feature': bin_mtx.columns.values.tolist(), 'v_importance' : modelo.feature_importances_.tolist()}) var_imp = var_imp.sort_values(by = 'v_importance', ascending=False) return var_imp def print_group(umbrales=None, var_imp=None, var_name=None,output_type='sql_query'): comment_chr = {'sql_query':'-- ','qlik_query':'// ','pandas_query':'# ','r_query':'# '} for k, v in enumerate(umbrales): if v == max(umbrales): p_max = 1 val_max = var_imp['v_importance'].quantile(p_max) + 0.00001 else: p_max = umbrales[k+1] val_max = var_imp['v_importance'].quantile(p_max) val_min = var_imp['v_importance'].quantile(umbrales[k]) gx = var_imp[(var_imp['v_importance']>=val_min) & (var_imp['v_importance'] < val_max)].iloc[:,0] gx = gx.tolist() if k==0: print(comment_chr[output_type], output_type.upper(), var_name.upper()) print(comment_chr[output_type],'desde: ',round(val_min,4),' hasta: ',round(val_max,4),' rango: ',round(val_max - val_min,4)) if output_type == 'sql_query': print('(case when '+var_name+' in (\'' + '\',\''.join(map(str, gx)) + '\''') then 1 else 0 end) as grupo'+str(k+1)+',') elif output_type == 'qlik_query': print('If (match('+var_name+',\'' + '\',\''.join(map(str, gx)) + '\'''),1,0) as '+var_name+'_grupo'+str(k+1)+',') elif output_type == 'pandas_query': print('df[\'grupo'+str(k+1)+'\'] = np.where(df.'+var_name+'.isin([\'' + '\',\''.join(map(str, gx)) + '\''']),1,0)') elif output_type == 'r_query': print('df$grupo'+str(k+1)+' <- ifelse(df$'+var_name+' %in% c(\'' + '\',\''.join(map(str, gx)) + '\'''),1,0)') if __name__ == '__main__': # PASO 1 #cargar data set y definir constantes df = pd.read_csv('https://www.dropbox.com/s/ed4j8l550zdy78j/churn3.csv?dl=1') var_name = 'state' class_name = 'churn' umbrales = [0.70,0.80,0.90,0.98] # PASO 2 # Transformar variable de discreta a matriz dispersa df = float_to_int(df) bin_mtx, bin_class = discrete_to_matrix(df=df, var_name=var_name, class_name=class_name) # PASO 3 # Crear importancia devariables var_imp = var_importance(bin_mtx=bin_mtx,bin_class=bin_class, n_tree=50) # PASO 4 # imprime query de grupos print_group(var_imp=var_imp, var_name=var_name, umbrales=umbrales, output_type='qlik_query') print_group(var_imp=var_imp, var_name=var_name, umbrales=umbrales, output_type='sql_query')
1. http://papers.nips.cc/paper/4928-understanding-variable-importances-in-forests-of-randomized-trees.pdf
2. http://blog.datadive.net/selecting-good-features-part-iii-random-forests/
No hay comentarios:
Publicar un comentario