机器学习之局部加权,岭回归

问题

在这里插入图片描述

前面教程我们已经讲了 怎么样求解 y = Q *X 的过程 。

过拟合 和欠拟合

但是当数据量较小的时候 会遇到 这样的问题: 过拟合 和欠拟合

奇异矩阵问题

在这里插入图片描述 这个矩阵当没有 逆矩阵的时候怎么样求解。

局部加权

局部加权线性回归是普通线性回归的一个改进,普通的线性回归努力寻找一个使得全局代价函数最小的模型。这个模型对于整体来说是最好的,但对于局部点来说,可能不是最好的。比如图一是线性回归得到的模型,相对于图二来说,明显不够完美,图三虽然最完美但是存在过拟合风险。那么,如何用线性回归得到一个局部更准确(可能非线性模型拟合更好)的结果呢?这时,局部加权线性回归出现了。

在这里插入图片描述

过拟合

在这里插入图片描述
线太依赖训练数据了,完全贴着数据走 如图三
在训练集(training set)上表现好,但是在测试集上效果差,也就是说在已知的数据集合中非常好,但是在添加一些新的数据进来训练效果就会差很多,造成这样的原因是考虑影响因素太多,超出自变量的维度过于多了

欠拟合

如上图二 模型拟合不够,在训练集(training set)上表现效果差,没有充分的利用数据,预测的准确度低。预测值和实际值偏差过大 。

局部加权

如图 下图红线 太直 欠拟合 。 我们可以在每一个 预测点 适当的增加 一个权重 也就是稍微变弯曲,也就是去接近图中的 那条弯曲线。给每一个点 都加上一个权重。

在这里插入图片描述

这个权重 我们怎么取呢 ?
通常 我们用的是 高斯核函数 。
在这里插入图片描述
它的图像如下 :
在这里插入图片描述

x是待测点,r控制了权值变化的速率,r越大,图像越瘦,离x越远权值下降越快

我们发现这个图像很像高斯分布,越靠近x,权值越大

在这里插入图片描述

k 的取值 也就是 公式中的 r 取值 得到的图像。
在这里插入图片描述

公式:

这个公式 推导过程就不赘述了 ,网上也有很多 。

Y = Q * X Q 求解如下:
在这里插入图片描述
W 取上述的高斯核函数。

python 实践:


def loaddataSet(filename):
    numfeat = len(open(filename).readline().split('\t'))-1
    dataMat = [];labelsVec = []
    file = open(filename)
    for line in file.readlines():
        lineArr = []
        curLine = line.strip().split('\t')
        for i in range(numfeat):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelsVec.append(float(curLine[-1]))
    return dataMat,labelsVec
#局部加权
def lwlr(testPoint,xArr,yArr,k = 1.0):
    xMat = mat(xArr);yMat = mat(yArr).T
    m = shape(xMat)[0]
    weights = mat(eye(m))
    print("weights.shape=",weights.shape,yMat.shape)
    #  求解 权重 W 
    for i in range(m):
        diffMat = testPoint - xMat[i,:]
        weights[i,i] = exp(diffMat * diffMat.T/(-2.0*k**2))
    xTWx = xMat.T * (weights*xMat)
    if linalg.det(xTWx)==0.0:
        print('this matrix is singular,cannot do inverse\n')
        return
    #求解  Q
    sigma = xTWx.I * (xMat.T * (weights * yMat))
    #print("sigma==",sigma.shape)
    return testPoint * sigma

def lwlrTest(testArr,xArr,yArr,k = 1.0):
    m = shape(testArr)[0]
    yHat = zeros(m)
    print("m==",m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i],xArr,yArr,k)
    return yHat
