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

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

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


(1)问题描述:

**训练集:**包含于文件horseColicTraining.txt中,用于训练得到模型的最佳系数。训练集包含299个样本(299行),每个样本含有21个特征(前21列),这些特征包含医院检测马疝病的指标;最后1列为类别标签,表示病马的死亡情况;部分样本含有缺失值。


**测试集:**包含于文件horseColicTest.txt中,通过预测测试样本中病马的死亡情况,来评估训练模型的优劣。测试集包含69个样本,部分样本部分特征缺失;最后1列为类别标签,用于计算错误率。


训练集与测试集存储形式如下:



(2)模型原理:

logistic回归是一种广义线性回归(generalized linear model),因此与多重线性回归分析有很多相同之处。它们的模型形式基本上相同,都具有 $ wx+b $ ,其中w和b是待求参数,其区别在于他们的因变量不同,多重线性回归直接将w‘x+b作为因变量,即 y = w x + b ,而logistic回归则通过函数L将 w x + b 对应一个隐状态 p = L ( w x + b ) ,然后根据p 与1-p的大小决定因变量的值。如果L是logistic函数,就是logistic回归。


(3)具体实现:

1.准备数据:


对于本次实验所用的数据集,需要进行如下预处理:


所有的缺失值必须用一个实数值来替换,这里选择实数0来替换所有缺失值,恰好能适用于Logistic回归,这样做在更新时不会影响回归系数的值。另外由于sigmoid(0)=0.5,即它对结果的预测不具有任何倾向性,因此上述做法也不会对误差造成任何影响。


测试数据集中发现一条数据的类别标签已经缺失,那么应将这条数据丢弃,这是因为类别标签与特征不同,很难确定采用某个合适的值来替换.


这里的 ‘horseColicTest.txt’ 和 ‘horseColicTraining.txt’ 为已经处理好的数据。


2.加载数据:

'''
数据加载
'''
def loadDataSet(filePath):
    f = open(filePath)
    dataList = []
    labelList = []
    for line in f.readlines():
        currLine = line.strip().split(' ')
        lineArr = []
        for i in range(21):
            lineArr.append(float(currLine[i]))
        dataList.append(lineArr)
        labelList.append(float(currLine[21]))
    return dataList, labelList


3.算法训练:


使用网络上改进后的随机梯度下降算法,修正系数:


改进内容为调整过程中步长的动态调整。

'''
sigmoid函数
'''
def sigmoid(inX):
    return 1.0 / (1 + np.exp(-inX))
'''
随机梯度下降算法
'''
def stoGradAscent1(dataMatrix, classLabels, numIter = 150):
    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 (list(dataIndex)[randIndex])
    return weights
'''
随机梯度下降算法
'''
def stocGradAscent0(dataList, labelList):
    dataArr = np.array(dataList)  # 数据转化为矩阵
    m, n = np.shape(dataArr)
    alpha = 0.01
    weights = np.ones(n)
    for i in range(m):
        h = sigmoid(np.sum(dataArr[i]*weights))
        error = (h-labelList[i])
        weights = weights-alpha*error*dataArr[i]
    return weights
'''
改进的随机梯度下降算法
'''
def stocGradAscent1(dataList, labelList, numIter=150):
    dataArr = np.array(dataList)
    m,n = np.shape(dataArr)
    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.01        # 步长为动态变化
            rand = int(np.random.uniform(0, len(dataIndex)))
            choseIndex = dataIndex[rand]
            h = sigmoid(np.sum(dataArr[choseIndex]*weights))
            error = h-labelList[choseIndex]
            weights = weights-alpha*error*dataArr[choseIndex]
            del(dataIndex[rand])
    return weights


4.使用模型分类:


该函数以回归系数和特征向量作为输入来计算对应的Sigmoid值,如果Sigmoid值大于0.5则函数返回1。

'''
进行分类
'''
def classifyVector(inX, weights):
    prob = sigmoid(np.sum(inX * weights))
    if prob > 0.5:
        return 1.0
    else:
        return 0.0


5.算法评估:


在测试集上计算分类精度,多次运行得到的结果可能稍有不同,主要是因为其中有随机的成分在里面。只有当梯度下降算法得到的回归系数已经完全收敛,那么结果才是确定的。

'''
在测试集上计算分类精度
'''
def colicTest(trainWeights, testDataList, testLabelList):
    rightCount = 0  # 判断错误的数量
    testCount = len(testDataList)
    for i in range(testCount):
        if int(classifyVector(np.array(testDataList[i]), trainWeights))==int(testLabelList[i]):
            rightCount += 1
    acc = float(rightCount)/testCount
    print("本次的精度为%f" % acc)
    return acc
