【機器學習筆記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]的相關程式碼集。原始資料參見:
程式碼示例
更新到 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. 機器學習實戰