笔记跟上一个Task内容放到一起了
Task03 作业
1. 一个具体的案例解释什么叫偏差&方差
偏差度量的是单个模型的学习能力,模型的偏差是指:为了选择一个简单的模型去估计真实函数所带入的误差。偏差度量了学习算法的期望预测与真实结果的偏离程度,即刻画了学习算法本身的拟合能力。而方差度量的是同一个模型在不同数据集上的稳定性。
方差:期望值与真实值之间的波动程度,衡量的是稳定性
偏差:期望值与真实值之间的一致差距,衡量的是准确性
比如这个图就显示出偏差和方差的区别。
2. 偏差与方差和误差的关系
误差可以分解成预测值的方差,预测值的偏差平方和误差项的方差
3. 训练误差和测试误差的联系区别,如何估计测试误差?
计算方法相同,但是当模型建立时,我们无法得到测试数据和测试误差。我们只能构造使得训练误差达到最小的模型。
4. 岭回归和LASSO回归的异同点
都是压缩估计的方法,对回归的系数进行约束或者加罚的技巧对p个特征的模型进行拟合,将回归系数往零的方向压缩,显著降低模型方差,这样也会提高模型的拟合效果。
但是方法不同。
岭回归是L2正则化,系数可以趋近于0但不能等于0.岭回归通过牺牲线性回归的无偏性降低方差,有可能使得模型整体的测试误差较小,提高模型的泛化能力。
LASSO回归时L1正则化,可以做到特征选择
5. PCA降维前是一个三维椭球,把图形降维成二维是一个什么样的图形?
椭球面x²/a²+y²/b²+z²/c²=1进行PCA降维,主成分为长半轴a和中半轴b,若a=b,则降维结果是个⚪,若a>b,则为椭圆.
6. 用对偶理论和核函数对PCA进行非线性拓展,使得PCA变成非线性降维
7. 三种模型简化方法有何异同点
8.尝试使用sklearn,对一组数据进行特征的简化,再使用回归模型,使用网格搜索进行调参,观察三种方法的优劣
step0 调包
from sklearn import datasets
from sklearn import linear_model
import pandas as pd
from statsmodels.formula.api import ols #加载ols模型
from sklearn.pipeline import make_pipeline # 引入管道简化学习流程
from sklearn.preprocessing import StandardScaler # 由于SVR基于距离计算,引入对数据进行标准化的类
from sklearn.model_selection import GridSearchCV # 引入网格搜索调优
from sklearn.model_selection import cross_val_score # 引入K折交叉验证
from sklearn.pipeline import Pipeline
from sklearn.svm import SVR
step1 读取数据 使用sklearn.datasets里的diabetes
diabetes = datasets.load_diabetes()
X = diabetes.data
y = diabetes.target
features = diabetes.feature_names
diabetes_data = pd.DataFrame(X,columns=features) #[age, sex, bmi, bp平均血压, s1~s6一年后疾病级数指标]
diabetes_data["Target"] = y
print(diabetes_data.head())
step2 根据AIC准则定义向前逐步回归进行变量筛选
def forward_select(data,target):
variate=set(data.columns) #将字段名转换成字典类型
variate.remove(target) #去掉因变量的字段名
selected=[]
current_score,best_new_score=float('inf'),float('inf') #目前的分数和最好分数初始值都为无穷大(因为AIC越小越好)
#循环筛选变量
while variate:
aic_with_variate=[]
for candidate in variate: #逐个遍历自变量
formula="{}~{}".format(target,"+".join(selected+[candidate])) #将自变量名连接起来
aic=ols(formula=formula,data=data).fit().aic #利用ols训练模型得出aic值
aic_with_variate.append((aic,candidate)) #将第每一次的aic值放进空列表
aic_with_variate.sort(reverse=True) #降序排序aic值
best_new_score,best_candidate=aic_with_variate.pop() #最好的aic值等于删除列表的最后一个值,以及最好的自变量等于列表最后一个自变量
if current_score>best_new_score: #如果目前的aic值大于最好的aic值
variate.remove(best_candidate) #移除加进来的变量名,即第二次循环时,不考虑此自变量了
selected.append(best_candidate) #将此自变量作为加进模型中的自变量
current_score=best_new_score #最新的分数等于最好的分数
print("aic is {},continuing!".format(current_score)) #输出最小的aic值
else:
print("for selection over!")
break
formula="{}~{}".format(target,"+".join(selected)) #最终的模型式子
print("final formula is {}".format(formula))
# model=ols(formula=formula,data=data).fit()
return selected
selected =forward_select(data=diabetes_data,target="Target")
输出
aic is 4912.038220667561,continuing!
aic is 4828.398482363347,continuing!
aic is 4813.225718253229,continuing!
aic is 4804.962491886372,continuing!
aic is 4800.083415059462,continuing!
aic is 4788.602540139351,continuing!
for selection over!
final formula is Target~bmi+s5+bp+s1+sex+s2
step3 线性回归
lin_reg = linear_model.LinearRegression() # 创建线性回归的类
lin_reg.fit(diabetes_data[selected],y) # 输入特征X和因变量y进行训练
print("筛选特征后模型系数:",lin_reg.coef_) # 输出模型的系数
print("筛选特征后模型得分:",lin_reg.score(diabetes_data[selected],y)) # 输出模型的决定系数R^2
lin_reg.fit(diabetes_data[features],y) # 输入特征X和因变量y进行训练
print("原特征模型系数:",lin_reg.coef_) # 输出模型的系数
print("原特征模型得分:",lin_reg.score(diabetes_data[features],y)) # 输出模型的决定系数
筛选特征后模型系数: [ 529.87302638 804.19228215 327.2198497 -757.93791293 -226.51059686
538.58585291]
筛选特征后模型得分: 0.5148848325387045
原特征模型系数: [ -10.01219782 -239.81908937 519.83978679 324.39042769 -792.18416163
476.74583782 101.04457032 177.06417623 751.27932109 67.62538639]
原特征模型得分: 0.5177494254132935
step4 网格搜索
pipe_svr = Pipeline([("StandardScaler",StandardScaler()),
("svr",SVR())])
param_range = [0.0001,0.001,0.01,0.1,1.0,10.0,100.0,1000.0]
param_grid = [{"svr__C":param_range,"svr__kernel":["linear"]}, # 注意__是指两个下划线,一个下划线会报错的
{"svr__C":param_range,"svr__gamma":param_range,"svr__kernel":["rbf"]}]
gs = GridSearchCV(estimator=pipe_svr,
param_grid = param_grid,
scoring = 'r2',
cv = 10) # 10折交叉验证
gs = gs.fit(X,y)
print("网格搜索最优得分:",gs.best_score_)
print("网格搜索最优参数组合:\n",gs.best_params_)
网格搜索最优得分: 0.4741539611612783
网格搜索最优参数组合:
{'svr__C': 100.0, 'svr__gamma': 0.01, 'svr__kernel': 'rbf'}