def main():
    numTests = 10
    accSum = 0.0
    trainDataList, trainLabelList = loadDataSet("horseColicTraining.txt")
    testDataList, testLabelList = loadDataSet("horseColicTest.txt")
    for i in range(numTests):
        trainWeights = stocGradAscent(trainDataList, trainLabelList, 500)
        errorSum += colicTest(trainWeights, testDataList, testLabelList)
    print("这%d次的平均精度为%f"%(numTests, accSum/numTests))


(4)实验结果:

运行结果如下图所示:


(5)使用Sklearn构建LR分类器

代码如下所示:

import numpy as np
from sklearn.linear_model import LogisticRegression
def colicSklearn():
    #使用np读取数据
    trainFiled=np.loadtxt('horseColicTraining.txt',delimiter="\t")
    trainSet = trainFiled[:,:-1]
    trainLables=trainFiled[:,-1:]
    testFiled = np.loadtxt('horseColicTest.txt', delimiter="\t")
    testSet = testFiled[:, :-1]
    testLables = testFiled[:, -1:]
    classifier=LogisticRegression(solver='liblinear',max_iter=10).fit(trainSet,trainLables)
    test_accurcy=classifier.score(testSet,testLables) *100
    print('正确率:%f%%'%test_accurcy)
if __name__ == '__main__':
    colicSklearn()


运行结果:


与之前结果相比有一定提升。


(6)实验小结:

Logistic 回归的目的是寻找一个非线性的函数Sigmoid最佳拟合参数,求解过程可以由最优化算法来实现。在最优化算法中,最常用的是梯度上升算法,而梯度上升算法又可以简化为随机梯度上升算法。


随机梯度上升算法与梯度上升算法的效果相当,但是占用更少的计算资源;此外随机梯度上升是一个在线算法,他可以在新数据到来时就程程参数的更新,而不需要重新读取整个数据集来进行批处理计算。


Logistic回归的优缺点

优点:实现简单,易于理解和实现;计算代价不高,速度很快,存储资源低。

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

目录
相关文章
|
21天前
|
机器学习/深度学习 算法 数据可视化
使用Logistic算法从疝气病症预测病马的死亡率
使用Logistic算法从疝气病症预测病马的死亡率
22 1
|
2月前
|
存储 数据可视化 文件存储
多变量(多元)多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化
多变量(多元)多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化
|
2月前
|
数据可视化
多变量(多元)多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化-2
多变量(多元)多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化
|
2月前
|
机器学习/深度学习 数据可视化
R语言非线性回归和广义线性模型:泊松、伽马、逻辑回归、Beta回归分析机动车事故、小鼠感染、蛤蜊数据、补剂钠摄入数据|数据分享(下)
R语言非线性回归和广义线性模型:泊松、伽马、逻辑回归、Beta回归分析机动车事故、小鼠感染、蛤蜊数据、补剂钠摄入数据|数据分享
|
2月前
|
机器学习/深度学习
R语言非线性回归和广义线性模型:泊松、伽马、逻辑回归、Beta回归分析机动车事故、小鼠感染、蛤蜊数据、补剂钠摄入数据|数据分享(上)
R语言非线性回归和广义线性模型:泊松、伽马、逻辑回归、Beta回归分析机动车事故、小鼠感染、蛤蜊数据、补剂钠摄入数据|数据分享
|
2月前
|
存储 数据可视化 文件存储
多变量(多元)多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化-1
多变量(多元)多项式曲线回归线性模型分析母亲吸烟对新生婴儿体重影响可视化
|
2月前
R语言样条曲线、泊松回归模型估计女性直肠癌患者标准化发病率(SIR)、死亡率(SMR)
R语言样条曲线、泊松回归模型估计女性直肠癌患者标准化发病率(SIR)、死亡率(SMR)
|
2月前
|
存储 数据可视化 数据库
R语言泊松Poisson回归模型预测人口死亡率和期望寿命
R语言泊松Poisson回归模型预测人口死亡率和期望寿命
|
2月前
R语言预测人口死亡率:用李·卡特(Lee-Carter)模型、非线性模型进行平滑估计
R语言预测人口死亡率:用李·卡特(Lee-Carter)模型、非线性模型进行平滑估计
|
7月前
微分方程——Volterra食饵-捕食者模型
微分方程——Volterra食饵-捕食者模型
217 0