利用多项式特征生成与递归特征消除解决特征组合与特征选择问题
目錄
- 項(xiàng)目背景
- 技術(shù)棧
- 實(shí)現(xiàn)
- 數(shù)據(jù)
- 代碼
- 總結(jié)
項(xiàng)目背景
無論是對(duì)于什么數(shù)據(jù)都存在兩個(gè)非常經(jīng)典的問題:問題一是,數(shù)據(jù)與標(biāo)簽之間,數(shù)據(jù)與數(shù)據(jù)之間的一些實(shí)際關(guān)系很難搞清楚。有些時(shí)候特征A,特征B可能都與標(biāo)簽存在正向關(guān)系。然而實(shí)際上的關(guān)系卻可能是標(biāo)簽與特征A,B的乘積存在實(shí)際關(guān)系;問題二,在不同機(jī)器學(xué)習(xí)的模型中,特征的最佳選擇往往并不一致。比如當(dāng)模型選擇為模型model1的時(shí)候,特征可能為特征ABC,而當(dāng)模型變?yōu)閙odel2的時(shí)候,最佳特征可能就變?yōu)榱薃CD。
為了解決這兩個(gè)問題,有一個(gè)比較成熟的自動(dòng)化方案可供我們使用。那就是多項(xiàng)式特征生成與自動(dòng)特征選擇。
這里我們借助sklearn中的多項(xiàng)式特征生成(sklearn.preprocessing.PolynomialFeatures)與RFECV(sklearn.feature_selection.RFECV,遞歸式特征消除)來解決這個(gè)問題。前者的作用是自動(dòng)生成多項(xiàng)式特征,如,x1,x2,生成特征為x1**x1,x1*x2,x2**x2等。而遞歸式特征消除,則是一種利用模型進(jìn)行特征消除的方法,需要模型本身帶有特征的重要程度這一項(xiàng),之后則不斷地遞歸調(diào)用自身,將不重要的特征去除,直到去除某個(gè)特征后,模型的預(yù)測(cè)效果下降為止。
技術(shù)棧
- Python3
- scikit-learn
- pandas
- numpy
- matplotlib
實(shí)現(xiàn)
數(shù)據(jù)
特征的自由組合有時(shí)會(huì)帶來性能提升,但并不一定一定是有效的。更多的時(shí)候我們需要要考慮的是實(shí)際業(yè)務(wù)的需要。這里我們選擇UCI的紅酒質(zhì)量數(shù)據(jù)集進(jìn)行處理,從實(shí)際業(yè)務(wù)上來說,紅酒質(zhì)量數(shù)據(jù)集中的特征都是單項(xiàng)的紅酒指標(biāo),但是實(shí)際上紅酒的評(píng)分本就并非直接與單項(xiàng)數(shù)據(jù)成正比,有些則是與特征之間的組合或者特征的幾次方成有效關(guān)系。因此我們這里就是用多項(xiàng)式特征生成與遞歸特征消除來自動(dòng)獲取符合實(shí)際業(yè)務(wù)的模型。
該數(shù)據(jù)的下載可以前往:http://archive.ics.uci.edu/ml/machine-learning-databases/wine-quality/winequality-red.csv
代碼
首先加載有關(guān)類庫
import numpy as np from sklearn.feature_selection import RFECV from sklearn.linear_model import LassoCV from sklearn.metrics import mean_squared_error from sklearn.model_selection import train_test_split from sklearn.preprocessing import StandardScaler之后創(chuàng)建數(shù)據(jù)加載的方法,并調(diào)用數(shù)據(jù);要注意的是我們這里使用的train_test_split方法進(jìn)行數(shù)據(jù)的分割,其中test_size=0.30,表示分割出百分之三十的數(shù)據(jù)作為測(cè)試數(shù)據(jù)集,隨機(jī)數(shù)種子為random_state=531,為隨機(jī)數(shù)種子賦值后我們將
def GetDataByPandas():import pandas as pdwine = pd.read_csv("/home/fonttian/Data/dataset/wine/wine.csv")y = np.array(wine.quality)X = np.array(wine.drop("quality", axis=1))columns = np.array(wine.columns)return X, y, columns X, y, wineNames = GetDataByPandas() scalar = StandardScaler() X = scalar.fit_transform(X)train_data, test_data, train_labels, test_labels = train_test_split(X, y, test_size=0.30, random_state=531)之后首先使用多項(xiàng)式特征生成方法進(jìn)行特征的自動(dòng)生成,具體代碼如下:
from sklearn.preprocessing import PolynomialFeaturespoly = PolynomialFeatures(2) print("原始數(shù)據(jù)的形狀:") print(train_data.shape) train_data_new = poly.fit_transform(train_data) test_data_new = poly.fit_transform(test_data) print("生成多項(xiàng)式特征之后的數(shù)據(jù)形狀:") print(train_data_new.shape) 原始數(shù)據(jù)的形狀: (1119, 11) 生成多項(xiàng)式特征之后的數(shù)據(jù)形狀: (1119, 78)此處參數(shù)2表示,特征生成的程度,如果需要生成3程度(也就是三次方和三個(gè)特征自由組合),只需要設(shè)置參數(shù)為3即可。另外還有一個(gè)參數(shù)interaction_only,表示是否只生成交互特征,如果為True,將不會(huì)生成特征與自身交互產(chǎn)生的特征(也就是幾次方之類的),該參數(shù)默認(rèn)為False。
之后我們需要選擇一個(gè)模型進(jìn)行數(shù)據(jù)的預(yù)測(cè),同時(shí)為了方便觀察以及避免超參數(shù)帶來的偶然性。我們這里選擇LassoCV方法進(jìn)行建模,該方法會(huì)使用交叉驗(yàn)證自動(dòng)選擇Lasso的最佳超參數(shù)alpha,這樣可以很大程度避免默認(rèn)超參數(shù)對(duì)實(shí)際結(jié)果的影響。具體代碼如下:
從最終結(jié)果來看,我們直接使用生成的67種特征+原11種特征進(jìn)行建模的效果并不好于直接使用原11種特征,這是必然是因?yàn)楫a(chǎn)生了大量的無用特征的緣故。下一步我們就需要借助遞歸式特征消除進(jìn)行特征選擇,將真正有效的特征選擇出來。
print("使用特征選擇,并進(jìn)行效果對(duì)比:")estimator = LassoCV(cv=10,n_jobs=-1) selector = RFECV(estimator, step=1, cv=5,n_jobs=-1) selector = selector.fit(X, y)selector_train_data = selector.fit_transform(train_data, train_labels) test_data_selector = selector.transform(test_data)print("特征選擇之后數(shù)據(jù)的shape:",selector_train_data.shape) wineModel = lcv_1.fit(selector_train_data, train_labels) print("alpha Value that Minimizes CV Error ", wineModel.alpha_) print("Minimum MSE ", min(wineModel.mse_path_.mean(axis=-1)))selector_train_data_new = selector.fit_transform(train_data_new, train_labels) test_data_new_selector = selector.transform(test_data_new)print("特征選擇之后數(shù)據(jù)的shape:",selector_train_data_new.shape) wineModel_new = lcv_2.fit(selector_train_data_new, train_labels) print("alpha Value that Minimizes CV Error ", wineModel_new.alpha_) print("Minimum MSE ", min(wineModel_new.mse_path_.mean(axis=-1))) 使用特征選擇,并進(jìn)行效果對(duì)比: 特征選擇之后數(shù)據(jù)的shape: (1119, 7) alpha Value that Minimizes CV Error 0.0008837665882418426 Minimum MSE 0.427181140352486 特征選擇之后數(shù)據(jù)的shape: (1119, 38) alpha Value that Minimizes CV Error 0.00038256145886961614 Minimum MSE 0.4002180554706169上面即是進(jìn)行特征選擇后的實(shí)際結(jié)果,可以很明顯的看到,如果僅僅對(duì)原始數(shù)據(jù)進(jìn)行特征選擇,那么大概能夠降低0.00413的平均誤差以及0.001的最小MSE;但是在對(duì)生成的多項(xiàng)式特征進(jìn)行特征選擇之后,其結(jié)果則得到的極大的下降(0.00588,0.234)。而且各位重要的是進(jìn)行特征選擇后的多項(xiàng)式數(shù)據(jù)集的擬合結(jié)果已經(jīng)明顯高于原有數(shù)據(jù)集的擬合結(jié)果。但是除了擬合結(jié)果之外更好地應(yīng)該是預(yù)測(cè)結(jié)果的變化,下面的代碼則是預(yù)測(cè)結(jié)果的變化:
# 輸出預(yù)測(cè)值 def show_prediction(model, X, y):prediction = model.predict(X)print("RMSE", np.sqrt(mean_squared_error(y, prediction)))print("MSE", mean_squared_error(y, prediction))show_prediction(lcv_1, test_data_selector, test_labels) show_prediction(lcv_2, test_data_new_selector, test_labels) RMSE 0.6440234501860966 MSE 0.4147662043896037 RMSE 0.6390612669439588 MSE 0.40839930290801785總結(jié)
從預(yù)測(cè)結(jié)果看,很明顯經(jīng)過多項(xiàng)式特征生成與遞歸特征消除的模型效果依舊要好于原有模型很多。同時(shí)更重要的地方在于,目前對(duì)于模型效果具有正面效果的數(shù)據(jù)很有可能是有意義的特殊特征組合。利用該方法我們也可以快速的獲得一個(gè)可能有用特殊意義的特征組合的集合,并引導(dǎo)我們發(fā)現(xiàn)這些特殊特征組合的現(xiàn)實(shí)意義。
總結(jié)
以上是生活随笔為你收集整理的利用多项式特征生成与递归特征消除解决特征组合与特征选择问题的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Applications模块解析(一)
- 下一篇: 自动化机器学习(二)自动构建机器学习流水