美文网首页
2019-3-11 机器学习-学习笔记

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

作者: DungSiugei | 来源:发表于2019-03-11 21:43 被阅读0次

    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]的时候会发生错误

    相关文章

      网友评论

          本文标题:2019-3-11 机器学习-学习笔记

          本文链接:https://www.haomeiwen.com/subject/fpripqtx.html