机器学习--基于线性回归,减缩系数来“理解”数据

  如果数据的特征比样本点还多应该怎么办?是否还可以使用线性回归?答案是否定的。多元线性回归的算法,需要输入数据的矩阵是满秩矩阵。如果特征比样本点多,则说明输入矩阵不是满秩矩阵。
  为了解决以上问题,我们可以引入 “岭回归”“lasso法”“前向逐步回归” 三种缩减方法。
  缩减: 通过引入惩罚项,减少不重要的参数,这个技术在统计学中叫做缩减。

岭回归

  岭回归就是在矩阵 X T X X^TX XTX上加上一个 λ I \lambda I λI从而使得矩阵非奇异,进而能对 X T X + λ I X^TX+\lambda I XTX+λI求逆。其中矩阵 I I I是一个mxm的单位矩阵,对角线上元素全为1,其他元素全为0。而 λ \lambda λ是一个用户定义的数值。回归系数的计算公式将变成:

     w ^ = ( X T X + λ I ) − 1 X T y \hat{w} = (X^TX+\lambda I)^{-1}X^Ty w^=(XTX+λI)1XTy

算法思想

  岭回归通过预测误差最小化得到 λ \lambda λ

  1. 获取数据后首先抽取一部分数据作为测试集,剩下数据作为训练集用于训练参数 w w w
  2. 训练完毕后在测试集上测试预测性能
  3. 选取不同的 λ \lambda λ重复上述的过程,最终得到一个使预测误差最小的 λ \lambda λ

代码实现

对岭回归代码的实现:

def ridgeRegress(xMat, yMat, lam = 0.2):
    xTx = xMat.T * xMat
    denom = xTx + eye(int(shape(xMat)[1])) * lam
    if linalg.det(denom) == 0:
        return
    ws = denom.I * (xMat.T * yMat)
    return ws

通过矩阵返回查看 λ \lambda λ对岭回归结果的影响,以便获取合适的惩罚值:

def ridgeTest(xArr, yArr):
    xMat2 = mat(xArr);
    yMat2 = mat(yArr).T
    yMean2 = mean(yMat2, 0)
    yMat2 = yMat2 - yMean2
    xMeans = mean(xMat2, 0)
    xVar = var(xMat2, 0)
    xMat2= (xMat2 - xMeans)/xVar
    numTestPts = 30
    wMat = zeros((numTestPts, int(shape(xMat2)[1])))
    for i in range(numTestPts):
        ws = ridgeRegress(xMat2, yMat2, exp(i-10))
        wMat[i, :] = ws.T
    return wMat


前向逐步回归

  前向逐步回归算法属于贪心算法,每一步都尽可能减少误差。一开始,所有的权重都设为1,然后每一步所做的决策对某个权重增加或减少一个很小的值。

伪代码实现:

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



代码实现:

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 stageWise(xArr, yArr, eps = 0.01, numIt = 100):
	xMat = mat(xArr); yMat = mat(yArr).T
	yMean = mean(yMat, 0)
	yMat = yMat - yMean
	xMat = regularize(xMat)
	m, n = shape(xMat)
	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.coy()

代码分析:
1.数据输入:xArr(输入数据), yArr(预测变量), eps(每次迭代需要调整的步长),numIt(迭代次数)
2.首先将输入数据转换并存入矩阵,然后把特征按照均值为0 方差为1进行标准化处理
3.创建一个ws来保存 w w w值,为了实现贪心算法建立ws的两份副本
4.通过迭代numIt次优化过程,并且每次迭代都打印出 w w w向量,用于分析算法执行的过程和效果

  通过使用平方误差,由函数rssError()得到。该误差初始值设为正无穷,经过所有的误差比较后取最小的误差。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值