mirror of
https://github.com/apachecn/ailearning.git
synced 2026-02-13 07:15:26 +08:00
修改添加注释,逻辑回归和回归
This commit is contained in:
@@ -19,7 +19,7 @@ def loadDataSet(file_name):
|
||||
fr = open(file_name)
|
||||
for line in fr.readlines():
|
||||
lineArr = line.strip().split()
|
||||
# 将 X0 的值设为 1.0
|
||||
# 为了方便计算,我们将 X0 的值设为 1.0 ,也就是在每一行的开头添加一个 1.0 作为 X0
|
||||
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
|
||||
labelMat.append(int(lineArr[2]))
|
||||
return dataMat,labelMat
|
||||
@@ -57,6 +57,7 @@ def gradAscent(dataMatIn, classLabels):
|
||||
# print 'weights====', weights
|
||||
# n*3 * 3*1 = n*1
|
||||
h = sigmoid(dataMatrix*weights) # 矩阵乘法
|
||||
# print 'hhhhhhh====', h
|
||||
# labelMat是实际值
|
||||
error = (labelMat - h) # 向量相减
|
||||
# 0.001* (3*m)*(m*1) 表示在每一个列上的一个误差情况,最后得出 x1,x2,xn的系数的偏移量
|
||||
@@ -110,6 +111,17 @@ def stocGradAscent1(dataMatrix, classLabels, numIter=150):
|
||||
|
||||
# 可视化展示
|
||||
def plotBestFit(dataArr, labelMat, weights):
|
||||
'''
|
||||
Desc:
|
||||
将我们得到的数据可视化展示出来
|
||||
Args:
|
||||
dataArr:样本数据的特征
|
||||
labelMat:样本数据的类别标签,即目标变量
|
||||
weights:回归系数
|
||||
Returns:
|
||||
None
|
||||
'''
|
||||
|
||||
n = shape(dataArr)[0]
|
||||
xcord1 = []; ycord1 = []
|
||||
xcord2 = []; ycord2 = []
|
||||
@@ -146,8 +158,8 @@ def main():
|
||||
# 因为数组没有是复制n份, array的乘法就是乘法
|
||||
dataArr = array(dataMat)
|
||||
# print dataArr
|
||||
# weights = gradAscent(dataArr, labelMat)
|
||||
weights = stocGradAscent0(dataArr, labelMat)
|
||||
weights = gradAscent(dataArr, labelMat)
|
||||
# weights = stocGradAscent0(dataArr, labelMat)
|
||||
# weights = stocGradAscent1(dataArr, labelMat)
|
||||
# print '*'*30, weights
|
||||
|
||||
|
||||
@@ -182,7 +182,6 @@ plt.show()
|
||||
|
||||
# Logistic Regression 3-class Classifier 逻辑回归 3-类 分类器
|
||||
|
||||
'''
|
||||
print(__doc__)
|
||||
|
||||
import numpy as np
|
||||
@@ -224,11 +223,11 @@ plt.xticks(())
|
||||
plt.yticks(())
|
||||
|
||||
plt.show()
|
||||
'''
|
||||
|
||||
# Logistic function 逻辑回归函数
|
||||
# 这个类似于咱们之前讲解 logistic 回归的 Sigmoid 函数,模拟的阶跃函数
|
||||
|
||||
'''
|
||||
print(__doc__)
|
||||
|
||||
import numpy as np
|
||||
@@ -276,5 +275,7 @@ plt.xlim(-4, 10)
|
||||
plt.legend(('Logistic Regression Model', 'Linear Regression Model'),
|
||||
loc="lower right", fontsize='small')
|
||||
plt.show()
|
||||
'''
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -48,7 +48,7 @@ def standRegres(xArr,yArr):
|
||||
xArr :输入的样本数据,包含每个样本数据的 feature
|
||||
yArr :对应于输入数据的类别标签,也就是每个样本对应的目标变量
|
||||
Returns:
|
||||
|
||||
ws:回归系数
|
||||
'''
|
||||
|
||||
# mat()函数将xArr,yArr转换为矩阵 mat().T 代表的是对矩阵进行转置操作
|
||||
@@ -71,67 +71,155 @@ def standRegres(xArr,yArr):
|
||||
def lwlr(testPoint,xArr,yArr,k=1.0):
|
||||
'''
|
||||
Description:
|
||||
局部加权线性回归
|
||||
局部加权线性回归,在待预测点附近的每个点赋予一定的权重,在子集上基于最小均方差来进行普通的回归。
|
||||
Args:
|
||||
testPoint:
|
||||
xArr:
|
||||
yArr:
|
||||
k:
|
||||
testPoint:样本点
|
||||
xArr:样本的特征数据,即 feature
|
||||
yArr:每个样本对应的类别标签,即目标变量
|
||||
k:关于赋予权重矩阵的核的一个参数,与权重的衰减速率有关
|
||||
Returns:
|
||||
|
||||
testPoint * ws:数据点与具有权重的系数相乘得到的预测点
|
||||
Notes:
|
||||
这其中会用到计算权重的公式,w = e^((x^((i))-x) / -2k^2)
|
||||
理解:x为某个预测点,x^((i))为样本点,样本点距离预测点越近,贡献的误差越大(权值越大),越远则贡献的误差越小(权值越小)。
|
||||
关于预测点的选取,在我的代码中取的是样本点。其中k是带宽参数,控制w(钟形函数)的宽窄程度,类似于高斯函数的标准差。
|
||||
算法思路:假设预测点取样本点中的第i个样本点(共m个样本点),遍历1到m个样本点(含第i个),算出每一个样本点与预测点的距离,
|
||||
也就可以计算出每个样本贡献误差的权值,可以看出w是一个有m个元素的向量(写成对角阵形式)。
|
||||
'''
|
||||
xMat = mat(xArr); yMat = mat(yArr).T
|
||||
m = shape(xMat)[0] # 获得xMat矩阵的行数
|
||||
weights = mat(eye((m))) # eye()返回一个对角线元素为1,其他元素为0的二维数组,创建权重矩阵
|
||||
for j in range(m): # 下面两行创建权重矩阵
|
||||
diffMat = testPoint - xMat[j,:] # 遍历数据集,计算每个样本点对应的权重值
|
||||
weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))#k控制衰减的速度
|
||||
# mat() 函数是将array转换为矩阵的函数, mat().T 是转换为矩阵之后,再进行转置操作
|
||||
xMat = mat(xArr)
|
||||
yMat = mat(yArr).T
|
||||
# 获得xMat矩阵的行数
|
||||
m = shape(xMat)[0]
|
||||
# eye()返回一个对角线元素为1,其他元素为0的二维数组,创建权重矩阵weights,该矩阵为每个样本点初始化了一个权重
|
||||
weights = mat(eye((m)))
|
||||
for j in range(m):
|
||||
# testPoint 的形式是 一个行向量的形式
|
||||
# 计算 testPoint 与输入样本点之间的距离,然后下面计算出每个样本贡献误差的权值
|
||||
diffMat = testPoint - xMat[j,:]
|
||||
# k控制衰减的速度
|
||||
weights[j,j] = exp(diffMat*diffMat.T/(-2.0*k**2))
|
||||
# 根据矩阵乘法计算 xTx ,其中的 weights 矩阵是样本点对应的权重矩阵
|
||||
xTx = xMat.T * (weights * xMat)
|
||||
if linalg.det(xTx) == 0.0:
|
||||
print ("This matrix is singular, cannot do inverse")
|
||||
return
|
||||
ws = xTx.I * (xMat.T * (weights * yMat)) # 计算出回归系数的一个估计
|
||||
# 计算出回归系数的一个估计
|
||||
ws = xTx.I * (xMat.T * (weights * yMat))
|
||||
return testPoint * ws
|
||||
|
||||
def lwlrTest(testArr,xArr,yArr,k=1.0): # 循环所有的数据点,并将lwlr运用于所有的数据点
|
||||
def lwlrTest(testArr,xArr,yArr,k=1.0):
|
||||
'''
|
||||
Description:
|
||||
测试局部加权线性回归,对数据集中每个点调用 lwlr() 函数
|
||||
Args:
|
||||
testArr:测试所用的所有样本点
|
||||
xArr:样本的特征数据,即 feature
|
||||
yArr:每个样本对应的类别标签,即目标变量
|
||||
k:控制核函数的衰减速率
|
||||
Returns:
|
||||
yHat:预测点的估计值
|
||||
'''
|
||||
# 得到样本点的总数
|
||||
m = shape(testArr)[0]
|
||||
# 构建一个全部都是 0 的 1 * m 的矩阵
|
||||
yHat = zeros(m)
|
||||
# 循环所有的数据点,并将lwlr运用于所有的数据点
|
||||
for i in range(m):
|
||||
yHat[i] = lwlr(testArr[i],xArr,yArr,k)
|
||||
# 返回估计值
|
||||
return yHat
|
||||
|
||||
def lwlrTestPlot(xArr,yArr,k=1.0): # 首先将 X 排序,其余的都与lwlrTest相同,这样更容易绘图
|
||||
yHat = zeros(shape(yArr))
|
||||
def lwlrTestPlot(xArr,yArr,k=1.0):
|
||||
'''
|
||||
Description:
|
||||
首先将 X 排序,其余的都与lwlrTest相同,这样更容易绘图
|
||||
Args:
|
||||
xArr:样本的特征数据,即 feature
|
||||
yArr:每个样本对应的类别标签,即目标变量,实际值
|
||||
k:控制核函数的衰减速率的有关参数,这里设定的是常量值 1
|
||||
Return:
|
||||
yHat:样本点的估计值
|
||||
xCopy:xArr的复制
|
||||
'''
|
||||
# 生成一个与目标变量数目相同的 0 向量
|
||||
yHat = zeros(shape(yArr))
|
||||
# 将 xArr 转换为 矩阵形式
|
||||
xCopy = mat(xArr)
|
||||
# 排序
|
||||
xCopy.sort(0)
|
||||
# 开始循环,为每个样本点进行局部加权线性回归,得到最终的目标变量估计值
|
||||
for i in range(shape(xArr)[0]):
|
||||
yHat[i] = lwlr(xCopy[i],xArr,yArr,k)
|
||||
return yHat,xCopy
|
||||
|
||||
def rssError(yArr,yHatArr): # yArr 和 yHatArr 两者都需要是数组
|
||||
def rssError(yArr,yHatArr):
|
||||
'''
|
||||
Desc:
|
||||
计算分析预测误差的大小
|
||||
Args:
|
||||
yArr:真实的目标变量
|
||||
yHatArr:预测得到的估计值
|
||||
Returns:
|
||||
计算真实值和估计值得到的值的平方和作为最后的返回值
|
||||
'''
|
||||
return ((yArr-yHatArr)**2).sum()
|
||||
|
||||
def ridgeRegres(xMat,yMat,lam=0.2): # 岭回归
|
||||
def ridgeRegres(xMat,yMat,lam=0.2):
|
||||
'''
|
||||
Desc:
|
||||
这个函数实现了给定 lambda 下的岭回归求解。
|
||||
如果数据的特征比样本点还多,就不能再使用上面介绍的的线性回归和局部现行回归了,因为计算 (xTx)^(-1)会出现错误。
|
||||
如果特征比样本点还多(n > m),也就是说,输入数据的矩阵x不是满秩矩阵。非满秩矩阵在求逆时会出现问题。
|
||||
为了解决这个问题,我们下边讲一下:岭回归,这是我们要讲的第一种缩减方法。
|
||||
Args:
|
||||
xMat:样本的特征数据,即 feature
|
||||
yMat:每个样本对应的类别标签,即目标变量,实际值
|
||||
lam:引入的一个λ值,使得矩阵非奇异
|
||||
Returns:
|
||||
经过岭回归公式计算得到的回归系数
|
||||
'''
|
||||
|
||||
xTx = xMat.T*xMat
|
||||
denom = xTx + eye(shape(xMat)[1])*lam # 按照书上的公式计算计算回归系数
|
||||
if linalg.det(denom) == 0.0: # 检查行列式是否为零,即矩阵是否可逆
|
||||
# 岭回归就是在矩阵 xTx 上加一个 λI 从而使得矩阵非奇异,进而能对 xTx + λI 求逆
|
||||
denom = xTx + eye(shape(xMat)[1])*lam
|
||||
# 检查行列式是否为零,即矩阵是否可逆,行列式为0的话就不可逆,不为0的话就是可逆。
|
||||
if linalg.det(denom) == 0.0:
|
||||
print ("This matrix is singular, cannot do inverse")
|
||||
return
|
||||
ws = denom.I * (xMat.T*yMat)
|
||||
return ws
|
||||
|
||||
def ridgeTest(xArr,yArr):
|
||||
xMat = mat(xArr); yMat=mat(yArr).T
|
||||
yMean = mean(yMat,0) # 计算Y均值
|
||||
yMat = yMat - yMean # Y的所有的特征减去均值
|
||||
# 标准化 x
|
||||
xMeans = mean(xMat,0) # X计算平均值
|
||||
xVar = var(xMat,0) # 然后计算 X的方差
|
||||
'''
|
||||
Desc:
|
||||
函数 ridgeTest() 用于在一组 λ 上测试结果
|
||||
Args:
|
||||
xArr:样本数据的特征,即 feature
|
||||
yArr:样本数据的类别标签,即真实数据
|
||||
Returns:
|
||||
wMat:将所有的回归系数输出到一个矩阵并返回
|
||||
'''
|
||||
|
||||
xMat = mat(xArr)
|
||||
yMat=mat(yArr).T
|
||||
# 计算Y的均值
|
||||
yMean = mean(yMat,0)
|
||||
# Y的所有的特征减去均值
|
||||
yMat = yMat - yMean
|
||||
# 标准化 x,计算 xMat 平均值
|
||||
xMeans = mean(xMat,0)
|
||||
# 然后计算 X的方差
|
||||
xVar = var(xMat,0)
|
||||
# 所有特征都减去各自的均值并除以方差
|
||||
xMat = (xMat - xMeans)/xVar
|
||||
# 可以在 30 个不同的 lambda 下调用 ridgeRegres() 函数。
|
||||
numTestPts = 30
|
||||
wMat = zeros((numTestPts,shape(xMat)[1]))# 创建30 * m 的全部数据为0 的矩阵
|
||||
# 创建30 * m 的全部数据为0 的矩阵
|
||||
wMat = zeros((numTestPts,shape(xMat)[1]))
|
||||
for i in range(numTestPts):
|
||||
ws = ridgeRegres(xMat,yMat,exp(i-10))# exp返回e^x
|
||||
# exp() 返回 e^x
|
||||
ws = ridgeRegres(xMat,yMat,exp(i-10))
|
||||
wMat[i,:]=ws.T
|
||||
return wMat
|
||||
|
||||
|
||||
Reference in New Issue
Block a user