写在前面: 我是「虐猫人薛定谔i」,一个不满足于现状,有梦想,有追求的00后
本博客主要记录和分享自己毕生所学的知识,欢迎关注,第一时间获取更新。
不忘初心,方得始终。
❤❤❤❤❤❤❤❤❤❤
数据介绍
该数据集来自UCI,记录了鲍鱼(一种介壳类水生动物)的年龄。鲍鱼的年龄可以通过鲍鱼壳的层数推算得到。
数据加载
def loadDataSet(fileName):
numFeat = len(open(fileName).readline().split('\t')) -1
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 standRegres(xArr, yArr):
xMat = np.mat(xArr)
yMat = np.mat(yArr).T
xTx = xMat.T * xMat
if np.linalg.det(xTx) == 0.0:
print("This matrix is singular, cannot do inverse")
return
ws = xTx.I * (xMat.T*yMat)
return ws
def main():
abX, abY = loadDataSet('./res/abalone.txt')
ws = standRegres(abX[0:99], abY[0:99])
yHat = np.mat(abX[100:199]) * ws
print(rssError(abY[100:199], yHat.T.A))
# yHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1)
# yHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1)
# yHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10)
# print(rssError(abY[0:99], yHat01.T))
# print(rssError(abY[0:99], yHat1.T))
# print(rssError(abY[0:99], yHat10.T))
局部加权线性回归
def rssError(yArr, yHatArr):
"""
计算预测误差
"""
return ((yArr - yHatArr)**2).sum()
def lwlr(testPoint, xArr, yArr, k=1.0):
xMat = np.mat(xArr)
yMat = np.mat(yArr).T
m = np.shape(xMat)[0]
weights = np.mat(np.eye((m)))
for j in range(m):
diffMat = testPoint - xMat[j, :]
weights[j, j] = np.exp(diffMat * diffMat.T / (-2.0*k**2))
xTx = xMat.T * (weights * xMat)
if np.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 = np.shape(testArr)[0]
yHat = np.zeros(m)
for i in range(m):
yHat[i] = lwlr(testArr[i], xArr, yArr, k)
return yHat
def main():
abX, abY = loadDataSet('./res/abalone.txt')
yHat01 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 0.1)
yHat1 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 1)
yHat10 = lwlrTest(abX[0:99], abX[0:99], abY[0:99], 10)
print(rssError(abY[0:99], yHat01.T))
print(rssError(abY[0:99], yHat1.T))
print(rssError(abY[0:99], yHat10.T))
可以看到,使用较小的核将得到较低的误差。下面我们来看看其在新数据集上的表现:
yHat01 = lwlrTest(abX[100:199],abX[0:99], abY[0:99], 0.1)
print(rssError(abY[100:199], yHat01.T))
yHat1 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 1)
print(rssError(abY[100:199], yHat1.T))
yHat10 = lwlrTest(abX[100:199], abX[0:99], abY[0:99], 10)
print(rssError(abY[100:199], yHat10.T))
从上面的结果,我们可以看到核大小等于10时的测试误差最小,但是它在训练集上的误差却是最大的。
岭回归
岭回归最先用来处理特征数多于样本数的情况,现在也用于在估计中加入偏差,从而得到更好的估计
def ridgeRegres(xMat, yMat, lam=0.2):
xTx = xMat.T*xMat
denom = xTx + np.eye(np.shape(xMat)[1]) * lam
if np.linalg.det(denom) == 0.0:
print("This matrix is singular, cannot do inverse")
return
ws = denom.T * (xMat.T * yMat)
return ws
def rigdeTest(xArr, yArr):
xMat = np.mat(xArr)
yMat = np.mat(yArr).T
yMean = np.mean(yMat, 0)
yMat = yMat - yMean
xMeans = np.mean(xMat, 0)
xVar = np.var(xMat, 0)
xMat = (xMat - xMeans)/xVar
numTestPts = 30
wMat = np.zeros((numTestPts, np.shape(xMat)[1]))
for i in range(numTestPts):
ws = ridgeRegres(xMat, yMat, np.exp(i-10))
wMat[i, :] = ws.T
return wMat
前向逐步回归
前向逐步回归属于贪心算法,即每一步都尽可能减少误差。一开始,所有权重都设为1,然后每一步所做的决策是对某个权重增加或减少一个很小的值。
def regularize(xMat):
inMat = xMat.copy()
inMeans = np.mean(inMat, 0)
inVar = np.var(inMat, 0)
inMat = (inMat - inMeans)/inVar
return inMat
def stageWise(xArr, yArr, eps=0.01, numIt=100):
xMat = np.mat(xArr)
yMat = np.mat(yArr).T
yMean = np.mean(yMat, 0)
yMat = yMat - yMean
xMat = regularize(xMat)
m, n = np.shape(xMat)
returnMat = np.zeros((numIt, n))
ws = np.zeros((n, 1))
wsTest = ws.copy()
wsMax = ws.copy()
for i in range(numIt):
print(ws.T)
lowestError = np.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
改变步长和步数
stageWise(abX, abY, 0.001, 5000)
逐步线性回归算法的主要优点是可以帮助人们理解现有的模型并做出改进。当构建了一个模型后,可以运行该算法找出重要的特征,这样就可以及时停止对那些不重要特征的收集。如果用于测试,该算法每100次迭代后就可以构建出一个模型,可以使用类似于10折交叉验证的方法比较这些模型,最终选择使误差最小的模型。
转载:https://blog.csdn.net/Deep___Learning/article/details/105718103
查看评论