线性模型最终训练出来的是 w 列向量; 验证以及判断都是基于这个训练出来的 w 列向量进行的. 所以, 所谓的线性模型是指数据的分布大体是满足一次方程的; 线性模型学习的结果就是把这个一次方程的 w 给获得, 这样就可以得到一个模型了; 未来只要向这个模型 (一次方程) 传入样本即可得到结果. 模型是一个什么概念? 总体来讲模型是一个盒子, 具有输入输出口, 你输入了样本数据, 就会输出接过来, 这个是模型的宏观样子; 那么在这个盒子的里面, 其实是一个函数, 输入的参数将会被直接, 或者处理后输入到这个函数中获得结果做返回; 作为函数, 那就是三部分: 因变量 (返回值 y), 自变量(x, 样本特征值) 以及系数(w, 这个就是线性回归学习的主要目标). 这样才是一个模型的概念.
MLInAction 这本书代码质量低下的一个体现就是没有很好的体现模型的概念, 训练出来 w 列向量之后, 直接拿来和 test 集数据作用, 虽然没有错误, 但是没有很好的提下出 "模型" 的概念, 其实应该至少封装成一个函数, 让他能够有输入输出的模型的样子啊; 否则给人感觉就是一个半成品的样子, 太糙了.
- from numpy import mat
- from numpy import linalg
- # 根据公式求出 w 值, 我们知道的是点集, 下面我们需要搞掂的根据点集来推断出趋势来, 也就是这一章的主题: 预测.
- # 那么我们就首先假设 (或者说根据点集分布进行推测) 数据是线性分布, 那么它就满足 y= w.T*x, 因为点集就是有 x,y 组成, 所以下面
- # 我们需要求解的就是 w, 这里求解 w 采用的方式就是最小二乘法(OLS,ordinary least square), 顾名思义, 二乘法, 两个数相乘,
- # 在这里则是 sum(yi - w.T*x)**2, 为了求 "最小", 下面我们对 sum 进行求导, 可以得到最小值 w=(x.T*x).I*x.T*y; 该方法就是利用
- # 这个求导后的最小值公式来求参数 w
- def standregres(xArr, yArr):
- xMat = mat(xArr)
- yMat = mat(yArr).T
- xTx = xMat.T*xMat
- if linalg.det(xTx) == 0:
- print("result is 0, can't invert")
- return
- ws = xTx.I * (xMat.T * yMat)
- return ws
- from numpy import eye
- from numpy import mat
- from numpy import exp
- from numpy import linalg
- # 基于本地权重计算预测值
- # 注意这里 X*Weight, 之类 weight 是一个对角矩阵, 根据矩阵乘法的规则, Weight 矩阵的意义其实就是指定了每个特征的权重.
- # 所以 LWLR 回归本质就是通过为特征赋权值来实现欠拟合到拟合的优化; 那么问题来了, 怎么设置这个权值呢? 公式来了:
- # exp(|xi - x|/-2k**2)
- # 于是下面我们需要做到的就是通过调参来找到最佳参数 k
- # 这个函数其实实现了两个功能: 根据 xArr 以及 yArr 训练出列权重矩阵 weightp[], 然后返回测试数据的 (参数 sample) 和 w 相乘的结果, 这个结果
- # 就是 yHat, 就是预测值!
- # 外部通过这个返回值 yHat 和 y 真值进行比较, 推断预测的水平怎么样.
- # 另外这里关于矩阵乘法有一个隐喻: 左乘的矩阵提供的是一个样本得特征, 右乘的矩阵提供的特征的系数, 所以样本和特征参数相乘, 因为样本只是 1 个
- # 所以结果上面来看, 行数和左乘矩阵是一致, 代表着样本数量是不会变得; 列数确实和右乘矩阵一致, 这是因为右乘矩阵代表对样本洗礼次数(通过
- # 特征值和参数相乘), 所以产生的是一个新的样本, 这样样本代表了基于原来样本的 N 此洗礼处理.
- def localWeightLinearRegression(sample, xArr, yArr, k):
- xMat = mat(xArr)
- yMat = mat(yArr)
- m = shape(xMat)[0]
- weight = mat(eye(m))
- for j in range(m):
- diff = sample - xMat[j, :]
- weight[j, j] = exp(diff*diff.T / (-2.0*k**2))
- xTx = xMat.T * (weight * xMat)
- if(linalg.det(xTx) == 0):
- print("det is zero, return")
- return
- wHat = xTx.I * (xMat.T * (weight * yMat.T))
- return sample * wHat
- # 用于验证, 对于一个特征数量大于样本数量的场景, linalg.det 是否为 0
- aMat = mat(ones((5,2)))
- tMat = aMat.T
- print("tMat*aMat")
- print(tMat*aMat)
- det = linalg.det(tMat*aMat)
- print("det:")
- print(det)
- # 验证一下 det 为 0 的方阵添加一个单位矩阵之后是否就会 det 不等于 0
- eyeMat = mat(eye((2)))
- print("init eyeMat:")
- print(eyeMat)
- print("tMat*aMat + eyeMat")
- print(tMat*aMat + eyeMat * 0.05)
- det = linalg.det(tMat*aMat + eyeMat * 0.05)
- print("added I, the det:")
- print(det)
来源: http://www.bubuko.com/infodetail-2983212.html