都说万事开头难,可一旦开头,就是全新的状态,就有可能收获自己未曾预料到的成果。记录是为了更好的监督、理解和推进,学习过程中用到的数据集和代码都将上传到github

  回归是对一个或多个自变量和因变量之间的关系进行建模,求解的一种统计方法,之前的博客中总结了在线性回归中使用最小二乘法推导最优参数的过程和logistic回归,接下来将对最小二乘法、局部加权回归、岭回归和前向逐步回归算法进行依次说明和总结

1. 用线性回归找到最佳拟合曲线

(1)回归的一般方法

  收集数据:采用任意方法收集数据

  准备数据:回归需要数值型数据,标称型数据将被转成数值型数据

  分析数据:绘出数据的可视化二维图将有助于对数据做出理解和分析,在采用缩减法求得新回归系数之后,可以将新拟合线绘在图上作为对比

  训练算法:找到回归系数

  测试算法:使用R2或者预测值和数据的拟合度,来分析模型的效果

  使用算法:使用回归,可以在给定输入的时候预测出一个数值,这是对分类方法的提升,因为这样可以预测连续性数据而不仅仅是离散的类别标签

(2)需求

  对dataset/ex0.txt文件中的数据集采用线性回归找到最拟合直线,数据集:https://github.com/lizoo6zhi/MachineLearn.samples/tree/master/dataset

(3)绘制数据的可视化二维图

  

(4)通过最小二乘法得到最优参数

  前面我们已经推导过使用最小二乘法求最优参数:

  代码实现:

def stand_regres(dataset,label):"""标准线性回归函数dataset:listlabel:list"""X = np.mat(dataset)Y = np.mat(label).Ttemp = X.T * Xif np.linalg.det(temp) == 0.0:  #计算行式的值print("X.T*X没有逆矩阵")return else:temp = temp.I * X.T * Yreturn temp

  注意上面代码中红色标记处,通过计算行列式的值判断X.T*X是否有逆矩阵

(5)通过计算出的最优参数对样本进行回归测试,并绘制拟合曲线

def plot_stand_regress(dataset,label,ws,ax):"""绘制数据集和拟合曲线"""dataset_matrix = np.mat(dataset)x = dataset_matrix[:,1]y = labelcal_y = dataset * wsax.scatter(x.T.getA(),y,s=10,c='red')ax.plot(x,cal_y)

(6)在python中,NumPy库提供了相关系数的计算方法,可以通过corrcoef(yEstimate,yActual)来计算预测值与真实值的相关性

print(np.corrcoef(cal_y.T,np.mat(y)))

  从上图可以看出,预测值与真实值之间的相关系数为0.98647356

  最佳拟合直线方法将数据视为直线进行建模,具有十分不错的效果,但若是数据的离散程度很大呢,那该怎么办?

2. 局部加权线性回归

  我们现实生活中的很多数据不一定都能用线性模型描述。比如房价问题,很明显直线非但不能很好的拟合所有数据点,而且误差非常大,但是一条类似二次函数的曲线却能拟合地很好。为了解决非线性模型建立线性模型的问题,我们预测一个点的值时,对这个点附近的点设置权值。基于这个思想,便产生了局部加权线性回归算法。在这个算法中,其他离一个点越近,权重越大,对回归系数的贡献就越多。损失函数如下:
  
  其中w(i)是权重,它根据要预测的点与数据集中的点的距离来为数据集中的点赋权值,当某点离要预测的点越远,其权重越小,否则越大。一个比较好的权重函数如下:

  
 
  该函数称为指数衰减函数,其中k为波长参数,它控制了权值随距离下降的速率,该函数形式上类似高斯分布(正态分布),但并没有任何高斯分布的意义。该算法解出回归系数如下:

  

注:局部加权线性回归中的上述内容摘抄自https://blog.csdn.net/herosofearth/article/details/51969517,非常感谢作者分享!

(1)需求

  使用局部加权线性回归对dataset/ex0.txt文件中的数据集进行曲线拟合

(2)实现

def lwrw(test_point, xarray, yarray, k = 1.0):"""局部加权回归函数(locally weighted linear regression)dataset:listlabel:list"""mat_x = np.mat(xarray)mat_y = np.mat(yarray).Trow,col = np.shape(mat_x)    weights = np.mat(np.eye(row))for i in range(row):diffmat = test_point - mat_x[i,:]weights[i,i] = np.exp((diffmat*diffmat.T)/(-2.0*k*k))temp = mat_x.T * weights * mat_xif np.linalg.det(temp) == 0.0:print("mat_x.T * weights * X没有逆矩阵")return else:temp = temp.I * mat_x.T * weights * mat_yreturn test_point*temp

