以下函数选自Sebastian Raschka的Python机器学习第二版,因为看到这的时候,发现有好多陌生的函数(本人没学过matplotlib和numpy),所以打算写一篇文章将我遇到的问题记录下来。
from matplotlib.colors import ListedColormap
import matplotlib.pyplot as plt
import numpy as np
def plot_decision_regions(X,y,classifier, test_idx=None, resolution=0.02):
'''
这个函数需要传入的参数:X:一个n*m矩阵,y:一个n维列向量,classifier:一个学习器对象
test_idx:测试集元素的编号,resolution:用于设置meshgrid网格的大小
'''
#设置标记符号和色域图
markers = ('s','x','o','^','v')
colors = ('red','blue','lightgreen','gray','cyan')
cmap = ListedColormap(colors[:len(np.unique(y))]) # y中有几个不同的元素,这个colormap就有几个颜色
这里用到了一个unique函数,作用是去除y中重复的元素,举个例子:
y = [1,2,2,3,4,4,4]
np.unique(y) = [1,2,3,4]
x1_min,x1_max = X[:,0].min()-1,X[:,0].max()+1# 设置x1范围
x2_min,x2_max = X[:,1].min()-1,X[:,1].max()+1# 设置x2范围
# 画出网格,同时将网格所有结点的x1坐标返回给xx1,x2坐标返回给xx2
xx1,xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),np.arange(x2_min,x2_max,resolution))
# 注:这里得到的xx1和xx2是两个矩阵
上面meshgrid的作用就是生成一个二维网格,这是绘制一个二维图像的基础,resolution设置了整个网格中每个小网格的宽度,resolution越小,图像越精细。
这里,向meshgrid()中传入了两个数组,分别表示网格的横坐标和纵坐标刻度
# 画出决策边界并上色
# 这里是对每个网格结点进行预测,将不同预测结果设置成不同颜色,就可以间接显示出决策边界了
Z = classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T) # ravel():将矩阵抻直成行向量
Z = Z.reshape(xx1.shape)
plt.figure(figsize=(20,12)) # 设置图片比例尺寸
plt.contourf(xx1,xx2,Z,alpha=0.3,cmap=cmap)
plt.xlim(xx1.min(),xx1.max())
plt.ylim(xx2.min(),xx2.max())
ravel():将矩阵拉直成行向量
contourf():这里是以Z为高,在二维平面上画出等高线并填充上颜色
xlim(),ylim():用于设置坐标轴的最小和最大刻度
# 画出样本点
for idx,cl in enumerate(np.unique(y)):#将y的所有可能取值对应到0,1,2,3...
plt.scatter(x=X[y==cl,0],y=X[y==cl,1],alpha=0.8,c=colors[idx],marker=markers[idx],
label=cl,edgecolor='black')
#高亮测试集的点
if test_idx:
X_test, y_test = X[test_idx, :], y[test_idx]
plt.scatter(X_test[:, 0], X_test[:, 1], c='', edgecolor='black', alpha=1.0,
linewidths=1, marker='o', s=100, label='test set')
enumerate():给y中的每个值设置一个索引(从0开始)
假如y=[-1, 0, 1],那么y中的-1的索引就是0,0的索引是1,1的索引是2,这个函数最后会返回一个enumerate对象,可以用for循环遍历