直线这种分类方式太简单,如图这种情况,不可能使用一根直线把样本分成两部分,但它可以使用一个圆形来分割。
因此,对于图中这个样本来说,决策边界应该是x1^2 + x2^2 -r^2 = 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])
plt.show()

使用逻辑回归

log_reg = LogisticRegression()   # 使用9-4中实现的LogisticRegression类
log_reg.fit(X, y)

log_reg.score(X, y)   # score = 0.605
plot_decision_boundary(log_reg, axis=[-4,4,-4,4])   # 使用9-5中的绘制决策边界的函数
plt.scatter(X[y==0,0],X[y==0,1])
plt.scatter(X[y==1,0],X[y==1,1])
plt.show()

逻辑回归 + 多项式

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())   # 遵循sklearn标准构建的类可以无缝结合到管道中
    ])

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])
plt.show()

degree取2时的决策边界:
degree取20时的决策边界:

Note 1:代码中的LogisticRegression是在9-4中自己实现的类。只要是遵循sklearn标准构建的类可以无缝结合到管道中。
Note 2:逻辑回归中如果使用了多项式,也可以使用与多项式回归相同的正则表达式来约束过拟合的情况。