RandomForestClassfier.fit(): ValueError: could not convert string to float

RandomForestClassfier.fit(): ValueError: could not convert string to float

给出的是一个简单的 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。

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

The training input samples. Internally, it will be converted to dtype=np.float32 and if a sparse matrix is provided to a sparse csc_matrix.

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

在使用 fit() 之前,您必须进行一些编码。正如它所说 fit() 不接受字符串,但你解决了这个问题。

有几个类可以使用:

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

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

我遇到了类似的问题,发现 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

你可能不会通过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中,OneHotEncoderLabelEncoderinpreprocessing模块中可用。 但是 OneHotEncoder 不支持到 fit_transform() 的字符串。 "ValueError: could not convert string to 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

由于您的输入是字符串,您会收到值错误消息使用 countvectorizer 它将数据集转换为稀疏矩阵并训练您的 ml 算法您将得到结果

事实上,单热编码器在这里工作得很好,用这种方式将你想要的任何字符串和数字分类变量转换为 1 和 0,随机森林应该不会抱怨。

嗯,OneHot EncodingLabel Encoding 的工作方式有重要区别:

  • 标签编码基本上会将您的字符串变量切换为 int。在这种情况下,找到的第一个 class 将被编码为 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"]

它将创建与您遇到的 class 一样多的变量。在我的示例中,它将创建 3 个二进制变量:Dog, Cat and Turtle。那么如果你有Animal = "Dog",编码会变成Dog = 1, Cat = 0, Turtle = 0.

然后你可以把这个给你的模型,他永远不会解释 DogCatTurtle 更近。

但是 OneHotEncoding 也有缺点。如果你有一个分类变量遇到 50 种 classes

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

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

例如:将 Turtle, Fish, Dolphin, Shark 重新组合到一个名为 Sea Animals 的同一个 class 中,然后应用 OneHotEncoding。