如何优雅的ML(四) Logistic 回归

来源:互联网 发布:中国为什么封闭网络 编辑:程序博客网 时间:2024/04/28 20:46

利用Logistic回归进行分类的主要思想是,根据现有数据对分类边界建立回归公式,以此进行分类。

这里的回归表示要找到最佳拟合参数集。训练分类器就是要寻找最佳拟合参数。

优点:计算代价不高、易于理解实现缺点:容易欠拟合、分类精度可能不高使用数据类型:数值型和标称型

Sigmoid函数:能够接受所有的输入然后预测出类别,在两个类的情况下,输出0或1。

计算公式f(x)=1/(1+e^-x)。

当x为0时,Sigmoid函数值为0.5。随着x的增大,对应的值逼近于1;随着x的减小,值逼近于0。

要实现Logistic回归分类器,在每个特征上乘以一个回归系数,然后把结果相加代入Sigmoid函数即可。

任何大于0.5的数据分为1类,小于0.5分为0类。


如何确定最佳回归系数:

若将Sigmoid函数的输入记为向量z,则z=w0x0+w1x1+...+wnxn,它表示系数向量与特征向量对应元素相乘后再相加的值。

寻找最佳系数要用到最优化理论。


梯度上升算法:

要找到某函数最大值,最好沿着该函数的梯度方向探寻。

如果梯度记为▽,则函数f(x,y)的梯度表示为:▽f(x,y)={∂f(x,y)/∂x, ∂f(x,y)/∂y},意味着沿x方向移动∂f(x,y)/∂x,沿y方向移动∂f(x,y)/∂y。

其中函数f(x,y)必须要在待计算的点上有定义且可微。

梯度算子总是指向函数值增长最快的方向。移动量称为步长,记做α。

用向量来表示梯度上升算法的迭代公式:w:=w+α▽_w{f(w)}

该公式将一直被迭代执行,直到迭代次数达到某个值或达到算法允许的误差范围。


梯度上升算法在每次更新回归系数时都要重新遍历整个数据集,复杂度太高。

一次仅用一个样本点来更新回归系数,称为随机梯度上升算法。

它可以在新样本到来时对分类器进行增量式更新,因此是一个在线学习算法。


# coding=gbkfrom numpy import *def loadDataSet(filename):    """    从文件中读取数据    Returns:        dataMat: 数据集        labelMat: 标签集    """    dataMat = [] # 数据集    labelMat = [] # 标签集    fr = open(filename)    for line in fr.readlines():        lineArr = line.strip().split() # 分割数据        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) # 输入前两个值属于数据集,为方便计算第一列置为 1        labelMat.append(int(lineArr[2])) # 第三个值属于标签集    return dataMat, labelMat # 返回数据集与标签集def sigmoid(inX):    """    Sigmoid 函数    """    return 1.0 / (1 + exp(-inX))def gradAscent(dataMatIn, classLabels):    """    梯度上升算法    Args:        dataMatIn: 数据集,二维矩阵,每列代表不同的特征,每行代表训练样本        classLabels: 标签集,类别标签,是一个一维向量    Returns:        weights: 回归系数    """    dataMatrix = mat(dataMatIn) # 数据样本矩阵    labelMat = mat(classLabels).transpose() # 标签矩阵的转置    m, n = shape(dataMatrix) # 读取矩阵的大小 m * n,m 是行数,n是列数    alpha = 0.001 # 向目标移动的步长    maxCycles = 500 # 迭代次数    weights = ones((n, 1)) # 创建 n*1 的数组    for k in range(maxCycles):        h = sigmoid(dataMatrix * weights) # 矩阵相乘,得到一个 m * 1 的矩阵        error = (labelMat - h)        weights = weights + alpha * dataMatrix.transpose() * error # 梯度上升算法的迭代公式    return weightsdef stocGradAscent0(dataMatIn, classLabels):    """    随机梯度上升算法 beta    """    dataMatrix = array(dataMatIn)    m, n = shape(dataMatrix)    alpha = 0.01    weights = ones(n)    for i in range(m):        h = sigmoid(sum(dataMatrix[i] * weights))        error = classLabels[i] - h        weights = weights + alpha * error * dataMatrix[i]    return weigthsdef stocGradAscent1(dataMatIn, classLabels, numIter = 150):    """    随机梯度上升算法    """    dataMatrix = array(dataMatIn)    m, n = shape(dataMatrix)    weights = ones(n)    for j in range(numIter):        dataIndex = range(m)        for i in range(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 weightsdef plotBestFit(dataMatIn, classLabels, wei):    """    画出数据集和Logistic回归最佳拟合直线的函数    """    import matplotlib.pyplot as plt    #weights = wei.getA()    weights = wei    dataMat, labelMat = dataMatIn, classLabels    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()




0 0
原创粉丝点击