Logistic回归

概念介绍

回归指的是假设现在有一些数据点,我们用一条直线对这些点进行拟合,这个拟合过程叫回归。利用Logistic回归进行分类的主要思想是:根据现有数据对分类边界线建立回归公式,以此进行分类。

优点:计算代价不高,易于理解和实现。

缺点:容易欠拟合,分类精度可能不高。

适用数据类型:数值型和标称型数据。

Logistic回归数学推导

id

id

id

Python实现

梯度上升优化方法

梯度上升和梯度下降本质上是一样的,只是公式中的假发需要编程剑法。梯度上升算法用来求函数的最大值,而梯度下降算法用来求函数的最小值。

梯度上升法的伪代码如下:

每个回归系数初始化为1

重复R次:

    计算整个数据集

    使用alpha*gradient更新回归系数的向量

    返回回归系数

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

def sigmoid(inX):
    return 1.0/(1+np.exp(-inX))

# 梯度上升
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 xrange(maxCycles):
        h = sigmoid(dataMatrix*weights)
        error = (labelMat - h)
        weights = weights + alpha * dataMatrix.transpose() * error
    return weights

画出决策边界

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 xrange(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)
    y = (-weights[0]-weights[1]*x)/weights[2]
    ax.plot(x, y)
    plt.xlabel('X1'); plt.ylabel('X2');
    plt.show()

id

随机梯度上升算法

先看伪代码:

所有回归系数初始化为1

对数据集中每个样本

    计算该样本的梯度

    使用alpha*gradient更新回归系数值

返回回归系数值

def stocGradAscent0(dataMatrix, classLabels):
    m, n = np.shape(dataMatrix)
    alpha = 0.01
    weights = np.ones(n)
    for i in xrange(m):
        h = sigmoid(sum(dataMatrix[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha * error * dataMatrix[i]
    return weights

下图为训练效果,发现效果不是很好,可以有改进的空间。

id

改进的随机梯度上升算法:

def stocGradAscent1(dataMatrix, classLabels, numIter = 150):
    import random
    m, n = np.shape(dataMatrix)
    weights = np.ones(n)
    for j in xrange(numIter):
        dataIndex = range(m)
        for i in xrange(m):
            alpha = 4/(1.0+j+i)+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

id

参考文献

[1][机器学习实战]

[2]Logistic回归总结