深入理解XGBoost(何龙 著)学习笔记(三)
原创 化心为海 微阅读札记
https://mp.weixin.qq.com/s/vBE3fu9AZDjRFd5niJU0lg 2025年05月06日 18:17 北京
第三章 机器学习算法基础
摘要:本章首先介绍了基础的机器学习算法的实现原理和应用;然后对决策树模型做了详细介绍;最后,讲解了排序问题、神经网络和支持向量机。
3.1 KNN
用一句通俗的话来讲,KNN的算法思想就是“近朱者赤,近墨者黑。”即同一类事务通常在很多方面都很接近。
定义:如果一个样本在特征空间中的K个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。(来源:百度百科)
如图1:
1.KNN的计算步骤:
1)计算测试样本与训练集中所有(或大部分)样本的距离,该距离可以是欧氏距离,余弦距离等。常用的是欧式距离。
2)找到步骤1)中距离最短的K个样本,作为预测样本的邻居。
3)对于分类问题,通过投票机制选出K个邻居中,最多的类别作为预测样本的预测值。对于回归问题,则采用K个邻居的平均值。
KNN的优点: 简单有效,易于实现;无须训练(或训练很快)。
KNN的缺点:懒惰算法,数据集的样本容量大时,运算量比较大,评分慢;样本不平均时,预测偏差比较大。
3.1.1.KNN的关键因素:
1.度量距离:不同的距离度量方式会影响KNN的结果。距离类别:欧氏距离,明可夫斯基距离(明氏距离,欧氏距离的一般形式,当p=2时即为欧氏距离),曼哈顿距离,余弦相似度等。
2.K值选择:K值比较小,会取较小邻域内的样本与输入样本比较,降低近似误差,但会增加估计误差。相反,如果K值较大,则会降低估计误差,增加近似误差。
3.决策规则:主要应用于分类问题,目前KNN采取的决策规则多为投票表决,多数票所属的类别作为预测样本的预测类别。
4.归一化:归一化把需要处理的数据通过某种算法限制在一定范围内,一般为0~1。
小贴士:关于估计误差和近似误差:
近似误差:像用一把刻度粗糙的尺子测量长度,误差来自工具本身的不精确。
估计误差:像因手抖导致多次测量结果波动,误差来自操作或数据的随机性。
在科学计算中,通常需要同时控制两者(如选择高精度方法+增加数据量)。
3.1.2 用KNN来预测鸢尾花品种 鸢尾花数据集(iris)是一个经典的多分类数据集,它通过萼片_sepal(长度、宽度)、花瓣_petal(长度、宽度)四个特征数据来预测鸢尾花品种是山鸢尾(Iris-setosa)、变色鸢尾(Iris-versicolor)还是维吉尼亚鸢尾(Iris-virginica)。
数据集的格式如下: 4.9,3.0,1.4,0.2,Iris_setosa 4.7,3.2,1.3,0.2,Iris_setosa ...... ......
数据集中第1~4列分别表示萼片长度、萼片宽度、花瓣长度、花瓣宽度4个特征,第5列表示鸢尾花品种
import pandas as pdiris_data = pd.read_csv('D:/xgboost-master/demo/data/iris.csv', sep=",", names=['sepal_length','sepal_width','petal_length','petal_width','class'])iris_data.head(5)

# 导入matplotlib的pyplot模块,用于数据可视化from matplotlib import pyplot as plt# 柱状图显示组平均数,可以从图中看出不同品种的鸢尾花属性特点# 按"class"列(鸢尾花种类)对数据进行分组# grouped_data是一个DataFrameGroupBy对象,包含分组后的数据grouped_data = iris_data.groupby("class")# 计算每个分组(每种鸢尾花)各特征的平均值# grouped_mean是一个DataFrame,包含每个品种各特征的平均值grouped_mean = grouped_data.mean()# 绘图部分# 使用DataFrame的plot方法绘制柱状图# kind='bar'指定图表类型为柱状图grouped_mean.plot(kind="bar")# 设置图例(右面的小图)位置和样式:# loc='center right' - 将图例的定位点设置在中心右侧# bbox_to_anchor=(1.4,0.3) - 将图例放在图表外的(1.4,0.3)坐标位置# ncol=1 - 图例按1列垂直排列plt.legend(loc='center right',bbox_to_anchor=(1.4, 0.3),ncol= 1)# 显示绘制的图表plt.show()

