基於sciket-learn實現邏輯迴歸
阿新 • • 發佈:2018-11-22
邏輯迴歸雖然名稱裡有迴歸兩個字,但是邏輯迴歸主要用來解決分類問題,並且只能解決二分類問題。(當然邏輯迴歸也可以解決迴歸問題;同時邏輯迴歸可以通過OvO、OvR等方法實現多分類,但本質還是二分類。)
邏輯迴歸與線性迴歸不同的是,線性迴歸得出的是一個具體的預測值,預測房價的模型得出的就是房價,預測成績的模型得出的就是成績,而邏輯迴歸得出的是概率,通過概率大於小於來進行分類。下面是邏輯迴歸的公式:
接下來通過程式碼,來具體看看邏輯迴歸是怎麼一回事。
先匯入基本類庫,生成模擬資料集,並且增加噪聲
import numpy as np import matplotlib.pyplot as plt np.random.seed(666) X = np.random.normal(0, 1, size=(200, 2)) y = np.array((X[:,0]**2+X[:,1])<1.5, dtype='int') for _ in range(20): y[np.random.randint(200)] = 1
視覺化資料
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
plt.show()
劃分測試集和預測集
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)
生成sciket-learn為我們封裝好的邏輯迴歸構造器進行fit操作
from sklearn.linear_model import LogisticRegression log_reg = LogisticRegression() log_reg.fit(X_train, y_train)
檢視分類結果
log_reg.score(X_train, y_train)
log_reg.score(X_test, y_test)
視覺化(這個視覺化函式不是重點,知道意思即可)
def plot_decision_boundary(model, axis): x0, x1 = np.meshgrid( np.linspace(axis[0], axis[1], int((axis[1]-axis[0])*100)).reshape(-1, 1), np.linspace(axis[2], axis[3], int((axis[3]-axis[2])*100)).reshape(-1, 1), ) X_new = np.c_[x0.ravel(), x1.ravel()] y_predict = model.predict(X_new) zz = y_predict.reshape(x0.shape) from matplotlib.colors import ListedColormap custom_cmap = ListedColormap(['#EF9A9A','#FFF59D','#90CAF9']) plt.contourf(x0, x1, zz, linewidth=5, cmap=custom_cmap)
plot_decision_boundary(log_reg, axis=[-4, 4, -4, 4])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
plt.show()
可以看出擬合結果非常不好,因為用直線去擬合一個二次曲線,結果必然是欠擬合的,所以增加一個特徵值,還是先使用管道的方式
from sklearn.preprocessing import PolynomialFeatures
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
def PolynomialLogisticRegression(degree):
return Pipeline([
('poly', PolynomialFeatures(degree=degree)),
('std_scaler', StandardScaler()),
('log_reg', LogisticRegression())
])
在這裡給degree傳入2進行訓練
poly_log_reg = PolynomialLogisticRegression(degree=2)
poly_log_reg.fit(X_train, y_train)
檢視結果並可視化
poly_log_reg.score(X_train, y_train)
poly_log_reg.score(X_test, y_test)
plot_decision_boundary(poly_log_reg, axis=[-4, 4, -4, 4])
plt.scatter(X[y==0,0], X[y==0,1])
plt.scatter(X[y==1,0], X[y==1,1])
plt.show()
可以看出現在擬合的已經很不錯了
在使用sciket-learn封裝好的類庫,degree傳入較大的值,檢視分類結果。
poly_log_reg2 = PolynomialLogisticRegression(degree=50)
poly_log_reg2.fit(X_train, y_train)
poly_log_reg2.score(X_train, y_train)
poly_log_reg2.score(X_test, y_test)
因為在生成預測資料集的時候,便已經知道了是條二次曲線,所以degree=2時的擬合結果及泛化能力都是最好的,但是實際業務中,往往需要綜合很多因素才能得出最佳的degree去值。