特徵工程可能包含的內容
- 基礎特徵構造
- 數據預處理
- 特徵衍生
- 特徵變換
- 特徵篩選
本文以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']])
特徵選擇
一般可以從兩個方面考慮來選擇特徵:
-
特徵是否發散
如果一個特徵不發散,例如方差接近於0,也就是說樣本在這個特徵上基本上沒有差異,這個特徵對於樣本的區分並沒有什麼用。 -
特徵與目標的相關性
這點比較顯見,與目標相關性高的特徵,應當優選選擇。除移除低方差法外,本文介紹的其他方法均從相關性考慮。
特徵選擇可以分爲3種:
- Filter:過濾法,按照發散性或者相關性對各個特徵進行評分,設定閾值或者待選擇閾值的個數,選擇特徵。
- 移除低方差的特徵
- 單變量特徵選擇
- Wrapper:包裝法,根據目標函數(通常是預測效果評分),每次選擇若干特徵,或者排除若干特徵。
- 遞歸特徵消除
- Embedded:嵌入法,先使用某些機器學習的算法和模型進行訓練,得到各個特徵的權值係數,根據係數從大到小選擇特徵。類似於Filter方法,但是是通過訓練來確定特徵的優劣。
- 使用SelectFromModel選擇特徵
- 將特徵選擇過程融入pipeline
Filter
- 移除低方差的特徵
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)
- 單變量特徵選擇
對於分類問題(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
【原創公衆號】:風控獵人
【簡介】:某創業公司策略分析師,積極上進,努力提升。乾坤未定,你我都是黑馬。
【轉載說明】:轉載請說明出處,謝謝合作!~