#我们需要划分训练集和测试集分别用于训练模型,检验模型的预测能力,所以需要划分训练集和测试集。import numpy as np# 生成一个与iris_data长度相同的随机数数组,范围在[0,1)之间# 比较每个随机数是否小于0.8,得到一个布尔型掩码(True/False数组)# 约80%的数据会被标记为True,20%为Falsemsk = np.random.rand(len(iris_data)) < 0.8# 使用掩码进行数据划分:# 选取掩码为True的行作为训练集train_data_origin = iris_data[msk]# 选取掩码为False的行作为测试集test_data_origin = iris_data[~msk]# 重置数据集的索引:# drop=True表示丢弃原来的索引列,不将其作为新列添加到数据中# 训练集重置索引train_data = train_data_origin.reset_index(drop=True)# 测试集重置索引test_data = test_data_origin.reset_index(drop=True)#定义训练集、测试集labeltrain_label = train_data['class']test_label = test_data['class']#定义训练集、测试集的特征train_fea = train_data.drop('class',1)test_fea = test_data.drop('class',1)##查看数据# train_label.head(10)# test_label.head(10)# train_fea.head(10)test_fea.head(10)

观察上述数据,萼片长度(sepal_length)和萼片宽度(sepal_width)特征的取值相比于另外两个特征要大很多,实际上我们认为这4个特征对于距离计算是同等重要的。因此,需要对特征进行归一化,即将特征的取值范围映射到0~1之间。常用的归一化方法是min-max标准化,公式如下:newValue = (oldValue - min)/(max - min),其中oldValue是原始值,newValue是归一化后的值。具体到代码如下:
train_norm = (train_fea - train_fea.min()) / (train_fea.max() - train_fea.min())train_norm.head(10)test_norm = (test_fea - test_fea.min()) / (test_fea.max() - test_fea.min())test_norm.head(10)

在执行KNN算法之前,要通过准确率这个评估指标来评估模型预测的正确率。
准确率:即对于给定的测试数据集,模型预测正确的样本数与总样本数之比。
#自定义准确率函数,供后续调用def getAccuracy(testSet,predictions):correct = 0#遍历每个测试样本,判断是否预测正确并进行统计for x in range(len(testSet)):if testSet[x] == predictions[x]:correct += 1#计算并返回准确率return(correct/float(len(testSet)))* 100.0
# 从scikit-learn库中导入neighbors模块,该模块包含K近邻(KNN)算法from sklearn import neighbors# 创建一个KNN分类器实例:# n_neighbors=3 表示使用最近的3个邻居来进行分类# 其他参数使用默认值(如距离度量使用欧氏距离)knn = neighbors.KNeighborsClassifier(n_neighbors=3)# 训练KNN模型:# train_norm - 经过归一化处理的训练集特征数据# train_label - 训练集对应的标签/类别# fit()方法会根据训练数据构建KNN模型(!!!实际上是存储训练数据)knn.fit(train_norm, train_label)# 使用训练好的KNN模型对测试集进行预测:# test_norm - 经过归一化处理的测试集特征数据# predict()方法会返回测试集中每个样本的预测类别predict = knn.predict(test_norm)# 调用自定义的准确率函数,计算模型在测试集上的准确率:# test_label - 测试集的真实标签# predict - 模型的预测结果accuracy = getAccuracy(test_label, predict)# 打印模型准确率:# repr()函数将准确率数值转换为字符串表示# 输出格式示例:"Accuracy:95.0%"print("Accuracy:" + repr(accuracy) + "%")
Accuracy:95.83333333333334%
小贴士:KNN的预测过程(来源:deepseek)
KNN 的预测步骤:
1)计算距离:计算 new_sample 和 train_norm 中每个样本的 欧氏距离(默认距离度量)。
2)找最近 3 个邻居(n_neighbors=3)。
3)投票决定类别:统计这 3 个邻居的类别,选择最多的类别作为预测结果。
例子: 新样本: [5.7, 2.8, 4.1, 1.3]
训练数据:
-
[5.1, 3.5, 1.4, 0.2] → Setosa (距离较远)
-
[7.0, 3.2, 4.7, 1.4] → Versicolor (距离最近)
-
[6.3, 3.3, 6.0, 2.5] → Virginica (距离较远)
-
[5.8, 2.7, 5.1, 1.9] → Virginica (距离次近)
-
[4.9, 3.0, 1.4, 0.2] → Setosa (距离最远)
最近的 3 个邻居:
-
Versicolor (距离最近)
-
Virginica (次近)
-
Setosa (第三近)
投票结果:
-
Versicolor: 1 票
-
Virginica: 1 票
-
Setosa: 1 票
如果 n_neighbors=3,可能出现平票情况(取决于 scikit-learn 的默认策略,可能选择排序靠前的类别)。
更多推荐

所有评论(0)