【Python】Pandas/Sklearn进行机器学习之特征筛选,有效提升模型性能
今天小編來說說如何通過pandas以及sklearn這兩個模塊來對數(shù)據(jù)集進(jìn)行特征篩選,畢竟有時候我們拿到手的數(shù)據(jù)集是非常龐大的,有著非常多的特征,減少這些特征的數(shù)量會帶來許多的好處,例如
提高預(yù)測的精準(zhǔn)度
降低過擬合的風(fēng)險(xiǎn)
加快模型的訓(xùn)練速度
增加模型的可解釋性
事實(shí)上,很多時候也并非是特征數(shù)量越多訓(xùn)練出來的模型越好,當(dāng)添加的特征多到一定程度的時候,模型的性能就會下降,從下圖中我們可以看出,
因此我們需要找到哪些特征是最佳的使用特征,當(dāng)然我們這里分連續(xù)型的變量以及離散型的變量來討論,畢竟不同數(shù)據(jù)類型的變量處理的方式不同,我們先來看一下對于連續(xù)型的變量而言,特征選擇到底是怎么來進(jìn)行的。
計(jì)算一下各個變量之間的相關(guān)性
我們先導(dǎo)入所需要用到的模塊以及導(dǎo)入數(shù)據(jù)集,并且用pandas模塊來讀取
from?sklearn.datasets?import?load_boston import?pandas?as?pd import?numpy?as?np import?matplotlib import?matplotlib.pyplot?as?plt import?seaborn?as?sns import?statsmodels.api?as?sm %matplotlib?inline from?sklearn.model_selection?import?train_test_split from?sklearn.linear_model?import?LinearRegression from?sklearn.feature_selection?import?RFE from?sklearn.linear_model?import?RidgeCV,?LassoCV,?Ridge,?Lasso這次用到的數(shù)據(jù)集是機(jī)器學(xué)習(xí)中尤其是初學(xué)者經(jīng)常碰到的,波士頓房價的數(shù)據(jù)集,其中我們要預(yù)測的這個對象是MEDV這一列
x?=?load_boston() df?=?pd.DataFrame(x.data,?columns?=?x.feature_names) df["MEDV"]?=?x.target X?=?df.drop("MEDV",1)???#將模型當(dāng)中要用到的特征變量保留下來 y?=?df["MEDV"]??????????#最后要預(yù)測的對象 df.head()output
CRIM????ZN??INDUS??CHAS????NOX??...????TAX??PTRATIO???????B??LSTAT??MEDV 0??0.00632??18.0???2.31???0.0??0.538??...??296.0?????15.3??396.90???4.98??24.0 1??0.02731???0.0???7.07???0.0??0.469??...??242.0?????17.8??396.90???9.14??21.6 2??0.02729???0.0???7.07???0.0??0.469??...??242.0?????17.8??392.83???4.03??34.7 3??0.03237???0.0???2.18???0.0??0.458??...??222.0?????18.7??394.63???2.94??33.4 4??0.06905???0.0???2.18???0.0??0.458??...??222.0?????18.7??396.90???5.33??36.2我們可以來看一下特征變量的數(shù)據(jù)類型
df.dtypesoutput
CRIM???????float64 ZN?????????float64 INDUS??????float64 CHAS???????float64 NOX????????float64 RM?????????float64 AGE????????float64 DIS????????float64 RAD????????float64 TAX????????float64 PTRATIO????float64 B??????????float64 LSTAT??????float64 MEDV???????float64 dtype:?object我們看到都是清一色的連續(xù)型的變量,我們來計(jì)算一下自變量和因變量之間的相關(guān)性,通過seaborn模塊當(dāng)中的熱力圖來展示,代碼如下
plt.figure(figsize=(10,8)) cor?=?df.corr() sns.heatmap(cor,?annot=True,?cmap=plt.cm.Reds) plt.show()相關(guān)系數(shù)的值一般是在-1到1這個區(qū)間內(nèi)波動的
相關(guān)系數(shù)要是接近于0意味著變量之間的相關(guān)性并不強(qiáng)
接近于-1意味著變量之間呈負(fù)相關(guān)的關(guān)系
接近于1意味著變量之間呈正相關(guān)的關(guān)系
我們來看一下對于因變量而言,相關(guān)性比較高的自變量有哪些
#?篩選出于因變量之間的相關(guān)性 cor_target?=?abs(cor["MEDV"]) #?挑選于大于0.5的相關(guān)性系數(shù) relevant_features?=?cor_target[cor_target>0.5] relevant_featuresoutput
RM?????????0.695360 PTRATIO????0.507787 LSTAT??????0.737663 MEDV???????1.000000 Name:?MEDV,?dtype:?float64篩選出3個相關(guān)性比較大的自變量來,然后我們來看一下自變量之間的相關(guān)性如何,要是自變量之間的相關(guān)性非常強(qiáng)的話,我們也只需要保留其中的一個就行,
print(df[["LSTAT","PTRATIO"]].corr()) print("="?*?50) print(df[["RM","LSTAT"]].corr()) print("="?*?50) print(df[["PTRATIO","RM"]].corr())output
LSTAT???PTRATIO LSTAT????1.000000??0.374044 PTRATIO??0.374044??1.000000 ==================================================RM?????LSTAT RM?????1.000000?-0.613808 LSTAT?-0.613808??1.000000 ==================================================PTRATIO????????RM PTRATIO??1.000000?-0.355501 RM??????-0.355501??1.000000從上面的結(jié)果中我們可以看到,RM變量和LSTAT這個變量是相關(guān)性是比較高的,我們只需要保留其中一個就可以了,我們選擇保留LSTAT這個變量,因?yàn)樗c因變量之間的相關(guān)性更加高一些
遞歸消除法
我們可以嘗試這么一種策略,我們選擇一個基準(zhǔn)模型,起初將所有的特征變量傳進(jìn)去,我們再確認(rèn)模型性能的同時通過對特征變量的重要性進(jìn)行排序,去掉不重要的特征變量,然后不斷地重復(fù)上面的過程直到達(dá)到所需數(shù)量的要選擇的特征變量。
LR=?LinearRegression() #?挑選出7個相關(guān)的變量 rfe_model?=?RFE(model,?7) #?交給模型去進(jìn)行擬合 X_rfe?=?rfe_model.fit_transform(X,y)?? LR.fit(X_rfe,y) #?輸出各個變量是否是相關(guān)的,并且對其進(jìn)行排序 print(rfe_model.support_) print(rfe_model.ranking_)output
[False?False?False??True??True??True?False??True??True?False??True?FalseTrue] [2?4?3?1?1?1?7?1?1?5?1?6?1]第一行的輸出包含True和False,其中True代表的是相關(guān)的變量對應(yīng)下一行的輸出中的1,而False包含的是不相關(guān)的變量,然后我們需要所需要多少個特征變量,才能夠使得模型的性能達(dá)到最優(yōu)
#將13個特征變量都依次遍歷一遍 feature_num_list=np.arange(1,13) #?定義一個準(zhǔn)確率 high_score=0 #?最優(yōu)需要多少個特征變量 num_of_features=0??????????? score_list?=[] for?n?in?range(len(feature_num_list)):X_train,?X_test,?y_train,?y_test?=?train_test_split(X,y,?test_size?=?0.3,?random_state?=?0)model?=?LinearRegression()rfe_model?=?RFE(model,feature_num_list[n])X_train_rfe_model?=?rfe_model.fit_transform(X_train,y_train)X_test_rfe_model?=?rfe_model.transform(X_test)model.fit(X_train_rfe_model,y_train)score?=?model.score(X_test_rfe_model,y_test)score_list.append(score)if(score>high_score):high_score?=?scorenum_of_features?=?feature_num_list[n] print("最優(yōu)的變量是:?%d個"?%num_of_features) print("%d個變量的準(zhǔn)確率為:?%f"?%?(num_of_features,?high_score))output
最優(yōu)的變量是:?10個 10個變量的準(zhǔn)確率為:?0.663581從上面的結(jié)果可以看出10個變量對于整個模型來說是最優(yōu)的,然后我們來看一下到底是哪10個特征變量
cols?=?list(X.columns) model?=?LinearRegression() #?初始化RFE模型,篩選出10個變量 rfe_model?=?RFE(model,?10)????????????? X_rfe?=?rfe.fit_transform(X,y)?? #?擬合訓(xùn)練模型 model.fit(X_rfe,y)?????????????? df?=?pd.Series(rfe.support_,index?=?cols) selected_features?=?df[df==True].index print(selected_features)output
Index(['CRIM',?'ZN',?'INDUS',?'CHAS',?'NOX',?'RM',?'DIS',?'RAD',?'PTRATIO','LSTAT'],dtype='object')正則化
例如對于Lasso的正則化而言,對于不相關(guān)的特征而言,該算法會讓其相關(guān)系數(shù)變?yōu)?,因此不相關(guān)的特征變量很快就會被排除掉了,只剩下相關(guān)的特征變量
lasso?=?LassoCV() lasso.fit(X,?y) coef?=?pd.Series(lasso.coef_,?index?=?X.columns)然后我們看一下哪些變量的相關(guān)系數(shù)是0
print("Lasso算法挑選了?"?+?str(sum(coef?!=?0))?+?"?個變量,然后去除掉了"?+??str(sum(coef?==?0))?+?"個變量")output
Lasso算法挑選了10個變量,然后去除掉了3個變量我們來對計(jì)算出來的相關(guān)性系數(shù)排個序并且做一個可視化
imp_coef?=?coef.sort_values() matplotlib.rcParams['figure.figsize']?=?(8,?6) imp_coef.plot(kind?=?"barh") plt.title("Lasso?Model?Feature?Importance")output
可以看到當(dāng)中有3個特征,‘NOX’、'CHAS'、'INDUS'的相關(guān)性為0
根據(jù)缺失值來進(jìn)行判斷
下面我們來看一下如何針對離散型的特征變量來做處理,首先我們可以根據(jù)缺失值的比重來進(jìn)行判斷,要是對于一個離散型的特征變量而言,絕大部分的值都是缺失的,那這個特征變量也就沒有存在的必要了,我們可以針對這個思路在進(jìn)行判斷。
首先導(dǎo)入所需要用到的數(shù)據(jù)集
train?=?pd.read_csv("credit_example.csv") train_labels?=?train['TARGET'] train?=?train.drop(columns?=?['TARGET'])我們可以先來計(jì)算一下數(shù)據(jù)集當(dāng)中每個特征變量缺失值的比重
missing_series?=?train.isnull().sum()?/?train.shape[0] df?=?pd.DataFrame(missing_series).rename(columns?=?{'index':?'特征變量',?0:?'缺失值比重'}) df.sort_values("缺失值比重",?ascending?=?False).head()output
缺失值比重 COMMONAREA_AVG????????????0.6953 COMMONAREA_MODE???????????0.6953 COMMONAREA_MEDI???????????0.6953 NONLIVINGAPARTMENTS_AVG???0.6945 NONLIVINGAPARTMENTS_MODE??0.6945我們可以看到缺失值最高的比重將近有70%,我們也可以用可視化的根據(jù)來繪制一下缺失值比重的分布圖
plt.rcParams['font.sans-serif']=['SimHei']?#用來正常顯示中文標(biāo)簽 plt.figure(figsize?=?(7,?5)) plt.hist(df['缺失值比重'],?bins?=?np.linspace(0,?1,?11),?edgecolor?=?'k',?color?=?'blue',?linewidth?=?2) plt.xticks(np.linspace(0,?1,?11)); plt.xlabel('缺失值的比重',?size?=?14);? plt.ylabel('特征變量的數(shù)量',?size?=?14);? plt.title("缺失值分布圖",?size?=?14);output
我們可以看到有一部分特征變量,它們?nèi)笔е档谋戎卦?0%以上,有一些還在60%以上,我們可以去除掉當(dāng)中的部分特征變量
計(jì)算特征的重要性
在基于樹的眾多模型當(dāng)中,會去計(jì)算每個特征變量的重要性,也就是feature_importances_屬性,得出各個特征變量的重要性程度之后再進(jìn)行特征的篩選
from?sklearn.ensemble?import?RandomForestClassifier clf?=?RandomForestClassifier() #?模型擬合數(shù)據(jù) clf.fit(X,Y) feat_importances?=?pd.Series(clf.feature_importances_,?index=X.columns) #?篩選出特征的重要性程度最大的10個特征 feat_importances.nlargest(10)我們同時也可以對特征的重要性程度進(jìn)行可視化,
feat_importances.nlargest(10).plot(kind='barh',?figsize?=?(8,?6))output
除了隨機(jī)森林之外,基于樹的算法模型還有很多,如LightGBM、XGBoost等等,大家也都可以通過對特征重要性的計(jì)算來進(jìn)行特征的篩選
Select_K_Best算法
在Sklearn模塊當(dāng)中還提供了SelectKBest的API,針對回歸問題或者是分類問題,我們挑選合適的模型評估指標(biāo),然后設(shè)定K值也就是既定的特征變量的數(shù)量,進(jìn)行特征的篩選。
假定我們要處理的是分類問題的特征篩選,我們用到的是iris數(shù)據(jù)集
iris_data?=?load_iris() x?=?iris_data.data y?=?iris_data.targetprint("數(shù)據(jù)集的行與列的數(shù)量:?",?x.shape)output
數(shù)據(jù)集的行與列的數(shù)量:??(150,?4)對于分類問題,我們采用的評估指標(biāo)是卡方,假設(shè)我們要挑選出3個對于模型最佳性能而言的特征變量,因此我們將K設(shè)置成3
select?=?SelectKBest(score_func=chi2,?k=3) #?擬合數(shù)據(jù) z?=?select.fit_transform(x,y) filter_1?=?select.get_support() features?=?array(iris.feature_names) print("所有的特征:?",?features) print("篩選出來最優(yōu)的特征是:?",?features[filter_1])output
所有的特征:??['sepal?length?(cm)'?'sepal?width?(cm)'?'petal?length?(cm)''petal?width?(cm)'] 篩選出來最優(yōu)的特征是:??['sepal?length?(cm)'?'petal?length?(cm)'?'petal?width?(cm)']那么對于回歸的問題而言,我們可以選擇上面波士頓房價的例子,同理我們想要篩選出對于模型最佳的性能而言的7個特征變量,同時對于回歸問題的評估指標(biāo)用的是f_regression
boston_data?=?load_boston() x?=?boston_data.data y?=?boston_data.target然后我們將擬合數(shù)據(jù),并且進(jìn)行特征變量的篩選
select_regression?=?SelectKBest(score_func=f_regression,?k=7) z?=?select_regression.fit_transform(x,?y)filter_2?=?select_regression.get_support() features_regression?=?array(boston_data.feature_names)print("所有的特征變量有:") print(features_regression)print("篩選出來的7個特征變量則是:") print(features_regression[filter_2])output
所有的特征變量有: ['CRIM'?'ZN'?'INDUS'?'CHAS'?'NOX'?'RM'?'AGE'?'DIS'?'RAD'?'TAX'?'PTRATIO''B'?'LSTAT'] 篩選出來的7個特征變量則是: ['CRIM'?'INDUS'?'NOX'?'RM'?'TAX'?'PTRATIO'?'LSTAT']本站qq群955171419,加入微信群請掃碼:
總結(jié)
以上是生活随笔為你收集整理的【Python】Pandas/Sklearn进行机器学习之特征筛选,有效提升模型性能的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 【深度学习】动漫风格迁移AnimeGAN
- 下一篇: java获取net地址 本机