Logistic回归
优点:计算代价不高,易于理解和实现
缺点:容易欠拟合,分类精度可能不高
适用数据类型:数值型和标称型数据
实现Logistic回归我们需要借助类似于阶跃函数的Sigmoid函数,sigmoid(z) = 1/(1+exp(-z))。
可以知道sigmoid函数的值域是(0,1),在足够大的定义域上此函数近似于阶跃函数。
要实现Logistic回归,在每个特征上都乘以一个回归系数,然后把所有的结果值相加,将这个结果代入Sigmoid函数中,进而得到一个范围在0-1之间的数值。任何大于0.5的数据被分入1类,小于0.5即被归入0类。
Sigmoid函数的输入记为z,由以下公式得出:
z = w0x0+w1x1+w2x2+w3x3+w4x4+......+wnxn
这个公式可以由矩阵相乘的方式简化:
z = wTx
其中x是分类器的输入数据,向量w也就是我们需要求得的最佳系数
结合梯度上升算法的迭代公式:
w:=w+a*xT*(y-h(z))
其中一定会有人疑惑a后面是怎么来的,它简而言之是在沿着梯度上升误差最小的方向,也就是离最大值最近的方向。
具体的证明可以查看
吴恩达视频的逻辑回归,推导过程可以查看最小二乘法的解法。
逻辑回归损失函数:逻辑回归损失函数
最小二乘法:最小二乘法
Logistic回归梯度上升优化算法python3.6实现:
#Logistic回归梯度上升优化算法
def gradAscent(dataMatIn,classLabels):
#将数据集、标签集转化为矩阵形式
dataMatrix = np.mat(dataMatIn)
labelMat = np.mat(classLabels).transpose()
#获得m*n的矩阵大小
m,n = np.shape(dataMatrix)
#a
alpha = 0.001
#迭代次数
maxCycles = 500
weights = np.ones((n,1))
for k in range(maxCycles):
#dataMatrix * weights 即为 wTx,是sigmoid函数的参数
h = sigmoid(dataMatrix * weights)
#计算标签值与实际值的差值
error = (labelMat - h)
#梯度上升算法,用这个差值方向调整回归系数
weights = weights + alpha*dataMatrix.transpose()*error
return weights
画出决策边界:
#画出数据集和Logistic回归最佳拟合直线的函数
def plotBestFit(weights):
import matplotlib.pyplot as plt
dataMat,labelMat = loadDataSet()
dataArr = np.array(dataMat)
n = np.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 = np.arange(-3.0,3.0,0.1)
#由线性方程转换:q0+q1*x+q2*y=0
#也即weight[0]*x0+weight[1]*x1+weight[2]*x2 = 0
y = (-weights[0]-weights[1]*x)/weights[2]
ax.plot(x,y)
plt.xlabel('X1');plt.ylabel('X2')
plt.show()
随机梯度上升算法:
def stocGradAscent(dataMatrix,classLabels,numTter):
dataMatrix = np.array(dataMatrix)
#得到数据集的矩阵m*n
m,n = np.shape(dataMatrix)
#初始化n长度的数组,元素值为1.0
weights = np.ones(n)
#迭代numTter次,
for j in range(numTter):
#样本随机算法-------与第三章方法一样,此处可避免周期性波动
dataIndex = list(range(m))
for i in range(m):
#对alpha进行动态调整,可以缓解数据波动和高频波动
#alpha虽然不断减小,但永远不会减小到0,不是严格下降
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