Logistic回归是一种经典的分类算法,主要用于解决二分类问题。该算法通过构建Logistic函数将输入特征映射到预测结果的概率上,从而实现分类。具体来说,Logistic函数会将输入特征线性组合后的结果通过一个sigmoid函数转换为0-1之间的概率值,其中0.5作为分类的阈值,大于0.5则为正类,小于0.5则为负类。
数据集
数据集包含,两个特征,第三列为标签值。
具体代码实现
读取数据集,并添加将值设置为1.0,把特征和标签分割为dataMat和labelMat。
def loadDataSet():
dataMat = []; labelMat = []
fr = open('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
sigmoid函数的输入可以是任意实数,而输出值范围为0到1之间,因此通常被用于二分类问题。它的图像可以形象地描述为一条"S"型曲线。
def sigmoid(inX):
return 1.0/(1+exp(-inX))
from numpy import*
def gradAscent(dataMatin,classLabels):
dataMatrix = mat(dataMatin)
labelMat = mat(classLabels).transpose()
m,n = shape(dataMatrix)
alpha = 0.001
maxCycles = 500
weights = ones((n,1))
for k in range(maxCycles):
h = sigmoid(dataMatrix*weights)
error = (labelMat-h)
weights = weights + alpha * dataMatrix.transpose() * error
return weights
采用梯度上升法计算w值。计算的三个w值如图:
绘制直线来完成分类可视化展示,轴表示,当=时可以求得和的关系式。
def plotBestFit(wei):
import matplotlib.pyplot as plt
weights = wei.getA()
dataMat,labelMat = loadDataSet()
dataArr = array(dataMat)
n = shape(dataArr)[0]
xcord1 = []; ycord1 = [];
xcord2 = []; ycord2 = [];
for i in range(n):
if int(labelMat[i])==1:
xcord1.append(dataArr[i,1]);ycord1.append(dataArr[i,2])
else:
xcord2.append(dataArr[i,1]);ycord2.append(dataArr[i,2])
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(xcord1,ycord1,s=30,c='red',marker='s')
ax.scatter(xcord2,ycord2,s=30,c='green')
x = arange(-3.0,3.0,0.1)
y = (-weights[0]-weights[1]*x)/weights[2]
ax.plot(x,y)
plt.xlabel('X1');plt.ylabel('X2')
plt.show()
最终分类结果如下
改进的梯度上升法
梯度上升算法在每次更新回归系数时需要遍历整个数据集,如果数据集过大,那么该方法的计算量就太大了。一种改进方法是仅用一个样本点来更新回归系数,该方法称为随机梯度上升算法。
def stocGradAscent(dataMatrix,classLabels,numIter=150):
m,n = shape(dataMatrix)
weights = ones(n)
for j in range(numIter):
dataIndex = list(range(m))
for i in range(m):
alpha = 4/(1.0+i+j)+0.01
randIndex = int(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
步长alpha会随着迭代次数的增加不断减小,并使用random函数随机选出一个值,然后删掉该值再进行下一次迭代。
最终分类结果如下,仅需更少的计算量就能达到与之前算法差不多的效果。