sklearn onehotencoder one labelencoder hot examples example estimator categorical_features python-2.7 scikit-learn

python 2.7 - onehotencoder - Scikit-Learn One-hot-encode antes o después de la división tren/prueba



onehotencoder onehotencoder categorical_features 1]) (2)

Estoy viendo dos escenarios construyendo un modelo usando scikit-learn y no puedo entender por qué uno de ellos devuelve un resultado que es tan fundamentalmente diferente que el otro. Lo único diferente entre los dos casos (que yo sepa) es que en un caso estoy codificando en caliente todas las variables categóricas a la vez (en todos los datos) y luego dividiendo entre el entrenamiento y la prueba. En el segundo caso, estoy dividiendo entre el entrenamiento y la prueba y luego uno de codificación en caliente ambos conjuntos basados ​​en los datos de entrenamiento.

Este último caso es técnicamente mejor para juzgar el error de generalización del proceso, pero este caso devuelve un gini normalizado que es radicalmente diferente (y malo, esencialmente, no modelo) en comparación con el primer caso. Sé que el primer caso gini (~ 0.33) está en línea con un modelo basado en estos datos.

¿Por qué el segundo caso devuelve un gini tan diferente? FYI El conjunto de datos contiene una combinación de variables numéricas y categóricas.

Método 1 (codificación completa en caliente y luego división) Devuelve: Validation Sample Score: 0.3454355044 (normalized gini).

from sklearn.cross_validation import StratifiedKFold, KFold, ShuffleSplit,train_test_split, PredefinedSplit from sklearn.ensemble import RandomForestRegressor , ExtraTreesRegressor, GradientBoostingRegressor from sklearn.linear_model import LogisticRegression import numpy as np import pandas as pd from sklearn.feature_extraction import DictVectorizer as DV from sklearn import metrics from sklearn.preprocessing import StandardScaler from sklearn.grid_search import GridSearchCV,RandomizedSearchCV from sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor from scipy.stats import randint, uniform from sklearn.metrics import mean_squared_error from sklearn.datasets import load_boston def gini(solution, submission): df = zip(solution, submission, range(len(solution))) df = sorted(df, key=lambda x: (x[1],-x[2]), reverse=True) rand = [float(i+1)/float(len(df)) for i in range(len(df))] totalPos = float(sum([x[0] for x in df])) cumPosFound = [df[0][0]] for i in range(1,len(df)): cumPosFound.append(cumPosFound[len(cumPosFound)-1] + df[i][0]) Lorentz = [float(x)/totalPos for x in cumPosFound] Gini = [Lorentz[i]-rand[i] for i in range(len(df))] return sum(Gini) def normalized_gini(solution, submission): normalized_gini = gini(solution, submission)/gini(solution, solution) return normalized_gini # Normalized Gini Scorer gini_scorer = metrics.make_scorer(normalized_gini, greater_is_better = True) if __name__ == ''__main__'': dat=pd.read_table(''/home/jma/Desktop/Data/Kaggle/liberty/train.csv'',sep=",") y=dat[[''Hazard'']].values.ravel() dat=dat.drop([''Hazard'',''Id''],axis=1) folds=train_test_split(range(len(y)),test_size=0.30, random_state=15) #30% test #First one hot and make a pandas df dat_dict=dat.T.to_dict().values() vectorizer = DV( sparse = False ) vectorizer.fit( dat_dict ) dat= vectorizer.transform( dat_dict ) dat=pd.DataFrame(dat) train_X=dat.iloc[folds[0],:] train_y=y[folds[0]] test_X=dat.iloc[folds[1],:] test_y=y[folds[1]] rf=RandomForestRegressor(n_estimators=1000, n_jobs=1, random_state=15) rf.fit(train_X,train_y) y_submission=rf.predict(test_X) print("Validation Sample Score: {:.10f} (normalized gini).".format(normalized_gini(test_y,y_submission)))

Método 2 (primera división y luego codificación única) Devuelve: Validation Sample Score: 0.0055124452 (normalized gini).

