利用OpenCV与Sklearn实现的Logistic Regression
學習機器學習已經有一周了。和許多機器學習的初學者一樣,首先接觸的就是Linear Regression和 Logistic Regression.
二者都是在確定了方法集(Model)之后,利用Gradient Descent 求的相關損失函數的最小值,從而確定權重W以及偏置Bias的過程。但是,二者在Model ,? Loss Functions 以及如何找最佳解答方向上有所區別,具體區別如下:
??????? 首先在Logistic regression中,Model采用Sigmod作為閾值函數,在Python中,實現sigmod函數十分簡單:
#定義sigmod 函數 def sig(x):'''input : x(mat):feature * woutput : sigmod 值即為 P(C1|X)的概率:param x: :return: '''return 1.0/(1+np.exp(-x))利用梯度下降(GD)原理,不斷調整W的值,使得其朝著梯度的方向進行移動:
#Logistic Regression model def Ir_train_bgd(features,labels,maxCycle,alpha):n = np.shape(features)[1] # 特征值的個數,并且將其賦值給nw = np.mat(np.ones((n,1))) # 初始化權重為1,而且數量為 n*1 的矩陣i = 0 # 目前做 GD 的次數為0while i<=maxCycle:i = i+1h = sig (features * w)err = labels-hif i%100==0:print('\t------------------------'+str(i)+\",train error rate= "+ str(error_rate(h,label)))w= w+ alpha* features.T *err #修正權重, learning datareturn w? 至于如何評價損失函數,Linear Regression 與 Logistic Regression區別在于 :? Linear Regression 損失函數 Loss Function 主要依據Square大小,而 Logistic Regression 則是交互熵損失函數來反應預測集和測試集兩個伯努利分布的接近程度。
在了解算法的基本原理后,我們看看利用Python經常使用的機器學習庫Sklearn 以及 OpenCv 的ML 庫來正真實現 Logistic Regression 中的 Binary Classification問題。
#進入ML相關庫文件import cv2 as cv import numpy as np import matplotlib.pyplot as plt from sklearn import model_selection from sklearn import metrics from sklearn import datasets #100表示樣本數 ,2 表示特征數,centers表示類別數目y,cluster_std表示類別方差 X,y=datasets.make_blobs(100,2,centers=2,random_state=1000,cluster_std=2) plt.scatter(X[:,0],X[:,1],s=100,c=y) plt.xlabel("X1") plt.ylabel("X2")首先利用dataset的make_blobs方法,生成隨意數組
為了能夠在OpenCV中使用,我們需要將數據轉化為float32
X=X.astype(np.float32) y=y.astype(np.float32)接著利用model_selection里面的train_test_spilt方法進行訓練集與測試集的分類;其中訓練集與測試集為9:1
X_train,X_test,y_train,y_test=model_selection.train_test_split(\X,y,test_size=0.1,random_state=42)利用Opencv的ml 庫中,建立一個Logistic Regression 的分類器,并且在GD的方式上采用SGD的模式,即每次使用完一個數據點使用完后就要更新一次,設置更新次數為100次,即求100次關于W的偏導數。
Lr1.setTrainMethod(cv.ml.LOGISTIC_REGRESSION_MINI_BATCH) Lr1.setMiniBatchSize(1) Lr1.setIterations(100)完成設置之后,對分類器Lr1進行訓練:
Lr1.train(X_train,cv.ml.ROW_SAMPLE,y_train)這個返回值的是一個布爾值,true/false 代表訓練是否成功
C:\Users\asus\AppData\Local\Programs\Python\Python35-32\python.exe "D:/BaiduYunDownload/python_exe/daily exercise/OpenCV and MachineLearning/CSDN_logistic_regression.py" TrueProcess finished with exit code 0我們可以使用分類型的類方法get_learnt_thetas()獲得最終的權重列表:
[[-0.00883594? 0.2545947?? 0.352442? ]]? 分別代表W0,W1,以及偏置常數b
我們可以將其轉為列表,然后將其作為 多元方程輸出:
weights=Lr1.get_learnt_thetas().tolist()[0] b=weights[-1] Ws= dict.fromkeys(['w0','w1']) for i in range (len(weights)-1):Ws['w{}'.format(str(i))]= weights[i] print("function is : ""y={}*X1+{}*X2+{}".format(Ws['w0'],Ws['w1'],b)) C:\Users\asus\AppData\Local\Programs\Python\Python35-32\python.exe "D:/BaiduYunDownload/python_exe/daily exercise/OpenCV and MachineLearning/CSDN_logistic_regression.py" function is : y=-0.008835938759148121*X1+0.25459471344947815*X2+0.3524419963359833Process finished with exit code 0然后,我們利用訓練好的分類器在測試集上做測試:
ret2,y_pred=Lr1.predict(X_test) score = metrics.accuracy_score(y_pred,y_test) print(score) 1.0Process finished with exit code 0我們可以看到,結果為1.0,? 我們的分類器在測試集上很好。
我們可以嘗試將最后的結果可視化:
def plot_descison_boundary(model,X_Train,y_train):h=0.02 #確定網格間距x_min,x_max=X_Train[:,0].min()-1,X_Train[:,0].max()+1 #確定feature 1的rangey_min,y_max=X_Train[:,1].min()-1,X_Train.max()+1 #確定 feature 2 的rangexx,yy=np.meshgrid(np.arange(x_min,x_max,h), #確定 feature 1與 feature 2 的位置矩陣 np.arange(y_min,y_max,h))X_hyop =np.column_stack((xx.ravel().astype(np.float32),#將連個矩陣進行合并,成為(F1,F2)yy.ravel().astype(np.float32))) 矩陣ret2,zz=model.predict(X_hyop) # predic()返回值為兩個,一個bool,一個predict-label zz = zz.reshape(xx.shape) #制作等高線,需要xx,yy,zz的shape相同plt.contourf(xx,yy,zz,cmap=plt.cm.coolwarm,alpha=0.8) #以冷熱與基調plt.scatter(X_Train[:,0],X_Train[:,1],c=y_train,s=100)plt.show()在函數中調用plot_descison_boundary,作用域在整體的數據集:
plt.title("this is a case of Logistic regression") print(score) plot_descison_boundary(Lr1,X,y)可以看到分割效果不錯。
?
接下來我們用Sklearn來進行實現:
from sklearn import linear_model Lr2= linear_model.LogisticRegression() Lr2.fit(X_train,y_train) y_predict=Lr2.predict(X_test)score= Lr2.score(X_test,y_test) print(score) plot_descison_boundary(Lr2,X,y)注意:Lr2.predict返回值只有一項,即為y_predict 的array ,與OpenCv 的ml 不同,因此需要修改plot_descison_boundary函數
def plot_descison_boundary(model,X_Train,y_train):h=0.02 #確定網格間距x_min,x_max=X_Train[:,0].min()-1,X_Train[:,0].max()+1 #確定feature 1的rangey_min,y_max=X_Train[:,1].min()-1,X_Train.max()+1 #確定 feature 2 的rangexx,yy=np.meshgrid(np.arange(x_min,x_max,h), #確定 feature 1與 feature 2 的位置矩陣np.arange(y_min,y_max,h))X_hyop =np.column_stack((xx.ravel().astype(np.float32),#將連個矩陣進行合并,成為(F1,F2)矩陣yy.ravel().astype(np.float32)))zz = model.predict(X_hyop) # predic()返回值為兩個,一個bool,一個predict-labelzz = zz.reshape(xx.shape) #制作等高線,需要xx,yy,zz的shape相同plt.contourf(xx,yy,zz,cmap=plt.cm.coolwarm,alpha=0.8) #以冷熱與基調plt.scatter(X_Train[:,0],X_Train[:,1],c=y_train,s=100)plt.show()ok,最后結果如下,分隔效果良好:
?
總結
以上是生活随笔為你收集整理的利用OpenCV与Sklearn实现的Logistic Regression的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: uniapp 显示消息提示框 操作
- 下一篇: ISE14.7 Spartan3e 呼吸