熱線電話:13121318867

登錄
首頁精彩閱讀Pandas/Sklearn進行機器學習之特征篩選,有效提升模型性能
Pandas/Sklearn進行機器學習之特征篩選,有效提升模型性能
2021-11-22
收藏

作者:俊欣

來源:關于數據分析與可視化

今天小編來說說如何通過pandas以及sklearn這兩個模塊來對數據集進行特征篩選,畢竟有時候我們拿到手的數據集是非常龐大的,有著非常多的特征,減少這些特征的數量會帶來許多的好處,例如

  • 提高預測的精準度
  • 降低過擬合的風險
  • 加快模型的訓練速度
  • 增加模型的可解釋性

事實上,很多時候也并非是特征數量越多訓練出來的模型越好,當添加的特征多到一定程度的時候,模型的性能就會下降,從下圖中我們可以看出,

因此我們需要找到哪些特征是最佳的使用特征,當然我們這里分連續型的變量以及離散型的變量來討論,畢竟不同數據類型的變量處理的方式不同,我們先來看一下對于連續型的變量而言,特征選擇到底是怎么來進行的。

Pandas/Sklearn進行<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>之<a href='/map/tezheng/' style='color:#000;font-size:inherit;'>特征</a>篩選,有效提升模型性能

計算一下各個變量之間的相關性

我們先導入所需要用到的模塊以及導入數據集,并且用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

這次用到的數據集是機器學習中尤其是初學者經常碰到的,波士頓房價的數據集,其中我們要預測的這個對象是MEDV這一列

x = load_boston()
df = pd.DataFrame(x.data, columns = x.feature_names)
df["MEDV"] = x.target
X = df.drop("MEDV",1) #將模型當中要用到的特征變量保留下來 y = df["MEDV"] #最后要預測的對象 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 

我們可以來看一下特征變量的數據類型

df.dtypes 

output

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 

我們看到都是清一色的連續型的變量,我們來計算一下自變量和因變量之間的相關性,通過seaborn模塊當中的熱力圖來展示,代碼如下

plt.figure(figsize=(10,8))
cor = df.corr()
sns.heatmap(cor, annot=True, cmap=plt.cm.Reds)
plt.show()

相關系數的值一般是在-1到1這個區間內波動的

  • 相關系數要是接近于0意味著變量之間的相關性并不強
  • 接近于-1意味著變量之間呈負相關的關系
  • 接近于1意味著變量之間呈正相關的關系

我們來看一下對于因變量而言,相關性比較高的自變量有哪些

# 篩選出于因變量之間的相關性 cor_target = abs(cor["MEDV"]) # 挑選于大于0.5的相關性系數 relevant_features = cor_target[cor_target>0.5]
relevant_features

output

RM 0.695360 PTRATIO 0.507787 LSTAT 0.737663 MEDV 1.000000 Name: MEDV, dtype: float64 

篩選出3個相關性比較大的自變量來,然后我們來看一下自變量之間的相關性如何,要是自變量之間的相關性非常強的話,我們也只需要保留其中的一個就行,

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 

從上面的結果中我們可以看到,RM變量和LSTAT這個變量是相關性是比較高的,我們只需要保留其中一個就可以了,我們選擇保留LSTAT這個變量,因為它與因變量之間的相關性更加高一些

遞歸消除法

我們可以嘗試這么一種策略,我們選擇一個基準模型,起初將所有的特征變量傳進去,我們再確認模型性能的同時通過對特征變量的重要性進行排序,去掉不重要的特征變量,然后不斷地重復上面的過程直到達到所需數量的要選擇的特征變量。

LR= LinearRegression() # 挑選出7個相關的變量 rfe_model = RFE(model, 7) # 交給模型去進行擬合 X_rfe = rfe_model.fit_transform(X,y)  
LR.fit(X_rfe,y) # 輸出各個變量是否是相關的,并且對其進行排序 print(rfe_model.support_)
print(rfe_model.ranking_)

output

[False False False True True True False True True False True False True] [2 4 3 1 1 1 7 1 1 5 1 6 1] 

第一行的輸出包含TrueFalse,其中True代表的是相關的變量對應下一行的輸出中的1,而False包含的是不相關的變量,然后我們需要所需要多少個特征變量,才能夠使得模型的性能達到最優

#將13個特征變量都依次遍歷一遍 feature_num_list=np.arange(1,13) # 定義一個準確率 high_score=0 # 最優需要多少個特征變量 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 = score num_of_features = feature_num_list[n] print("最優的變量是: %d個" %num_of_features) print("%d個變量的準確率: %f" % (num_of_features, high_score)) 

output

最優的變量是: 10 10個變量的準確率為: 0.663581 

從上面的結果可以看出10個變量對于整個模型來說是最優的,然后我們來看一下到底是哪10個特征變量

cols = list(X.columns)
model = LinearRegression() # 初始化RFE模型,篩選出10個變量 rfe_model = RFE(model, 10)             
X_rfe = rfe.fit_transform(X,y) # 擬合訓練模型 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正則化而言,對于不相關的特征而言,該算法會讓其相關系數變為0,因此不相關的特征變量很快就會被排除掉了,只剩下相關的特征變量

