1. 程式人生 > >機器學習基礎系列(2)——資料預處理

機器學習基礎系列(2)——資料預處理

本文系PWN2WEB原創,轉載請說明出處

機器學習演算法最終學習結果的優劣取決於資料質量和資料中蘊含的有用資訊數量,對資料的處理對模型高效性起到了巨大的作用。

一 缺失資料的處理 

資料採集過程中的錯誤導致缺失值的出現,我們無法忽略這些缺失值,所以我們需要對這些缺失值進行處理。

首先我們構造一個csv檔案來舉例說明問題的所在。

構造如下的CSV檔案:

 

  •  read_csv函式是將CSV格式資料讀取到pandas的資料框(DataFrame)中
  • StringIO僅僅起到演示作用:如果我們的資料是儲存在硬碟上的CSV檔案,就可以通過此函式以字串的方式從檔案中讀取資料,並將器轉換成DataFrame的格式賦值給csv_data

0x01 方法一 —— 缺失值的特徵或樣本刪除

最簡單的方法就是直接刪除缺失資料,可以使用的方法是dropna, 即df.dropna()

 

 

 可以看到,該函式預設刪除行,如果需要刪除列的話則需要加上一個引數axis:

 

 axis=1表示刪除含NaN的列,0表示刪除具備NaN值的行

 

 此函式還有其他幾個引數:

  • dropna(how='all')   丟棄一行的所有列全為NaN的
    •  

       

  • dropna(thresh=4)   丟棄沒有達到至少四個非NAN值的行
    •  

       

  • dropna(subset=['C'])    刪除NaN值出現在特定的列的行

 

 

 

0x02   缺失資料填充

一般來說直接刪除是整列或整行是不行的,會丟失很多珍貴的資料,這種情況下我們可以使用不同的插值技術,最常用的是均值插補通過資料集中其他訓練的資料來估計缺失值,我們使用Impute類實現

均值插補一般是用計算行或列的平均值來進行插補,如下圖及程式碼,這裡axis=1,是計算每行除缺失值的其他所有數字和的均值,並填入。

axis=0則就是計算每列的平均值。

 

 

 同時,引數strategy可以有median和most_frequent,根據特定情況具體應用

這裡,Imputer為轉換器類API,常用的兩個方法是fit和transform,二者區別見此文:https://blog.csdn.net/weixin_38278334/article/details/82971752

 

二   處理類別資料

真實情況下,經常會出現一個或多個類別資料的特徵列。在討論類別資料時,又可以進一步將他們劃分為標稱特徵和有序特徵,有序特徵可以理解為類別的值時有序的或者時可以排序的。標稱特徵則不具備排序的特性。討論這個問題前我們先構造資料集:

 

 0x01 有序特徵的對映

一般來說,為了確保演算法可以有效、高效的使用有序特徵,我們需要將字串轉換為整數,通常情況下需要我們手動構造對映:

 

0x02 類標的編碼

上一小節我們提到了對有序特徵的對映,仔細想想,其實這些數字的順序並不是很有意義,只要是一一對應即可,那麼這裡有個小技巧:

 

 

 classmapping1通過列舉的方式(enumerate),這裡我解釋一下這個class_mapping1後面字典的程式碼是什麼個原理,

首先,np.unique( ) 函式,轉自(https://blog.csdn.net/u012193416/article/details/79672729):

 

 

那就是說,將 將df1中的classlabel這個標的所有值去除重複值取出來

 

 

 然後是我們的enumerate函式,這個函式主要是將一個可遍歷的資料物件(如列表、元組或字串)組合為一個索引序列

 

 

 然後我們回過頭來看label:idx這個東西,我們先看這個

這個map對應的是   label:數字 , 但是label:idx這種寫法就是將字典的鍵值對轉換成這種表達方式

最後就是for idx,label in 這句話就是將idx,label組合並分別賦值

 

上面兩種方案太麻煩了,使用LabelEncoder類可以更加方便的完成對類標的整數編碼工作

 

0x03 標稱特徵上的one-hot編碼

用上面的方法去標識標稱特徵往往會出現如blue=1 > red=0這種情況,然而blue和red是無法比較的,這種情況下我們就要用到one-hot編碼了

具體可參考:

https://zhuanlan.zhihu.com/p/35287916

https://www.imooc.com/article/35900

我簡要說明一下,舉例:{紅,黃,藍},{男,女},{東,西,南,北}、

首先,紅黃藍,一個特徵三個類別,那就是N=3,就用三位數表示:100紅 010黃 001藍

其次,男女,一個特徵兩個類別,那就是N=2,就用兩位數表示:10男  01女

東西南北以此類推。當一個樣本為[男 黃 女 藍 北]時,就直接按順序把對應的編碼放進去就行了:[1,0,     0,1,0,     0,1,     0,0,1,     0,0,0,1] 。這樣的化會讓特徵空間很大,一般會結合PCA使用,我們後面會說到。

 

三  訓練集和測試集劃分

這部分雖就簡單的幾行程式碼,但是需要注意的有很多

選取UCI的葡萄酒資料舉例,一共13個特徵,下面第二個cell的第二行,是將numpy陣列的第2-13個特徵賦值給X,第一個類標特徵賦值給y。這裡簡要介紹一下,df_wine.iloc[:, 1:]這個東西,逗號前的那個冒號,意味著第幾條到第幾條資料傳給X,因為是冒號,那麼就是所有。逗號後的1:,是第幾個到第幾個的特徵賦值。

 

 之後,我們要70:30劃分資料集和測試集(即上圖種的0.3),實際應用中,我們基於資料大小劃分資料集,一般是60:40, 70:30,80:20,對於非常龐大的資料集,那就是90:10或者99:1了,然而,測試集不能太小,否則就會對泛化誤差的估計將會越不準確。

 

四 將特徵的值縮放到相同的區間

特徵縮放的定義是特徵縮放就是標準化資料特徵的範圍,從而使得每個特徵的範圍有可比性,比如將取值範圍處理為0到1之間。

將特徵縮放到相同的區間有歸一化和標準化兩個常用方法。

 

歸一化:一般是縮放到[0,1]區間,為最小-最大縮放的一個特例

 

from sklearn.preprocesing import MinMaxScaler
mms = MinMaxScaler()

 

標準化:可以將均值設為0,方差設為1,使得特徵列的值呈標準正態分佈,易於權重的更新。

from sklearn.preprocessing import StandardScaler
stdsc = StandardScaler()