第1关:kNN算法原理
任务描述
本关任务:通过学习本关知识,完成选择题。
相关知识
为了完成本关任务,你需要掌握:
-
什么是
kNN
算法; -
kNN
算法的优缺点。
什么是K最近邻算法
在许多机器学习相关的书籍当中,最开始被介绍的算法很多都是kNN
算法。这是因为kNN
算法与机器学习中的其他算法相比有着简单易懂的特点。
机器学习让人真正感到困难的部分其实是它的数学部分,很多数学基础不好的同学在学习机器学习时看见满篇的多元求导恐怕都快疯了吧。这确实是一个无可避免的门槛,虽然很多书都会说不用看数学也可以学会机器学习,但这样学来的知识宛若无根之木,是靠不住的,大家在学习知识的时候一定不能只注重怎么实现,也要注意其背后的原理,知其然而知其所以然才是我们的目标。
但kNN
算法则没有这方面的问题,它的原理十分简单,在介绍它的理论时,我们不需要复杂的推导就可以向大家清楚地说明它的由来,确确实实是一个很适合入门的算法。
kNN
算法属于监督学习,监督学习所需要做的是在给定一部分带有特征和标签两部分数据的情况下,根据这一部分的特征和数据建立一个模型,之后当我们输入新的特征时,这个模型可以返回这种特征所应该贴上的标签。
这段话有点绕,但大家如果不理解的话需要多读几遍。
好,现在我们该怎么样从原有的数据中建立一个模型呢?kNN
算法的思想就是,物以类聚人以群分。即相似的人和物会相聚在一起。
如果觉得有点抽象的话,就看一下上面这个图,是不是就一点感觉了呢?
然后我们现在就来描述一下kNN
算法吧:
-
计算待测数据与已有的数据之间的距离;
-
按照距离的递增关系排序;
-
选取距离最小的K个点;
-
取这K个点中的最多的类别作为待测数据的类别。
算法步骤虽然有4
步,但用一句话就能说明白。kNN
算法判定待测数据属于哪个类别的依据就是根据离它最近的k
个点的类别。哪个类别多,它就属于哪个类别。很深刻的体现了“近朱者赤,近墨者黑”的思想。
如图所示,当我们设定K
为3
时,离绿色的待测点最近的3
个点的类别分别为蓝色,红色,红色。由于蓝红的比分是1:2
,所以绿色的待测点属于红色类。
当设定K
为5
时,离绿色的待测点最近的5
个点的类别分别为红色、红色、蓝色、蓝色、蓝色。蓝红的比分是3:2
,所以绿色的待测点属于蓝色类。
kNN
算法的优缺点
任何事物都有优缺点,kNN
算法也不例外。kNN
算法的优点有:
-
理解简单,数学知识基本为
0
; -
既能用于分来,又能用于回归;
-
支持多分类。
kNN
算法可以用于回归,回归的思路是将离待测点最近的k
个点的平均值作为待测点的回归预测结果。
kNN
算法在测试阶段是看离待测点最近的k
个点的类别比分,所以不管训练数据中有多少种类别,都可以通过类别比分来确定待测点类别。
注意:当然会有类别比分打平的情况,这种情况下可以看待测点离哪个类别最近,选最近的类别作为待测点的预测类别。
当然kNN
算法的缺点也很明显,就是当训练集数据量比较大时,预测过程的效率很低。这是因为kNN
算法在预测过程中需要计算待测点与训练集中所有点的距离并排序。可想而知,当数据量比较大的时候,效率会奇低。对于时间敏感的业务不太适合。
闯关要求
根据所学知识完成右侧选择题。
开始你的任务吧,祝你成功!
答案
AD
A
第2关:使用sklearn中的kNN算法进行分类
任务描述
本关任务:编写一个能对数据进行分类的程序。
相关知识
为了完成本关任务,你需要:
-
更进一步了解
kNN
算法; -
了解
sklearn
中KNeighborsClassifier
的参数。
更进一步了解K近邻算法
在上一节的内容中,我们已经介绍了kNN
算法的基础知识,在这一节我们再介绍一下kNN
算法的更多内容。
在kNN
算法中,待分析样本的类别是由离其最近的K
个样本的类别来决定的。所以kNN
算法所考虑到的历史数据信息是很少的,基本只由K
值的选择以及距离函数的选择来决定。当K
值比较大时,所能考虑到的样本数目会更多,但是kNN
算法的初衷,“近朱者赤,近墨者黑”的基本思想就无法得到运用了。而当K
值比较小时,所能考虑到的样本数量就很少,这时kNN
算法在噪音比较多的数据里效果很差。
除了K
值之外,kNN
算法的另一个核心参数是距离函数的选择。虽然在上一个实训的描述中,我们是用图片来举例说明kNN
算法的。但实际上这里所说的距离与我们日常生活中所意识到的距离是不同的。在日常生活中我们所说的距离往往是欧氏距离,也即平面上两点相连后线段的长度。
欧氏距离的定义如下:
p(A,B)=i=0∑(Ai−Bi)2
除此之外,在机器学习中常见的距离定义有以下几种:
-
汉明距离:两个字符串对应位置不一样的个数。汉明距离是以理查德·卫斯里·汉明的名字命名的。在信息论中,两个等长字符串之间的汉明距离是两个字符串对应位置的不同字符的个数。换句话说,它就是将一个字符串变换成另外一个字符串所需要替换的字符个数;
-
马氏距离:表示数据的协方差距离。计算两个样本集相似度的距离;
-
余弦距离:两个向量的夹角作为一种判别距离的度量;
-
曼哈顿距离:两点投影到各轴上的距离总和;
-
切比雪夫距离:两点投影到各轴上距离的最大值;
-
标准化欧氏距离: 欧氏距离里每一项除以标准差。
还有一种距离叫闵可夫斯基距离,如下:
d(A,B)=(i=0∑(Ai−Bi)p)q1
当q
为1
时,即为曼哈顿距离。当q
为2
时,即为欧氏距离。
虽然一下子介绍了很多,但大家肯定还是觉得不明就里,但是不用着急,距离的定义在机器学习中是一个核心概念,在之后的学习中还会经常遇到它。在这里介绍距离的目的一个是为了让大家使用k近邻算法时,如果发现效果不太好时,可以通过使用不同的距离定义来尝试改进算法的性能。
了解sklearn中KNeighborsClassifier的参数
想要使用sklearn
中使用kNN
算法,只需要如下的代码(其中train_feature
、train_label
和test_feature
分别表示训练集数据、训练集标签和测试集数据):
from sklearn.neighbors import KNeighborsClassifier
clf=KNeighborsClassifier() #生成K近邻分类器
clf.fit(train_feature, train_label) #训练分类器
predict_result=clf.predict(test_feature) #进行预测
当我们的kNN
算法需要不同的参数时,上面的代码就不能满足我的需要了。所需要做的改变是在 clf=KNeighborsClassifier()
这一行中。KNeighborsClassifier()
的构造函数其实还是有其他参数的。
比较常用的参数有以下几个:
-
n_neighbors
,即K近邻算法中的K值,为一整数,默认为5
; -
metric
,距离函数。参数可以为字符串(预设好的距离函数)或者是callable
(可调用对象,大家不明白的可以理解为函数即可)。默认值为闵可夫斯基距离; -
p
,当metric
为闵可夫斯基距离公式时,上文中的q
值,默认为2
。
编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End
区域内进行代码补充,具体任务如下:
-
完成
classification
函数。函数需要完成的功能是使用KNeighborsClassifier
对test_feature
进行分类。其中函数的参数如下: -
train_feature
: 训练集数据; -
train_label
: 训练集标签; -
test_feature
: 测试集数据。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。
平台会对你返回的预测结果来计算准确率,你只需完成classification
函数即可。准确率高于0.75
视为过关。
预期输出:你的准确率高于0.75
开始你的任务吧,祝你成功!
from sklearn.neighbors import KNeighborsClassifier
def classification(train_feature, train_label, test_feature):
'''
使用KNeighborsClassifier对test_feature进行分类
:param train_feature: 训练集数据
:param train_label: 训练集标签
:param test_feature: 测试集数据
:return: 测试集预测结果
'''
#********* Begin *********#
clf = KNeighborsClassifier()
clf.fit(train_feature,train_label)
predict_result = clf.predict(test_feature)
return predict_result
#********* End *********#
第3关:使用sklearn中的kNN算法进行回归
任务描述
本关任务:编写一个能对数据进行回归的程序。
相关知识
为了完成本关任务,你需要掌握在sklearn
中使用KNeighborsRegressor
。
在sklearn中使用KNeighborsRegressor
在使用kNN
算法进行分类器时,我们是这样子使用sklearn
库的:
from sklearn.neighbors import KNeighborsClassifier
clf=KNeighborsClassifier() #生成K近邻分类器
clf.fit(train_feature, train_label) #训练分类器
predict_result=clf.predict(test_feature) #进行预测
而对应的,当我们需要使用kNN
算法进行回归器时,只需要把KNeighborsClassifier
换成KNeighborsRegressor
即可。代码如下:
from sklearn.neighbors import KNeighborsRegressor
clf=KNeighborsRegressor() #生成K近邻分类器
clf.fit(train_feature, train_label) #训练分类器
predict_result=clf.predict(test_feature) #进行预测
KNeighborsRegressor
和KNeighborsClassifier
的参数是完全一样的,所以在优化模型时可以参考上一关的内容。
编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End
区域内进行代码补充,具体任务如下:
-
完成
regression
函数。函数需要完成的功能是使用KNeighborsRegressor
对test_feature
进行分类。其中函数的参数如下: -
train_feature
: 训练集数据; -
train_label
: 训练集标签; -
test_feature
: 测试集数据。
测试说明
平台会对你返回的预测结果来计算准确率,你只需完成regression
函数即可。r2 score
高于0.75
视为过关。
预期输出:你的r2 score
高于0.75
。
开始你的任务吧,祝你成功!
from sklearn.neighbors import KNeighborsRegressor
def regression(train_feature, train_label, test_feature):
'''
使用KNeighborsRegressor对test_feature进行分类
:param train_feature: 训练集数据
:param train_label: 训练集标签
:param test_feature: 测试集数据
:return: 测试集预测结果
'''
#********* Begin *********#
clf = KNeighborsRegressor()
clf.fit(train_feature,train_label)
predict_result = clf.predict(test_feature)
return predict_result
#********* End *********#
第4关:分析红酒数据
任务描述
本关任务:编写Python
代码,实现平均酒精含量的功能。
相关知识
为了完成本关任务,你需要掌握简单的数据分析。
红酒数据分析
sklearn
中已经内置的红酒数据,获取红酒数据的代码如下:
from sklearn.datasets import load_wine
wine_dataset = load_wine()
# 打印红酒数据集中的特征的名称
print(wine_dataset['feature_names'])
打印结果如下:
['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
从打印结果可以看出,该数据集中包含了红酒的酒精含量、苹果酸含量、颜色饱和度等信息。
同样我们可以看下红酒的标签名称,代码如下:
from sklearn.datasets import load_wine
wine_dataset = load_wine()
# 打印红酒数据集中的标签的名称
print(wine_dataset['target_names'])
打印结果如下:
['class_0' 'class_1' 'class_2']
可以看出该数据集中红酒的种类总共为3
类。也就是说如果用机器学习算法来对其进行分类的话,属于多分类问题。而我们所学习的kNN
算法正好可以解决多分类问题。
编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End
区域内进行代码补充,完成alcohol_mean
函数。该函数需要完成返回红酒数据中的平均酒精含量。其中函数的参数解释如下:
data
:红酒数据对象。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。
预期输出:平均酒精含量计算正确。
开始你的任务吧,祝你成功
import numpy as np
def alcohol_mean(data):
'''
返回红酒数据中红酒的酒精平均含量
:param data: 红酒数据对象
:return: 酒精平均含量,类型为float
'''
#********* Begin *********#
# 提取红酒数据中的酒精含量特征
alcohol_feature = data['data'][:, 0]
# 计算酒精含量的平均值
mean_alcohol = np.mean(alcohol_feature)
return mean_alcohol
#********* End **********#
第5关:对数据进行标准化
任务描述
本关任务:编写Python
代码,实现标准化数据的功能。
相关知识
为了完成本关任务,你需要掌握标准化的相关知识。
标准化相关知识
我们可以计算以下红酒数据中每个特征所对应的均值和标准差,代码如下:
from sklearn.datasets import load_wine
wine_dataset = load_wine()
print(wine_dataset.data.mean(0))
print(wine_dataset.data.std(0))
打印结果如下:
[1.30006180e+01 2.33634831e+00 2.36651685e+00 1.94949438e+01 9.97415730e+01 2.29511236e+00 2.02926966e+00 3.61853933e-01 1.59089888e+00 5.05808988e+00 9.57449438e-01 2.61168539e+00 7.46893258e+02]
[8.09542915e-01 1.11400363e+00 2.73572294e-01 3.33016976e+00 1.42423077e+01 6.24090564e-01 9.96048950e-01 1.24103260e-01 5.70748849e-01 2.31176466e+00 2.27928607e-01 7.07993265e-01 3.14021657e+02]
从打印结果可以看出,有的特征的均值和标准差都比较大,例如如最后一个特征。如果现在用kNN
算法来对这样的数据进行分类的话,kNN
算法会认为最后一个特征比较重要。 因为假设有两个样本的最后一个特征值分别为1
和100
,那么这两个样本之间的距离可能就被这最后一个特征决定了。这样就很有可能会影响kNN
算法的准确度。为了解决这种问题,我们可以对数据进行标准化。
标准化的手段有很多,而最为常用的就是StandardScaler
。
StandardScaler
通过删除平均值和缩放到单位方差来标准化特征,并将标准化的结果的均值变成0
,标准差为1
。
假设标准化后的特征为z,标准化之前的特征为x,特征的均值为μ,方差为s。则StandardScaler
可以表示为z=(x−μ)/s。
sklearn
中已经提供了StandardScaler
的接口,使用代码如下:
from sklearn.preprocessing import StandardScaler
data = [[0, 0], [0, 0], [1, 1], [1, 1]]
# 实例化StandardScaler对象
scaler = StandardScaler()
# 用data的均值和标准差来进行标准化,并将结果保存到after_scaler
after_scaler = scaler.fit_transform(data)
# 用刚刚的StandardScaler对象来进行归一化
after_scaler2 = scaler.transform([[2, 2]])
print(after_scaler)
print(after_scaler2)
打印结果如下:
[[-1. -1.]
[-1. -1.]
[ 1. 1.]
[ 1. 1.]]
[[3. 3.]]
根据打印结果可以看出,经过准换后,数据已经缩放成了均值为0
,标准差为1
的分布。
编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End
区域内进行代码补充,完成scaler
函数。该函数需要完成是返回标准化后的数据。其中函数的参数解释如下:
data
:红酒数据对象。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即为通过。
预期输出:标准化成功
开始你的任务吧,祝你成功!
from sklearn.preprocessing import StandardScaler
def scaler(data):
'''
返回标准化后的红酒数据
:param data: 红酒数据对象
:return: 标准化后的红酒数据,类型为ndarray
'''
#********* Begin *********#
# 获取红酒数据的特征部分
features = data['data']
# 实例化StandardScaler对象
scaler = StandardScaler()
# 用数据的均值和标准差进行标准化
standardized_data = scaler.fit_transform(features)
return standardized_data
#********* End **********#
第6关:使用kNN算法进行预测
任务描述
本关任务:编写Python
代码,实现红酒分类功能。
相关知识
略
编程要求
请仔细阅读右侧代码,根据方法内的提示,在Begin - End
区域内进行代码补充,完成classification
函数。该函数需要完成是对测试数据进行红酒分类,并将分类结果返回。其中函数的参数解释如下:
-
train_feature
:训练集数据,类型为ndarray
; -
train_label
:训练集标签,类型为ndarray
; -
test_feature
:测试集数据,类型为ndarray
。
测试说明
补充完代码后,点击测评,平台会对你编写的代码进行测试,当你的结果与预期输出一致时,即分类准确率高于0.92
视为过关。
预期输出:你的分类准确率高于0.92
。
开始你的任务吧,祝你成功!
from sklearn.neighbors import KNeighborsClassifier
from sklearn.preprocessing import StandardScaler
def classification(train_feature, train_label, test_feature):
'''
对test_feature进行红酒分类
:param train_feature: 训练集数据,类型为ndarray
:param train_label: 训练集标签,类型为ndarray
:param test_feature: 测试集数据,类型为ndarray
:return: 测试集数据的分类结果
'''
#********* Begin *********#
# 实例化StandardScaler对象,用于标准化数据
scaler = StandardScaler()
# 对训练集和测试集数据进行标准化
train_feature_standardized = scaler.fit_transform(train_feature)
test_feature_standardized = scaler.transform(test_feature)
knn_classifier = KNeighborsClassifier()
# 使用训练集数据进行模型训练
knn_classifier.fit(train_feature_standardized, train_label)
# 对测试集数据进行分类
predictions = knn_classifier.predict(test_feature_standardized)
return predictions
#********* End **********#
觉得有用就点个赞,让创作更有动力哦😉🥱