在邏輯回歸中使用多項式特征以及在sklearn中使用邏輯回歸並添加多項式
在邏輯回歸中使用多項式特征
在上面提到的直線划分中,很明顯有個問題,當樣本並沒有很好地遵循直線划分(非線性分布)的時候,其預測的結果是不太准的,所以可以引用多項式項,從線性回歸轉換成多項式回歸,同理,為邏輯回歸添加多項式項,基於這基礎,就可以對邏輯回歸進行一個比較好的分類,可以使用將degree設置成各種大小來構建任意大小的決策邊界
具體實現
(在notebook中)
熟悉的加載包環節,然后設置一個隨機數,種子為666,生成X和y,x為兩百個樣本,每個樣本為兩個特征,是第一個特征的平方和第二個特征的平方相加小於1.5,小於1.5為1,大於為0,然后繪制圖像
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]**2 < 1.5,dtype='int')
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
圖像如下

使用邏輯回歸,使用封裝好的方法,進行實例化,然后fit操作
from LogisticRegression import LogisticRegression
log_reg = LogisticRegression()
log_reg.fit(X,y)
可以得到准確度
log_reg.score(X,y)
結果如下

圖像繪制函數:
from matplotlib.colors import ListedColormap
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)
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])
圖像如下

添加多項式項,詳細參照這里的思想
簡要概述:做一個為邏輯回歸添加多項式項的管道
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
def PolynomialLogisticRegression(degree):
return Pipeline([
('poly',PolynomialFeatures(degree=degree)),
('std_scaler',StandardScaler()),
('log_reg',LogisticRegression())
])
進行實例化,最后fit操作
poly_log_reg = PolynomialLogisticRegression(degree=2)
poly_log_reg.fit(X,y)
結果如下

其准確率為

繪制圖像:
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])
圖像如下

設置degree為20,再試驗一下
poly_log_reg2 = PolynomialLogisticRegression(degree=20)
poly_log_reg2.fit(X,y)
結果如下

繪制圖像:
plot_decision_boundary(poly_log_reg2,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])
圖像如下

出現這種決策邊界很奇怪的情況,估計就是degree太大了,導致了形狀不太規則,顯然發生了過擬合的形象,模型越復雜越容易產生過擬合的情況,此時就要解決過擬合的情況,使用模型正則化就可以很好的解決
在邏輯回歸中使用正則化同時使用sklearn中的邏輯回歸
為邏輯回歸添加正則項
關於正則項,可以
點擊這里
這里可以使用新的計算方式

這種方式的好處是,如果c越大,在優化損失函數的時候就可以更好更快的將前項減到最小,這種就是在sklearn中的使用的方式
具體實現
(在notebook中)
與上面不同的是,生成的測試用例不同,對第一個特征平方,第二個特征為正常,同樣的使相加的和小於1.5,添加一些噪音,挑二十個點,將其強制變為分類結果為1
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])
圖像如下

使用sklearn來進行邏輯回歸
首先還是分割數據集,要想使用sklearn中的邏輯回歸,調用LogisticRegression即可,實例化以后在進行fit,傳入訓練集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,random_state=666)
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)
結果如下

繪制函數:
from matplotlib.colors import ListedColormap
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)
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])
圖像如下

和上面一樣,使用管道來組合一個多項式邏輯回歸方法
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import PolynomialFeatures
from sklearn.preprocessing import StandardScaler
def PolynomialLogisticRegression(degree):
return Pipeline([
('poly',PolynomialFeatures(degree=degree)),
('std_scaler',StandardScaler()),
('log_reg',LogisticRegression())
])
然后進行實例化,設置degree為2,並進行fit操作
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])
圖像如下

設置degree為20
poly_log_reg2 = PolynomialLogisticRegression(degree=20)
poly_log_reg2.fit(X_train,y_train)
訓練數據集准確度結果如下

測試數據集准確度結果如下(此時可以看出來一些過擬合的現象)

繪制出決策邊界
plot_decision_boundary(poly_log_reg2,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])
圖像如下

設置一個新的管道,傳入一個新的C的參數,然后調用操作,設置c為0.1,degree為20
def PolynomialLogisticRegression(degree,C):
return Pipeline([
('poly',PolynomialFeatures(degree=degree)),
('std_scaler',StandardScaler()),
('log_reg',LogisticRegression(C=C))
])
poly_log_reg3 = PolynomialLogisticRegression(degree=20,C=0.1)
poly_log_reg3.fit(X_train,y_train)
訓練數據集准確度結果如下

測試數據集准確度結果如下

繪制決策邊界
plot_decision_boundary(poly_log_reg3,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])
圖像如下

多設置一個參數penalty,設置以后進行操作
def PolynomialLogisticRegression(degree,C,penalty='l1'):
return Pipeline([
('poly',PolynomialFeatures(degree=degree)),
('std_scaler',StandardScaler()),
('log_reg',LogisticRegression(C=C,penalty=penalty))
])
poly_log_reg4 = PolynomialLogisticRegression(degree=20,C=0.1,penalty='l1')
poly_log_reg4.fit(X_train,y_train)
此時報錯
這里表示Solver僅能使用L2正則項,意思是只能使用L2正則項?(疑惑)
那怎么使用L1正則項來添加呢?
乂,我也不清楚…
等大佬解答

