一、高效的嵌入法embedded 二、调逻辑回归的类LR_,通过画C的学习曲线来实现 三、系数累加法 四、包装法
#高效的嵌入法embedded
data = load_breast_cancer()
print(data.data.shape)
LR_ = LR(solver="liblinear",C=0.9,random_state=420)
cross_val_score(LR_,data.data,data.target,cv=10).mean()
x_embeded = SelectFromModel(LR_,norm_order=1).fit_transform(data.data,data.target) #norm_order=1表示使用l1范式进行筛选,模型会删除掉在l1范式下无效的特征
print(x_embeded.shape)
cross_val_score(LR_,x_embeded,data.target,cv=10).mean()
#能否让模型的拟合效果更好呢?在这里,我们有两种调整方式:
'''
一旦调整threshold,就不是在使用L1正则化选择特征,
而是使用模型的属性.coef_中生成的各个特征的系数来选择。
coef_虽然返回的是特征的系数,
但是系数的大小和决策树中的feature_ importances_以及降维算法中的可解释性方差explained_vairance_概念相似,
其实都是衡量特征的重要程度和贡献度的,
因此SelectFromModel中的参数threshold可以设置为coef_的阈值,即可以剔除系数小于threshold中输入的数字的所有特征
'''
full_x = []
not_full = []
threthod = np.linspace(0,abs(LR_.fit(data.data,data.target).coef_).max(),20)
k= 0
for i in threthod:
LR_ = LR(solver="liblinear",C=0.9,random_state=420)
x_dr = SelectFromModel(LR_,threshold = i).fit_transform(data.data,data.target)
full_x.append(cross_val_score(LR_,data.data,data.target,cv=10).mean())
not_full.append(cross_val_score(LR_,x_dr,data.target,cv=10).mean())
print(threthod[k],x_dr.shape[1]) #查看本次循环阈值和留下的特征个数
k += 1
plt.figure(figsize=(20,5))
plt.plot(threthod,full_x,label='full')
plt.plot(threthod,not_full,label='not_full')
plt.legend()
plt.xticks(threthod)
plt.show()
# threshold越来越大,被删除的特征越来越多,模型的效果也越来越差,模型效果最好的情况下需要保证有17个以上的特征。
#尝试细化学习曲线
full_x = []
not_full = []
threthod = np.linspace(0,0.10897274787330495,20)
k= 0
for i in threthod:
LR_ = LR(solver="liblinear",C=0.9,random_state=420)
x_dr = SelectFromModel(LR_,threshold = i).fit_transform(data.data,data.target)
full_x.append(cross_val_score(LR_,data.data,data.target,cv=10).mean())
not_full.append(cross_val_score(LR_,x_dr,data.target,cv=10).mean())
print(threthod[k],x_dr.shape[1]) #查看本次循环阈值和留下的特征个数
k += 1
plt.figure(figsize=(20,5))
plt.plot(threthod,full_x,label='full')
plt.plot(threthod,not_full,label='not_full')
plt.legend()
plt.xticks(threthod)
plt.show()
#通过细化的学习曲线,可知如果要保证模型的效果比降维前更好,我们需要保留25个特征,这对于现实情况来说,是一种无效的降维:需要30个指标来判断病情,和需要25个指标来判断病情,对医生来说区别不大。
#第二种方法是调逻辑回归的类LR_,通过画C的学习曲线来实现:
full_x = []
not_full = []
C = np.arange(0.01,10.01,0.5)
for i in C:
LR_ = LR(solver="liblinear",C=i,random_state=420)
x_dr = SelectFromModel(LR_,norm_order=1).fit_transform(data.data,data.target)
full_x.append(cross_val_score(LR_,data.data,data.target,cv=10).mean())
not_full.append(cross_val_score(LR_,x_dr,data.target,cv=10).mean())
print(max(not_full),C[not_full.index(max(not_full))]) #查看最大的值和对应的C
plt.figure(figsize=(20,5))
plt.plot(C,full_x,label='full')
plt.plot(C,not_full,label='not_full')
plt.legend()
plt.xticks(C)
plt.show()
#进一步细化学习曲线
full_x = []
not_full = []
C = np.arange(6.05,7.05,0.005)
for i in C:
LR_ = LR(solver="liblinear",C=i,random_state=420)
x_dr = SelectFromModel(LR_,norm_order=1).fit_transform(data.data,data.target)
full_x.append(cross_val_score(LR_,data.data,data.target,cv=10).mean())
not_full.append(cross_val_score(LR_,x_dr,data.target,cv=10).mean())
print(max(not_full),C[not_full.index(max(not_full))]) #查看最大的值和对应的C
plt.figure(figsize=(20,5))
plt.plot(C,full_x,label='full')
plt.plot(C,not_full,label='not_full')
plt.legend()
plt.xticks(C)
plt.show()
#验证模型:降维前
LR_ = LR(solver="liblinear",C=6.069999999999999,random_state=420)
cross_val_score(LR_,data.data,data.target,cv=10).mean()
#验证模型:降维后
LR_ = LR(solver="liblinear",C=6.069999999999999,random_state=420)
x_dr = SelectFromModel(LR_,norm_order=1).fit_transform(data.data,data.target)
cross_val_score(LR_,x_dr,data.target,cv=10).mean()