(3)测试

  分别设置k为0.01和0.003,当k=1时拟合效果和最小二乘法拟合效果一样

def plot_lwrw_regress(dataset,label,cal_y_list,ax):"""绘制数据集和拟合曲线"""dataset_matrix = np.mat(dataset)x = dataset_matrix[:,1]y = labelax.scatter(x.T.getA(),y,s=10,c='red')#对dataset进行排序sorted_index = x.argsort(0)sorted_x = dataset_matrix[sorted_index][:,0,:] #关键ax.plot(sorted_x[:,1],cal_y_list[sorted_index])if __name__ == "__main__":dataset,label = load_dataset('dataset/ex0.txt')fig = plt.figure()#当k为0.01时for row in range(rows):cal_y = lwrw(dataset[row],dataset,label,0.01)x_y_map[row] = cal_yax = fig.add_subplot(323)ax.text(0.05,4.2,'k=0.01')plot_lwrw_regress(dataset,label,x_y_map,ax)#当k为0.003for row in range(rows):cal_y = lwrw(dataset[row],dataset,label,0.003)x_y_map[row] = cal_yax = fig.add_subplot(325)ax.text(0.05,4.2,'k=0.003')plot_lwrw_regress(dataset,label,x_y_map,ax)plt.show()

  效果:

  大家可以通过不同的k系数测试效果,局部加权线性回归存在一个问题就是增加了计算量,因为它对每个点做预测时都必须使用整个数据集

3. 岭回归

  思考下,如果数据的特征比样本还多应该怎么办?是否还可以使用线性回归和之前的方法来做预测?

  答案是否定的,即不能再使用前面介绍的方法,这是因为在计算(X.T*X)的逆矩阵的时候会出错

  有逆矩阵的矩阵一定是方正,但方正不一定有逆矩阵,只有方正的行列式不为0时才有逆矩阵

  为了解决整个问题,统计学家引入了岭回归(ridge regression)的概念,简单的说,岭回归就是在X.T * X上加一个λI使得矩阵非奇异,进而确保(X.T * X + λI)一定可逆,其中I为m*m的单位矩阵,λ是用户定义的一个数值,我们可以通过测试使用不同的λ参数来确定最优λ

  岭回归与多项式回归唯一的不同在于代价函数上的差别。岭回归的代价函数如下:

  

  为了方便计算导数,通常也写成下面的形式:

  

  上式中的w是长度为n的向量,不包括截距项的系数θ0;θθ是长度为n+1的向量,包括截距项的系数θ0;m为样本数;n为特征数

  岭回归的代价函数仍然是一个凸函数,因此可以利用梯度等于0的方式求得全局最优解(正规方程):

  

(1)需求

  通过可视化图形描述λ与回归系数之间的关系

(2)实现

  通过以e为底的指数函数设置λ的值,如:exp(i-10),i为[0,30],同公式计算不同λ下回归系数的变化

(3)代码

def ridge_regres(xarray,yarray,lam=0.2):"""岭回归处理当特征比样本点还多,也酒水说输入数据的矩阵X不是满秩矩阵,非满秩矩阵在求逆时会出现问题w = (X.T*X + rI).I * X.T * Y"""xmat = np.mat(xarray)ymat = np.mat(yarray).Txtx = xmat.T * xmatdenom = xtx + np.eye(np.shape(xmat)[1])*lamif np.linalg.det(denom) == 0.0:print('denom 没有逆矩阵')ws = denom.I * xmat.T * ymatreturn wsdef ridge_test(xarray,yarray,ax):xmat = np.mat(xarray)row,col = np.shape(xmat)ymat = np.mat(yarray)xmean,xvar = data_normalize(xarray) #对数据进行标准化处理np.seterr(divide='ignore',invalid='ignore')xmat = (xmat - xmean) / xvarnum_test_pts = 30wmat = np.ones((num_test_pts,col))lam_list = []for i in range(num_test_pts):lam = np.exp(i-10)lam_list.append(i-10)ws = ridge_regres(xarray,yarray,lam)wmat[i,:] = ws.T#绘制不同lam情况下参数变化情况for j in range(np.shape(wmat)[1]):ax.plot(lam_list,wmat[:,j])

  效果:

  x轴为i的取值,y轴为回归系数值,从图可以看出当λ非常小时,系数和普通回归一样,当λ非常大时,所有回归系数都缩减为0,因此,我们可以在中间某处找到是的预测的结果最好的λ值

  以下为λ=0.02的效果图

  这样我们可以结合局部加权和岭回归计算最优回归系数,还有其他一些缩减方法,如lasso、LAR、PCA回归以及子集选择等,这些方法不仅可以提高预测精确率,而且还可以解释回归系数,将后续进行总结

  再使用岭回归对数据集dataset/abalone.txt测试,看看回归系数变化

