機器學習實戰(5):Logistic回歸

機器學習實戰(5):Logistic回歸

來自專欄半仙數據分析之路

第5章: Logistic回歸

  • 優點:計算代價不高,易於理解和實現。
  • 缺點:容易欠擬合,分類精度可能不高。
  • 適用數據類型:數值型和標稱型數據

Charles Xiao:邏輯回歸和SVM的區別是什麼?各適用於解決什麼問題?

邏輯回歸

通常遇到缺值的情況,我們會有幾種常見的處理方式

  • 如果缺值的樣本佔總數比例極高,我們可能就直接捨棄了,作為特徵加入的話,可能反倒帶入noise,影響最後的結果了
  • 如果缺值的樣本適中,而該屬性非連續值特徵屬性(比如說類目屬性),那就把NaN作為一個新類別,加到類別特徵中
  • 如果缺值的樣本適中,而該屬性為連續值特徵屬性,有時候我們會考慮給定一個step(比如這裡的age,我們可以考慮每隔2/3歲為一個步長),然後把它離散化,之後把NaN作為一個type加到屬性類目中。
  • 有些情況下,缺失的值個數並不是特別多,那我們也可以試著根據已有的值,擬合一下數據,補充上。

9.1 模型係數關聯分析

親,你以為結果提交上了,就完事了?

我不會告訴你,這只是萬里長征第一步啊(淚牛滿面)!!!這才剛擼完baseline model啊!!!還得優化啊!!!

看過Andrew Ng老師的machine Learning課程的同學們,知道,我們應該分析分析模型現在的狀態了,是過/欠擬合?,以確定我們需要更多的特徵還是更多數據,或者其他操作。我們有一條很著名的learning curves對吧。

不過在現在的場景下,先不著急做這個事情,我們這個baseline系統還有些粗糙,先再挖掘挖掘。

  • 首先,Name和Ticket兩個屬性被我們完整捨棄了(好吧,其實是因為這倆屬性,幾乎每一條記錄都是一個完全不同的值,我們並沒有找到很直接的處理方式)。
  • 然後,我們想想,年齡的擬合本身也未必是一件非常靠譜的事情,我們依據其餘屬性,其實並不能很好地擬合預測出未知的年齡。再一個,以我們的日常經驗,小盆友和老人可能得到的照顧會多一些,這樣看的話,年齡作為一個連續值,給一個固定的係數,應該和年齡是一個正相關或者負相關,似乎體現不出兩頭受照顧的實際情況,所以,說不定我們把年齡離散化,按區段分作類別屬性會更合適一些。

*********************************************************************

5.1 基於Logistic 回歸和Sigmoid 函數的分類

Sigmoid函數

Sigmoid函數在不同坐標尺度下的兩條曲線圖。當x為0時,Sigmoid函數值為0.5。隨著x的增大,對應的Sigmoid值將逼近於1;而隨著x的減小,Sigmoid值將逼近於0。如果橫坐標刻度足夠大,Sigmoid函數看起來很像一個階躍函數。

為了實現Logistic回歸分類器,我們可以在每個特徵上都乘以一個回歸係數,然後把所有的結果值相加,將這個總和代入Sigmoid函數中,進而得到一個範圍在0~1之間的數值。任何大於0.5的數據被分入1類,小於0.5即被歸入0類

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

它表示將這兩個數值向量對應元素相乘,然後全部加起來即得到z值。其中的向量x是分類器的輸入數據,向量w也就是我們要找到的最佳參數。

5.2.1 梯度上升法

思想:要找到某函數的最大值,最好的方法是沿著該函數的梯度方向探尋。如果梯度記為?,則函數f(x,y)的梯度由下式表示:

偏微分方程,在該點有定義,且可微分。

偏微分方程

迭代公式

梯度下降法

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

#導出numpy所有from numpy import * 定義函數,獲得txt文件的特徵和標籤,存儲至dataMat和labelMat集合中。def loadDataSet(): #定義空集合 dataMat = []; labelMat = [] #讀取txt文件 fr = open(testSet.txt) #for循環逐行讀取 for line in fr.readlines(): # strip()去除字元串空格和換行字元,split()按空格和換行字元分開 lineArr = line.strip().split() #加入到dataMat,第一個值設置為1.0 dataMat.append([1.0, float(lineArr[0]), float(lineArr[1])]) #求類別標籤 labelMat.append(int(lineArr[2])) return dataMat,labelMat

