资讯专栏INFORMATION COLUMN

【数据科学系统学习】机器学习算法 # 西瓜书学习记录 [3] Logistic 回归实践

MSchumi / 1839人阅读

摘要:根据错误率决定是否回退到训练阶段,通过改变迭代的次数和步长等参数来得到更好的回归系数。使用回归方法进行分类所需做的是把测试集上每个特征向量乘以最优化方法得来的回归系数,再将该乘积结果求和,最后输入到函数即可。

本篇内容为《机器学习实战》第 5 章 Logistic 回归程序清单。

书中所用代码为 python2,下面给出的程序清单是在 python3 中实践改过的代码,希望对你有帮助。


训练算法:使用梯度上升找到最佳参数

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

每个回归系数初始化为 1
重复 R 次:
————计算整个数据集的梯度
————使用 alpha $ imes$ gradient 更新回归系数的向量
返回回归系数

程序清单 5-1:Logisitc 回归梯度上升优化算法
# 打开文本文件 testSet.txt 并逐行读取
def loadDataSet():
    dataMat = []; lableMat = []
    fr = open("testSet.txt")
    for line in fr.readlines():
        lineArr = line.strip().split()
        # 为计算方便,将 X0 的值设为 1.0
        dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])])
        lableMat.append(int(lineArr[2]))
    return dataMat, lableMat

def sigmoid(intX):
    return 1.0/(1+exp(-intX))

# 参数 dataMatIn 是一个 2 维 numpy 数组,存放的是一个 100*3 的矩阵
# 每列分别代表每个不同的特征,每行代表每个训练样本
def gradAscent(dataMatIn, classLabels):
    # 转换为 numpy 矩阵的数据类型
    dataMatrix = mat(dataMatIn)
    # classLabels 类别标签
    labelMat = mat(classLabels).transpose()
    # 得到矩阵大小
    m,n = shape(dataMatrix)

    # 设置梯度上升法所需参数
    # alpha 步长,maxCycles 迭代次数
    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

在 python 提示符下,执行代码并得到结果:

>>> import logRegres
>>> dataArr, labelMat=logRegres.loadDataSet()
>>> logRegres.gradAscent(dataArr, labelMat)
matrix([[ 4.12414349],
        [ 0.48007329],
        [-0.6168482 ]])
分析数据:画出决策边界 程序清单 5-2:画出数据集和 Logistic 回归最佳拟合直线的函数
# 画出数据集和logistic回归最佳拟合直线的函数
def plotBestFit(weights):
    import matplotlib.pyplot as plt
    dataMat, labelMat = loadDataSet()
    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)
    # 形状参数 marker "s":正方形,参数 s:点的大小
    ax.scatter(xcord1, ycord1, s=30, c="red", marker="s")
    ax.scatter(xcord2, ycord2, s=30, c="green")

    # arange(start, end, step),返回一个array对象
    x = arange(-3.0, 3.0, 0.1)
    # 设置 sigmoid 函数为0
    y = (-weights[0]-weights[1]*x)/weights[2]
    ax.plot(x, y)
    plt.xlabel("X1")
    plt.ylabel("X2")
    plt.show()

在 python 提示符下,执行代码并得到结果:

>>> import importlib
>>> importlib.reload(logRegres)

>>> weights = logRegres.gradAscent(dataArr, labelMat)
>>> logRegres.plotBestFit(weights.getA())

训练算法:随机梯度上升

随机梯度上升算法的伪代码如下:
所有回归系数初始化为 1
对数据集中每个样本
————计算该样本的梯度
————使用 alpha $ imes$ gradient 更新回归系数值
返回回归系数值

程序清单 5-3:随机梯度上升算法
# 随机梯度上升算法
def stocGradAscent0(dataMatrix, classLabels):
    m,n = shape(dataMatrix)
    alpha = 0.01
    weights = ones(n)
    for i in range(m):
        # 变量 h 和误差 error 都是向量
        h = sigmoid(sum(dataMatrix[i]*weights))
        error = classLabels[i] - h
        weights = weights + alpha * error * dataMatrix[i]
    return weights

在 python 提示符下,执行代码并得到结果:

