Logistic回歸
Logistic回歸的一般過程
(1)收集數據:采用任意方法收集數據
(2)准備數據:由於需要進行距離計算,因此要求數據類型為數值型。另外,結構化數據格式最佳
(3)分析數據:采用任意方法對數據進行分析
(4)訓練算法:大部分時間用於訓練,訓練的目的是為了找到最佳的分類回歸系數
(5)測試算法:一旦訓練步驟完成,分類將會很快
(6)使用算法:首先,我們需要輸入一些數據,並將其轉化成對應的結構化數值;接着,基於訓練好的回歸系數就可以對這些數值進行
簡單的回歸計算,判定他們屬於哪個類別;在這之后,我們就可以在輸出的類別上做一些其他的分析工作
Logistic回歸的優缺點
優點:計算代價不高,易於理解和實現
缺點:容易欠擬合,分類精度可能不高
適用數據類型:數值型和標稱型數據
Sigmoid函數的計算公式:

1 import os 2 os.getcwd() 3 os.chdir('F:\machine_learning\logistic回歸') 4 5 #加載數據集 6 def loadDataSet(): 7 dataMat=[]#用於存放數據集 8 labelMat=[]#用於存放標簽集 9 fr=open('test.txt','r')#打開測試數據集 10 for line in fr.readlines():#逐行讀取 11 lineArr=line.strip().split('\t')#將數據集按照標准格式划分 12 dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])#在dataMat中添加數據集 13 labelMat.append(lineArr[2])#在labelMat中添加標簽數據 14 return dataMat,labelMat 15 16 dataMat,labelMat=loadDataSet() 17 18 from math import exp 19 from math import log 20 #建立sigmoid函數 21 def sigmoid(inX): 22 return 1/(1+exp(-inX))#返回sigmoid函數值 23 from numpy import * 24 #Logistic回歸梯度上升優化算法 25 def stocGradAscent0(dataMatrix,classLabels): 26 dataMatrix=array(dataMatrix) 27 m,n=shape(dataMatrix)#計算數據集的行和列 28 classLabels=array(classLabels).astype('float64') 29 alpha=0.01#閾值設定為0.01 30 weights=ones(n)#初始化權重矩陣 31 for i in range(m): 32 h=sigmoid(sum(dataMatrix[i]*weights))#計算在sigmoid函數作用下的標簽值 33 error=classLabels[i]-h#計算誤差 34 weights=weights+alpha*(error*dataMatrix[i].transpose())#更新權重 35 return weights.tolist() 36 weights=stocGradAscent0(dataMat,labelMat)
1 import matplotlib.pyplot as plt 2 plt.rcParams['font.sans-serif']=['SimHei']#解決中文顯示問題 3 plt.rcParams['axes.unicode_minus']=False#解決中文顯示問題 4 def plotBestFit(weights): 5 dataMat,labelMat=loadDataSet()#加載數據集 6 dataArr=mat(dataMat)#將數據集轉化成矩陣 7 n=shape(dataMat)[0]#求出數據集的行數 8 xcord1=[];ycord1=[]#用於存放標簽是1的數據集 9 xcord2=[];ycord2=[]#用於存放標簽是2的數據集 10 for i in range(n): 11 if int(labelMat[i])==1: 12 xcord1.append(dataArr[i,1])#將標簽是1對應的x1的值存放在xcord1中 13 ycord1.append(dataArr[i,2])#將標簽是2對應的x2的值存放在ycord1中 14 elif int(labelMat[i])==0: 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')#繪制對應數據集是1的點,s代表點的大小,c代表顏色,marker代表線型,默認是原型 20 ax.scatter(xcord2,ycord2,s=30,c='green') 21 x=arange(-3.0,3.0,0.1) 22 y=(-weights[0]-weights[1]*x)/weights[2]#線性方程y=ax+b 23 ax.plot(x,y) 24 plt.xlabel('X1') 25 plt.ylabel('Y1') 26 plt.show() 27 plotBestFit(weights)
得出的最佳擬合直線如圖:

