机器学习实战四(Logistic Regression)

机器学习实战四(Logistic Regression)

这一章会初次接触最优化算法,在日常生活中应用很广泛。这里我们会用到基本的梯度上升法,以及改进的随机梯度上升法。

Logistic回归

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

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

原理:根据现有数据堆分类边界线建立回归公式,依次进行分类。

这里的回归其实就是最佳拟合的意思。

1、基于Logistic回归和Sigmoid函数的分类。

我们需要一个这样的函数:接受所有的输入,然后预测出类别。例如,如果只有两类,则输出0和1,有个函数就有类似的性质,Sigmoid函数:

Sigmoid函数的具体计算公式如下:\(\sigma \left( z\right) =\dfrac {1}{1+e^{-z}}\)

很容易证明界限在0-1之间,这样就保证,无论Sigmoid函数吃进去什么数,吐出来的数一定在0-1之间。

于是Logistic分类器就可以这样构造:对于每个特征乘以一个回归系数,然后相加,将这个数放入Sigmoid函数,如果得出来数字大于0.5,分类为1,否则为0.从这个角度来看,Logistic回归也是一种概率估计。

2、基于最优化方法的最佳回归系数确定

Sigmoid函数的输入记为z,那么:
\(z=w_{0}x_{0}+w_{1}x_{1}+\ldots +w_{n}x_{n}\),也可以写成:\(z=w^{T}x\),这里的向量w就是最佳回归系数。

这里我们采用的是梯度上升算法,具体原理按下不表,直接看代码。

from matplotlib import pyplot as plt
import numpy as np
import random


# 加载数据集
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[-1]))
    return dataMat, labelMat


# Sigmoid函数
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 = dataMatrix.shape
    alpha = 0.01
    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

梯度上升算法在每次更新回归系数时都需要遍历整个数据集,这样的计算复杂度无疑是太高了。有一种改进的方法是每次只用一个样本点来更新回归系数,这种方法被称为随机梯度上升算法,在新的样本到来时可以增量更新,是一种在线学习算法。

# 随机梯度上升
def stocGradAscent(dataMatrix, classLabel, numIter=150):
    dataIndex = np.array(dataMatrix)
    classLabel = np.array(classLabel)
    m, n = dataMatrix.shape
    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.0001
            randIndex = int(random.uniform(0, len(dataIndex)))
            h = sigmoid(np.sum(dataMatrix[randIndex] * weights))
            error = classLabel[randIndex] - h
            weights = weights + alpha * error * dataMatrix[randIndex]
            del dataIndex[randIndex]
    return weights

书中的预测病马死亡率的例子不难实现,而且介绍到数据预处理在机器学习中的重要性,因为机器学习的算法输入数据是有格式要求的,有时我们获取的数据会存在异常值或者缺失值的时候,就有进行预处理的必要。

Logistic小结:
寻找一个非线性函数Sigmoid的最佳拟合参数,求解过程由最优化算法完成,常用梯度上升算法,但是计算量大,可以由随机梯度上升算法改进,这是一个在线算法,在新数据到来时完成参数更新,不需要重新读取整个数据集。


Next:支持向量机,一种与Logistic回归类似的分类算法,被认为是目前最好的现成的算法之一。

总结:Logistic的原理并不复杂,这里只是初步接触最优化算法,像梯度上升和梯度下降之类的,还需要好好的研究。

References:https://github.com/plantree/Machine-Learing-In-Action/chapter5

posted @ 2018-01-10 15:59  plantree  阅读(355)  评论(0编辑  收藏  举报