1. 程式人生 > >《機器學習實戰》筆記之五——Logistic迴歸

《機器學習實戰》筆記之五——Logistic迴歸

第五章 Logistic迴歸

迴歸:對一些資料點,演算法訓練出直線引數,得到最佳擬合直線,能夠對這些點很好的擬合。

訓練分類器主要是尋找最佳擬合引數,故為最優化演算法。

5.1 基於Logistic迴歸和sigmoid函式的分類

實現Logistic迴歸分類器:在每個特徵上都乘以一個迴歸係數,然後把所有的結果值相加,總和帶入sigmoid函式,其結果大於0.5分為第0類,結果小於0.5分為第0類。

sigmoid函式公式:

Figure 5-1: sigmoid函式公式

Figure 5-2: sigmoid曲線

sigmoid函式具有很好的性質,如其導數可以用其本身表示等等。

5.2 基於最優化方法的最佳迴歸係數確定

sigmoid函式輸入z:

其可以寫成z=w.T*x,向量x為分類器的輸入資料, w為訓練器尋找的最佳引數。

梯度上升法:

思想:要找到某函式的最大值,最好的方法是沿著該函式的梯度方向探尋。

函式f(x,y)的梯度:

沿x的方向移動,沿y的方向移動,最後能夠到達最優點,但是f(x,y)在待計算點需要有定義並且可微。

梯度運算元總是指向函式值增長最快的方向。移動方向為梯度方向,移動量大小需要乘以一個引數,稱之為步長。引數迭代公式為:

公式可一直執行,直到某個條件停止為止。如迭代次數或者演算法達到某個可以允許的誤差範圍。

訓練演算法:使用梯度上升找到最佳引數

梯度上升法虛擬碼:

資料點:

演算法:

  1. def loadDataSet():  
  2.     dataMat  = []  
  3.     labelMat = []  
  4.     fr = open("testSet.txt")  
  5.     for line in fr.readlines():  
  6.         lineArr = line.strip().split("\t")  
  7.         dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #對應三個引數,第一個對應著常熟
  8.         labelMat.append(int(lineArr[2]))  
  9.     return dataMat, labelMat  
  10. def sigmoid(inX):  
  11.     return1.0/(1+exp(-inX))  
  12. def gradAscent(dataMatIn, classLabels):  
  13.     '''''Logistic迴歸梯度上升優化演算法'''
  14.     dataMatrix = mat(dataMatIn)                         #100行3列
  15.     labelMat   = mat(classLabels).transpose()           #transpose()將1行100列的矩陣轉為100行1列mat(classLabels).T也可破
  16.     m,n        = shape(dataMatrix)                      #m=100,n=3
  17.     alpha      = 0.001
  18.     maxCycles  = 500
  19.     weights    = ones((n,1))                            #100行1列
  20.     for k in range(maxCycles):  
  21.         h       = sigmoid(dataMatrix*weights)           #dataMatrix*weights,100×3和3×1的矩陣相乘,得到100×1的矩陣
  22.         error   = (labelMat - h)  
  23.         weights = weights + alpha*dataMatrix.transpose()*error  
  24.     return weights  
  25. dataMat, labelMat = loadDataSet()  
  26. weights = gradAscent(dataMat, labelMat)  
  27. print weights     

Figure5-4: 演算法引數

分析資料:畫出決策邊界