def PlotLine1(testArr,xArr,yArr,k = 1.0):
    xMat = mat(xArr)
    yMat = mat(yArr)
    print(xMat.shape,yMat.shape)
    yHat = lwlrTest(testArr,xArr,yArr,k)
    srtInd = xMat[:,1].argsort(0)
    xsort = xMat[srtInd][:,0,:]
    ax = plt.subplot(111)
    ax.scatter(xMat[:,1].flatten().A[0],yMat.T[:,0].flatten().A[0],s = 2,c = 'red')
    ax.plot(xsort[:,1],yHat[srtInd])
    plt.show()
        

def Testlwlr():
    
    x,y=loaddataSet("./ex0.txt")

    print("xMat==",x.__sizeof__())

    x1,y1=loaddataSet("./ex1.txt")

    PlotLine1(x,x,y,0.05)

上述的 需要的txt 在git 上下载

岭回归

矩阵的知识

奇异矩阵:

若矩阵A相应的行列式D=0,称A为奇异矩阵,否则称为非奇异矩阵.

矩阵 的秩:

定义1:用初等行变换将矩阵A化为阶梯形矩阵, 则矩阵中非零行的个数就定义为这个矩阵的秩, 记为r(A),根据这个定义, 矩阵的秩可以通过初等行变换求得。需要注意的是, 矩阵的阶梯形并不是唯一的, 但是阶梯形中非零行的个数总是一致的

在这里插入图片描述

初等变换 和矩阵的秩 概念查看

结论:

在这里插入图片描述
若R(A)=n,称A为满秩矩阵(可逆矩阵,非奇异矩阵);
若R(A)<n,称A为降秩矩阵(不可逆矩阵,奇异矩阵)。
满秩矩阵是一个很重要的概念, 它是判断一个矩阵是否可逆的充分必要条件。

当 矩阵 M(n*n) 不是满秩矩阵的时候 就会 出现 在这里插入图片描述 为 0 的情况 。 也就是 这样的情况

在这里插入图片描述 为了 避免出现这种情况 我们给 他加上一个单位矩阵 乘上一个系数 。

在这里插入图片描述

最后:

在这里插入图片描述

那么 就变成了一个 满秩矩阵 不会出现为 0 的情况 。

所以 Q 的求解 方程 就可以变成如下 : 推导过程网上也很多 。
在这里插入图片描述

python 实现

#coding=utf-8

from  numpy  import *

import  numpy  as np 

import  matplotlib.pyplot  as plt 



filename='./ex0.txt' #文件目录
def loaddataSet(filename):
    numfeat = len(open(filename).readline().split('\t'))-1
    dataMat = [];labelsVec = []
    file = open(filename)
    for line in file.readlines():
        lineArr = []
        curLine = line.strip().split('\t')
        for i in range(numfeat):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelsVec.append(float(curLine[-1]))
    return dataMat,labelsVec




def   RidgeRegress(xMat ,yMat,lam=0.2):

     xTx = xMat.T *xMat

     print("xTx shape==",xTx.shape)



     denom=xTx + eye(shape(xMat)[1])*lam

     print("denom==", denom.shape)

     if  linalg.det(denom) == 0.0:

     	print ("  this  matrix   is singular  cannot do  inverse")

     	return 
     ws = denom.I *(xMat.T *yMat)

     print("ws shape==",ws.shape)

     return  ws 


def   RidgeTest(xArr,yArr):
      
      xMat = mat(xArr)

      yMat = mat(yArr).T
      
      yMen = mean(yMat,0)


      #yMat= yMat - yMen

      xMean = mean(xMat,0)

      #xMat =(xMat - xMean)


      print("xMat==",xMat)

      number =200

      wMat = zeros( (number,shape(xMat)[1]) )

      print("wMat=33=",wMat.shape)

      for  i in range(number):
         ws = RidgeRegress(xMat,yMat, exp(i-15) )


         wMat[i,:] = ws.T 
      return  wMat


def TestRidge():

     x,y= loaddataSet(filename)
     wMat = RidgeTest(x,y)
     
     print("wMat==",wMat.shape)

     PlotLine(x,wMat)

TestRidge()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值