1. 程式人生 > >【機器學習筆記2.2】用邏輯迴歸預測馬疝病的死亡率

【機器學習筆記2.2】用邏輯迴歸預測馬疝病的死亡率

資料預處理:如何處理資料中的缺失值

       假設有 100 個樣本和 20 個特徵 ,這些資料都是機器收集回來的。若機器上的某個感測器損壞導致一個特徵無效時該怎麼辦?此時是否要扔掉整個資料?這種情況下,另外19 個特徵怎麼辦?它們是否還可用?答案是肯定的。因為有時候資料相當昂貴,扔掉和重新獲取都是不可取的,所以必須採用一些方法來解決這個問題。

       在預處理階段需要做兩件事: 第一,所有的缺失值必須用一個實數值來替換,因為我們使用的numpy資料型別不允許包含缺失值。這裡選擇實數 0 來替換所有缺失值,恰好能適用於Logistic迴歸。這樣做的直覺在於,我們需要的是一個在更新時不會影響係數的值。迴歸係數的更新公式如下:

weights = weights + alpha * error * dataMatrix[randIndex]

如果dataMatrix的某特徵對應值為 0,那麼該特徵的係數將不做更新,即:

weights = weights

另外,由於sigmoid(0) = 0.5,即它對結果的預測不具有任何傾向性,因此上述做法也不會對誤差項造成任何影響。基於上述原因,將缺失值用 0 代替既可以保留現有資料,也不需要對優化演算法進行修改。此外,該資料集中的特徵取值一般不為 0,因此在某種意義上說它也滿足“特殊值”這個要求。

預處理中做的第二件事是,如果在測試資料集中發現了一條資料的類別標籤已經缺失,那麼我們的簡單做法是將該條資料丟棄。這是因為類別標籤與特徵不同,很難確定採用某個合適的值來替換。採用Logistic迴歸進行分類時這種做法是合理的,而如果採用類似kNN的方法就可能不太可行。預處理後的資料參見[1]的相關程式碼集。原始資料參見:

http://archive.ics.uci.edu/ml/datasets/Horse+Colic

程式碼示例

更新到 logRegres.py,參見【機器學習筆記2】
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, weights_arr = 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)))
        

main.py

import logRegres
errorRate = logRegres.multiTest()

實驗結果如下:


參考文獻

[2] Peter. 機器學習實戰