上一步確定了迴歸係數,確定了不同類別資料之間的分割線。這一步畫出分割線:

  1. def plotBestFit(weights):  
  2.     dataMat, labelMat = loadDataSet()  
  3.     dataArr           = array(dataMat)              #將每個資料點的x,y座標存為矩陣的形式
  4.     n                 = shape(dataArr)[0]           #取其行數,也即資料點的個數
  5.     #======畫資料點
  6.     xcord1 = []  
  7.     ycord1 = []      
  8.     xcord2 = []  
  9.     ycord2 = []  
  10.     for i in range(n):  
  11.         if int(labelMat[i]) == 1:                   #若是正例,存到(x1,y1)中
  12.             xcord1.append(dataArr[i,1])  
  13.             ycord1.append(dataArr[i,2])  
  14.         else:  
  15.             xcord2.append(dataArr[i,1])  
  16.             ycord2.append(dataArr[i,2])  
  17.     fig = plt.figure()  
  18.     ax  = fig.add_subplot(111)  
  19.     ax.scatter(xcord1,ycord1,s=30,c="red",marker = "s")  
  20.     ax.scatter(xcord2,ycord2,s=30,c="green")  
  21.     #============
  22.     x = arange(-3.0,3.0,0.1)                    #x為numpy.arange格式,並且以0.1為步長從-3.0到3.0切分。
  23.     #擬合曲線為0 = w0*x0+w1*x1+w2*x2, 故x2 = (-w0*x0-w1*x1)/w2, x0為1,x1為x, x2為y,故有
  24.     y = (-weights[0] - weights[1]*x)/weights[2]   
  25.     #x為array格式,weights為matrix格式,故需要呼叫getA()方法,其將matrix()格式矩陣轉為array()格式
  26.     ax.plot(x,y)  
  27.     plt.xlabel("X1")  
  28.     plt.ylabel("X2")  
  29.     plt.show()  
  30. dataMat, labelMat = loadDataSet()  
  31. weights = gradAscent(dataMat, labelMat)  
  32. #getA()方法,其將matrix()格式矩陣轉為array()格式,type(weights),type(weights.getA())可觀察到。
  33. plotBestFit(weights.getA())  

Figure 5-5: 分割線

訓練演算法:隨機梯度上升

梯度上升演算法中,每次更新迴歸係數需要遍歷整個資料集。資料量若是大了,計算複雜度較高。

改進方法:一次僅用一個樣本點更新迴歸係數,這便是隨機梯度上升演算法。

虛擬碼:

程式碼:

  1. def stocGradAscent0(dataMatrix, classLabels):  
  2.     '''''隨機梯度上升演算法'''
  3.     m,n     = shape(dataMatrix)  
  4.     alpha   = 0.01
  5.     weights = ones(n)  
  6.     for i in range(m):  
  7.         h       = sigmoid(sum(dataMatrix[i]*weights))           #此處h為具體數值
  8.         error   = classLabels[i] - h                            #error也為具體數值
  9.         weights = weights + alpha*error*dataMatrix[i]           #每次對一個樣本進行處理,更新權值
  10.     return weights  
  11. dataArr, labelMat = loadDataSet()  
  12. weights = stocGradAscent0(array(dataArr), labelMat)  
  13. plotBestFit(weights)  

Figure 5-6: 隨機梯度上升演算法分割線

結果顯示其效果還不如梯度上升演算法,不過不一樣,梯度上升演算法,500次迭代每次都用上了所有資料,而隨機梯度上升演算法總共也只用了500次。需要對其進行改進:

  1. def stocGradAscent1(dataMatrix, classLabels, numIter=150):  
  2.     '''''改進的隨機梯度上升演算法,收斂得更快'''
  3.     m,n = shape(dataMatrix)  
  4.     weights = ones(n)  
  5.     for j in range(numIter):  
  6.         dataIndex = range(m)  
  7.         for i in range(m):  
  8.             alpha = 4/(1.0+i+j)+0.0001#alpha迭代次數不斷變小,1.非嚴格下降,2.不會到0
  9.             #隨機選取樣本更新系數weights,每次隨機從列表中選取一個值,用過後刪除它再進行下一次迭代            
  10.             randIndex = int(random.uniform(0, len(dataIndex)))#每次迭代改變dataIndex,而m是不變的,故不用unifor(0, m)
  11.             h = sigmoid(sum(dataMatrix[randIndex]*weights))  
  12.             error = classLabels[randIndex] - h  
  13.             weights = weights + alpha*error*dataMatrix[randIndex]  
  14.             del(dataIndex[randIndex])  
  15.     return weights  
  16. dataArr, labelMat = loadDataSet()  
  17. weights = stocGradAscent1(array(dataArr), labelMat)  
  18. plotBestFit(weights)  

Figure 5-7: 改進的隨機梯度上升演算法分割線

5.3 示例:從疝氣病症預測病馬的死亡率

準備資料:處理資料中的缺失值

可選做法:

  • 使用可用特徵的均值來填補缺失值
  • 使用特殊值來填補缺失值,如-1
  • 忽略有缺失值的樣本
  • 使用相似樣本的均值添補缺失值
  • 使用另外的機器學習演算法預測缺失值

資料探勘軟體clementine幾乎可以做以上資料預處理的工作。可破有問題的資料。

資料:

Figure 5-8: train data

Figure 5-9: test data

