0A03 无监督学习:分类(1) 线性回归Ridge(岭回归)
岭回归是对OLS的改进,防止OLS随着维度使回归参数疯狂的增长.
在最小二乘法的基础上增加了惩罚项:aΣw2
a是一个可以调节的超参数,w是线性模型中所有参数的权重.
废话不多说,直接实战:
import numpy as np import matplotlib.pyplot as plt from sklearn import linear_model # 线性回归 # 初始化数据 def make_data(nDim): x0 = np.linspace(1,np.pi,50) x = np.vstack([[x0],[i**x0 for i in range(2,nDim+1)]]) # 按行不断相加 y = np.sin(x0) + np.random.normal(0,0.15,len(x0)) return x.transpose(),y # 关键是对X转置了 x,y = make_data(12) # 使用最小二乘法的结果 def linear_regression(): dims = [1,3,6,12] for idx, i in enumerate(dims): plt.subplot(2,len(dims)/2,idx+1) # 初始化子图 reg = linear_model.LinearRegression() sub_x = x[:,0:i] # 取x中前i个维度的特征 reg.fit(sub_x,y) # 训练 plt.plot(x[:,0],reg.predict(sub_x)) # 绘制模型曲线 plt.plot(x[:,0], y, '.') # x[:,0] 的意思就是取全部行,中的第一个值 ------> 就是取第一列 plt.title("dim=%s"%i) print("intercept_ %s"%(reg.intercept_,)) # 查看截距参数 print("coef: %s"%(reg.coef_,)) # 查看回归参数 plt.show() # linear_regression() # 使用岭回归 def ridge_regression(): alphas = [1e-12,1e-5,1e-1,10] # a参数 for idx,i in enumerate(alphas): plt.subplot(2, len(alphas)/2, idx+1) # 初始化子图 reg = linear_model.Ridge(alpha=i) # 岭回归模型 sub_x = x[:,0:12] # 抽取全部12维的特征 reg.fit(sub_x,y) # 训练 plt.plot(x[:,0], reg.predict(sub_x)) plt.plot(x[:,0], y, '.') plt.title("dim=12,alpha=%e"%i) print("alpha %e"%i) print("intercept_ %s"% (reg.intercept_)) print("coef_: %s"% (reg.coef_)) plt.show() ridge_regression()
结果:
可以看出 a越大,回归参数越小,模型越平缓.
不足:
可以看出岭回归的模型参数都只有非常小的绝对值,很难达到零值.这样造成的一个结果就是:可能有很多特征对最终结果的影响都微乎其微,但是我们还是要进行计算.
在大叔据系统中,这会对数据的产生,储存,传输,计算等各环节产生较大的浪费.
为了解决这个问题,下来我们将使用Lasso回归解决这个问题.