資料預處理和特徵工程
阿新 • • 發佈:2020-07-24
[toc]
# 資料探勘的五大流程
1. 獲取資料
2. 資料預處理
- 資料預處理是從資料中檢測,糾正或刪除孫華,不準確或不適用於模型的記錄的過程
- 目的: 讓資料適應模型, 匹配模型的需求
3. 特徵工程
- 特徵工程是將原始資料轉換為更能代表預測模型的潛在無問題的特徵的過程, 可以通過挑選最相關的特徵,提取特徵以及創造特徵來實現.
- 目的: 降低計算成本,提高模型上限
4. 建模,測試模型並預測出結果
5. 上線,驗證模型效果
# 資料預處理(preprocessing)
## 資料歸一化
當資料按照最小值中心化後,在按照極差(最大值-最小值)縮放,資料移動了最小值個單位,並且會被收斂到[0, 1]之間的過程稱為**資料歸一化**(Normalization, 又稱Min-Max Scaling)
$$
x*=\frac{x-min(x)}{max(x)-min(x)}
$$
**sklearn中的實現方法**
```python
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
scaler.fit(data)
result = scaler.transform(data)
# 也可以使用fit_transform將結果一步達成
# result = scaler.fit_transform(data)
# 將歸一化結果逆轉
scaler.inverse_transform(result)
```
> 當特徵數量特別多的時候,`fit`會報錯,這時需要使用`partial_fit`,與`fit`用法相同
## 資料標準化
當資料按均值中心化後,再按照標準差進行縮放,資料就會服從均值為0,方差為1的正態分佈,這個過程稱為**資料標準化**(Standardization, 又稱Z-score normalization)
$$
x* = \frac{x-\mu}{\sigma}, \mu為均值,\sigma為標準差
$$
**sklearn中的實現方法**
```python
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(data)
# 均值
scaler.mean_
# 方差
scaler.var_
# 標準化後的結果
x_std = scaler.transform(data)
# 也可以使用fit_transform將結果一步達成
# x_std = scaler.fit_transform(data)
# 將歸一化結果逆轉
scaler.inverse_transform(x_std)
```
**StandardScaler和MinMaxScaler選哪個**
大多數機器學習演算法中,會選擇StandardScaler來進行特徵縮放,因為MinMaxScaler對異常值非常敏感.在PCA, 聚類, 邏輯迴歸, 支援向量機, 神經網路等演算法中,StandardScaler往往會是更好地選擇
MinMaxScaler在不涉及距離度量,梯度,協方差計算以及資料需要被壓縮到特定區間時使用廣泛,如數字影象處理中量化畫素強度時.
## 缺失值處理
**pandas中檢視是否存在缺失值以及缺失值數量**
```python
data.info()
```
**填補缺失值的方法有**
- 均值填補
- 中值填補
- 眾數填補
- 也可以使用預測等方法填補
**sklearn中的缺失值填補方法**
```python
sklearn.impute.SimpleImputer(missing_values: 缺失值的樣子,預設為np.nan, strategy: 填補方式, 預設為均值("mean": 均值, 'median': 中值, 'most_frequent': 眾數, 'constant': fill_value中的值), fill_value: 當strategy為'constant'時填充該值, copy: 是否返回新副本,否的話在原來資料基礎上進行填充)
```
> 也可以直接使用pandas提供的fillna直接進行填補
> `data.loc[:, 'Age'] = data.loc[:, 'Age'].fillna(data.loc[:, 'Age'].median())`
**也可以直接刪除有缺失值的行**
```python
data = data.dropna(axis=0, inplace=False)
```
## 處理離散型特徵和非數值型標籤
將離散型特徵資料轉換成one-hot(向量)格式, 非數值型標籤轉換為數值型標籤
**sklearn中將離散型非數值便籤轉換為數值型標籤**
```python
sklearn.preprocessing.LabelEncoder()
```
可以使用`inverse_transform`方法進行逆轉
**sklearn中將離散型非數值型特徵轉換為數值型特徵**
```python
sklearn.preprocessing.OrdinalEncoder()
```
> **一般情況下,會將離散型特徵轉換為One-hot編碼格式**
**sklearn中轉換為One-hot格式的方法**
```python
sklearn.preprocessing.OneHotEncoder(categories='auto': 表示自動指定每個特徵的類別數)
```
> **訓練後進行`transform`返回的是一個稀疏矩陣,需要使用toarray()來轉換為array**
> 可以使用`categories_`屬性檢視新的特徵索引
> 可以使用`inverse_transform`方法進行逆轉
> 可以使用`onehot.get_feature_names()`獲取每個係數矩陣的列名
**sklearn中將標籤轉換為one-hot型別**
```python
sklearn.preprocessing.LabelBinarizer()
```
## 處理連續型特徵
### 二值化
將連續型特徵變數,大於閾值的對映為1,小於閾值的對映為0.
**sklearn中的二值化方法**
```python
from sklearn.preprocessing import Binarizer(threshold: 閾值)
```
### 分箱
將連續型變數進行多個劃分,每個劃分為一定的範圍
**sklearn中的分箱方法**
```python
sklearn.preprocessing.KBinsDiscretizer(
n_bins: 每個特徵分箱的個數,預設為5,
encode: 編碼方式,預設為"onehot.('onehot'為one-hot編碼, 'ordinal'表示將每一組編碼為一個整數, 'onehot-dense': 進行one-hot編碼後返回一個密集陣列),
strategy: 定義箱寬de方式,預設為"quantile".('uniform': 等寬分箱,即間隔大小相同, 'quantile': 等位分箱,即樣本數量相同, 'kmeans': 表示聚類分箱)
)
```
> 可以通過`bin_edges_`屬性檢視其分箱**邊緣**(不是列名)
# 特徵選擇(feature selection)
> **一定要先理解資料的含義**
## 特徵提取(feature extraction)
### Filter過濾法
根據各種統計檢驗中的各項指標來選擇特爾正
#### 方差過濾
通過特徵本身的方差來篩選特徵的類.比如一個特徵本身的方差特別小,那麼這個特徵基本上沒有存在的必要(資料之間的該特徵基本沒什麼差別).所以,需要**先消除方差為0的特徵**
**sklearn中的方差過濾方法**
```python
sklearn.feature_selection.VarianceThreshold(threshold: float型別, 要過濾的方差大小,預設為0.0)
```
> 可以直接使用pandas中的var檢視方差,然後使用drop進行刪除
> 如果特徵是伯努利隨機變數,可以使用p*(1-p)來計算方差(p為某一類的概率)
#### 相關性過濾
##### 卡方過濾
卡方過濾是專門針對離散型標籤(即分類問題)的相關性過濾.在sklearn中,卡方檢驗類feature_selection.chi2計算每個非負特徵與便籤之間的卡方統計量,並按照卡方統計量由高到低為特徵排名.再結合feature_selection.SelectKBest這個可以輸入"評分標準"來選出前k個分數最高的特徵的類.
**sklearn中的卡方統計量**
```python
sklearn.feature_selection.chi2(x, y)
```
**sklearn中的卡方過濾方法**
```python
sklearn.feature_selection.SelectKBest(chi2, k: 選擇的特徵數)
```
> 選擇k值時可以使用p值,當小於等於0.05或0.01表示相關,大於表示不相關,p值可以通過`pvalues_`屬性獲得,也可以通過`chi2`獲得(返回值是卡方值和p值)
##### F檢驗
F檢驗,又稱ANOVA,方差齊性檢驗,是用來捕捉每個特徵與標籤之間的**線性關係**的過濾方法.它既可以做迴歸又可以做分類.
> F檢驗之前需要先將資料轉換成服從**正態分佈**的形式
> 通常會將卡方檢驗和F檢驗一起使用
**sklearn中的F檢驗方法**
```python
sklearn.feature_selection.f_classif(x, y)
sklearn.feature_selection.f_regression(x, y)
```
> 該方法會返回兩個數,分別是F值和p值,p值的判斷方式與卡方檢驗相同
判斷出k值(特徵數量)後,然後使用`SelectKBest`進行選取特徵,不同的是第一個引數為F檢驗的方法
```python
sklearn.feature_selection.SelectKBest(f_classif, k: 選擇的特徵數)
sklearn.feature_selection.SelectKBest(f_regression, k: 選擇的特徵數)
```
##### 互資訊法
互資訊法是用來捕捉每個特徵與標籤之間的任意關係(包括線性關係和非線性關係)的過濾方法,可以做迴歸也可以做分類
**sklearn中的互資訊法**
```
sklearn.feature_selection.mutual_info_calssif(x, y)
sklearn.feature_selection.mutual_indo_regression(x, y)
```
> 會返回一個值表示每個特徵與目標之間的互資訊量的估計,0表示兩個變數獨立,1表示兩個變數完全相關,通過該值可以確定k的具體數值
其用法與F檢驗和卡方檢驗相同,需要搭配`SelectKBest`使用
```python
sklearn.feature_selection.SelectKBest(mutual_info_calssif, k: 選擇的特徵數)
sklearn.feature_selection.SelectKBest(mutual_indo_regression, k: 選擇的特徵數)
```
### Embedded嵌入法
嵌入法是一種讓演算法自己決定使用哪些特徵的方法,即特徵選擇和演算法訓練同時進行.在使用嵌入法時,我們先使用某些機器學習的演算法和模型進行訓練,得到各個特徵的權值係數,根據權值係數從大到小選擇特徵
**sklearn中的嵌入法**
```python
sklearn.feature_selection.SelectionFromModel(estimator: 模型,只要到feature_importances_或coef_屬性或者帶懲罰項的模型,
threshold: 特徵重要性的閾值,低於這個閾值的會被刪除,
prefit: 預設為False,判斷是否將例項化後的模型直接傳遞給建構函式,若為True,則必須呼叫fit和transform,不能使用fit_transform,
norm_order: k可輸入非整數,正無窮,負無窮,預設為1.在模型的coef_屬性高於一維的情況下,用於過濾低於閾值的係數的向量的範數的階數,
max_features: 在閾值設定下,要選擇的最大特徵數.要禁用閾值並僅根據max_features選擇,需要配置threshold=-np.inf
)
```
> SelectionFromModel可以與任何一個在擬合後具有`coef_`, `feature_importances_`屬性或者引數中具有可懲罰項的模型一起使用
### Wrapper包裝法
包裝法也是一個特徵選擇和孫發訓練同時進行的方法,如嵌入法十分相似,他也是依賴於演算法自身具有`coef_`, `feature_importances_`屬性來完成特徵選擇.但是不同的是,我們往往使用一個目標函式作為黑盒來選取特徵.
最典型的目標函式是遞迴特徵消除法(Recursive feature elimination,簡稱RFE), 它是一種貪婪的優化演算法,旨在找到效能最佳的特徵子集.它反覆建立模型,並且在每次迭代時保留最佳特徵或剔除最差特徵,下一次,他會使用上一次建模中沒有被選中的特徵來構建下一個模型,知道所有特徵都耗盡為止. 然後,他根據自己保留或剔除特徵的順序來對特徵進行排名,最終選出一個最佳子集.
包裝法的效果時多有的特徵選擇方法中最有利於提升模型表現的,它可以使用很少的特徵達到很優秀的效果
**sklearn中的遞迴特徵消除法(RFE)**
```python
sklearn.feature_selection.RFE(estimator: 模型,
n_features_to_selection: 特徵選擇的個數,
step=1: 每次迭代中希望移除的特徵個數,
verbose=0: 控制輸出的長度
)
```
> support屬性為所有特徵的布林矩陣, ranking屬性為特徵按次數迭代中綜合重要性的排名
**部落格