点一下关注吧!!!非常感谢!!持续更新!!!
目前已经更新到了:
- Hadoop(已更完)
- HDFS(已更完)
- MapReduce(已更完)
- Hive(已更完)
- Flume(已更完)
- Sqoop(已更完)
- Zookeeper(已更完)
- HBase(已更完)
- Redis (已更完)
- Kafka(已更完)
- Spark(已更完)
- Flink(已更完)
- ClickHouse(已更完)
- Kudu(已更完)
- Druid(已更完)
- Kylin(已更完)
- Elasticsearch(已更完)
- DataX(已更完)
- Tez(已更完)
- 数据挖掘(正在更新…)
章节内容
上节我们完成了如下的内容:
- 机器学习理论 基础内容
- 有监督、无监督、半监督、强化学习
监督学习算法
KNN/K近邻算法
它的本质是通过距离判断两个样本是否相似,如果距离够近就认为他们足够相似属于同一个类别。
当然只对比一个样本是不够的,误差会很大,他们就需要找到离其最近的 K 个样本,并将这些样本称为【近邻】nearest neighbor,对这 K 个近邻,查看它们都属于任何类别(这些类别称为称为【标签】labels)。
实现过程
假设 X_test 待标记的数据样本,X_train 为已标记的数据集。
- 遍历已标记数据集中的所有样本,计算每个样本与待标记的点的距离,并把距离保存在 Distance 数组中。
- 对 Distance 数组进行排序,取距离最近的 K 个点,记为X_knn。
- 在 X_knn 中统计每个类别的个数,即 class0 在 X_knn 中有几个样本,class1 在 X_knn中有几个样本
- 待标记样本的类别,就是在 K_knn 中样本个数最多的那类别。
距离的确定
该算法的【距离】在二维坐标轴就表示两点之间的距离,计算距离的公式有很多。我们常说的欧拉公式,即“欧氏距离”,回忆一下,一个平面直角坐标系上,如何计算两点之间的距离?一个立体直角坐标系上,又如何计算两点之间的距离?
当特征数量有很多个形式多维空间时,再用上述的写法就不方便了,我们换一个写法,用 X 加下角标的方式表示特征维度,则在 N 维空间中,有两个点 A 和B,它们坐标分别为:
而在机器学习中,坐标轴上的 x1、x2、x3等,正是我们样本上的N 个特征。
算法优点
算法参数是k,k 可以理解为标记数据周围几个数作为参考对象,参数选择需要根据数据来决定。
- k 值越大,模型的偏差越大,对噪声数据不敏感。
- k 值很大时,可能造成模型的欠拟合。
- k 值越小,模型的方差就会很大。
- 但是 k 值太小,容易过拟合。
算法变种
变种 1
默认情况下,在计算距离时,权重都是相同的,但实际上可以针对不同的领居指定不同的距离权重,比如距离越近权重越高。
可以通过指定算法的 weights 参数来实现。
变种2
使用一定半径内的点取代距离最近的 k 个点
- 在 scikit-learn 中,RadiusNeighborsClassifier 实现了这种算法的变种
- 当数据采样不均匀时,该算法变种可以获得更好的性能
代码实现
导入相关包
# 全部行都能输出from IPython.core.interactiveshell import InteractiveShell
InteractiveShell.ast_node_interactivity ="all"import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
# 解决坐标轴刻度负号乱码
plt.rcParams['axes.unicode_minus']=False# 解决中文乱码问题
plt.rcParams['font.sans-serif']=['Simhei']
plt.style.use('ggplot')# plt.figure(figsize=(2,3),dpi=720)
执行结果如下:
构建已经分类好的原始数据集
首先随机设置十个样本表示十杯酒,这里去了部分样本点。
为了方便验证,使用 Python 的字典 dict 构建数据集,然后再将其转换为DataFrame 格式。
rowdata ={'颜色深度':[14.13,13.2,13.16,14.27,13.24,12.07,12.43,11.79,12.37,12.04],'酒精浓度':[5.64,4.28,5.68,4.80,4.22,2.76,3.94,3.1,2.12,2.6],'品种':[0,0,0,0,0,1,1,1,1,1]}# 0 代表 “黑皮诺”,1 代表 “赤霞珠”
wine_data = pd.DataFrame(rowdata)
执行结果如下图所示:
编写代码进行处理:
X = np.array(wine_data.iloc[:,0:2])#我们把特征(酒的属性)放在X
y = np.array(wine_data.iloc[:,-1])#把标签(酒的类别)放在Y#探索数据,假如我们给出新数据[12.03,4.1] ,你能猜出这杯红酒是什么类别么?
new_data = np.array([12.03,4.1])
plt.scatter(X[y==1,0], X[y==1,1], color='red', label='赤霞珠')#画出标签y为1
的、关于“赤霞珠”的散点
plt.scatter(X[y==0,0], X[y==0,1], color='purple', label='黑皮诺')#画出标签y为0
的、关于“黑皮诺”的散点
plt.scatter(new_data[0],new_data[1], color='yellow')# 新数据点
new_data
plt.xlabel('酒精浓度')
plt.ylabel('颜色深度')
plt.legend(loc='lower right')
plt.savefig('葡萄酒样本.png')
执行结果如下如下所示:
计算已知类别数据集中的点与当前之间的距离
我们使用欧式距离公式,计算新数据点 new_data 与现存的 X 数据集每一个点的距离:
from math import sqrt
distance =[sqrt(np.sum((x-new_data)**2))for x in X ]
distance
执行结果如下:
[2.6041505332833594,
1.1837651794169315,
1.9424983912477256,
2.3468276459936295,
1.2159358535712326,
1.3405968819895113,
0.4308131845707605,
1.0283968105745949,
2.0089798406156287,
1.500033332962971]
运行结果如下所示:
将距离升序排列 选取距离最小的 K 个点
sort_dist = np.argsort(distance)
sort_dist
执行结果如下所示:
所以,6、7、1 为最近的3个“数据点”的索引值,那么这些索引值对应的原数据的标签是什么?
k =3
topK =[y[i]for i in sort_dist[:k]]
topK
执行结果如下所示:
确定前k个点所在类别的计数
pd.Series(topK).value_counts().index[0]
执行结果如下所示:
封装函数
将数据的过程封装成一个函数:
defKNN(new_data,dataSet,k):'''
函数功能:KNN分类器
参数说明:
new_data: 需要预测分类的数据集
dataSet: 已知分类标签的数据集
k: k-近邻算法参数,选择距离最小的k个点
return:
result: 分类结果
'''from math import sqrt
from collections import Counter
import numpy as np
import pandas as pd
result =[]
distance =[sqrt(np.sum((x-new_data)**2))for x in
np.array(dataSet.iloc[:,0:2])]
sort_dist = np.argsort(distance)
topK =[dataSet.iloc[:,-1][i]for i in sort_dist[:k]]
result.append(pd.Series(topK).value_counts().index[0])return result
测试函数的运行结果:
new_data=np.array([12.03,4.1])
k =3
KNN(new_data,wine_data,k)
执行结果如下所示:
版权归原作者 武子康 所有, 如有侵权,请联系我们删除。