前言
- 🍨 本文为🔗365天深度学习训练营 中的学习记录博客
- 🍖 原作者:K同学啊
一、我的环境
- 电脑系统:Windows 11
- 语言环境:Python 3.9.7
- 编辑器:Jupyter Lab
二、基本概念
商业哲学家 Jim Rohn 说过一句话,“你,就是你最常接触的五个人的平均。”那么,在分析一个人时,我们不妨观察和他最亲密的几个人。同理的,在判定一个未知事物时,可以观察离它最近的几个样本,这就是KNN(k-近邻)算法。
- K-近邻算法是一种基本分类和回归方法。
K-近邻算法,即是给定一个训练数据集,输入一个新的实例,在训练数据集中找到与该实例最邻近的K个实例,这K个实例主要是哪一类别,那么就把该实例分类到这个类中。引用维基百科上的一幅图:
蓝色方块与红色三角形为训练集中的实例,绿色小圆是新输入的实例,现在在现有实例中取K个离小绿圆最近实例用于判断其类别。
- 当K=3时,所取实例在实线圆内,红三角占比最大,将新输入实例归为红三角一类。
- 当K=5时,所取实例在虚线圆内,绿方块占比最大,将新输入实例归为绿方块一类。
在KNN中存在两个重要问题,一个是K的取值问题,一个是距离计算问题,这里先不做讨论,仅仅引入KNN这个概念,明白它是一个什么东西,在后面文章中我们再对这两个问题进行深入讨论。下文将通过sklearn包来实现KNN。
三、代码实现
1.问题简介
背景: 海伦一直使用在线约会网站寻找适合自己的约会对象。尽管约会网站会推荐不同的人选,但她没有从中找到喜欢的人。经过一番总结,她发现曾交往过三种类型的人:
● ①不喜欢的人;
● ②魅力一般的人;
● ③极具魅力的人。
她现在总结好的数据中(即训练集)包含三种特征:
● ①每年获得的飞行常客里程数
● ②玩视频游戏所耗时间百分比
● ③每周消费的冰淇淋公升数
她希望根据现有的数据来判断一个陌生男人会被她归到哪一类。
2. 导入数据
数据标签详解:
● 0:每年获得的飞行常客里程数
● 1:玩视频游戏所耗时间百分比
● 2:每周消费的冰淇淋公升数
● 3:人物类别(不喜欢的人、魅力一般的人、极具魅力的人)
import pandas as pd
##sep='\t'指定了数据的分隔符是制表符(Tab),意味着数据是以制表符分隔的
##header=None告诉Pandas这个文件没有列标题行,因此Pandas不会尝试将文件的第一行作为列名
data=pd.read_table('F:\\博士期间\\课程学习\\机器学习\\365训练营\\data\\datingTestSet2.txt',
sep='\t',
header=None)
##默认返回DataFrame的前5行数据
data.head()
##使用iloc方法来选取data DataFrame中的行和列。iloc用于基于行和列的整数位置进行索引
##:表示选择所有的行,即从第一行到最后一行
##:3表示选择前3列,即从第一列到第三列
##将这个子集赋值给变量X,X代表特征矩阵
X = data.iloc[:,:3]
#3表示选择第四列,因为在Python中索引是从0开始的,所以索引3实际上指向的是第四列
y = data.iloc[:,3]
3. 将数据集分成训练集和测试集
##将数据集分成训练集和测试集
#train_test_split函数用于将数据集分割成两部分:一部分用于模型的训练,另一部分用于测试模型的性能。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y,
test_size=0.25,
random_state=3)
4. K-邻近算法模型
##K-邻近算法模型
from sklearn.neighbors import KNeighborsClassifier
#knc将使用KNeighborsClassifier类的默认参数。默认情况下,K值(即邻居的数量)是3,距离度量是欧氏距离
knc = KNeighborsClassifier()
knc.fit(X_train, y_train)
5. 结果预测
##结果预测
#预测的结果被直接赋值给data DataFrame的一个新列,列名为"预测结果"
data["预测结果"] = knc.predict(data.iloc[:,:3])
data.head(10)
6. 模型评分
##模型评分
scoreK = knc.score(X_test,y_test)
print(scoreK)
四、心得体会
-
K邻近算法
K-邻近算法(K-Nearest Neighbors,简称KNN)是一种基本的分类和回归算法,它基于一个非常直观的概念:通过观察一个数据点周围的邻居来预测这个数据点的标签或值。以下是KNN算法的一些关键特点和步骤:
特点:
非参数化:KNN不假设数据的分布,不需要训练阶段,因此它是一种惰性学习算法。
简单性:算法实现简单,易于理解和应用。
灵活性:适用于分类和回归问题。
敏感性:对数据规模、噪声和不相关特征敏感。
计算密集型:在大数据集上可能计算成本较高。
步骤:
确定K值:选择一个正整数K,表示考虑的最近邻居的数量。
距离度量:定义一个距离度量方法,如欧氏距离、曼哈顿距离或闵可夫斯基距离等,来计算数据点之间的距离。
寻找邻居:对于每个待分类或预测的数据点,根据距离度量找到其K个最近的邻居。
决策规则:
分类问题:在K个邻居中,根据多数投票原则(即出现次数最多的类别)来确定待分类点的类别。
回归问题:计算K个邻居的值的平均值或加权平均值,作为待预测点的预测值。
输出结果:根据决策规则得到最终的分类标签或预测值。 -
默认参数调参
在上述代码中,knc将使用KNeighborsClassifier类的默认参数。默认情况下,K值(即邻居的数量)是3,距离度量是欧氏距离。
在使用KNeighborsClassifier时,可以通过在实例化时传递不同的参数来修改默认设置。以下是一些常用的参数及其说明: -
n_neighbors: 指定邻居的数量(K值)。默认是3。增加K值可以减少模型的方差,但可能会增加偏差。
weights: 指定权重函数。可以是’uniform’(每个邻居的权重相同,即默认设置),或者’distance’(权重与距离成反比)。 -
algorithm: 指定查找最近邻居的算法。可以是’auto’(自动选择)、‘ball_tree’、‘kd_tree’、‘brute’。
-
metric: 指定距离度量方式。可以是’minkowski’(默认)、‘euclidean’、‘manhattan’、'chebyshev’等。
-
metric_params: 与metric参数配合使用的额外参数,例如在使用’minkowski’度量时可以指定p值。
-
p: 指定闵可夫斯基距离的幂次。仅当metric='minkowski’时使用。
-
n_jobs: 指定并行执行的作业数量。可以提高计算效率。
-
leaf_size: 指定在树结构中每个节点的叶子数量。影响算法的效率。
-
outlier_label: 指定异常值的标签。如果指定,异常值将被分类到这个标签。
-
method: 指定用于确定标签的方法。可以是’simple’(默认)或’uniform’。
下面是如何修改默认参数的一个例子:
from sklearn.neighbors import KNeighborsClassifier
# 修改K值和权重函数
knc = KNeighborsClassifier(n_neighbors=5, weights='distance')
# 使用不同的距离度量方式
knc = knc.set_params(metric='manhattan')
# 训练模型
knc.fit(X_train, y_train)
调参后的模型评分为