機器學習實戰python3 Logistic Regression


代碼及數據:https://github.com/zle1992/MachineLearningInAction

logistic regression

優點:計算代價不高,易於理解實現,線性模型的一種。

缺點:容易欠擬合,分類精度不高。但是可以用於預測概率。

適用數據范圍:數值型和標稱型。

准備數據:

1 def loadDataSet():
2     dataMat,labelMat = [],[]
3     with open(filename,"r") as  fr:  #open file
4         for line in fr.readlines():
5             lineArr = line.split() #split each line
6             dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])  #創建2維list
7             labelMat.append(int(lineArr[2]))
8     return dataMat,labelMat

 

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

Sigmoid函數:

 

 

1 def sigmoid(inX):
2     return 1.0/(1+np.exp(-inX))

 

2基於最優化方法的最佳回歸系數確定

梯度上升法:

梯度上升法的偽代碼如下:
每個回歸系數初始化為1
重復R次:
計算整個數據集的梯度
使用alpha x gradient更新回歸系數的向量
返回回歸系數

代碼:

 1 def sigmoid(inX):
 2     return 1.0/(1+np.exp(-inX))
 3 
 4 def gradAscent(dataMat,labelMat):
 5     dataMatrix = np.mat(dataMat)  #translate list to matrix
 6     labelMatrix = np.mat(labelMat).transpose() #轉置
 7     m,n = np.shape(dataMatrix) #100 rows  3 coulums
 8     alpha = 0.001 #步長 or 學習率
 9     maxCyclse = 500
10     weight = np.ones((n,1)) #初始值隨機更好吧
11     #weight = np.random.rand(n,1)
12     for k in range(maxCyclse):
13         h = sigmoid(dataMatrix * weight) # h 是向量
14         error = (labelMatrix - h)  #error 向量
15         weight = weight + alpha * dataMatrix.transpose() *error  #更新
16      #   print(k,"  ",weight)
17     return weight

 

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

 1 def plotfit(wei):
 2     import matplotlib.pyplot as plt
 3     weight = np.array(wei) #???????? #return array
 4     dataMat ,labelMat = loadDataSet() 
 5     dataArr = np.array(dataMat)
 6     n = np.shape(dataArr)[0]  #row
 7     fig = plt.figure()   #plot
 8     ax = fig.add_subplot(111)
 9     ax.scatter(dataArr[:,1],dataArr[:,2],s =50, c = np.array(labelMat)+5) #散點圖 #參考KNN 的畫圖
10     x = np.arange(-3.0,3.0,0.1)   #畫擬合圖像
11     y = (-weight[0] - weight[1] *x ) / weight[2]
12     ax.plot(x,y)
13     plt.xlabel("x1")
14     plt.ylabel("x2")
15     plt.show()

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

偽代碼:
所有回歸系數初始化為1
對數據集中每個樣本
計算該樣本的梯度
使用alpha x gradient更新回歸系數值
返回回歸系數值

原始梯度上升計算數據集的梯度,涉及的是矩陣運算。h,error都是向量

隨機梯度算法計算的是數據集中每個樣本的梯度,s計算量減小,h,error都是數值

1 ef stocGradAscent0(dataMatrix,labelMatrix):
2     m,n = np.shape(dataMatrix)
3     alpha = 0.1
4     weight = np.ones(n)
5     for i in range(m):
6         h = sigmoid(sum(dataMatrix * weight))
7         error = labelMatrix[i] - h
8         weight = weight + alpha * error * dataMatrix[i]
9     return weight

上面的算法是固定的步長,固定的步長,不穩定,會產生震盪,所以下面的算法采用不固定的步長。

距離目標值遠的時候,步長大,距離目標值近的時候,步長小。

 1 def stocGradAscent1(dataMat,labelMat,numIter = 150):
 2     dataMatrix = np.mat(dataMat)  #translate list to matrix
 3     labelMatrix = np.mat(labelMat).transpose() #轉置
 4     m,n = np.shape(dataMat)
 5     alpha = 0.1
 6     weight = np.ones(n) #float 
 7     #weight = np.random.rand(n)
 8     for j in range(numIter):
 9         dataIndex = list(range(m)) #range 沒有del 這個函數  所以轉成list  del 見本函數倒數第二行
10         for i in range(m):
11             alpha = 4/(1.0 +j + i) + 0.01
12             randIndex = int(np.random.uniform(0,len(dataIndex))) #random.uniform(0,5) 生成0-5之間的隨機數
13             #生成隨機的樣本來更新權重。
14             h = sigmoid(sum(dataMat[randIndex] * weight))
15             error = labelMat[randIndex] - h
16             weight = weight + alpha * error * np.array(dataMat[randIndex])  #!!!!一定要轉成array才行
17             #dataMat[randIndex] 原來是list  list *2 是在原來的基礎上長度變為原來2倍,
18             del(dataIndex[randIndex]) #從隨機list中刪除這個
19     return weight

5從病氣病症預測病馬的死亡率

 

 1 def classifyVector(inX,weight):  #輸入測試帶測試的向量 返回類別
 2     prob = sigmoid(sum(inX * weight))
 3     if prob > 0.5 :
 4         return 1.0
 5     else: return 0.0
 6 def colicTest():
 7     trainingSet ,trainingSetlabels =[],[]
 8     with open("horseColicTraining.txt") as frTrain:
 9         for lines in frTrain.readlines():
10             currtline = lines.strip().split('\t')  # strip()remove the last string('/n') in everyline 
11             linearr = [] #每行臨時保存str 轉換float的list
12             for i in range(21):   #將讀進來的每行的前21個str 轉換為float 
13                 linearr.append(float(currtline[i]))
14             trainingSet.append(linearr)  #tianset 是2維的list
15             trainingSetlabels.append(float(currtline[21]))#第22個是類別
16     trainWeights = stocGradAscent1(trainingSet,trainingSetlabels,500)
17     errorCount = 0
18     numTestVec = 0.0
19     with open("horseColicTest.txt") as frTrain:
20         for lines in frTrain.readlines():
21             numTestVec += 1.0
22             currtline = lines.strip().split('\t')  # strip()remove the last string('/n') in everyline 
23             linearr = []  #測試集的每一行
24             for i in range(21):
25                 linearr.append(float(currtline[i]))#轉換為float
26             if int(classifyVector(np.array(linearr),trainWeights)) != int(currtline[21]) :
27                 errorCount += 1  #輸入帶分類的向量,輸出類別,類別不對,errorCount ++
28             errorRate = float(errorCount)/numTestVec
29             print("the error rate of this test is : %f"%errorRate)
30     return errorRate
31 def multiTest(): #所有測試集的錯誤率
32     numTests = 10
33     errorSum = 0.0
34     for k in range(numTests):
35         errorSum +=colicTest()
36     print("after %d iterations the average error rate is : %f" %(numTests,errorSum/float(numTests)))

主函數:

1 if __name__ == '__main__':
2     filename = "testSet.txt" 
3     dataMat,labelMat = loadDataSet()
4     #weight = gradAscent(dataMat,labelMat)
5     weight = stocGradAscent1(dataMat,labelMat)
6     print(weight)
7     plotfit(weight)#畫分類圖像在小數據集上
8     multiTest() #真實數據集上測試

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM