如果数据的特征比样本点还多应该怎么办?是否还可以使用线性回归?答案是否定的。多元线性回归的算法,需要输入数据的矩阵是满秩矩阵。如果特征比样本点多,则说明输入矩阵不是满秩矩阵。
为了解决以上问题,我们可以引入 “岭回归”,“lasso法”,“前向逐步回归” 三种缩减方法。
缩减: 通过引入惩罚项,减少不重要的参数,这个技术在统计学中叫做缩减。
岭回归
上加上一个从而使得矩阵非奇异,进而能对求逆。其中矩阵是一个mxm的单位矩阵,对角线上元素全为1,其他元素全为0。而是一个用户定义的数值。回归系数的计算公式将变成:
算法思想
:
- 获取数据后首先抽取一部分数据作为测试集,剩下数据作为训练集用于训练参数
- 训练完毕后在测试集上测试预测性能
- 选取不同的重复上述的过程,最终得到一个使预测误差最小的
代码实现
对岭回归代码的实现:
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
通过矩阵返回查看对岭回归结果的影响,以便获取合适的惩罚值:
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为正无穷
对每个特征:
增大或缩小:
改变一个系数得到一个新的
计算新下的误差
如果误差Error小于当前最小误差lowestError:设置Wbest等于当前的
将设置为新的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来保存值,为了实现贪心算法建立ws的两份副本
4.通过迭代numIt次优化过程,并且每次迭代都打印出向量,用于分析算法执行的过程和效果
通过使用平方误差,由函数rssError()得到。该误差初始值设为正无穷,经过所有的误差比较后取最小的误差。