4. 前向逐步回归

  前向逐步回归算法可以得到与lasso差不多的效果,但更加简单。前向回归算法属于一种贪心算法,即每一步都尽可能减少误差,一开始,所有的权重都设为1,然后每一步所作的决策是对某个权重增加或减少一个很小的值

  伪代码如下: 

数据标准化,使其分布满足0均值和单位方差
在每轮迭代过程中:设置当前最小误差lowestError为正无穷对每个特征:增大或减少:改变一个系数得到一个新的w计算新w下的误差如果误差error小于当前最小误差:设置wbest等于当前的w将当前w设置为新的wbest

(1)需求

  使用前向逐步回归算法,算出最优回归参数,并可视化显示回归参数随迭代次数的变化情况,最后标准回归算法进行比较

(2)代码实现

def stage_wise(dataset,label,step,numiter=100):"""前向逐步回归"""xmat = np.mat(dataset)xmean,xvar = data_normalize(dataset) #平均值和标准差ymat = np.mat(label).Tymat = ymat - np.mean(ymat,0)xmat = (xmat - xmean) / xvarm,n = np.shape(xmat)return_mat = np.zeros((numiter,n))ws = np.zeros((n,1))ws_test = ws.copy()ws_max = ws.copy()for iter in range(numiter):  #迭代次数lowest_error = np.inffor j in range(n):  #对每个特征进行变量for sign in [-1,1]:ws_test = ws.copy()ws_test[j] += step*signytest = xmat * ws_testrssE = ((ymat.A-ytest.A)**2).sum()if rssE < lowest_error:lowest_error = rssEws_max = ws_testws = ws_max.copy()return_mat[iter,:] = ws.Treturn return_mat    def stage_wise_test(ws_mat,iternum,ax):"""前向逐步回归算法中回归系数随迭代次数的变化情况"""    x = range(iternum)for i in range(np.shape(ws_mat)[1]):ax.plot(x,ws_mat[:,i])

(3)测试,输出可视化效果

#前向逐步回归
ax = fig.add_subplot(326)
ws = stage_wise(dataset,label,0.01,500)
print("前向逐步回归经过迭代后的最后回归系数:",ws[-1,:])
stage_wise_test(ws,500,ax)

  效果:

  上图表示了回归系数随迭代次数的变化情况,当迭代150次时,回归系数稳定分别为:

(4)接下来使用标准回归算法,也就是最小二乘法对dataset/abalone.txt数据集进行测试,计算回归系数

    #使用标准回归对"dataset/abalone.txt"数据集进行测试#对数据进行标准化处理xman,xvar = data_normalize(dataset)xmat = np.mat(dataset)xmat = (xmat - xman) / xvarymat = np.mat(label)ax = stand_regres(xmat,ymat)print("标准回归后得到的回归系数:",ws[-1,:])

  最终输出结果和前向逐步回归算出系数一样:

5. 总结

  与分类一样,回归也是预测目标值的过程,回归与分类的不同点在于,前者预测连续性变量,而后者预测离散型变量,回归是统计学中最有力的工具之一,在回归方程里,求得特征对应的最佳回归系数的方法是最小 化误差的平方和,给定输入的矩阵X,如果X.T * X的逆存在并可以求得的化,回归法可以直接使用,数据集上计算出的回归方程并不一定意味着它是最佳的,可以使用预测值yHat和原始值y的相关性来度量回归方程的好坏。 

  当数据的样本数比特征数还少的时候,矩阵X.T * X的逆不能直接计算,即便当样本数比特征数多时,X.T * X的逆仍可能无法直接计算,这是因为特征有可能高度相关,这时可以考虑使用岭回归,因为当X.T * X的逆不能计算时,它仍保证能求得回归系数

  岭回归是缩减法的一种,相当于对回归系数的大小施加了限制,另一种很好的缩减法是lasso,lasso难以求解,但可以 使用计算简便的逐步线性回归方法来求得近似解

  最后来张综合图:

转载于:https://www.cnblogs.com/xiaobingqianrui/p/10260453.html

