将数据绘制散点图
导入包
设置中文显示
将中优差等生和未知学生的成绩以 ndarray 数组的形式储存
分别对四种学生进行散点图绘图,设置不同的颜色图例
算法原理
KNN(K-Nearest Neighbor),即近邻算法。近邻就是个最近的邻居,当需要预测一个未知样本的时候,就由与该样本最接近的个邻居来决定。KNN 既可以用于分类问题,也可以用于回归问题。
- 当进行分类预测时,使用个邻居中,类别数量最多(或加权最多)者,作为预测结果。
- 当进行回归预测时,使用个邻居的均值(或加权均值),作为预测结果。
KNN 算法的原理在于,样本映射到多维空间时,相似度较高的样本,其距离也会比较接近,反之,相似度较低的样本,其距离也会比较疏远。我们可以将该算法理解为“近朱者赤,近墨者黑”。
算法超参数
K 值
K 值表示使用周围最近的 K 个邻居来预测当前样本,K 的取值会对模型造成如下的影响
- 当 K 值较小时,模型会依赖于附近的邻居样本,具有较好的敏感性,但是稳定性会较弱,容易受到异常值的影响,容易过拟合。
- 当 K 值较大时,稳定性增加,但是敏感性会减弱,容易导致欠拟合。
通常情况下,我们可以通过交叉验证的方式,选择最合适的 K 值。
距离度量方式
默认闵可夫斯基距离
当 P 为 1 时,距离就是曼哈顿距离,当 p 等于 2 时,距离就是欧几里得距离(欧式距离),p 为无穷大是切比雪夫距离
切比雪夫距离:两个点坐标数值差的绝对值的最大值,max(|x1-y1|,|x2-y2|)。
权重计算方式
权重分为两种:
- 统一权重:所有样本的权重相同
- 距离加权权重:样本的权重与待测样本的距离成反比,设置为倒数,表示距离越近的影响越大。权重之和为 1,要进行归一化操作。
算法步骤
-
确定算法超参数:
近邻的数量 K、距离度量方式、权重计算方式,其他超参数
-
从训练集中选择离待测样本 A 最近的 K 个样本
-
根据这 K 个样本预测 A
对于分类,使用 K 个样本的类别(或加权类别)预测 A,谁的权重高预测为谁
对于回归,使用 K 个样本目标值(y)的均值(或加权均值)预测 A
对于传统的 KNN,在 knn.if()中实际上什么都没有做,只是接收数据而已,核心内容都是在 predict 过程中做的。但是在现在用的 sklearn 中,训练时还会进行 kd 树的建立
使用 KNN 实现分类
建模预测
n_neighbors:邻居的数量
weights:权重计算方式,可选值为 uniform(统一权重)和 distance(加权权重)
距离度量方式默认 p=2
from sklearn.neighbors import KNeighborsClassifier
knn=KNeighborsClassifier(n_neighbors=3,weights='uniform')
knn.fit(X_train,y_train)
超参数调整
product 计算 weights 与 ks 笛卡尔集组合,这样就可以使用单层循环取代嵌套循环,增加代码的可读性与可理解性
from itertools import product
product(weights,ks)
绘制决策边界
DecisionBoundaryDisplay 类的参数
from sklearn.inspection import DecisionBoundaryDisplay
estimator:评估器,即模型,指决策边界显示哪个模型的预测结果。
X:数据集,必须为 m 行 2 列的数据。用来确定决策边界的范围。
response_method:模型的预测结果是由什么方式产生的。
alpha:透明度,取值范围为 0-1,0 为完全透明,1 为不透明。
ax:指定绘图的 axes 对象。即在哪个 axes 对象上绘制。
grid_resolution:用于绘制决策边界的网格点数。如果分解曲线不够平滑,可增大该值。
# 超参数对模型的影响
# 颜色映射的类,在可视化时,可以显示不同的颜色主题风格
from matplotlib.colors import ListedColormap
# 绘制决策边界的类
from sklearn.inspection import DecisionBoundaryDisplay
# 定义绘制决策边界和样本散点图的类
def plot_decision_boundary(model,X,y):
# 定义y不同类别的颜色与符号,此时有3个分类,因此分别有3个颜色和符号
color=['r','g','b']
marker=['o','v','x']
# 获取数据中不重复的标签,即y中不一样的值
class_label=np.unique(y)
# 定义颜色映射,在绘制(填充)等高线时使用,不同的值使用不同的颜色来填充
# 切片表示获取的颜色个数与y中的标签数相等
cmap=ListedColormap(color[:len(class_label)])
# 创建DecisionBoundaryDisplay类的对象,用于显示决策边界。
DecisionBoundaryDisplay.from_estimator(model,X,response_method='predict',alpha=0.5,cmap=cmap,grid_resolution=100,ax=plt.gca())
# 绘制样本数据X
for i,class_ in enumerate(class_label):
plt.scatter(x=X[y==class_,0],y=X[y==class_,1],c=cmap.colors[i],label=class_,marker=marker[i],s=15)
plt.legend()
from itertools import product
# 不同超参数下绘制决策边界
weights=['uniform','distance']
ks=[2,15]
plt.figure(figsize=(12,10))
# 计算weights与ks笛卡尔集组合,这样就可以使用单层循环取代嵌套循环,增加代码的可读性与可理解性
for i,(w,k) in enumerate(product(weights,ks),start=1):
plt.subplot(2,2,i)
plt.title(f'K值:{k}权重:{w}')
knn=KNeighborsClassifier(n_neighbors=k,weights=w)
# 这里只看决策边界,不考虑模型预测效果,因此使用所有数据训练
knn.fit(X,y)
plot_decision_boundary(knn,X,y)
欢迎来到这里!
我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。
注册 关于