机器学习实战之回归

1.线性回归

1.1 优缺点

  • 结果易于理解,计算不复杂
  • 对非线性数据拟合效果不好,线性回归将数据视为线性的,可能会出现欠拟合现象,导致不能取得最好的预测效果.

1.2 回归的一般流程

      (1) 收集数据

      (2) 准备数据:回归需要数值型数据,标称型数据应该转换为二值型数据

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

      (4) 训练算法: 找到回归系数

      (5) 测试算法: 使用R的平方或者预测值和数据的拟合度来分析模型的效果

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

1.3 标准线性回归

     (1)误差函数为: 预测y值和真实y值之间的差值,该误差的平方和的累加

      通过最小二乘法来求解回归系数w的计算公式如下:

       此种求解方法只在XTX可逆的情况下有解.

       (2) 实现函数如下:

<span style="font-size:18px;">#实现标准回归函数
def standardRegres(xArr,yArr):
	xMat = mat(xArr) ; yMat = mat(yArr).T
	xTx = xMat.T*xMat
	#矩阵的逆不存在的话
	if linalg.det(xTx) == 0.0:
		print "this matrix is singular, cannot do inverse"
		return
	theta = xTx.I * (xMat.T * yMat)
	return theta</span>
      (3) 两个序列的相关系数,可以用来计算两个序列的匹配程度.即coefficient.
2. 局部加权线性回归(locally weighted linear regression)

2.1 算法思想

       给每个待预测点周围的点赋予一定的权重,越近的点权重越高,以此来选出该预测点对应的数据子集,然后在此数据子集上基于最小均方差进行普通的回归.

       局部加权线性回归采用"核"对附近的点赋予权重,此处采用高斯核,其中参数k需要用户指定,其决定了对附近的点赋予多大的权重.W是对角矩阵.xi与x越近,w(i,i)越大.


2.2 实现代码

<span style="font-size:18px;">#局部加权线性回归
def lwlr(testPoint,xArr,yArr,k=1.0):
	xMat = mat(xArr) ; yMat = mat(yArr).T
	m = shape(xMat)[0]
	weights = mat(eye((m)))
	for i in range(m):
		diffMat = testPoint - xMat[i,:]
		weights[i,i] = exp(diffMat * diffMat.T/(-2.0*k**2))
	xTx = xMat.T * (weights * xMat)
	if linalg.det(xTx) == 0.0:
		print "this matrix is singular "
		return
	theta = xTx.I * (xMat.T * (weights * yMat))
	return testPoint * theta

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</span>

当k越大时,越多的数据参与到线性回归中,效果和标准线性回归类似;当k越小时,越少的数据参与到线性回归中,容易产生过拟合.因此合适的k非常重要. 下图的k逐渐增大:

2.3 优缺点

     缺点: 增加了计算量, 因为其对每个点做预测时都必须使用整个数据集.在计算的过程中,发现大多数数据点的权重都接近0,如果避免这些计算将可以大大减少程序运行时间.


3. 岭回归(ridge regression)

3.1 定义

岭回归是一种缩减方法;

就是在矩阵XTX上加了一项从而使得矩阵非奇异,lamda由用户自己定义.

此时回归系数计算公式为:

3.2 训练过程

lamda用于限制所有w之和,通过引入该惩罚项,能够减少不重要的参数,因此能更好的理解数据.

确定lamda的过程:

       数据获取之后,分为训练集和测试集,选取不同的lamda来重复上述过程,最后选择使得预测误差最小的lamda.

下图是回归系数与log(lamda)之间的关系,当lamda最小时,得到的结果和线性回归一样,在最右边,回归系数全部减为0,即最好的结果应该处于中间.

除此之外,为了判断哪些变量对结果更具影响力,观察其对应系数大小即可.


实现代码如下:

<span style="font-size:18px;">#岭回归
def ridgeRegres(xMat,yMat,lam=0.2):
	xTx = xMat.T*xMat
	m = shape(xMat)[1]
	denom = xTx + eye(m)*lam
	if linalg.det(denom) == 0.0:
		print "this matrix is singular"
		return
	theta = denom.I * (xMat.T*yMat)
	return theta

def ridgeTest(xArr,yArr):
	xMat = mat(xArr); yMat = mat(yArr)
	ymean = mean(yMat,0)
	yMat = yMat - ymean
	
	xmean = mean(xMat,0)
	xvar = var(xMat,0)
	xMat = (xMat - xmean)/xvar

	testtimes = 30
	wMat = zeros((testtimes,shape(xMat)[1]))
	for i in range(testtimes):
		theta = ridgeRegres(xMat,yMat,exp(i-10))
		wMat[i,:] = theta.T
	return wMat</span>
3.3 数据预处理

  处理过程: 将所有特征减去各自的均值并除以其方差.测试时,也要将测试数据标准化处理,应该使用训练时的参数来对测试数据标准化.

3.4 tips

 增加如下约束时,普通的最小二乘法回归会得到和岭回归一样的公式:

这个式子限制了所有回归系数的平方和不能大于lamda.


另外一种缩减方法lasso,其对应的回归系数约束条件为所有回归系数的绝对值之和不能大于lamda.

4. 前向逐步回归

4.1 前向逐步回归定义

    一种贪心算法,每一步都尽可能减少误差.一开始, 所有的权重都设为1, 然后每一步所做的决策是对某个权重增加或减少一个很小的值,

4.2 算法过程

算法伪代码对应如下:

数据标准化,是其分布满足0均值和单位方差

在每轮迭代中:

        设置当前最小误差为正无穷

        对每个特征对应的系数:

              增大或减小:

                       改变一个系数得到一个新的w

                         计算新w下的误差,若小于u当前最小误差,更新最小误差

               更新w

真实代码如下:

<span style="font-size:18px;">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

#分别计算对每个w增加或减少特定的值后,读整体误差的影响
def stageWise(xArr,yArr,eps=0.01,numIt=100):
    xMat = mat(xArr); yMat=mat(yArr).T
    yMean = mean(yMat,0)
    yMat = yMat - yMean     #can also regularize ys but will get smaller coef
    xMat = regularize(xMat)
    m,n=shape(xMat)
    #returnMat = zeros((numIt,n)) #testing code remove
    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  #eps表示每次迭代需要调整的步长
                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
</span>
4.3 算法评价

   其主要优点在于可以帮助人们理解现有的模型并作出改进. 当构建了一个模型后, 可以运行该算法找出重要的特征, 可以及时的停止对不重要特征的收集.


5. 偏差与方差

误差: 模型与真实值之间存在差异,就存在误差

方差指的是模型之间的差异,偏差指的是模型预测值和数据之间的差异.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值