机器学习之局部加权、岭回归和前向逐步回归相关推荐

  1. 机器学习实战--局部加权线性回归(LWR)

    一 概述 通常情况下的线性拟合不能很好地预测所有的值,因为它容易导致欠拟合(under fitting),比如数据集是 一个钟形的曲线.而多项式拟合能拟合所有数据,但是在预测新样本的时候又会变得很糟糕 ...

  2. 机器学习之LASSO,岭回归

    回归算法 文章参考 1.线性回归 假设有数据有 其中: 其中m为训练集样本数,n为样本维度,y是样本的真实值.线性回归采用一个多维的线性函数来尽可能的拟合所有的数据点,最简单的想法就是最小化函数值与真 ...

  3. 机器学习(13)岭回归(线性回归的改进)

    目录 一.基础理论 API 二.岭回归:预测波士顿房价 总代码 一.基础理论 岭回归:带有L2正则化的线性回归.(为了解决过拟合) 对病态数据的拟合要强于最小二乘法 API sklearn.linea ...

  4. 深入浅出python机器学习_4.3.1_岭回归的原理 4.3.2_岭回归的参数调节

    # 重启显示图加这句代码就好了 %matplotlib inlinefrom sklearn.linear_model import LinearRegressionfrom sklearn.mode ...

  5. 【机器学习】2. 线性模型 - 岭回归

    上一篇:[普通最小二乘法] 文章目录 岭回归 增大alpha 减小alpha alpha与模型复杂度的对应关系 完整代码 岭回归 Ridge 回归通过对系数的大小施加惩罚来解决 普通最小二乘法 的一些 ...

  6. 深入浅出python机器学习_4.3.2_岭回归的参数调节-2_绘制折线图

    # 重启显示图加这句代码就好了 %matplotlib inlineimport numpy as npimport matplotlib.pyplot as pltfrom sklearn.line ...

  7. 机器学习实战——岭回归、缩减法

    一.基本知识 1.岭回归:从公式看,加入正则化项(2范数). 回归系数的计算公式为: 问题引入:若给定数据集X,如果XTX的逆存在,可以使用常规的线性回归方法.但是, (1)数据样本数比特征数少的情况 ...

  8. 殊途同归的两种角度理解岭回归(内含有sklearn例子)

    在学习统计学专业课<回归分析技术>时学过岭回归,学机器学习时也涉及到岭回归,但是两个角度的思想方法略有不同,但最后的结果却是殊途同归的,最近准备统计学考研的复试时,对比了两种思路,觉得很有 ...

  9. 套索回归 岭回归_使用kydavra套索选择器进行回归特征选择

    套索回归 岭回归 机器学习(Machine Learning) We all know the Occam's Razor: 我们都知道Occam的剃刀: From a set of solution ...

最新文章

  1. HDU 3632 A Captivating Match
  2. java获取mysql表结构
  3. poj 2001 trie
  4. 建议15: 使用dynamic来简化反射实现
  5. 智能卡电子钱包应用密钥体系
  6. Matlab绘图添加直角坐标轴
  7. VMware ESX 5.0 网卡负载均衡配置3种方法
  8. 你还在因为数学对AI望而却步?看看这本秘籍吧
  9. HBase海量数据高效入仓解决方案
  10. java设计模式案例及使用
  11. 天下手游一直显示连接服务器,《天下手游》4月11日合服公告
  12. 第1天学习打卡(Javaweb 邮件发送:原理、发送简单文本邮件、发送带图片和附件邮件、网站注册发送邮件Servlet实现)
  13. android 触摸 事件,Android触屏事件和MotionEvent详解
  14. Python实现孤立森林(IForest)+SVR的组合预测模型
  15. 几个shape格式、tiff格式地图免费下载网站
  16. 少女枪战怎么用电脑玩 少女枪战模拟器玩法教程
  17. 复旦大学游记(r10笔记第88天)
  18. 拼多多获得搜索词推荐 API
  19. Centos7安装jdk1.8和tomcat9
  20. pytorch 定义torch类型数据_PyTorch官方中文文档:torch.Tensor

热门文章

  1. NIDS阻断功能研究
  2. Protege-OWL笔记3推理机(非一致性)
  3. *1.设计一个异常类表示对负数求平方根的错误,在类Test的main方法中,* 从键盘中输入一个数字,若输入的数不小于0,则输出该数的平方根(用Math.sprt());* 若小于0,则抛出自定义
  4. 关于移动硬盘突然变成RAW格式后如何自救数据
  5. 冰蓝云支付系统 可对接官方接口易支付码支付
  6. 适合小朋友的Scratch动手项目!AI在生活中的19个应用
  7. 安卓硬件模拟大师_安卓模拟器电脑版下载有哪些好用的?试试这4款(软件篇)...
  8. H264视频编码级别说明profile level Encoder
  9. python检测微信好友是否删除_基于Python+adb实现微信是否好友检测
  10. 重庆车检院联合联通、华为共建“5G-V2X自动驾驶创新平台”