这个单子让我学到了一种处理特征的过程,如何进行特征的选择
需求:最终项目报告应采用专业格式,内容应以提案为基础。一份好的结案报告详细介绍了项目提案的不同组成部分,作者的贡献,以及未来可以做的工作。木星笔记本:它应该展示所有的步骤,你执行得到的结果。它可能包括但不限于:YouTube视频。数据Descriptionw数据清洗和准备建模性能Evaluatione改进性能的步骤在您的图形和结果的模型分析中显示过拟合/非过拟合的证据。商务建议(根据你的分析,你的商务建议是什么?)如果你用R写程序,你应该用木星笔记本显示你的结果,并提交你的R文件。演示:在课堂上或通过YouTube视频进行5-10分钟的演示。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
%matplotlib inline
import numpy as np
from sklearn.feature_selection import RFE
#进行数据的获取
test=pd.read_excel('AirQualityUCI.xlsx')
#展示前5行
test.head()
Date | Time | CO(GT) | PT08.S1(CO) | NMHC(GT) | C6H6(GT) | PT08.S2(NMHC) | NOx(GT) | PT08.S3(NOx) | NO2(GT) | PT08.S4(NO2) | PT08.S5(O3) | T | RH | AH | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 2004-03-10 | 18:00:00 | 2.6 | 1360.00 | 150 | 11.881723 | 1045.50 | 166.0 | 1056.25 | 113.0 | 1692.00 | 1267.50 | 13.60 | 48.875001 | 0.757754 |
1 | 2004-03-10 | 19:00:00 | 2.0 | 1292.25 | 112 | 9.397165 | 954.75 | 103.0 | 1173.75 | 92.0 | 1558.75 | 972.25 | 13.30 | 47.700000 | 0.725487 |
2 | 2004-03-10 | 20:00:00 | 2.2 | 1402.00 | 88 | 8.997817 | 939.25 | 131.0 | 1140.00 | 114.0 | 1554.50 | 1074.00 | 11.90 | 53.975000 | 0.750239 |
3 | 2004-03-10 | 21:00:00 | 2.2 | 1375.50 | 80 | 9.228796 | 948.25 | 172.0 | 1092.00 | 122.0 | 1583.75 | 1203.25 | 11.00 | 60.000000 | 0.786713 |
4 | 2004-03-10 | 22:00:00 | 1.6 | 1272.25 | 51 | 6.518224 | 835.50 | 131.0 | 1205.00 | 116.0 | 1490.00 | 1110.00 | 11.15 | 59.575001 | 0.788794 |
test=test.replace(-200,np.nan)
test.isnull().sum()
Date 0
Time 0
CO(GT) 1683
PT08.S1(CO) 366
NMHC(GT) 8443
C6H6(GT) 366
PT08.S2(NMHC) 366
NOx(GT) 1639
PT08.S3(NOx) 366
NO2(GT) 1642
PT08.S4(NO2) 366
PT08.S5(O3) 366
T 366
RH 366
AH 366
dtype: int64
mean_cols=test.mean()
test = test.fillna(mean_cols)
test.isnull().sum()
Date 0
Time 0
CO(GT) 0
PT08.S1(CO) 0
NMHC(GT) 0
C6H6(GT) 0
PT08.S2(NMHC) 0
NOx(GT) 0
PT08.S3(NOx) 0
NO2(GT) 0
PT08.S4(NO2) 0
PT08.S5(O3) 0
T 0
RH 0
AH 0
dtype: int64
#使用皮尔逊相关性,不明白就百度下corr函数
plt.figure(figsize=(15,15))
cor = test.corr()
sns.heatmap(cor, annot=True, cmap=plt.cm.Reds)
plt.show()
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-EBrPlehs-1575808765743)(output_6_0.png)]
#由于图像中C6H6(GT)和其他变量相关性系数最高,所以提取C6H6(GT),并取相关性系数大于0.3的变量
features_cor =cor[abs(cor["C6H6(GT)"])>0.3]
#构建一个表,将相关性系数排列出来
features_cor = pd.DataFrame(features_cor["C6H6(GT)"])
#进行升序排列
features_cor.sort_values(by='C6H6(GT)')
C6H6(GT) | |
---|---|
PT08.S3(NOx) | -0.735711 |
NO2(GT) | 0.536178 |
NOx(GT) | 0.616880 |
PT08.S4(NO2) | 0.765717 |
CO(GT) | 0.812392 |
PT08.S5(O3) | 0.865727 |
PT08.S1(CO) | 0.883821 |
PT08.S2(NMHC) | 0.981962 |
C6H6(GT) | 1.000000 |
#观察相关性,由于RH,T,AH相关性很高,所以比较他们三的关系,由结果知道,他们三可以用一个变量表示,所以只取AH
print(test[["AH","T"]].corr())
print(test[["RH","T"]].corr())
AH T
AH 1.000000 0.656471
T 0.656471 1.000000
RH T
RH 1.000000 -0.578569
T -0.578569 1.000000
通过关系图我们可以提取出最有关系的几个变量为 自变量C6H6(GT) 因变量为 PT08.S1(CO) PT08.S2(NMHC) PT08.S3(NOx) PT08.S4(NO2) PT08.S5(O3),由于AH,T,HR的相关性很高,所以可以用一个自变量代替
df = test.loc[:,['PT08.S1(CO)','PT08.S2(NMHC)','PT08.S3(NOx)','PT08.S4(NO2)','PT08.S5(O3)','C6H6(GT)','AH']]
#查看他们的属性类别
df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 9357 entries, 0 to 9356
Data columns (total 7 columns):
PT08.S1(CO) 9357 non-null float64
PT08.S2(NMHC) 9357 non-null float64
PT08.S3(NOx) 9357 non-null float64
PT08.S4(NO2) 9357 non-null float64
PT08.S5(O3) 9357 non-null float64
C6H6(GT) 9357 non-null float64
AH 9357 non-null float64
dtypes: float64(7)
memory usage: 511.8 KB
#数据可视化
df.hist(figsize=(20,20))
array([[<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F96342E10>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F9658C6A0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F97879D30>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F9788C400>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F97ABAA90>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F97ABAAC8>],
[<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F9762F7F0>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F97659E80>,
<matplotlib.axes._subplots.AxesSubplot object at 0x0000029F976C9550>]],
dtype=object)
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-VnfprUF6-1575808765744)(output_12_1.png)]
#将原始数据划分
from sklearn.model_selection import train_test_split
#删除C6H6(GT)字段变为自变量
independent_vars=df.drop('C6H6(GT)',1)
#除了C6H6(GT)字段变为因变量
dependent_var=df['C6H6(GT)']
#调用函数train_test_split,三七划分训练集和测试集
x, x_holdout, y, y_holdout = train_test_split(independent_vars,dependent_var, test_size = 0.3, random_state = 0)
- 递归特征消除 (Recursive Feature Elimination)
递归消除特征法使用一个基模型来进行多轮训练,每轮训练后,移除若干权值系数的特征,再基于新的特征集进行下一轮训练。
sklearn官方解释:对特征含有权重的预测模型(例如,线性模型对应参数coefficients),RFE通过递归减少考察的特征集规模来选择特征。首先,预测模型在原始特征上训练,每个特征指定一个权重。之后,那些拥有最小绝对值权重的特征被踢出特征集。如此往复递归,直至剩余的特征数量达到所需的特征数量。
RFECV 通过交叉验证的方式执行RFE,以此来选择最佳数量的特征:对于一个数量为d的feature的集合,他的所有的子集的个数是2的d次方减1(包含空集)。指定一个外部的学习算法,比如SVM之类的。通过该算法计算所有子集的validation error。选择error最小的那个子集作为所挑选的特征。
from sklearn.svm import LinearSVR
#没用变量加入,建立数组
nof_list=np.arange(1,7)
#记录成绩
high_score=0
#变量来存储最优特征
nof=0
score_list =[]
for n in range(len(nof_list)):
x_train, x_test, y_train, y_test = train_test_split(x,y, test_size = 0.2, random_state = 1550)
model = LinearSVR(C=0.3,loss='squared_epsilon_insensitive',max_iter=5000)
# model= LinearSVR()
#n_features_to_select为选择的特征个数
rfe = RFE(model,nof_list[n])
x_train_rfe = rfe.fit_transform(x_train,y_train)
x_test_rfe = rfe.transform(x_test)
model.fit(x_train_rfe,y_train)
score = model.score(x_test_rfe,y_test)
score_list.append(score)
if(score>high_score):
high_score = score
nof = nof_list[n]
print("Optimum number of features: %d" %nof)
print("Score with %d features: %f" % (nof, high_score))
Optimum number of features: 2
Score with 2 features: 0.941529
cols = list(x.columns)
model = LinearSVR(C=0.3,loss='squared_epsilon_insensitive',max_iter=5000)
#初始化具有最优特征数的RFE模型
rfe = RFE(model,2)
#转换数据格式
x_rfe = rfe.fit_transform(x,y)
#模型拟合
model.fit(x_rfe,y)
temp = pd.Series(rfe.support_,index = cols)
selected_features_rfe = temp[temp==True].index
print(selected_features_rfe)
Index(['PT08.S2(NMHC)', 'AH'], dtype='object')
#建立selected_features_rfe数据,将最优特征选择
selected_features_rfe=pd.DataFrame(selected_features_rfe,columns=['features'])
selected_features_rfe=pd.DataFrame(selected_features_rfe,index=selected_features_rfe['features'])
LassoCV:Lasso回归可以使得一些特征的系数变小,甚至还使一些绝对值较小的系数直接变为0,从而增强模型的泛化能力
使用场景:对于高纬的特征数据,尤其是线性关系是稀疏的,就采用Lasso回归,或者是要在一堆特征里面找出主要的特征,那么 Lasso回归更是首选了
#使用svm算法进行模型预测
from sklearn.svm import SVR
from sklearn.linear_model import RidgeCV, LassoCV, Ridge, Lasso
lasso_model = LassoCV()
lasso_model.fit(x, y)
features_lasso = pd.DataFrame(lasso_model.coef_, index = x.columns,columns=['coef'])
features_lasso
coef | |
---|---|
PT08.S1(CO) | 0.001811 |
PT08.S2(NMHC) | 0.028699 |
PT08.S3(NOx) | 0.004177 |
PT08.S4(NO2) | -0.000184 |
PT08.S5(O3) | 0.000634 |
AH | 0.000000 |
#将特征选择lasso大于0.4选择
features_lasso=features_lasso[abs(features_lasso['coef'])>0.4]
features_lasso
coef |
---|
features_cor.index
Index(['CO(GT)', 'PT08.S1(CO)', 'C6H6(GT)', 'PT08.S2(NMHC)', 'NOx(GT)',
'PT08.S3(NOx)', 'NO2(GT)', 'PT08.S4(NO2)', 'PT08.S5(O3)'],
dtype='object')
features_lasso.index
Index([], dtype='object')
selected_features_rfe.index
Index(['PT08.S2(NMHC)', 'AH'], dtype='object', name='features')
pd.Series(list(features_cor.index)+list(features_lasso.index)+list(selected_features_rfe.index))
0 CO(GT)
1 PT08.S1(CO)
2 C6H6(GT)
3 PT08.S2(NMHC)
4 NOx(GT)
5 PT08.S3(NOx)
6 NO2(GT)
7 PT08.S4(NO2)
8 PT08.S5(O3)
9 PT08.S2(NMHC)
10 AH
dtype: object
#去重之后进行合并特征
merged_features=pd.Series(list(features_cor.index)+list(features_lasso.index)+list(selected_features_rfe.index)).unique()
merged_features
array(['CO(GT)', 'PT08.S1(CO)', 'C6H6(GT)', 'PT08.S2(NMHC)', 'NOx(GT)',
'PT08.S3(NOx)', 'NO2(GT)', 'PT08.S4(NO2)', 'PT08.S5(O3)', 'AH'],
dtype=object)
#通过逻辑回归模型进行预测
from sklearn import linear_model
model =linear_model.LinearRegression()
model.fit(x_train,y_train)
#训练集的结果
train_score = model.score(x_train, y_train)
#测试集的结果
test_score = model.score(x_test, y_test)
print('train score: {train_score:.6f}; test score: {test_score:.6f}'.format(
train_score=train_score, test_score=test_score))
train score: 0.971132; test score: 0.971982
print(model.predict(x_test))
[ 4.24564562 12.24119766 4.72304685 ... 13.54784616 6.92773087
5.95113968]