给出一个简单的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。
答案 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
模块中提供了LabelEncoder
和inpreprocessing
。
但是OneHotEncoder
不支持fit_transform()
字符串。
" ValueError:无法将字符串转换为float"可能在变换期间发生。
您可以使用LabelEncoder
从str
转移到连续数值。然后,您可以根据需要按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编码和标签编码的工作方式之间存在重要区别:
int
。在这种情况下,找到的第一个类将被编码为1
,第二个类将被编码为2
,...
但是这种编码会产生问题。让我们以变量Animal = ["Dog", "Cat", "Turtle"]
为例。
如果在其上使用标签编码器,则Animal
将为[1, 2, 3]
。如果将其解析为机器学习模型,它将解释Dog
比Cat
更近,比Turtle
更远(因为1
和2
之间的距离小于1
和3
之间的距离。
标签编码实际上非常好。
例如,如果您有一个值Age = ["Child", "Teenager", "Young Adult", "Adult", "Old"]
,
然后使用标签编码非常完美。 Child
比Teenager
更近Young Adult
。您的变量顺序自然
让我们回顾上一个示例Animal = ["Dog", "Cat", "Turtle"]
。
它将创建与您遇到的类一样多的变量。在我的示例中,它将创建3个二进制变量:Dog, Cat and Turtle
。然后,如果您有Animal = "Dog"
,则将其编码为Dog = 1, Cat = 0, Turtle = 0
。
然后,您可以将其提供给模型,他将永远不会解释Dog
离Cat
比离Turtle
更近。
但是OneHotEncoding也有缺点。如果您的分类变量遇到50种类
例如:Dog, Cat, Turtle, Fish, Monkey, ...
然后它将创建50个二进制变量,这可能会导致复杂性问题。在这种情况下,您可以创建自己的类并手动更改变量
例如:将Turtle, Fish, Dolphin, Shark
重新分组到称为Sea Animals
的同一类中,然后应用OneHotEncoding。
答案 6 :(得分:0)
由于您的输入为字符串形式,因此您会收到错误消息,请使用countvectorizer将其转换为稀疏矩阵并训练您的ml算法,以得到结果
答案 7 :(得分:0)
实际上,一键编码器在这里可以正常工作,以这种方式将所需的任何字符串和数字分类变量转换为1和0,并且随机森林不应该抱怨。