1 #改進的隨機梯度上升法 2 def stocGradAscent1(dataMatrix, classLabels, numIter=150): 3 dataMatrix=array(dataMatrix) 4 m,n = shape((dataMatrix)) 5 weights =ones(n) #initialize to all ones 6 classLabels=array(classLabels).astype('float64') 7 for j in range(numIter): 8 dataIndex = range(m) 9 for i in range(m): 10 alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not 11 randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant 12 h = sigmoid(sum(dataMatrix[randIndex]*weights)) 13 error = classLabels[randIndex] - h 14 weights = weights + alpha *error *(dataMatrix[randIndex].transpose()) 15 # del(dataIndex[randIndex]) 16 return weights.tolist() 17 weights=stocGradAscent1(dataMat,labelMat)
示例:從疝氣病症預測病馬的死亡率
1 ###預測算法,用Logistic回歸進行分類 2 def ClassifyVector(inX,weights): 3 prob=sigmoid(sum(inX*weights))#計算在sigmoid函數作用下的函數值 4 if prob>0.5:return 1 5 else:return 0 6 7 8 #計算錯誤率 9 def colicTest(): 10 frtrain=open('horseColicTraining.txt')#打開訓練數據集 11 frtest=open('horseColicTest.txt')#打開測試數據集 12 trainingSet=[]#用於存放訓練數據集 13 trainingLabels=[]#用於存放標簽數據集 14 for line in frtrain.readlines(): 15 currLine=line.strip().split('\t')#將每行數據以四個空格分割 16 lineArr=[] 17 for i in range(21):#共有20個特征,1個類別數據 18 lineArr.append(float(currLine[i])) 19 trainingSet.append(lineArr) 20 trainingLabels.append(float(currLine[21])) 21 trainWeights=stocGradAscent1(trainingSet,trainingLabels)#求出訓練數據的權重 22 errorCount=0.0;numTestVec=0.0#記初始錯誤數據為0個 23 for line in frtest.readlines(): 24 numTestVec+=1 25 currLine=line.strip().split('\t') 26 lineArr=[] 27 for i in range(21): 28 lineArr.append(float(currLine[i])) 29 if int(ClassifyVector(array(lineArr),trainWeights))!=int(currLine[21]): 30 errorCount+=1 31 errorRate=(float(errorCount))/numTestVec 32 print('錯誤率為:%f'%(errorRate)) 33 return errorRate 34 #errorRate=colicTest() 35 def multiTest1(): 36 errorSum=0;numTests=10 37 for i in range(10): 38 errorSum+=colicTest() 39 print('average rate ratio is:%f'%(errorSum/float(numTests)))
結果如下:
錯誤率為:0.313433
錯誤率為:0.328358
錯誤率為:0.417910
錯誤率為:0.298507
錯誤率為:0.283582
錯誤率為:0.283582
錯誤率為:0.298507
錯誤率為:0.253731
錯誤率為:0.283582
錯誤率為:0.313433
average rate ratio is:0.307463
全部代碼
1 # -*- coding: utf-8 -*- 2 """ 3 Created on Fri May 11 18:51:10 2018 4 5 @author: wangmengzhu 6 """ 7 8 '''logistic回歸''' 9 10 import os 11 os.getcwd() 12 os.chdir('F:\machine_learning\logistic回歸') 13 14 #加載數據集 15 def loadDataSet(): 16 dataMat=[]#用於存放數據集 17 labelMat=[]#用於存放標簽集 18 fr=open('test.txt','r')#打開測試數據集 19 for line in fr.readlines():#逐行讀取 20 lineArr=line.strip().split('\t')#將數據集按照標准格式划分 21 dataMat.append([1.0,float(lineArr[0]),float(lineArr[1])])#在dataMat中添加數據集 22 labelMat.append(lineArr[2])#在labelMat中添加標簽數據 23 return dataMat,labelMat 24 25 dataMat,labelMat=loadDataSet() 26 27 from math import exp 28 from math import log 29 #建立sigmoid函數 30 def sigmoid(inX): 31 return 1/(1+exp(-inX))#返回sigmoid函數值 32 from numpy import * 33 #Logistic回歸梯度上升優化算法 34 def stocGradAscent0(dataMatrix,classLabels): 35 dataMatrix=array(dataMatrix) 36 m,n=shape(dataMatrix)#計算數據集的行和列 37 classLabels=array(classLabels).astype('float64') 38 alpha=0.01#閾值設定為0.01 39 weights=ones(n)#初始化權重矩陣 40 for i in range(m): 41 h=sigmoid(sum(dataMatrix[i]*weights))#計算在sigmoid函數作用下的標簽值 42 error=classLabels[i]-h#計算誤差 43 weights=weights+alpha*(error*dataMatrix[i].transpose())#更新權重 44 return weights.tolist() 45 weights=stocGradAscent0(dataMat,labelMat) 46 47 48 #改進的隨機梯度上升法 49 def stocGradAscent1(dataMatrix, classLabels, numIter=150): 50 dataMatrix=array(dataMatrix) 51 m,n = shape((dataMatrix)) 52 weights =ones(n) #initialize to all ones 53 classLabels=array(classLabels).astype('float64') 54 for j in range(numIter): 55 dataIndex = range(m) 56 for i in range(m): 57 alpha = 4/(1.0+j+i)+0.0001 #apha decreases with iteration, does not 58 randIndex = int(random.uniform(0,len(dataIndex)))#go to 0 because of the constant 59 h = sigmoid(sum(dataMatrix[randIndex]*weights)) 60 error = classLabels[randIndex] - h 61 weights = weights + alpha *error *(dataMatrix[randIndex].transpose()) 62 # del(dataIndex[randIndex]) 63 return weights.tolist() 64 weights=stocGradAscent1(dataMat,labelMat) 65 #畫出數據集和Logistic回歸最佳擬合直線的函數 66 import matplotlib.pyplot as plt 67 plt.rcParams['font.sans-serif']=['SimHei']#解決中文顯示問題 68 plt.rcParams['axes.unicode_minus']=False#解決中文顯示問題 69 def plotBestFit(weights): 70 dataMat,labelMat=loadDataSet()#加載數據集 71 dataArr=mat(dataMat)#將數據集轉化成矩陣 72 n=shape(dataMat)[0]#求出數據集的行數 73 xcord1=[];ycord1=[]#用於存放標簽是1的數據集 74 xcord2=[];ycord2=[]#用於存放標簽是2的數據集 75 for i in range(n): 76 if int(labelMat[i])==1: 77 xcord1.append(dataArr[i,1])#將標簽是1對應的x1的值存放在xcord1中 78 ycord1.append(dataArr[i,2])#將標簽是2對應的x2的值存放在ycord1中 79 elif int(labelMat[i])==0: 80 xcord2.append(dataArr[i,1]) 81 ycord2.append(dataArr[i,2]) 82 fig=plt.figure() 83 ax=fig.add_subplot(111) 84 ax.scatter(xcord1,ycord1,s=30,c='red',marker='s')#繪制對應數據集是1的點,s代表點的大小,c代表顏色,marker代表線型,默認是原型 85 ax.scatter(xcord2,ycord2,s=30,c='green') 86 x=arange(-3.0,3.0,0.1) 87 y=(-weights[0]-weights[1]*x)/weights[2]#線性方程y=ax+b 88 ax.plot(x,y) 89 plt.xlabel('X1') 90 plt.ylabel('Y1') 91 plt.show() 92 plotBestFit(weights) 93 94 95 96 ###預測算法,用Logistic回歸進行分類 97 def ClassifyVector(inX,weights): 98 prob=sigmoid(sum(inX*weights))#計算在sigmoid函數作用下的函數值 99 if prob>0.5:return 1 100 else:return 0 101 102 103 #計算錯誤率 104 def colicTest(): 105 frtrain=open('horseColicTraining.txt')#打開訓練數據集 106 frtest=open('horseColicTest.txt')#打開測試數據集 107 trainingSet=[]#用於存放訓練數據集 108 trainingLabels=[]#用於存放標簽數據集 109 for line in frtrain.readlines(): 110 currLine=line.strip().split('\t')#將每行數據以四個空格分割 111 lineArr=[] 112 for i in range(21):#共有20個特征,1個類別數據 113 lineArr.append(float(currLine[i])) 114 trainingSet.append(lineArr) 115 trainingLabels.append(float(currLine[21])) 116 trainWeights=stocGradAscent1(trainingSet,trainingLabels)#求出訓練數據的權重 117 errorCount=0.0;numTestVec=0.0#記初始錯誤數據為0個 118 for line in frtest.readlines(): 119 numTestVec+=1 120 currLine=line.strip().split('\t') 121 lineArr=[] 122 for i in range(21): 123 lineArr.append(float(currLine[i])) 124 if int(ClassifyVector(array(lineArr),trainWeights))!=int(currLine[21]): 125 errorCount+=1 126 errorRate=(float(errorCount))/numTestVec 127 print('錯誤率為:%f'%(errorRate)) 128 return errorRate 129 #errorRate=colicTest() 130 def multiTest1(): 131 errorSum=0;numTests=10 132 for i in range(10): 133 errorSum+=colicTest() 134 print('average rate ratio is:%f'%(errorSum/float(numTests)))
