RandomForestClassfier.fit():ValueError:无法将字符串转换为float

时间:2015-05-21 21:51:16

标签: python scikit-learn random-forest

给出一个简单的CSV文件:

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

显然真正的数据集比这复杂得多,但是这个数据集再现了错误。我试图为它构建一个随机森林分类器,如下所示:

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)

但是我在调​​用fit()时得到这个回溯:

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

scikit-learn版本是0.16.1。

8 个答案:

答案 0 :(得分:41)

在使用fit之前,您必须进行一些编码。因为它被告知fit()不接受字符串,但你解决了这个问题。

可以使用几个类:

我个人在不久前在StackOverflow上发布了几乎the same question。我想要一个可扩展的解决方案,但没有得到任何答案。我选择了将所有字符串二值化的OneHotEncoder。它非常有效但是如果你有很多不同的字符串,那么矩阵会很快增长并且需要内存。

答案 1 :(得分:10)

LabelEncoding为我工作(基本上你可以根据功能对数据进行编码) (mydata是字符串数据类型的二维数组):

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])

答案 2 :(得分:8)

您无法将str传递给模型fit()方法。正如它提到here

  

培训输入样本。在内部,它将被转换为dtype = np.float32,并且如果稀疏矩阵被提供给稀疏的csc_matrix。

尝试将您的数据转换为浮动并尝试LabelEncoder

答案 3 :(得分:5)

我有一个类似的问题,发现pandas.get_dummies()解决了这个问题。具体来说,它将分类数据列拆分为多组布尔列,每个输入列中每个唯一值一个新列。在您的情况下,您可以将train_x = test[cols]替换为:

train_x = pandas.get_dummies(test[cols])

这会将train_x Dataframe转换为以下形式,RandomForestClassifier可以接受:

   C  A_Hello  A_Hola  B_Bueno  B_Hi
0  0        1       0        0     1
1  1        0       1        1     0

答案 4 :(得分:3)

您可能无法通过str来适应这种分类器。

例如, 如果您有一个名为' grade'的功能列它有3个不同的等级:

A,B和C

您必须转移str " A"," B"," C " 到编码器矩阵,如下所示:

A = [1,0,0]

B = [0,1,0]

C = [0,0,1]

因为str对分类器没有数字含义。

在scikit-learn中,OneHotEncoder模块中提供了LabelEncoderinpreprocessing。 但是OneHotEncoder不支持fit_transform()字符串。 " ValueError:无法将字符串转换为float"可能在变换期间发生。

您可以使用LabelEncoderstr转移到连续数值。然后,您可以根据需要按OneHotEncoder转移。

在Pandas数据框中,我必须编码归类为dtype:object的所有数据。以下代码适用于我,我希望这对您有所帮助。

 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

答案 5 :(得分:1)

嗯, OneHot编码标签编码的工作方式之间存在重要区别:

  • 标签编码基本上会将您的String变量切换为int。在这种情况下,找到的第一个类将被编码为1,第二个类将被编码为2,... 但是这种编码会产生问题。

让我们以变量Animal = ["Dog", "Cat", "Turtle"]为例。

如果在其上使用标签编码器,则Animal将为[1, 2, 3]。如果将其解析为机器学习模型,它将解释DogCat更近,比Turtle更远(因为12之间的距离小于13之间的距离。

当您具有 ordinal 变量时,

标签编码实际上非常好。

例如,如果您有一个值Age = ["Child", "Teenager", "Young Adult", "Adult", "Old"]

然后使用标签编码非常完美。 ChildTeenager更近Young Adult。您的变量顺序自然

  • 当变量之间没有自然顺序时,OneHot编码(也由pd.get_dummies完成)是最佳解决方案。

让我们回顾上一个示例Animal = ["Dog", "Cat", "Turtle"]

它将创建与您遇到的类一样多的变量。在我的示例中,它将创建3个二进制变量:Dog, Cat and Turtle。然后,如果您有Animal = "Dog",则将其编码为Dog = 1, Cat = 0, Turtle = 0

然后,您可以将其提供给模型,他将永远不会解释DogCat比离Turtle更近。

但是OneHotEncoding也有缺点。如果您的分类变量遇到50种类

例如:Dog, Cat, Turtle, Fish, Monkey, ...

然后它将创建50个二进制变量,这可能会导致复杂性问题。在这种情况下,您可以创建自己的类并手动更改变量

例如:将Turtle, Fish, Dolphin, Shark重新分组到称为Sea Animals的同一类中,然后应用OneHotEncoding。

答案 6 :(得分:0)

由于您的输入为字符串形式,因此您会收到错误消息,请使用countvectorizer将其转换为稀疏矩阵并训练您的ml算法,以得到结果

答案 7 :(得分:0)

实际上,一键编码器在这里可以正常工作,以这种方式将所需的任何字符串和数字分类变量转换为1和0,并且随机森林不应该抱怨。