《机器学习实战》学习笔记-[11]-回归-前向逐步回归

《机器学习实战》学习笔记-[11]-回归-前向逐步回归

其他学习:你应该掌握的七种回归技术 7 Types of Regression Techniques you should know!

原理简介

参考: Stepwise regression 学习笔记 、  Stepwise regression

(1)在特征较多时,我们面临降低维度分析的问题,也就是统计学中的缩减,去掉不重要的参数,对数据进行降维,根据在特定领域中的知识或是理论假设,选择其中一些可能更有意义的变量进行后续分析。但不是任何情况下我们都掌握这些先验信息,所以基于数据本身的特征提取方法应运而生。

(2)在 stepwise regression 中,提取哪些变量主要基于的假设是:在线性条件下,哪些变量组合能够解释更多的因变量变异,则将其保留。也就是那些参数的变化会更严重的影响到因变量(这些参数对因变量是主要影响因素)

(3)逐步线性回归优点:构建一个模型后,利用本算法找出重要的特征,及时停止对不重要特征的收集

具体操作方法有三种:

  • Forward selection: 首先模型中只有一个单独解释因变量变异最大的自变量,之后尝试将加入另一自变量,看加入后整个模型所能解释的因变量变异是否显著增加(这里需要进行检疫,可以用 F-test, t-test 等等);这一过程反复迭代,直到没有自变量再符合加入模型的条件。
  • Backward elimination: 与 Forward selection 相反,此时,所有变量均放入模型,之后尝试将其中一个自变量从模型中剔除,看整个模型解释因变量的变异是否有显著变化,之后将使解释量减少最少的变量剔除;此过程不断迭代,直到没有自变量符合剔除的条件。
  • Bidirectional elimination: 这种方法相当于将前两种结合起来。可以想象,如果采用第一种方法,每加入一个自变量,可能会使已存在于模型中的变量单独对因变量的解释度减小,当其的作用很小(不显著)时,则可将其从模型中剔除。而第三种方法就做了这么一件事,不是一味的增加变量,而是增加一个后,对整个模型中的所有变量进行检验,剔除作用不显著的变量。最终尽可能得到一个最优的变量组合。

实现

实现的伪代码如下:
《机器学习实战》学习笔记-[11]-回归-前向逐步回归_第1张图片

迭代numIT次,每次迭代对每个特征的系数增加或减少一个很小是值,看效果,保存本轮迭代中对因变量变化最大(使得预计值与真实值越接近)的这个特征值的系数;
比如第i个特征值的本轮wi 保存,w=[。。。。。,wi,。。。。],以这个w进行下一轮的迭代。
代码git: gitHub
'''
机器学习实战-回归
'''

from numpy import *


def loadDataSet(fileName):      #general function to parse tab -delimited floats
    numFeat = len(open(fileName).readline().split('\t')) - 1 #get number of fields
    dataMat = []; labelMat = []
    fr = open(fileName)
    for line in fr.readlines():
        lineArr =[]
        curLine = line.strip().split('\t')
        for i in range(numFeat):
            lineArr.append(float(curLine[i]))
        dataMat.append(lineArr)
        labelMat.append(float(curLine[-1]))
    return dataMat,labelMat

def rssError(yArr,yHatArr): #yArr and yHatArr both need to be arrays
    return ((yArr-yHatArr)**2).sum()


def regularize(xMat):#regularize by columns
    inMat = xMat.copy()
    inMeans = mean(inMat,0)   #calc mean then subtract it off
    inVar = var(inMat,0)      #calc variance of Xi then divide by it
    inMat = (inMat - inMeans)/inVar
    return inMat


def stepWise(xArr, yArr, eps=0.01, numIt=100):
    xMat = mat(xArr)
    yMat = mat(yArr).T
    # yMat归一化
    yMean = mean(yMat, 0)
    yMat = yMat - yMean
    # xMat归一化
    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): #迭代n个特征
            for sign in [-1,1]: #对每个特征加上或减去步进值对比效果
                wsTest= ws.copy()
                wsTest[j] += eps*sign
                yTest = xMat*wsTest
                rssErr = rssError(yMat.A,yTest.A)
                if rssErr < lowestError:
                    lowestError = rssErr
                    wsMax = wsTest
        ws = wsMax.copy()
        returnMat[i,:] = ws.T
    return returnMat
测试
import os

from numpy import *
import matplotlib.pyplot as plt


#导入训练数据集
from ML_Learn.com.ML.Regression.Regres_Stepwise import stepWiseRegres

xArr, yArr = stepWiseRegres.loadDataSet(os.getcwd() + '/resource/abalone.txt')

ridegeWeights = stepWiseRegres.stepWise(xArr, yArr,0.01,200)

[[ 0.  0.  0.  0.  0.  0.  0.  0.]]
[[ 0.    0.    0.    0.01  0.    0.    0.    0.  ]]
[[ 0.    0.    0.    0.02  0.    0.    0.    0.  ]]
[[ 0.    0.    0.    0.03  0.    0.    0.    0.  ]]
[[ 0.    0.    0.    0.04  0.    0.    0.    0.  ]]
[[ 0.    0.    0.    0.05  0.    0.    0.    0.  ]]
[[ 0.    0.    0.    0.06  0.    0.    0.    0.  ]]
[[ 0.    0.    0.01  0.06  0.    0.    0.    0.  ]]
[[ 0.    0.    0.01  0.06  0.    0.    0.    0.01]]

。。。。

[[ 0.05  0.    0.09  0.03  0.31 -0.64  0.    0.36]]
[[ 0.04  0.    0.09  0.03  0.31 -0.64  0.    0.36]]

以上

每次迭代中只改变一个wi 元素

最后
[[ 0.04  0.    0.09  0.03  0.31 -0.64  0.    0.36]]

可见w1和w6对目标值无影响,这两个特征值可以不需要,减少步长,增加迭代次数如0.001好5000,可以得到和最小二乘近似的结果。

【结论】

逐步线性回归优点:构建一个模型后,利用本算法找出重要的特征,及时停止对不重要特征的收集


你可能感兴趣的:([18]机器学习)