Plusieurs articles expliquent comment coder des données catégoriques dans les arbres de Sklearn Decission, mais la documentation de Sklearn nous en fournit
Certains avantages des arbres de décision sont:
(...)
Capable de traiter à la fois des données numériques et catégoriques. D'autres techniques sont généralement spécialisées dans l'analyse de jeux de données ne comportant qu'un seul type de variable. Voir algorithmes pour plus d'informations.
Mais exécuter le script suivant
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
data = pd.DataFrame()
data['A'] = ['a','a','b','a']
data['B'] = ['b','b','a','b']
data['C'] = [0, 0, 1, 0]
data['Class'] = ['n','n','y','n']
tree = DecisionTreeClassifier()
tree.fit(data[['A','B','C']], data['Class'])
renvoie l'erreur suivante:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/python2.7/site-packages/sklearn/tree/tree.py", line 154, in fit
X = check_array(X, dtype=DTYPE, accept_sparse="csc")
File "/usr/local/lib/python2.7/site-packages/sklearn/utils/validation.py", line 377, in check_array
array = np.array(array, dtype=dtype, order=order, copy=copy)
ValueError: could not convert string to float: b
Je sais qu’en R il est possible de transmettre des données catégoriques, avec Sklearn, est-ce possible?
Contrairement à la réponse acceptée, je préférerais utiliser les outils fournis par Scikit-Learn à cette fin. La raison principale en est qu’ils peuvent être facilement intégrés dans un Pipeline .
Scikit-Learn lui-même fournit de très bonnes classes pour gérer des données catégorielles. Au lieu d'écrire votre fonction personnalisée, vous devriez utiliser LabelEncoder
qui est spécialement conçu à cet effet .
Reportez-vous au code suivant de la documentation:
from sklearn import preprocessing
le = preprocessing.LabelEncoder()
le.fit(["paris", "paris", "tokyo", "amsterdam"])
le.transform(["tokyo", "tokyo", "paris"])
Cela les code automatiquement en nombres pour vos algorithmes d’apprentissage automatique. Maintenant, cela permet également de retourner aux chaînes à partir d'entiers. Vous pouvez le faire en appelant simplement inverse_transform
comme suit:
list(le.inverse_transform([2, 2, 1]))
Cela retournerait ['tokyo', 'tokyo', 'paris']
.
Notez également que pour de nombreux autres classificateurs, mis à part les arbres de décision, tels que la régression logistique ou SVM, vous souhaitez coder vos variables catégorielles à l'aide de codage One-Hot . Scikit-learn prend également en charge cela via la classe OneHotEncoder
.
J'espère que cela t'aides!
(Ceci est juste un reformat de mon commentaire ci-dessus à partir de 2016 ... cela reste vrai.)
La réponse acceptée pour cette question est trompeuse.
Dans l'état actuel des choses, les arbres de décision à utiliser ne traitent pas les données catégoriques - cf. numéro 5442 .
L'approche recommandée consistant à utiliser le codage d'étiquettes convertit en entiers que la DecisionTreeClassifier()
traitera comme numérique . Si vos données catégorielles ne sont pas ordinales, ce n'est pas bon - vous allez vous retrouver avec des fractionnements qui n'ont pas de sens.
L'utilisation de OneHotEncoder
est la seule méthode valide en vigueur, permettant des scissions arbitraires ne dépendant pas de l'ordre des étiquettes mais coûtant cher en calculs.
(..)
Capable de traiter à la fois des données numériques et catégoriques.
Cela signifie seulement que vous pouvez utiliser
Dans tous les cas, vous devez encoder à chaud les variables catégoriques avant d'adapter une arborescence à sklearn, comme ceci:
import pandas as pd
from sklearn.tree import DecisionTreeClassifier
data = pd.DataFrame()
data['A'] = ['a','a','b','a']
data['B'] = ['b','b','a','b']
data['C'] = [0, 0, 1, 0]
data['Class'] = ['n','n','y','n']
tree = DecisionTreeClassifier()
one_hot_data = pd.get_dummies(data[['A','B','C']],drop_first=True)
tree.fit(one_hot_data, data['Class'])
Les arbres de décision Sklearn ne gèrent pas la conversion de chaînes catégorielles en nombres. Je vous suggère de trouver une fonction dans Sklearn (peut-être this ) qui le fait ou d'écrire manuellement du code comme:
def cat2int(column):
vals = list(set(column))
for i, string in enumerate(column):
column[i] = vals.index(string)
return column