sigmoid(),確定分類

#定義sigmoid(),確定分類def sigmoid(inX): z=1.0/(1+exp(-inX)) return z

mat()函數:numpy一維數組array轉化為矩陣

定義函數gradAscent(),transpose() 矩陣轉置函數,mat()函數list轉化為martix,數組轉為矩陣.dataMat里存放的是特徵,但是第一列都為1.0,實際上為100*3的矩陣LabelMat里存放的是類別標籤,1*100的行向量def gradAscent(dataMat,labelMat): # 將列錶轉化為矩陣 dataMatrix = mat(dataMat) # 將列錶轉化為矩陣 ,且進行轉置 labelMat = mat(labelMat).transpose() #計算dataMatrix行數m,列數n m,n = shape(dataMatrix) #目標移動步長 alpha = 0.001 #迭代次數 maxCycles = 500 #權重初始化為1 weights = ones((n,1)) for k in range(maxCycles): #注意,這裡h是一個m*1的列向量 h = sigmoid(dataMatrix*weights) #求得誤差 error = (labelMat - h) #更新權重 weights = weights + alpha * dataMatrix.transpose()* error #matrix mult return weights

調用函數

dataMat,labelMat=loadDataSet()gradAscent(dataMat,labelMat)

print(dataMat數據類型是,type(dataMat))print(labelMat數據類型是,type(labelMat))

5.2.3 分析數據:畫出決策邊界

get()將矩陣轉化為一維數組array,與mat()作用相反

#導入數據包import numpy as npimport pandas as pdimport matplotlib.pyplot as pltimport warningswarnings.filterwarnings(ignore)%matplotlib inline

繪製決策邊界線

#繪製決策邊界線def plotBestFit(weights): dataArr=array(dataMat) n=shape(dataArr)[0] xcord1=[]; ycord1=[] xcord2=[]; ycord2=[] for i in range(n): if int(labelMat[i])==1: xcord1.append(dataArr[i,1]); ycord1.append(dataArr[i,2]) else: xcord2.append(dataArr[i,1]); ycord2.append(dataArr[i,2]) #設置畫板 fig=plt.figure() fig.set_size_inches(12,8) #設置畫紙 ax=fig.add_subplot(111) ax.scatter(xcord1,ycord1,color=red,marker=*) ax.scatter(xcord2,ycord2,color=green,marker=s) x=arange(-3,3,0.1) #x=arange(-3,3,0.1) y= (-weights[0]-weights[1]*x)/weights[2] #ax.plot(x,y) ax.plot(x,y) plt.xlabel(X1) plt.ylabel(X2) plt.title(決策邊界線) plt.grid(False) plt.show() return xcord1, ycord1,xcord2, ycord2, y

調用函數

weights=gradAscent(dataMat,labelMat)#getA()將矩陣轉化為一維數組,與mat()作用相反plotBestFit(weights.getA())

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

def stocGradAscent0(dataMat,labelMat): m,n=shape(dataMat) #目標移動步長 alpha=0.01 #設置初始權重為1,array([1., 1., 1.])list weights=ones(n) for i in range(m): #dtaMat[i]是(1*n)array; #weights是(m,)array; #dataMat[i]*weights,必須是array結構,乘積是一個數值 #h是數值 h=sigmoid(sum(dataMat[i]*weights)) #labelMat是(m=m2,)array-list error=labelMat[i]-h weights=weights+alpha*error*dataMat[i] return weights,m,n,h,error

調用函數

from numpy import *#reload(logRegres)dataArr,labelMat=loadDataSet()#weights=stocGradAscent0(dataMat,labelMat)value=stocGradAscent0(array(dataMat),labelMat)value

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

5.4 本章小結

參考資料

Logistic回歸及梯度上升演算法 - CSDN博客

《機器學習實戰》--logistic回歸 - CSDN博客

python中mat()函數 - CSDN博客

python--zeros函數和ones函數 - chamie - 博客園

python 學習筆記(1)--numpy數組轉置 - CSDN博客

數組與矩陣的區別 Python - CSDN博客


推薦閱讀:

BP神經網路演算法:將參數矩陣向量化
gradient descent計算流程和注意事項
斯坦福公開課-機器學習筆記 1
Mac tensorflow 的安裝
高斯過程簡介

TAG:數據分析 | 數據挖掘 | 機器學習 |