直线这种分类方式太简单,如图这种情况,不可能使用一根直线把样本分成两部分,但它可以使用一个圆形来分割。
因此,对于图中这个样本来说,决策边界应该是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:逻辑回归中如果使用了多项式,也可以使用与多项式回归相同的正则表达式来约束过拟合的情况。