機器學習之混合型別資料的使用
在機器學習中,經常會碰到不同型別的資料(numeric, categorical, Continuous and Text data)混合使用的情況,而機器學習演算法一般只接受數值型的資料。比如說,雖然神經網路很強大,但是也沒辦法直接處理類別型的變數,需要經過如one-hot編碼的預處理之後才能放進網路去訓練。因此,必須對這些資料進行預處理。但是,不同的處理方式,可能對模型的效果產生重要的影響。
Understanding Categorical Data
類別型資料,主要有兩種:Nominal(名稱)、Ordinal(順序)
名稱型類別資料,在該屬性的值之間沒有排序的概念,如天氣、城市等。
順序分類特徵,它的值的大小是有一定意義的(如襯衫尺寸、鞋子大小、學歷高低等)
Feature Engineering on Categorical Data
通常,特徵工程中的標準工作流都涉及到將這些類別值經某種形式的轉換,轉化為數字標籤的形式,然後在這些值上應用一些編碼方案。
Transforming Nominal Attributes
遊戲類別欄位Genre和Publisher、Platform都是名稱屬性。
檢視遊戲類別有多少類
genres = np.unique(vg_df['Genre'])
genres
Output
------
array(['Action' , 'Adventure', 'Fighting', 'Misc', 'Platform',
'Puzzle', 'Racing', 'Role-Playing', 'Shooter', 'Simulation',
'Sports', 'Strategy'], dtype=object)
通過利用scikit-learn來生成一個標籤編碼方案,將每個類別對映到一個數值。
from sklearn.preprocessing import LabelEncoder
gle = LabelEncoder()
genre_labels = gle.fit_transform(vg_df['Genre' ])
genre_mappings = {index: label for index, label in
enumerate(gle.classes_)}
genre_mappings
Output
------
{0: 'Action', 1: 'Adventure', 2: 'Fighting', 3: 'Misc',
4: 'Platform', 5: 'Puzzle', 6: 'Racing', 7: 'Role-Playing',
8: 'Shooter', 9: 'Simulation', 10: 'Sports', 11: 'Strategy'}
vg_df['GenreLabel'] = genre_labels
vg_df[['Name', 'Platform', 'Year', 'Genre', 'GenreLabel']].iloc[1:7]
GenreLabel作為屬性使用時,還需要對它進行額外的編碼才能使用,因為它們不應該存在大小的關係。
Transforming Ordinal Attributes
poke_df = pd.read_csv('datasets/Pokemon.csv', encoding='utf-8')
poke_df = poke_df.sample(random_state=1, frac=1).reset_index(drop=True)
np.unique(poke_df['Generation'])
Output
------
array(['Gen 1', 'Gen 2', 'Gen 3', 'Gen 4', 'Gen 5', 'Gen 6'], dtype=object)
妖怪有6個世代,每個妖怪屬於其中一個世代。這是特徵是有順序的,在遊戲中,第一代的“口袋妖怪”比第二代更早出現。
一般情況下,沒有通用的模組或函式來對映和將這些特性轉換為基於順序的數字表示。因此,可以使用自定義編碼\對映方案。
gen_ord_map = {'Gen 1': 1, 'Gen 2': 2, 'Gen 3': 3, 'Gen 4': 4, 'Gen 5': 5, 'Gen 6': 6}
poke_df['GenerationLabel'] = poke_df['Generation'].map(gen_ord_map)
poke_df[['Name', 'Generation', 'GenerationLabel']].iloc[4:10]
Encoding Categorical Attributes
至此,已經將類別轉換為數字標籤,為什麼還需要編碼?
比如,對於電子遊戲種類來說,如果直接將GenreLabel餵給機器學習模型,模型會認為它是連續的數字特徵,同時會認為10(sports)會比6(Racing)大,但是這個大小是沒有意義的,不能直接比較大小。因此,需要一種額外的編碼方案,即在每個特徵的所有不同值中,為每個獨特的值建立虛擬特性(啞變數)。
One-hot Encoding Scheme
Dummy Coding Scheme
當一個特徵中,類別很多時,採用上述的編碼方式,會存在維數災難的問題。此時可以使用區間計數方案(Bin-counting Scheme),如分箱操作。
text data
對於文字資料,同樣需要將文字轉化為向量的形式才能被機器學習模型處理,處理的方法主要有:
- 詞袋模型(Bag of Word)
這應該是非結構化文字中最簡單的向量空間表示法。向量的每個維度都是特定的特徵/屬性。詞袋模型將每個文字文件表示為數值向量,其中維度是來自語料庫的一個特定的詞,而該維度的值可以用來表示這個詞在文件中的出現頻率、是否出現(由0和1表示),或者加權值。將這個模型叫做詞袋模型,是因為每個文件可以看作是裝著單詞的袋子,而無須考慮單詞的順序和語法。當語料規模比較大時,會存在維數災難的問題,而且該方法沒有考慮語義。
- N元詞袋模型(Bag of N-Gram Model)
一個單詞是一個標記,通常被稱為單元(unigram)或者一元(1-gram)。詞袋模型不考慮單詞的順序,但是如果我們想要考慮序列中出現的短語或者詞彙集合呢?N元模型能夠幫我們實現這一點。N-Gram是來自文字文件的單詞記號的集合,這些記號是連續的,並以序列的形式出現。二元表示階數為二的N-Gram,也就是兩個單詞。同理三元表示三個單詞。N元詞袋模型是普通詞袋模型的一種拓展,使得我們可以利用基於N元的特徵。
- TF-IDF 模型
在大型語料庫中使用詞袋模型可能會出現一些潛在的問題。由於特徵向量是基於詞的頻率,某些單詞可能會在文件中頻繁出現,這可能會在特徵集上掩蓋掉其他單詞。TF-IDF模型試圖通過縮放或者在計算中使用歸一化因子來解決這個問題。TF-IDF 即 Term Frequency-Inverse Document Frequency,在計算中結合了兩種度量:詞頻(Term Frequency)和逆文件頻率(Inverse Document Frequency)。這種技術是為搜尋引擎中查詢排序而開發的,現在它是資訊檢索和 NLP 領域中不可或缺的模型。
- 主題模型
也可以使用一些摘要技術從文字中提取主題或者基於概念的特徵。主題模型圍繞提取關鍵主題或者概念。每個主題可以表示為文件語料庫中的一個詞袋或者一組詞。總之,這些術語表示特定的話題、主題或概念,憑藉這些單詞所表達的語義含義,可以輕鬆將每個主題與其他主題區分開來。這些概念可以從簡單的事實、陳述到意見、前景。主題模型在總結大量文字來提取和描繪關鍵概念時非常有用。它們也可用於從文字資料中捕捉潛在的特徵。
- 神經網路(word embedding)
word2vec、doc2vec、glove