使用sklearn來處理類別資料
在處理真實的資料集的時候,我們經常會遇見一個或多個的類別資料的特徵。類別資料可以被分為標稱特徵(nominal feature)和有序特徵(ordinal feature)。有序特徵指的是類別的值是有序的或者是可以排序的,例如,衣服的尺碼S、M、X、XL、XXL...就是屬於有序特徵。再例如,衣服的顏色,黑色、藍色、白色、黃色...這些就屬於標稱特徵。
一、有序特徵的對映
我們可以將有序特徵裝換成為整數,整數包含一定的順序。沒有一個合適的方法可以自動將尺寸特徵轉換成為正確的順序,所以我們需要手動來指定相應的對映關係。例如,S:1,M:2,X:3,我們可以利用pandas的map方法來實現。
import pandas as pd if __name__ == "__main__": #定義衣服尺寸的對映關係 size_mapping = {"S":1,"M":2,"X":3,"XL":4} #定義一個DataFrame資料 data = pd.DataFrame([ ["green","S",100], ["blue", "M", 110], ["red", "X", 120], ["black", "XL", 130] ]) #設定列名 data.columns = ["color","size","price"] #對size列的類別資料進行對映 data["size"] = data["size"].map(size_mapping) print(data)
二、類標的編碼
許多的機器學習演算法都要求將類標換成整數值來進行處理。對於類標進行編碼與之前對於有序特徵的對映有所不同,類標並不要求是有序的,對於特定的字串類標賦予哪個整數值給它對於我們來說並不重要,所以在對於類標進行編碼的時候我們可以使用列舉的方式從0開始設定類標。
import pandas as pd import numpy as np if __name__ == "__main__": # 定義一個DataFrame資料 data = pd.DataFrame([ ["green", "S", 100,"label1"], ["blue", "M", 110,"label2"], ["red", "X", 120,"label3"], ["black", "XL", 130,"label4"] ]) # 設定列名 data.columns = ["color", "size", "price","label"] #通過列舉獲取類標與整數之間的對映關係 label_mapping = {label:idx for idx,label in enumerate(np.unique(data["label"]))} print(label_mapping) #對label列進行對映 data["label"] = data["label"].map(label_mapping) print(data)
通過下面的方法可以將整數類標還原為字串
inv_label_mapping = {v:k for k,v in label_mapping.items()}
data["label"] = data["label"].map(inv_label_mapping)
print(data)
還可以通過sklearn的LabelEncoder類來實現類標的編碼
import pandas as pd import numpy as np from sklearn.preprocessing import LabelEncoder if __name__ == "__main__": # 定義一個DataFrame資料 data = pd.DataFrame([ ["green", "S", 100,"label1"], ["blue", "M", 110,"label2"], ["red", "X", 120,"label3"], ["black", "XL", 130,"label4"] ]) # 設定列名 data.columns = ["color", "size", "price","label"] class_label = LabelEncoder() data["label"] = class_label.fit_transform(data["label"].values) print(data)
通過sklearn的inverse_transform方法可以將整數類標還原為原始的字串
data["label"] = class_label.inverse_transform(data["label"])
print(data)
三、標稱特徵上的獨熱編碼(one-hot encoding)
我們對上面衣服的顏色特徵進行編碼,將顏色對映為{"green":0,"blue":1,"red":2,"black":3}。看起來這樣對映好像沒什麼問題,真的沒有問題嗎?實則不然,我們這樣對映實際上給顏色強加了一個大小關係,即black>red>blue>green,實際上顏色是不存在這種關係的,很顯然結果肯定也不是最優的。這時,我們可以通過獨熱編碼(one-hot encoding)來解決這一類問題。獨熱編碼是通過建立一個新的虛擬特徵,虛擬特徵的每一列各代表標稱資料的一個值。例如,顏色一共有四個取值green、blue、red、black,獨熱編碼是通過四位二進位制來表示,如果是green就表示為[1,0,0,0],對應的顏色是[green,blue,red,black],如果屬於哪一種顏色,則取值為1,否則為0。
使用sklearn的OneHotEncoder實現OneHot編碼
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
if __name__ == "__main__":
# 定義一個DataFrame資料
data = pd.DataFrame([
["green", "S", 100, "label1"],
["blue", "M", 110, "label2"],
["red", "X", 120, "label3"],
["black", "XL", 130, "label4"]
])
# 設定列名
data.columns = ["color", "size", "price", "label"]
X = data[["color", "price"]].values
#通過類標編碼將顏色裝換成為整數
color_label = LabelEncoder()
X[:,0] = color_label.fit_transform(X[:,0])
#設定顏色列使用oneHot編碼
one_hot = OneHotEncoder(categorical_features=[0])
print(one_hot.fit_transform(X).toarray())
注意:在使用OneHotEncoder進行OneHot編碼的時候,需要先將字串轉換成為整數之後才能進行OneHot編碼,不然會報錯。
使用pandas來實現oneHot編碼
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder
from sklearn.preprocessing import OneHotEncoder
if __name__ == "__main__":
# 定義一個DataFrame資料
data = pd.DataFrame([
["green", "S", 100, "label1"],
["blue", "M", 110, "label2"],
["red", "X", 120, "label3"],
["black", "XL", 130, "label4"]
])
# 設定列名
data.columns = ["color", "size", "price", "label"]
X = data[["color", "price"]].values
#pandas的get_dummies方法只對字串列進行轉換,其他的列保持不變
print(pd.get_dummies(data[["color","price"]]))