web-dev-qa-db-fra.com

RandomForestClassfier.fit (): ValueError: impossible de convertir une chaîne en float

Donné est un simple fichier CSV:

A,B,C
Hello,Hi,0
Hola,Bueno,1

Évidemment, le jeu de données réel est beaucoup plus complexe que cela, mais celui-ci reproduit l'erreur. J'essaie de construire un classifieur de forêt aléatoire pour cela, comme ceci:

cols = ['A','B','C']
col_types = {'A': str, 'B': str, 'C': int}
test = pd.read_csv('test.csv', dtype=col_types)

train_y = test['C'] == 1
train_x = test[cols]

clf_rf = RandomForestClassifier(n_estimators=50)
clf_rf.fit(train_x, train_y)

Mais je viens d'obtenir cette trace en appelant fit ():

ValueError: could not convert string to float: 'Bueno'

la version de scikit-learn est 0.16.1.

45
nilkn

Vous devez faire un certain encodage avant d’utiliser fit. Comme il a été dit, fit () n'accepte pas les chaînes mais vous résolvez ceci.

Plusieurs classes peuvent être utilisées:

  • LabelEncoder : transformez votre chaîne en valeur incrémentielle
  • OneHotEncoder : utilisez l'algorithme One-of-K pour transformer votre chaîne en entier

Personnellement, j'ai posté presque la même question sur StackOverflow il y a quelque temps. Je voulais une solution évolutive mais je n’ai pas eu de réponse. J'ai sélectionné OneHotEncoder qui binarise toutes les chaînes. C'est assez efficace, mais si vous avez beaucoup de chaînes différentes, la matrice se développera très rapidement et de la mémoire sera nécessaire.

48
RPresle

LabelEncoding a fonctionné pour moi (en gros, vous devez encoder vos données en fonction des fonctionnalités) (mydata est un tableau 2D de type de données chaîne):

myData=np.genfromtxt(filecsv, delimiter=",", dtype ="|a20" ,skip_header=1);

from sklearn import preprocessing
le = preprocessing.LabelEncoder()
for i in range(*NUMBER OF FEATURES*):
    myData[:,i] = le.fit_transform(myData[:,i])
10
SinOfWrath

Vous ne pouvez pas passer str à votre méthode model fit(). comme il a mentionné ici

Les échantillons d'entrée de formation. En interne, il sera converti en dtype = np.float32 et si une matrice clairsemée est fournie à un csc_matrix clairsemé.

Essayez de transformer vos données en données flottantes et essayez LabelEncoder .

8
farhawa

J'ai eu un problème similaire et j'ai constaté que pandas.get_dummies () résolvait le problème. Plus précisément, il divise les colonnes de données catégorielles en ensembles de colonnes booléennes, une nouvelle colonne pour chaque valeur unique dans chaque colonne en entrée. Dans votre cas, vous remplaceriez train_x = test[cols] avec:

train_x = pandas.get_dummies(test[cols])

Ceci transforme le train de données train_x en la forme suivante, que RandomForestClassifier peut accepter:

   C  A_Hello  A_Hola  B_Bueno  B_Hi
0  0        1       0        0     1
1  1        0       1        1     0
6
pittsburgh137

Vous ne pouvez pas passer str pour adapter ce type de classificateur.

Par exemple, si vous avez une colonne de caractéristiques nommée "note" qui comporte 3 notes différentes:

A, B et C .

vous devez transférer ces str "," B "," C " à la matrice par encodeur comme suit:

A = [1,0,0]

B = [0,1,0]

C = [0,0,1]

parce que str n'a pas de signification numérique pour le classificateur.

Dans scikit-learn, OneHotEncoder et LabelEncoder sont disponibles dans le module inpreprocessing. Cependant, OneHotEncoder ne prend pas en charge fit_transform() de chaîne. "ValueError: impossible de convertir la chaîne en float" peut survenir pendant la transformation.

Vous pouvez utiliser LabelEncoder pour transférer de str vers des valeurs numériques continues. Ensuite, vous pouvez transférer par OneHotEncoder comme vous le souhaitez.

Dans le Pandas dataframe, je dois encoder toutes les données classées en dtype:object. Le code suivant fonctionne pour moi et j'espère que cela vous aidera.

 from sklearn import preprocessing
    le = preprocessing.LabelEncoder()
    for column_name in train_data.columns:
        if train_data[column_name].dtype == object:
            train_data[column_name] = le.fit_transform(train_data[column_name])
        else:
            pass
4
jo nova