2019-3-11 机器学习-学习笔记

2019-03-11  本文已影响0人  DungSiugei

1. 线性回归

根据已有的数据点拟合出回归系数。

1)普通最小二乘法(OLS)

找出使误差最小的w(使用平方误差),即最小化:


平方误差

求一阶导,得其解为:


系数项得解
python代码为:
def loadDataSet(filename):
    numFeat = len(open(filename).readline().split('\t')) - 1
    #numFeat的值是2,因为文件一行有三个特征
    dataMat = []
    labelMat = []
    fr = open(filename)
    for line in fr.readlines():
        lineArr = []
        curLine = line.strip().split('\t')
        #一个有三个元素的list
        for i in range(numFeat):#(0,2)
            lineArr.append(float(curLine[i]))
            #提取前两个元素,最后一元素为标签
        dataMat.append(lineArr)
        #dataMat为一个list,每个元素是数据集前两项的list
        labelMat.append(float(curLine[-1]))
        #-1代表最后一行
    return dataMat, labelMat

def standRegres(xArr, yArr):
    xMat = mat(xArr)
    #mat()使每个元素单独成行,向量形式
    yMat = mat(yArr).T
    xTx = xMat.T*xMat
    #x转置乘x
    if linalg.det(xTx) == 0.0:
        print("this matrix is singular, cannot do inverse")
        return
    ws =xTx.I * (xMat.T*yMat)
    #回归系数
    return ws

尝试绘制图表

import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xMat[:, 1].flatten().A[0], yMat.T[:, 0].flatten().A[0], s=2, c='red')
#[a:b, n]代表从a开始到b行,输出list的第n-1列
#flatten() 将矩阵的每一个元素提取出来成为list的单独元素
ax.plot(xSort[:, 1], yHat[srtInd])
plt.show()

数据松散与否都有可能拟合出相同的曲线,所以要引进计算相关系数的办法,相关系数越大匹配越完美。

2. 局部加权线性回归

目的:解决线性回归欠拟合的问题
解的形式:


解的形式

而使用的核为高斯核,其权重为:


高斯核权重
而我们只需要确定一个合理的k值即可。
局部加权线性回归函数的代码如下:
def lwlr(testPoint, xArr, yArr, k=1.0):
    xMat = mat(xArr)
    yMat = mat(yArr).T
    m = shape(xMat)[0]
    #shape得出来是一个元祖:(行数, 列数)
    #这里m取了行数
    weights = mat(eye((m)))
    #生成一个m行m列对角线为1的对角矩阵
    for j in range(m):
        diffMat = testPoint - xMat[j, :]
        weights[j, j] = exp(diffMat * diffMat.T/(-2.0*k**2))
    xTx = xMat.T * (weights * xMat)
    if linalg.det(xTx) == 0.0:
        print("this matrix is singular, cannot do inverse")
        return
    ws = xTx.I * (xMat.T * (weights * yMat))
    return testPoint * ws

def lwlrTest(testArr, xArr, yArr, k=1.0):
    m = shape(testArr)[0]
    yHat = zeros(m)
    for i in range(m):
        yHat[i] = lwlr(testArr[i], xArr, yArr, k)
    return yHat

若k值过小会产生过拟合现象。

3. 缩减系数方法

目的:防止特征多于样本点数,出现矩阵不满秩的情况,这会在求逆时出现问题。解决方法:

1) 岭回归

加入一些东西让矩阵非奇异


岭回归系数形式

实现代码如下:

def ridgeRegres(xMat, yMat, lam = 0.2):
    xTx = xMat.T * xMat
    denom = xTx +eye(shape(xMat)[1]) * lam
    if linalg.det(denom) == 0.0:
        print("this matrix cannot inverse")
        return
    ws = denom.I * (xMat.T*yMat)
    return ws

def ridgeTest(xArr, yArr):
    xMat = mat(xArr)
    yMat = mat(yArr).T
    yMean = mean(yMat, 0)
    yMat = yMat - yMean
    xMean = mean(xMat, 0)
    xVar = var(xMat, 0)
    xMat = (xMat - xMean)/xVar
    numTestPts = 30
    wMat = zeros((numTestPts, shape(xMat)[1]))
    for i in range(numTestPts):
        ws = ridgeRegres(xMat, yMat, exp(i-10))
        wMat[i, :] = ws.T
    return wMat

λ越小,越接近普通回归;越大,则回归系数缩减为0.

2) lasso

普通最小二乘法回归加入如下约束


系数约束

因为计算太复杂了所以选用一个简单的方法:前向逐步回归,从1开始,每一步对某个权重增加或者减少一个很小的值
伪代码如下:

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

其代码如下:

def stageWise(xArr, yArr, eps=0.01, numIt=100):
    xMat = mat(xArr)
    yMat = mat(yArr).T
    yMean = mean(yMat, 0)
    #压缩行,对各列求值。如果是1则反过来
    yMat = yMat-yMean
    xMat = regularize(xMat)
    m, n = shape(xMat)
    returnMat = zeros((numIt, n))
    ws = zeros((n, 1))
    wsTest = ws.copy()
    wsMax = ws.copy()
    for i in range(numIt):
        print(ws.T)
        lowestError = inf
        for j in range(n):
            for sign in [-1, 1]:
                wsTest = ws.copy()
                wsTest[j] += eps*sign
                yTest = xMat*wsTest
                rssE = rssError(yMat.A, yTest.A)
                if rssE < lowestError:
                    lowestError = rssE
                    wsMax = wsTest
        ws = wsMax.copy()
        returnMat[i, :] = ws.T
    return returnMat
注:今天遇到的error

IndexError:list out of range
第一,可能是访问越界
第二,可能是list本身为空,访问list[0]的时候会发生错误

上一篇下一篇

猜你喜欢

热点阅读