机器学习实战之Logistic回归-详细笔记

概念

  1. 最优化算法

  2. 回归:用一条直线对点(多个数据)进行拟合,(该线条称为最佳拟合直线)这个拟合过程就称作回归

  3. 主要思想:根据现有数据对分类边界线建立回归公式,以此进行分类

  4. 过程:

    收集数据
    准备数据,数值型,结构化数据格式最佳
    分析数据
    训练算法,大部分时间用于训练,目的是为了找到最佳回归系数。
    测试算法
    使用算法,首先输入一些数据,转换成对应的结构化数值,接着基于训练好的回归系数,就可以对这些数值进行简单的回归计算,判断它们属于哪个类别,在这之后,我们就可以在输出的类别上做一些其他分析工作。
    优点,代价不高,易于理解和实现,缺点:容易欠拟合,分类精度可能不高,数值型和标称型。

  5. sigmoid函数
    δ ( z ) = 1 / ( 1 + e x p ( − z ) ) \delta(z) = 1/(1+exp(-z)) δ(z)=1/(1+exp(z))

  6. 基于最优化方法的最佳回归系数确定
    sigmoid的输入记为z:
    z = w 1 x 0 + w 1 x 1 + w 2 x 2 + . . . + w n x n . = > z = w T x z = w_1x_0+w_1x_1+w_2x_2+...+w_nx_n.\\=>z=w^Tx z=w1x0+w1x1+w2x2+...+wnxn.=>z=wTx
    x是分类器的输入数据,向量W也就算最佳参数(系数)

  7. 梯度上升法
    思想:要找到某函数的最大值,最好的方法是沿着该函数的梯度方向探寻。
    梯度公式: ∇ f ( x , y ) = [ ∂ f ( x , y ) ∂ x , ∂ f ( x , y ) ∂ y ] \nabla f(x,y) = [ \frac{\partial f(x,y)}{\partial x} , \frac{\partial f(x,y)}{\partial y} ] f(x,y)=[xf(x,y),yf(x,y)]
    f ( x , y ) f(x,y) f(x,y)必须在待计算的点上有定义并且可微;
    梯度上升算法的迭代公式: w : = w + α ∇ w f ( w ) w: = w + \alpha\nabla_wf(w) w:=w+αwf(w)
    梯度下降算法的迭代公式: w : = w − α ∇ w f ( w ) w: = w - \alpha\nabla_wf(w) w:=wαwf(w)
    上升算法求函数的最大值,下降算法求函数的最小值。

例子: 使用梯度上升找到最佳参数。

给定100个样本点,每个点两个数值型特征: x 1 和 x 2 , x_1和x_2, x1x2,伪代码如下:
每个回归系数初始化为1:
重复R次:
计算整个数据集的梯度,
使用alpha*gradient更新回归系数的向量
返回回归系数

def gradAscent(dataMatIn, classLabels):
    """
    返回一个最佳权值
    :param dataMatIn:
    :param classLabels:
    :return:
    """
    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

其分类效果:
在这里插入图片描述

改进1:使用随机梯度上升

一次仅用一个样本点来更新回归系数
伪代码:
所有回归系数初始化为1.
对数据集中每个样本。
计算该样本的梯度
使用alpha*gradient更新回归系数值
返回回归系数值。
随机梯度上升比梯度上升算法要省一些时间,但是结果比较粗糙,分类不是最佳状态。

def stocGradAscent0(dataMatrix, classLabels):
    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 weights

分类效果:
在这里插入图片描述

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

def stocGradAscent1(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 + 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

分类效果:
在这里插入图片描述
使用样本随机选择和alpha动态减少机制的随机梯度上升算法,比采用固定alpha的方法收敛速度更快。

示例:从疝气病症预测病马的死亡率

步骤:
1. 收集数据
2. 准备数据,用python解析文本文件并填充缺失值
3. 分析数据:可视化并观察数据
4. 训练算法:使用优化算法,找到最佳的系数
5. 测试算法:为了量化回归的效果,需要观察错误率,根据错误率决定是否回退到训练阶段,通过改变迭代次数和步长等参数来得到更好的回归系数
6. 使用算法

def classifyVector(inX, weights):
    """
    计算出sigmod函数结果,大于0.5返回1,否则返回0
    :param inX:特征向量
    :param weights:权重向量
    :return: 返回分类结果
    """
    prob = sigmoid(sum(inX * weights))
    if prob > 0.5:
        return 1.0
    else:
        return 0.0


def colicTest():
    frTrain = open("horseColicTraining.txt")
    frTest = open("horseColicTest.txt")
    trainingSet = []
    trainingLabels = []
    for line in frTrain.readlines():
        currLine = line.strip().split('\t')
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        trainingSet.append(lineArr)
        trainingLabels.append(float(currLine[21]))
    trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 500)
    errorCount = 0; numTestVec = 0.0
    for line in frTest.readlines():
        numTestVec += 1.0
        currLine = line.strip().split('\t')
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        if int(classifyVector(array(lineArr), trainWeights)) != int(currLine[21]):
            errorCount += 1

    errorRate = (float(errorCount) / numTestVec)
    print("the error rate of this test is: %f" % errorRate)
    return errorRate

def multiTest():
    numTests = 10; errorSum = 0.0
    for k in range(numTests):
        errorSum += colicTest()
    print("after %d iterations the average error rate is : %f " % (numTests, errorSum/float(numTests)))


测试:multiTest()
测试结果:

the error rate of this test is: 0.402985
the error rate of this test is: 0.313433
the error rate of this test is: 0.298507
the error rate of this test is: 0.343284
the error rate of this test is: 0.313433
the error rate of this test is: 0.388060
the error rate of this test is: 0.388060
the error rate of this test is: 0.283582
the error rate of this test is: 0.358209
the error rate of this test is: 0.432836
after 10 iterations the average error rate is : 0.352239 

平均错误率是 0.352239

详细代码参考项目:github机器学习实战第五章

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

小鱼儿LY

一切随缘

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值