lasso = LassoCV()
lasso.fit(X, y)
coef = pd.Series(lasso.coef_, index = X.columns)

然后我們看一下哪些變量的相關系數是0

print("Lasso算法挑選了 " + str(sum(coef != 0)) + " 個變量,然后去除掉了" + str(sum(coef == 0)) + "個變量")

output

Lasso算法挑選了10個變量,然后去除掉了3個變量

我們來對計算出來的相關性系數排個序并且做一個可視化

imp_coef = coef.sort_values()
matplotlib.rcParams['figure.figsize'] = (8, 6)
imp_coef.plot(kind = "barh")
plt.title("Lasso Model Feature Importance")

output

Pandas/Sklearn進行<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>之<a href='/map/tezheng/' style='color:#000;font-size:inherit;'>特征</a>篩選,有效提升模型性能

可以看到當中有3個特征,‘NOX’、'CHAS'、'INDUS'的相關性為0

根據缺失值來進行判斷

下面我們來看一下如何針對離散型的特征變量來做處理,首先我們可以根據缺失值的比重來進行判斷,要是對于一個離散型的特征變量而言,絕大部分的值都是缺失的,那這個特征變量也就沒有存在的必要了,我們可以針對這個思路在進行判斷。

首先導入所需要用到的數據集

train = pd.read_csv("credit_example.csv") train_labels = train['TARGET'] train = train.drop(columns = ['TARGET'])

我們可以先來計算一下數據集當中每個特征變量缺失值的比重

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%,我們也可以用可視化的根據來繪制一下缺失值比重的分布圖

plt.rcParams['font.sans-serif']=['SimHei'] #用來正常顯示中文標簽 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('特征變量的數量', size = 14); plt.title("缺失值分布圖", size = 14); 

output

Pandas/Sklearn進行<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>之<a href='/map/tezheng/' style='color:#000;font-size:inherit;'>特征</a>篩選,有效提升模型性能

我們可以看到有一部分特征變量,它們缺失值的比重在50%以上,有一些還在60%以上,我們可以去除掉當中的部分特征變量

計算特征的重要性

在基于樹的眾多模型當中,會去計算每個特征變量的重要性,也就是feature_importances_屬性,得出各個特征變量的重要性程度之后再進行特征的篩選

from sklearn.ensemble import RandomForestClassifier clf = RandomForestClassifier() # 模型擬合數據 clf.fit(X,Y) feat_importances = pd.Series(clf.feature_importances_, index=X.columns) # 篩選出特征的重要性程度最大的10個特征 feat_importances.nlargest(10) 

我們同時也可以對特征的重要性程度進行可視化,

feat_importances.nlargest(10).plot(kind='barh', figsize = (8, 6))

output

Pandas/Sklearn進行<a href='/map/jiqixuexi/' style='color:#000;font-size:inherit;'>機器學習</a>之<a href='/map/tezheng/' style='color:#000;font-size:inherit;'>特征</a>篩選,有效提升模型性能

除了隨機森林之外,基于樹的算法模型還有很多,如LightGBM、XGBoost等等,大家也都可以通過對特征重要性的計算來進行特征的篩選

Select_K_Best算法

Sklearn模塊當中還提供了SelectKBest的API,針對回歸問題或者是分類問題,我們挑選合適的模型評估指標,然后設定K值也就是既定的特征變量的數量,進行特征的篩選。

假定我們要處理的是分類問題的特征篩選,我們用到的是iris數據集

iris_data = load_iris()
x = iris_data.data
y = iris_data.target print("數據集的行與列的數量: ", x.shape)  

output

數據集的行與列的數量:  (150, 4)

對于分類問題,我們采用的評估指標是卡方,假設我們要挑選出3個對于模型最佳性能而言的特征變量,因此我們將K設置成3

select = SelectKBest(score_func=chi2, k=3)
# 擬合數據
z = select.fit_transform(x,y)
filter_1 = select.get_support()
features = array(iris.feature_names) print("所有的特征: ", features) print("篩選出來最優的特征是: ", features[filter_1])

output

所有的特征:  ['sepal length (cm)' 'sepal width (cm)' 'petal length (cm)' 'petal width (cm)']
篩選出來最優的特征是:  ['sepal length (cm)' 'petal length (cm)' 'petal width (cm)']

那么對于回歸的問題而言,我們可以選擇上面波士頓房價的例子,同理我們想要篩選出對于模型最佳的性能而言的7個特征變量,同時對于回歸問題的評估指標用的是f_regression

boston_data = load_boston() x = boston_data.data y = boston_data.target

然后我們將擬合數據,并且進行特征變量的篩選

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']

數據分析咨詢請掃描二維碼

若不方便掃碼,搜微信號:CDAshujufenxi

數據分析師資訊
更多

OK
客服在線
立即咨詢
日韩人妻系列无码专区视频,先锋高清无码,无码免费视欧非,国精产品一区一区三区无码
客服在線
立即咨詢