測試演算法:用Logistic迴歸進行分類

  1. def colicTest():  
  2.     frTrain              = open("horseColicTraining.txt")  
  3.     frTest                = open("horseColicTest.txt")  
  4.     #==========訓練資料準備  
  5.     trainingSet       = []  
  6.     trainingLabels = []  
  7.     for line in frTrain.readlines():  
  8.         currLine = line.strip().split("\t")  
  9.         lineArr   = []  
  10.         for i in range(21):  
  11.             lineArr.append(float(currLine[i]))  
  12.         trainingSet.append(lineArr)  
  13.         trainingLabels.append(float(currLine[21]))  
  14.     #==========  
  15.     trainWeights = stocGradAscent1(array(trainingSet), trainingLabels, 500) #進行500次迭代,計算權重  
  16.     errorCount = 0
  17.     numTestVec = 0.0  
  18.     #========準備測試集並進行測試計算錯誤率  
  19.     for line in frTest.readlines():  
  20.         numTestVec +=1.0  
  21.         currLine = line.strip().split("\t")  
  22.         lineArr   = []  
  23.         for i in range(21):  
  24.             lineArr.append(float(currLine[i]))  
  25.         if int(classifyVector(array(lineArr), trainWeights)) != int(currLine[21]):  
  26.             errorCount +=1  
  27.     errorRate = (float(errorCount)/numTestVec)  
  28.     #=======  
  29.     print "the error rate of this test is: %f" % errorRate  
  30. 相關推薦

    機器學習實戰筆記——Logistic迴歸

    第五章 Logistic迴歸 迴歸:對一些資料點,演算法訓練出直線引數,得到最佳擬合直線,能夠對這些點很好的擬合。 訓練分類器主要是尋找最佳擬合引數,故為最優化演算法。 5.1 基於Logistic迴歸和sigmoid函式的分類 實現Logistic迴歸分類器

    機器學習實戰筆記4—Logistic迴歸

    注:此係列文章裡的部分演算法和深度學習筆記系列裡的內容有重合的地方,深度學習筆記裡是看教學視訊做的筆記,此處文章是看《機器學習實戰》這本書所做的筆記,雖然演算法相同,但示例程式碼有所不同,多敲一遍沒有壞處,哈哈。(裡面用到的資料集、程式碼可以到網上搜索,很容易找到。)。Python版本3.6

    機器學習實戰》第章----Logistic迴歸

    Logistic迴歸 所謂迴歸,就是給一組資料,構建一個多項式對整個資料進行擬合.建立多項式 f=θ0x0+θ1x1+⋯+θnxn=θTX f =

    機器學習實戰》第章:Logistic迴歸(1)基本概念和簡單例項

    最近感覺時間越來越寶貴,越來越不夠用。不過還是抽空看了點書,然後整理到部落格來。 加快點節奏,廢話少說。 Keep calm & carry on. ----------------------------------------------------------

    機器學習實戰筆記5(logistic迴歸)

    1:簡單概念描述 假設現在有一些資料點,我們用一條直線對這些點進行擬合(該線稱為最佳擬合直線),這個擬合過程就稱為迴歸。訓練分類器就是為了尋找最佳擬合引數,使用的是最優化演算法。 這就是簡單的線性迴歸問題,可以通過最小二乘法求解其引數,最小二乘法和最大似然估計見:http

    機器學習實戰(四)邏輯迴歸LR(Logistic Regression)

    目錄 0. 前言 1. Sigmoid 函式 2. 梯度上升與梯度下降 3. 梯度下降法(Gradient descent) 4. 梯度上升法(Gradient ascent) 5. 梯度下降/上升法的數學推導

    機器學習實戰教程():樸素貝葉斯實戰新浪新聞分類

    原文連結: Jack-Cui,https://cuijiahua.com/blog/2017/11/ml_5_bayes_2.html 一、前言 上篇文章機器學習實戰教程(四):樸素貝葉斯基礎篇之言論過濾器講解了樸素貝葉斯的基礎知識。本篇文章將在此基礎上進行擴充套件,你將看到以下內容: 拉普拉

    機器學習基石筆記-Lecture 10 Logistic regression

    pan wiki app 方向 resource 註意 實現 comment sce soft binary classification的概念:軟二分類,不直接化為-1、1,而是給出一個概率值。 目標函數是一個概率值,但是拿到的data中y只有0、1(或者-1、1),可以

    機器學習實戰筆記(python3實現)01--概述

    apriori 一個 python 系列 k-均值聚類 思路 機器學習實戰 st算法 apr 寫在前面:這一個多月都在學習python,從python3基礎、python爬蟲、python數據挖掘與數據分析都有接觸,最近看到一本機器學習的書(主要是學習相關算法) 於是就打算

    機器學習實戰筆記(K近鄰)

    最終 而是 類別 頻率 n) 簡單 因此 當前 要素 K近鄰算法(KNN) k近鄰算法 ??k近鄰(k-nearest neighbor,KNN)是一種基本的分類與回歸算法。於1968年由Cover和Hart提出。k近鄰的輸入是實例的特征向量,對應於特征空間的點;輸出為實

    斯坦福CS229機器學習課程筆記一:線性迴歸與梯度下降演算法

    機器學習三要素 機器學習的三要素為:模型、策略、演算法。 模型:就是所要學習的條件概率分佈或決策函式。線性迴歸模型 策略:按照什麼樣的準則學習或選擇最優的模型。最小化均方誤差,即所謂的 least-squares(在spss裡線性迴歸對應的模組就叫OLS即Ordinary Least Squares):

    機器學習實戰(八)分類迴歸樹CART(Classification And Regression Tree)

    目錄 0. 前言 1. 迴歸樹 2. 模型樹 3. 剪枝(pruning) 3.1. 預剪枝 3.2. 後剪枝 4. 實戰案例 4.1. 迴歸樹 4.2. 模型樹

    機器學習實戰(七)線性迴歸(Linear Regression)

    目錄 0. 前言 1. 假設函式(Hypothesis) 2. 標準線性迴歸 2.1. 代價函式(Cost Function) 2.2. 梯度下降(Gradient Descent) 2.3. 特徵縮放(Feat

    機器學習實戰筆記一:K-近鄰演算法在約會網站上的應用

    K-近鄰演算法概述 簡單的說,K-近鄰演算法採用不同特徵值之間的距離方法進行分類  K-近鄰演算法 優點:精度高、對異常值不敏感、無資料輸入假定。 缺點:計算複雜度高、空間複雜度高。 適用範圍:數值型和標稱型。   k-近鄰演算法的一般流程 收集資料:可使用任何方法

    機器學習實戰筆記5—支援向量機

    注:此係列文章裡的部分演算法和深度學習筆記系列裡的內容有重合的地方,深度學習筆記裡是看教學視訊做的筆記,此處文章是看《機器學習實戰》這本書所做的筆記,雖然演算法相同,但示例程式碼有所不同,多敲一遍沒有壞處,哈哈。(裡面用到的資料集、程式碼可以到網上搜索,很容易找到。)。Python版本3.6

    機器學習實戰筆記6—AdaBoost

    注:此係列文章裡的部分演算法和深度學習筆記系列裡的內容有重合的地方,深度學習筆記裡是看教學視訊做的筆記,此處文章是看《機器學習實戰》這本書所做的筆記,雖然演算法相同,但示例程式碼有所不同,多敲一遍沒有壞處,哈哈。(裡面用到的資料集、程式碼可以到網上搜索,很容易找到。)。Python版本3.6

    機器學習實戰筆記3—樸素貝葉斯

    注:此係列文章裡的部分演算法和深度學習筆記系列裡的內容有重合的地方,深度學習筆記裡是看教學視訊做的筆記,此處文章是看《機器學習實戰》這本書所做的筆記,雖然演算法相同,但示例程式碼有所不同,多敲一遍沒有壞處,哈哈。(裡面用到的資料集、程式碼可以到網上搜索,很容易找到。)。Python版本3.6

    機器學習實戰筆記2—決策樹

    注:此係列文章裡的部分演算法和深度學習筆記系列裡的內容有重合的地方,深度學習筆記裡是看教學視訊做的筆記,此處文章是看《機器學習實戰》這本書所做的筆記,雖然演算法相同,但示例程式碼有所不同,多敲一遍沒有壞處,哈哈。(裡面用到的資料集、程式碼可以到網上搜索,很容易找到。)。Python版本3.6

    C++單刷《機器學習實戰二——決策樹

    演算法概述:決策樹是用於分類的一種常用方法,根據資料集特徵值的不同,構造決策樹來將資料集不斷分成子資料集,直至決策樹下的每個分支都是同一類或用完所有的特徵值。 決策樹的一般流程: (1)收集資料 (2)準備資料:樹構造演算法只適用於標稱型資料,因此數值型資料必須離散化,最好轉為bool型