from sklearn.cross_validation import StratifiedKFold, KFold, ShuffleSplit,train_test_split, PredefinedSplit from sklearn.ensemble import RandomForestRegressor , ExtraTreesRegressor, GradientBoostingRegressor from sklearn.linear_model import LogisticRegression import numpy as np import pandas as pd from sklearn.feature_extraction import DictVectorizer as DV from sklearn import metrics from sklearn.preprocessing import StandardScaler from sklearn.grid_search import GridSearchCV,RandomizedSearchCV from sklearn.ensemble import RandomForestRegressor, ExtraTreesRegressor from scipy.stats import randint, uniform from sklearn.metrics import mean_squared_error from sklearn.datasets import load_boston def gini(solution, submission): df = zip(solution, submission, range(len(solution))) df = sorted(df, key=lambda x: (x[1],-x[2]), reverse=True) rand = [float(i+1)/float(len(df)) for i in range(len(df))] totalPos = float(sum([x[0] for x in df])) cumPosFound = [df[0][0]] for i in range(1,len(df)): cumPosFound.append(cumPosFound[len(cumPosFound)-1] + df[i][0]) Lorentz = [float(x)/totalPos for x in cumPosFound] Gini = [Lorentz[i]-rand[i] for i in range(len(df))] return sum(Gini) def normalized_gini(solution, submission): normalized_gini = gini(solution, submission)/gini(solution, solution) return normalized_gini # Normalized Gini Scorer gini_scorer = metrics.make_scorer(normalized_gini, greater_is_better = True) if __name__ == ''__main__'': dat=pd.read_table(''/home/jma/Desktop/Data/Kaggle/liberty/train.csv'',sep=",") y=dat[[''Hazard'']].values.ravel() dat=dat.drop([''Hazard'',''Id''],axis=1) folds=train_test_split(range(len(y)),test_size=0.3, random_state=15) #30% test #first split train_X=dat.iloc[folds[0],:] train_y=y[folds[0]] test_X=dat.iloc[folds[1],:] test_y=y[folds[1]] #One hot encode the training X and transform the test X dat_dict=train_X.T.to_dict().values() vectorizer = DV( sparse = False ) vectorizer.fit( dat_dict ) train_X= vectorizer.transform( dat_dict ) train_X=pd.DataFrame(train_X) dat_dict=test_X.T.to_dict().values() test_X= vectorizer.transform( dat_dict ) test_X=pd.DataFrame(test_X) rf=RandomForestRegressor(n_estimators=1000, n_jobs=1, random_state=15) rf.fit(train_X,train_y) y_submission=rf.predict(test_X) print("Validation Sample Score: {:.10f} (normalized gini).".format(normalized_gini(test_y,y_submission)))


No puedo ejecutar tu código, pero creo que en el conjunto de datos de prueba tampoco

  • no se ven todos los niveles de algunas de las variables categóricas y, por lo tanto, si calcula las variables ficticias solo en estos datos, en realidad tendrá columnas diferentes.
  • De lo contrario, ¿quizás tienes las mismas columnas pero están en un orden diferente?

Si bien los comentarios anteriores sugieren correctamente que es mejor mapear primero todo su espacio de características, en su caso, tanto el Tren como la Prueba contienen todos los valores de las características en todas las columnas.

Si compara el vectorizer.vocabulary_ entre las dos versiones, son exactamente iguales, por lo que no hay diferencia en el mapeo. Por lo tanto, no puede estar causando el problema.

La razón por la que falla el Método 2 es porque su dat_dict se vuelve a ordenar por el índice original cuando ejecuta este comando.

dat_dict=train_X.T.to_dict().values()

En otras palabras, train_X tiene un índice mezclado yendo a esta línea de código. Cuando lo convierte en un dict , el orden dict vuelve a clasificarse en el orden numérico del índice original. Esto hace que sus datos de Tren y Prueba se descorrelacionen completamente con y .

El Método 1 no sufre este problema porque mezcla los datos después de la asignación.

Puede solucionar el problema agregando un .reset_index() dos veces que asigne el dat_dict en el Método 2, por ejemplo,

dat_dict=train_X.reset_index(drop=True).T.to_dict().values()

Esto garantiza que el orden de los datos se conserve al convertir a un dict .

Cuando agrego ese bit de código, obtengo los siguientes resultados:
- Método 1: Puntuación de muestra de validación: 0.3454355044 (gini normalizado)
- Método 2: Puntuación de muestra de validación: 0.3438430991 (gini normalizado)