今天学习了机器学习的相关基础知识,其中重点学习了KNN算法,KNN简单来说,就是提取与目标最近的K个邻居,其中哪种邻居占数较多,那么目标就属于那个种类。

1. 如果“平票”了怎么办?(例如K 为偶数时)

虽然总结出的是“哪种占多数”,但如果 K=4,结果是 2票 vs 2票(平局)怎么办?
 sklearn 中,默认会依据距离的远近来打破平局(距离近的邻居权重更高),或者直接按数据集的顺序选第一个。所以,在使用KNN算法的时候,大家都建议选奇数,也就是将k的值定义为奇数,图个省心,直接避免平局。

今天在学习过程中也做了实践。实践内容就是用KNN算法来分类大学生宿舍划分问题,将性格相识的学生划分在同一宿舍,最后选择一组数据,观察运行结果是否正确。首先创建一个.txt文件,里面存储我们所需要的数据,如下图1.1所示:

图1.1

然后在代码中导入相关的库和模块,Numpy库负责 np.loadtxt()读取文件,以及data[:,-1]这种高维数组的切片、筛选和布尔索引运算。Matplotlib 库中的pyplot模块,负责plt.figure()来创建画布,和plt.show()来弹出窗口展示图片。将先前txt文件中的数据分为3类,分别用数字1,2,3标注。

再创建3维空间,坐标轴分别为xyz,并且支持旋转视角。最后将标签1定义为圆形,标签2定义为三角形,标签3定义为+。后面的展示结果如图1.2所示:

图1.2

紧接着在程序导入了NumPy库并简称为np,其核心用途在于高效处理二维矩阵和数值型数组数据,同时从sklearn.neighbors模块中导入了KNeighborsClassifier分类器用于构建K近邻分类模型;接着,程序调用np.loadtxt函数直接读取名为datingTestSet2.txt的文本数据文件(该函数默认以空格或制表符作为分隔符,将文件内容加载为一个二维浮点型NumPy数组对象data),随后通过数组的切片操作对数据进行特征与标签的分离——使用data[:, :-1]获取所有行的全部特征列(即剔除最后一列的所有列)作为训练特征矩阵x,使用data[:, -1]获取所有行的最后一列作为训练标签向量y;完成数据划分后,程序实例化一个近邻数n_neighbors设置为8的KNN分类器对象neigh(该值选取偶数意味着在二分类可能出现平票,但程序会按sklearn内置的平局处理机制进行决策),并通过调用fit方法将特征矩阵x与标签向量y传入模型进行训练,由于KNN属于惰性学习算法,该训练过程的实质是将训练数据全部存储在模型内部并未进行任何迭代计算或参数拟合,而是等待后续接收到新样本时实时计算该样本与所有训练样本之间的欧氏距离来选取最近邻;模型训练完毕后,程序首先调用predict方法并传入一个包含三个特征值的列表(注意该列表必须转换为二维结构,以符合sklearn要求输入为二维数组的接口规范)进行单次预测,并将预测出的类别数字直接打印输出;紧接着,程序手动定义了一个包含四个样本特征数据的二维列表predict_data(其中值得特别注意的是最后一个样本的第三维特征值远大于其他特征值的数量级,由于代码中未对输入数据进行任何标准化或归一化预处理,该极大值将严重主导欧氏距离的计算,从而可能使预测结果偏向于受该维度影响较大的邻近点),并在打印提示语“再次多人同时预测”之后,调用predict方法将该二维列表整体传入模型,实现对四个新样本的批量并行预测,最终将预测结果以数组形式一次性打印输出,从而完成了从数据加载、特征标签分离、模型训练到单点预测和批量预测的完整应用流程。如图1.3所示。

图1.3

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