>>> from numpy import *
>>> importlib.reload(logRegres)

>>> dataArr, labelMat=logRegres.loadDataSet()
>>> weights = logRegres.stocGradAscent0(array(dataArr), labelMat)
>>> logRegres.plotBestFit(weights)

程序清单 5-4:改进的随机梯度上升算法
# 改进的随机梯度上升算法
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
            # uniform() 方法将随机生成下一个实数
            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

在 python 提示符下,执行代码并得到结果:

>>> importlib.reload(logRegres)

>>> dataArr, labelMat=logRegres.loadDataSet()
>>> weights = logRegres.stocGradAscent1(array(dataArr), labelMat)
>>> logRegres.plotBestFit(weights)

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

使用 Logistic 回归估计马疝病的死亡率

收集数据:给定数据文件。

准备数据:用 Python 解析文本文件并填充缺失值。

分析数据:可视化并观察数据。

训练算法:使用优化算法,找到最佳的系数。

测试算法:为了量化回归的效果,需要观察错误率。根据错误率决定是否回退到训练阶段,通过改变迭代的次数和步长等参数来得到更好的回归系数。

使用算法:实现一个简单的命令行程序来收集马的症状并输出预测结果。

使用 Logistic 回归方法进行分类所需做的是把测试集上每个特征向量乘以最优化方法得来的回归系数,再将该乘积结果求和,最后输入到 sigmoid 函数即可。如果对应的 sigmoid 值大于 0.5 就预测类别标签为 1,否则为 0。
程序清单 5-5:Logistic 回归分类函数
# 以回归系数和特征向量作为输入来计算对应的 sigmoid 值
def classifyVector(inX, weights):
    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("	")
        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("	")
        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("这个测试集的错误率是:%f" % errorRate)
    return errorRate

def multiTest():
    numTests = 10
    errorSum = 0.0
    
    for k in range(numTests):
        errorSum += colicTest()
        
    print("经过 %d 次迭代后平均错误率是:%f" % (numTests, errorSum/float(numTests)))

在 python 提示符下,执行代码并得到结果:

>>> importlib.reload(logRegres)

>>> logRegres.multiTest()
这个测试集的错误率是:0.358209
这个测试集的错误率是:0.373134
这个测试集的错误率是:0.253731
这个测试集的错误率是:0.402985
这个测试集的错误率是:0.358209
这个测试集的错误率是:0.298507
这个测试集的错误率是:0.343284
这个测试集的错误率是:0.298507
这个测试集的错误率是:0.402985
这个测试集的错误率是:0.417910
经过 10 次迭代后平均错误率是:0.350746

Logistic 回归的目的是寻找一个非线性函数 sigmoid 的最佳拟合参数,求解过程可以由最优化算法来完成。


不足之处,欢迎指正。

$$$$

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/42338.html

相关文章

  • 数据学系学习机器学习算法 # 西瓜学习记录 [5] 支持向量机实践

    摘要:本篇内容为机器学习实战第章支持向量机部分程序清单。支持向量机优点泛化错误率低,计算开销不大,结果易解释。注以上给出的仅是简化版算法的实现,关于完整的算法加速优化并应用核函数,请参照机器学习实战第页。 本篇内容为《机器学习实战》第 6 章 支持向量机部分程序清单。所用代码为 python3。 支持向量机优点:泛化错误率低,计算开销不大,结果易解释。 缺点:对参数调节和核函数的选择敏感,...

    RebeccaZhong 评论0 收藏0
  • 数据学系学习机器学习算法 # 西瓜学习记录 [10] 决策树实践

    摘要:本篇内容为机器学习实战第章决策树部分程序清单。适用数据类型数值型和标称型在构造决策树时,我们需要解决的第一个问题就是,当前数据集上哪个特征在划分数据分类时起决定性作用。下面我们会介绍如何将上述实现的函数功能放在一起,构建决策树。 本篇内容为《机器学习实战》第 3 章决策树部分程序清单。所用代码为 python3。 决策树优点:计算复杂度不高,输出结果易于理解,对中间值的缺失不敏感,可...

    suemi 评论0 收藏0

发表评论

0条评论

MSchumi

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<