机器学习笔记之Logistic回归
基于 Logistic 回归和 Sigmoid 函数的分类
当x为0时,Sigmoid函数值为0.5。
随着x的增大,对应的Sigmoid值将逼近于1;而随着x的减小,Sigmoid值将逼近于0。
为了实现Logistic回归分类器,我们可以在每个特征上都乘以一个回归系数,然后把
所有的结果值相加,将这个总和代入Sigmoid函数中,进而得到一个范围在0~1之间的数值。任
何大于0.5的数据被分入1类,小于0.5即被归入0类。所以,Logistic回归也可以被看成是一种概
率估计。
基于最优化方法的最佳回归系数确定
Sigmoid函数的输入记为z,可以视为每个特征乘以系数相加的和,那么为了使分类器尽可能的精确,就需要寻找最佳系数。
梯度上升法
梯度上升法基于的思想是:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。
Logistic回归梯度上升优化算法
## 读取数据集
def loadDataSet():
dataMat = []
labelMat = []
fr = open('D:/BaiduNetdiskDownload/ml_action/Ch05/testSet.txt')
for line in fr.readlines():
lineArr = line.strip().split()
dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
labelMat.append(int(lineArr[2]))
return dataMat, labelMat
dataMat, labelMat = loadDataSet()
## 创建sigmoid函数
def sigmoid(inX):
return 1.0/(1 + np.exp(-inX))
## 创建梯度上升算法
import numpy as np
def gradAscent(dataMatIn, classLabels):
dataMatrix = np.mat(dataMatIn)
labelMat = np.mat(classLabels).transpose()
m, n = np.shape(dataMatrix)
alpha = 0.001
maxCycles = 500
weights = np.ones((n, 1))
for k in range(maxCycles):
h = sigmoid(dataMatrix*weights)
error = (labelMat - h)
weights = weights + alpha*dataMatrix.transpose()*error #矩阵求导?
return weights
gradAscent(dataMat, labelMat)
matrix([[ 4.12414349],
[ 0.48007329],
[-0.6168482 ]])
0是两个分类(类别1和类别0)的分界处。因此,我们设定 0 = w0x0 + w1x1 +
w2x2,可解出X2和X1的关系式(即分隔线的方程,注意X0=1)
随机梯度上升算法
梯度上升算法在每次更新回归系数时都需要遍历整个数据集,该方法在处理100个左右的数
据集时尚可,但如果有数十亿样本和成千上万的特征,那么该方法的计算复杂度就太高了。一种
改进方法是一次仅用一个样本点来更新回归系数,该方法称为随机梯度上升算法。
## 随机梯度上升算法
def stocGradAscent0(dataMatrix, classLabels):
m, n = np.shape(dataMatrix)
alpha = 0.01
weights = np.ones(n)
for i in range(m):
h = sigmoid(sum(dataMatrix[i]*weights))
error = classLabels[i] - h
weights = weights + alpha * error * dataMatrix[i]
return weights
stocGradAscent0(np.array(dataMat), labelMat)
array([ 1.01702007, 0.85914348, -0.36579921])
## 改进的随机梯度上升算法
def stocGradAscent1(dataMatrix, classLabels, numIter = 150):
m, n = np.shape(dataMatrix)
weights = np.ones(n)
for j in range(numIter):
dataIndex = list(range(m))
for i in range(m):
alpha = 4/(1.0 + j + i) + 0.01
randIndex = int(np.random.uniform(0, len(dataIndex)))
h = sigmoid(sum(dataMatrix[randIndex]*weights))
error = classLabels[randIndex] - h
weights = weights + alpha * error * dataMatrix[randIndex]
del dataIndex[randIndex]
return weights
使用Logistic回归进行分类
使用Logistic回归方法进行分类并不需要做很多工作,所需做的只是把测试集上每个特征向量乘以最优化方法得来的回归系数,再将该乘积结果求和,最后输入到Sigmoid函数中即可。如果对应的Sigmoid值大于0.5就预测类别标签为1,否则为0。
##Logistic回归分类函数
def classifyVector(inX, weights):
prob = sigmoid(sum(inX*weights))
if prob > 0.5:
return 1.0
else:
return 0.0
def colicTest():
frTrain = open('D:/BaiduNetdiskDownload/ml_action/Ch05/horseColicTraining.txt')
frTest = open('D:/BaiduNetdiskDownload/ml_action/Ch05/horseColicTest.txt')
trainingSet = []
trainingLabels = []
for line in frTrain.readlines():
currLine = line.strip().split('\t')
lineArr = []
for i in range(21):
lineArr.append(float(currLine[i]))
trainingSet.append(lineArr)
trainingLabels.append(float(currLine[21]))
trainWeights = stocGradAscent1(np.array(trainingSet), trainingLabels, 500)#训练模型,返回参数字典
errorCount = 0
numTestVec = 0
for line in frTest.readlines():
numTestVec += 1.0
currLine = line.strip().split('\t')
lineArr = []
for i in range(21):
lineArr.append(float(currLine[i]))
if int(classifyVector(np.array(lineArr), trainWeights)) != int(currLine[21]):#输入测试数据集返回分类结果
errorCount += 1
errorRate = (float(errorCount)/numTestVec)
print("the error rate of this test is: %f" %errorRate)
return errorRate
def multiTest():
numTests = 10
errorSum = 0
#训练多次,因为随机梯度上升具有一定的随机性
for k in range(numTests):
errorSum += colicTest()
print("after %d iterations the average error rate is: %f" %(numTests, errorSum/float(numTests)))
multiTest()
the error rate of this test is: 0.417910
the error rate of this test is: 0.358209
the error rate of this test is: 0.492537
the error rate of this test is: 0.402985
the error rate of this test is: 0.253731
the error rate of this test is: 0.373134
the error rate of this test is: 0.253731
the error rate of this test is: 0.477612
the error rate of this test is: 0.522388
the error rate of this test is: 0.268657
after 10 iterations the average error rate is: 0.382090