《機器學習實戰》Logistic迴歸python3原始碼
阿新 • • 發佈:2018-11-05
邏輯迴歸:
1 梯度上升優化演算法 2 隨機梯度上升演算法 3 改進的隨機梯度上升法
開啟pycharm建立一個logRegression.py檔案,輸入如下程式碼:
#coding:utf-8 from numpy import * """下載資料集,返回dataMat和labelMat,都是list型別""" def loadDataSet(): dataMat=[];labelMat=[] fr=open('testSet.txt') for line in fr.readlines(): lineArr=line.strip().split() dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])]) #將x0設為1.0 labelMat.append(float(lineArr[2])) # print("shape(labelMat):",shape(labelMat)) # print("type(dataMat", type(dataMat)) # print("shape(dataMat",shape(dataMat)) return dataMat,labelMat """sigmod 函式的定義""" def sigmod(inX): return 1.0/(1+exp(-inX)) """----------------Logistic迴歸梯度上升優化演算法-----------------""" """ 梯度上升法的虛擬碼: 每個迴歸係數初始化為1 重複R次: 計算整個資料集的梯度 使用alpha*gradient更新迴歸係數的向量 返回迴歸係數 """ def gradAscent(dataMatIn,classLabels): #dataMatIn,classLabels都是list型別 dataMatrix=mat(dataMatIn) #dataMatrix是矩陣型別 #labelMat=mat(classLabels).T labelMat = mat(classLabels).transpose() #和上面一條語句含義相同,對行進行轉置,labelMat是m*1的列向量 m,n=shape(dataMatrix) #求出dataMatrix的行(樣本數)和列(特徵數) alpha=0.001 #向目標移動的步長 maxCycles=500 #迭代的次數 weights=ones((n,1)) #建立一個n行1列全為1的陣列,即初始化迴歸係數全為1 for k in range(maxCycles): h=sigmod(dataMatrix*weights) #這個步驟包含了m*n次乘積。h是sigmod返回的結果,即預測值,h為m*1的列向量 error=(labelMat-h) #真實值與預測值之差 weights=weights+alpha*dataMatrix.transpose()*error return weights """----------畫出資料集和Logistic迴歸最佳擬合直線的函式(輸入wei為矩陣)------""" def plotBestFit(wei): # wei是一個矩陣 import matplotlib.pyplot as plt weights=wei.getA() #矩陣.getA()是把矩陣變成陣列array型別 dataMat,labelMat=loadDataSet() #下載資料集,dataMat,labelMat都是list型別 dataArr=array(dataMat) #轉換成array型別,方便後面陣列訪問 dataArr[i,j] n=shape(dataArr)[0] #dataArr資料集的行數,即樣本的個數 xcord1=[];ycord1=[] #定義兩個空陣列,用來存放不同label的x1和x2值 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() ax=fig.add_subplot(111) ax.scatter(xcord1,ycord1,s=30,c='r',marker='s') ax.scatter(xcord2,ycord2,s=30,c='g') #畫出最佳擬合直線 x=arange(-3.0,3.0,0.1) y=(-weights[0]-weights[1]*x)/weights[2] ax.plot(x,y) plt.xlabel("X1");plt.ylabel("X2") plt.show() """----------畫出資料集和Logistic迴歸最佳擬合直線的函式(輸入weights為陣列)------""" def plotBestFit2(weights): # weights是numpy的array陣列 import matplotlib.pyplot as plt dataMat, labelMat = loadDataSet() # 下載資料集,dataMat,labelMat都是list型別 dataArr = array(dataMat) # 轉換成array型別,方便後面陣列訪問 dataArr[i,j] n = shape(dataArr)[0] # dataArr資料集的行數,即樣本的個數 xcord1 = [];ycord1 = [] # 定義兩個空陣列,用來存放不同label的x1和x2值 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() ax = fig.add_subplot(111) ax.scatter(xcord1, ycord1, s=30, c='r', marker='s') ax.scatter(xcord2, ycord2, s=30, c='g') # 畫出最佳擬合直線 x = arange(-3.0, 3.0, 0.1) y = (-weights[0] - weights[1] * x) / weights[2] ax.plot(x, y) plt.xlabel("X1");plt.ylabel("X2") plt.show() """-----------------------------隨機梯度上升演算法------------------------""" """ 虛擬碼: 所有迴歸係數初始化為1 對資料集中每個樣本 計算該樣本的梯度 使用alpha*gradient更新迴歸係數值 返回迴歸係數值 """ def stocGradAscent0(dataMatIn,classlabels): dataMatrix=array(dataMatIn) m,n=shape(dataMatrix) alpha=0.01 weights=ones(n) #建立n行1列全為1的陣列 for i in range(m): h=sigmod(sum(dataMatrix[i]*weights))#兩個一維陣列對應元素相乘返回一個一維陣列再求和作為sigmod的輸入 error=classlabels[i]-h #h,error都是數值 weights=weights+alpha*error*dataMatrix[i] return weights """--------------------------改進的隨機梯度上升法-----------------------""" def stocGradAscent1(dataMatIn,classlabels,numIter=150): dataMatrix = array(dataMatIn) m, n = shape(dataMatrix) weights = ones(n) for j in range(numIter): dataIndex=list(range(m)) for i in range(m): alpha=4/(1.0+j+i)+0.01 #alpha每次迭代時需要調整 randIndex=int(random.uniform(0,len(dataIndex)))# 隨機選取更新 # uniform() 方法將隨機生成下一個實數,它在[0,len(dataIndex)]範圍內。 h=sigmod(sum(dataMatrix[randIndex]*weights)) error=classlabels[randIndex]-h #計算誤差 weights=weights+alpha*error*dataMatrix[randIndex] #更新迴歸係數 #del(dataMatrix[randIndex]) #刪除已使用的樣本 return weights
重新建立一個python檔案,用於呼叫logRegression.py檔案,對各個演算法進行驗證並畫出擬合曲線。
#couding:utf-8 from numpy import * import matplotlib.pyplot as plt import logRegress dataAtrr,labelMat=logRegress.loadDataSet() """----------------Logistic迴歸梯度上升優化演算法-----驗證----------------""" wei=logRegress.gradAscent(dataAtrr,labelMat) #wei是一個矩陣 logRegress.plotBestFit(wei) """-----------------隨機梯度上升演算法---驗證---------------------""" w=logRegress.stocGradAscent0(dataAtrr,labelMat) #w是1*3陣列 logRegress.plotBestFit2(w) """---------------改進的隨機梯度上升法---驗證--------------------""" w1=logRegress.stocGradAscent1(dataAtrr,labelMat,500) #w是1*3陣列 logRegress.plotBestFit2(w1)