特徵工程(上)

目錄

特徵工程可能包含的內容

  1. 基礎特徵構造
  2. 數據預處理
  3. 特徵衍生
  4. 特徵變換
  5. 特徵篩選

本文以kaggle入門賽的Titanic數據集爲例,講解一些特徵工程中通用的方法,主要是數據預處理這部分。

預覽數據

import pandas as pd
import numpy as np

df_train = pd.read_csv('train.csv')
df_train.shape
df_train.info()
df_train.describe()

#變量的百分位以及離羣點
%matplotlib inline
df_train.boxplot(column='Age')

%matplotlib inline
import seaborn as sns
sns.set(color_codes=True)
np.random.seed(sum(map(ord, "distributions")))
sns.distplot(df_train.Age, kde=True, bins=20, rug=True)

數據預處理

缺失值處理

df_train['Age'].fillna(value=df_train['Age'].mean())

from sklearn.preprocessing import Imputer
imp = Imputer(missing_values='NaN', strategy='mean', axis=0)
age = imp.fit_transform(df_train[['Age']].values).copy()
df_train.loc[:,'Age'] = df_train['Age'].fillna(value=df_train['Age'].mean()).copy()

數值型

數值縮放

# 取對數等變換
import numpy as np
log_age = df_train['Age'].apply(lambda x:np.log(x))
df_train.loc[:,'log_age'] = log_age

# 幅度縮放,最大最小值縮放到[0,1]區間內
from sklearn.preprocessing import MinMaxScaler
mm_scaler = MinMaxScaler()
fare_trans = mm_scaler.fit_transform(df_train[['Fare']])

# 幅度縮放,將每一列的數據標準化爲正態分佈的
from sklearn.preprocessing import StandardScaler
std_scaler = StandardScaler()
fare_std_trans = std_scaler.fit_transform(df_train[['Fare']])

#中位數或者四分位數去中心化數據,對異常值不敏感
from sklearn.preprocessing import robust_scale
fare_robust_trans = robust_scale(df_train[['Fare','Age']])

#將同一行數據規範化,前面的同一變爲1以內也可以達到這樣的效果
from sklearn.preprocessing import Normalizer
normalizer = Normalizer()
fare_normal_trans = normalizer.fit_transform(df_train[['Age','Fare']])
fare_normal_trans

統計值

# 最大最小值
max_age = df_train['Age'].max()
min_age = df_train["Age"].min()

# 分位數,極值處理,我們最粗暴的方法就是將前後1%的值抹去
age_quarter_01 = df_train['Age'].quantile(0.01)
age_quarter_99 = df_train['Age'].quantile(0.99)


# 四則運算
df_train.loc[:,'family_size'] = df_train['SibSp']+df_train['Parch']+1

# 多項式特徵生成
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(degree=2)
df_train[['SibSp','Parch']].head()
poly_fea = poly.fit_transform(df_train[['SibSp','Parch']])

離散化/分箱/分桶

#等距切分
df_train.loc[:, 'fare_cut'] = pd.cut(df_train['Fare'], 20)

# 等頻切分
df_train.loc[:,'fare_qcut'] = pd.qcut(df_train['Fare'], 10)

#OneHot encoding/獨熱向量編碼 
embarked_oht = pd.get_dummies(df_train[['Embarked']])

特徵選擇

一般可以從兩個方面考慮來選擇特徵:

  1. 特徵是否發散
    如果一個特徵不發散,例如方差接近於0,也就是說樣本在這個特徵上基本上沒有差異,這個特徵對於樣本的區分並沒有什麼用。

  2. 特徵與目標的相關性
    這點比較顯見,與目標相關性高的特徵,應當優選選擇。除移除低方差法外,本文介紹的其他方法均從相關性考慮。

特徵選擇可以分爲3種:

  1. Filter:過濾法,按照發散性或者相關性對各個特徵進行評分,設定閾值或者待選擇閾值的個數,選擇特徵。
    • 移除低方差的特徵
    • 單變量特徵選擇
  2. Wrapper:包裝法,根據目標函數(通常是預測效果評分),每次選擇若干特徵,或者排除若干特徵。
    • 遞歸特徵消除
  3. Embedded:嵌入法,先使用某些機器學習的算法和模型進行訓練,得到各個特徵的權值係數,根據係數從大到小選擇特徵。類似於Filter方法,但是是通過訓練來確定特徵的優劣。
    • 使用SelectFromModel選擇特徵
    • 將特徵選擇過程融入pipeline

Filter

  1. 移除低方差的特徵
from sklearn.feature_selection import VarianceThreshold
X = [[0, 0, 1], [0, 1, 0], [1, 0, 0], [0, 1, 1], [0, 1, 0], [0, 1, 1]]
sel = VarianceThreshold(threshold=(.8 * (1 - .8)))
sel.fit_transform(X)
  1. 單變量特徵選擇

對於分類問題(y離散),可採用:

  • 卡方檢驗
  • f_classif
  • mutual_info_classif
  • 互信息

對於迴歸問題(y連續),可採用:

  • 皮爾森相關係數
  • f_regression,
  • mutual_info_regression
  • 最大信息係數

卡方(Chi2)檢驗

經典的卡方檢驗是檢驗定性自變量對定性因變量的相關性。比如,我們可以對樣本進行一次chi2 測試來選擇最佳的兩項特徵:

from sklearn.datasets import load_iris
from sklearn.feature_selection import SelectKBest
from sklearn.feature_selection import chi2
iris = load_iris()
X, y = iris.data, iris.target
X_new = SelectKBest(chi2, k=2).fit_transform(X, y)

Pearson相關係數

皮爾森相關係數是一種最簡單的,能幫助理解特徵和響應變量之間關係的方法,該方法衡量的是變量之間的線性相關性。

import numpy as np
from scipy.stats import pearsonr
np.random.seed(0)
size = 300
x = np.random.normal(0, 1, size)
# pearsonr(x, y)的輸入爲特徵矩陣和目標向量,能夠同時計算 相關係數 和p-value.
print("Lower noise", pearsonr(x, x + np.random.normal(0, 1, size)))
print("Higher noise", pearsonr(x, x + np.random.normal(0, 10, size)))

注意,使用Pearson相關係數主要是爲了看特徵之間的相關性,而不是和因變量之間的。

Wrapper

遞歸特徵消除

遞歸消除特徵法使用一個基模型來進行多輪訓練,每輪訓練後,移除若干權值係數的特徵,再基於新的特徵集進行下一輪訓練。

對特徵含有權重的預測模型(例如,線性模型對應參數coefficients),RFE通過遞歸減少考察的特徵集規模來選擇特徵。首先,預測模型在原始特徵上訓練,每個特徵指定一個權重。之後,那些擁有最小絕對值權重的特徵被踢出特徵集。如此往復遞歸,直至剩餘的特徵數量達到所需的特徵數量。

RFECV 通過交叉驗證的方式執行RFE,以此來選擇最佳數量的特徵:對於一個數量爲d的feature的集合,他的所有的子集的個數是2的d次方減1(包含空集)。指定一個外部的學習算法,比如SVM之類的。通過該算法計算所有子集的validation error。選擇error最小的那個子集作爲所挑選的特徵。

from sklearn.feature_selection import RFE
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris

rf = RandomForestClassifier()
iris=load_iris()
X,y=iris.data,iris.target
rfe = RFE(estimator=rf, n_features_to_select=3)
X_rfe = rfe.fit_transform(X,y)
X_rfe.shape

Embedded

基於L1的特徵選擇

使用L1範數作爲懲罰項的線性模型(Linear models)會得到稀疏解:大部分特徵對應的係數爲0。當你希望減少特徵的維度以用於其它分類器時,可以通過 feature_selection.SelectFromModel 來選擇不爲0的係數。

特別指出,常用於此目的的稀疏預測模型有 linear_model.Lasso(迴歸), linear_model.LogisticRegression 和 svm.LinearSVC(分類)

from sklearn.feature_selection import SelectFromModel
from sklearn.svm import LinearSVC
lsvc = LinearSVC(C=0.01, penalty="l1", dual=False).fit(X,y)
model = SelectFromModel(lsvc, prefit=True)
X_embed = model.transform(X)
X_embed.shape

說了這麼多,大概把特徵工程中經典的方法都提了。大家可能看的雲裏霧裏的,上手做工程的時候還是一臉懵圈。明天還會更一篇,主要針對風控建模中常用的特徵工程的方法,今天的內容有個大致的瞭解就行。

【作者】:Labryant
【原創公衆號】:風控獵人
【簡介】:某創業公司策略分析師,積極上進,努力提升。乾坤未定,你我都是黑馬。
【轉載說明】:轉載請說明出處,謝謝合作!~

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章