《机器学习实战笔记--第一部分 分类算法:logistic回归2》

    本节将使用logistic回归来预测患有病的马的存活问题。数据集包括368个样本和28特征。

    

    数据集中有部分指标是主观的难以测量,数据集中有30%是缺失的。下面我们将介绍如何处理数据集中的数据缺失问题,然后再利用logistic回归和随机梯度上升法来预测病马的生死。

    1.准备数据:处理数据中的缺失值

    数据采集过程中若某个传感器损坏导致一个特征无效该怎么办?所以我们必须采取一些方法来解决这个问题。

    下面给出一些可选的做法:

    

        现在对数据集做预处理,使其可以顺利地使用分类算法。在预处理阶段,必须要做两件事:第一,所有的缺失值必须使用一个实数值来替换,因为我们的Numpy数据类型不允许包含缺失值。这里选择实数0来替换所有的缺失值,恰好能用于Logistic回归。这样做的直觉在于我们需要一个在更新时不会影响系数的值。回归系数的更新公式如下:

    

        如果dataMatrix的某特征对应值为0,那么该特征对应的系数将不更新。

        另外由于sigmoid(0)=0.5,即它对结果的预测不具有任何的倾向性,因此上述做法也不会对误差造成任何影响。基于上述原因,将缺失值用0代替既可以保留现有的数据,也不需要对优化算法进行修改。此外,该数据集中的特征值一般不取0,因此在某种意义上说他也满足“特殊值”这个要求。

        预处理中的第二件事是,如果在测试数据集中发现了一条数据的类别标签标记为缺失,那么我们的简单做法是将该数据丢弃。这是因为数据标签与特征不同,很难确定采用某个合适的值来代替。采用logistic回归进行分类时这种做法是合理的,而如果采用类似KNN的方法就不太可行。

        采用上述方法处理完数据集之后,现在就有一个干净的数据集来进行优化算法了。

    2.测试算法:用Logistic回归进行分类

    我们将上述处理后的数据集作为输入来训练我们的分类器:

    

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('\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, 1000)
    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)))

    数据导入后就可以计算梯度再估计分类了。整体来看colicTest()具有完全独立的功能,多次运行得到的结果可能稍有不同,我们最后一个函数就是求10个结果然后取平均。

    运行效果如下所示:

    

    可以看到最后错误率在32%左右,考虑到数据样本缺失在30%左右,所以这个结果还是可以接受的。

    实际上更改步长和迭代次数,平均错误率可以降到20%左右,在第七章中我们会再使用这次数据集。

    

    

猜你喜欢

转载自blog.csdn.net/qq_41635352/article/details/80682463