tfidfvectorizer tfidftransformer spanish idf hashingvectorizer countvectorizer python machine-learning scikit-learn

python - tfidftransformer - Usar DictVectorizer con sklearn DecisionTreeClassifier



tfidfvectorizer (2)

vec.fit_transform devuelve una matriz dispersa. Y IIRC DecisionTreeClassifier no funciona bien con eso.

Pruebe train_fea = train_fea.toarray() antes de pasarlo a DecisionTreeClassifier .

Intento comenzar un árbol de decisión con python y sklearn. El enfoque de trabajo fue así:

import pandas as pd from sklearn import tree for col in set(train.columns): if train[col].dtype == np.dtype(''object''): s = np.unique(train[col].values) mapping = pd.Series([x[0] for x in enumerate(s)], index = s) train_fea = train_fea.join(train[col].map(mapping)) else: train_fea = train_fea.join(train[col]) dt = tree.DecisionTreeClassifier(min_samples_split=3, compute_importances=True,max_depth=5) dt.fit(train_fea, labels)

Ahora trato de hacer lo mismo con DictVectorizer, pero mi código no funciona:

from sklearn.feature_extraction import DictVectorizer vec = DictVectorizer(sparse=False) train_fea = vec.fit_transform([dict(enumerate(sample)) for sample in train]) dt = tree.DecisionTreeClassifier(min_samples_split=3, compute_importances=True,max_depth=5) dt.fit(train_fea, labels)

Tengo un error en la última línea: "ValueError: número de etiquetas = 332448 no coincide con el número de muestras = 55". Como aprendí de la documentación, DictVectorize fue diseñado para transformar las características nominales en numéricas. ¿Qué hago mal?

corregido (gracias ogrisel por empujarme a hacer un ejemplo completo):

import pandas as pd import numpy as np from sklearn import tree ################################## # working example train = pd.DataFrame({''a'' : [''a'', ''b'', ''a''], ''d'' : [''e'', ''e'', ''f''], ''b'' : [0, 1, 1], ''c'' : [''b'', ''c'', ''b'']}) columns = set(train.columns) columns.remove(''b'') train_fea = train[[''b'']] for col in columns: if train[col].dtype == np.dtype(''object''): s = np.unique(train[col].values) mapping = pd.Series([x[0] for x in enumerate(s)], index = s) train_fea = train_fea.join(train[col].map(mapping)) else: train_fea = train_fea.join(train[col]) dt = tree.DecisionTreeClassifier(min_samples_split=3, compute_importances=True,max_depth=5) dt.fit(train_fea, train[''c'']) ########################################## # example with DictVectorizer and error from sklearn.feature_extraction import DictVectorizer vec = DictVectorizer(sparse=False) train_fea = vec.fit_transform([dict(enumerate(sample)) for sample in train]) dt = tree.DecisionTreeClassifier(min_samples_split=3, compute_importances=True,max_depth=5) dt.fit(train_fea, train[''c''])

El último código fue arreglado con la ayuda de ogrisel:

import pandas as pd from sklearn import tree from sklearn.feature_extraction import DictVectorizer from sklearn import preprocessing train = pd.DataFrame({''a'' : [''a'', ''b'', ''a''], ''d'' : [''e'', ''x'', ''f''], ''b'' : [0, 1, 1], ''c'' : [''b'', ''c'', ''b'']}) # encode labels labels = train[[''c'']] le = preprocessing.LabelEncoder() labels_fea = le.fit_transform(labels) # vectorize training data del train[''c''] train_as_dicts = [dict(r.iteritems()) for _, r in train.iterrows()] train_fea = DictVectorizer(sparse=False).fit_transform(train_as_dicts) # use decision tree dt = tree.DecisionTreeClassifier() dt.fit(train_fea, labels_fea) # transform result predictions = le.inverse_transform(dt.predict(train_fea).astype(''I'')) predictions_as_dataframe = train.join(pd.DataFrame({"Prediction": predictions})) print predictions_as_dataframe

Todo funciona


La forma en que enumeras tus muestras no es significativa. Simplemente imprímalos para que sean obvios:

>>> import pandas as pd >>> train = pd.DataFrame({''a'' : [''a'', ''b'', ''a''], ''d'' : [''e'', ''e'', ''f''], ... ''b'' : [0, 1, 1], ''c'' : [''b'', ''c'', ''b'']}) >>> samples = [dict(enumerate(sample)) for sample in train] >>> samples [{0: ''a''}, {0: ''b''}, {0: ''c''}, {0: ''d''}]

Ahora bien, esta es, sintácticamente, una lista de dictados, pero nada de lo que cabría esperar. Intenta hacer esto en su lugar:

>>> train_as_dicts = [dict(r.iteritems()) for _, r in train.iterrows()] >>> train_as_dicts [{''a'': ''a'', ''c'': ''b'', ''b'': 0, ''d'': ''e''}, {''a'': ''b'', ''c'': ''c'', ''b'': 1, ''d'': ''e''}, {''a'': ''a'', ''c'': ''b'', ''b'': 1, ''d'': ''f''}]

Esto se ve mucho mejor, intentemos vectorizar esos dicts:

>>> from sklearn.feature_extraction import DictVectorizer >>> vectorizer = DictVectorizer() >>> vectorized_sparse = vectorizer.fit_transform(train_as_dicts) >>> vectorized_sparse <3x7 sparse matrix of type ''<type ''numpy.float64''>'' with 12 stored elements in Compressed Sparse Row format> >>> vectorized_array = vectorized_sparse.toarray() >>> vectorized_array array([[ 1., 0., 0., 1., 0., 1., 0.], [ 0., 1., 1., 0., 1., 1., 0.], [ 1., 0., 1., 1., 0., 0., 1.]])

Para obtener el significado de cada columna, pregúntale al vectorizador:

>>> vectorizer.get_feature_names() [''a=a'', ''a=b'', ''b'', ''c=b'', ''c=c'', ''d=e'', ''d=f'']