[英]“ValueError: could not convert string to float: ” machine learning fit classifier
[英]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。
在使用fit()
之前,您必須進行一些編碼。 據說fit()
不接受字符串,但你解決了這個問題。
有幾個類可以使用:
LabelEncoder
: 把你的字符串變成增量值OneHotEncoder
:使用 One-of-K 算法將您的字符串轉換為整數就個人而言,我前段時間在 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
傳遞給您的模型fit()
方法。 正如這里提到的
訓練輸入樣本。 在內部,它將被轉換為 dtype=np.float32 並且如果將稀疏矩陣提供給稀疏 csc_matrix。
嘗試將您的數據轉換為浮動並嘗試使用LabelEncoder 。
您可能不會通過str
來適應這種分類器。
例如,如果您有一個名為“等級”的特征列,它有 3 個不同的等級:
A、B 和 C。
您必須通過編碼器將那些str
"A","B","C "傳輸到矩陣,如下所示:
A = [1,0,0]
B = [0,1,0]
C = [0,0,1]
因為str
對分類器沒有數字含義。
在 scikit-learn 中, inpreprocessing
模塊中提供了OneHotEncoder
和LabelEncoder
。 但是OneHotEncoder
不支持fit_transform()
的字符串。 “ValueError:無法將字符串轉換為浮點數”可能會在轉換過程中發生。
您可以使用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
好吧, 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。
由於您的輸入是字符串,您會收到值錯誤消息,使用 countvectorizer 它將數據集轉換為稀疏矩陣並訓練您的 ml 算法,您將得到結果
確實,單熱編碼器在這里可以正常工作,以這種方式將您想要的任何字符串和數字分類變量轉換為 1 和 0,隨機森林不應該抱怨。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.