大数据-195 数据发掘 机器学习理论 - 监督学习算法 KNN 近邻 代码实现 Pyth ...

打印 上一主题 下一主题

主题 845|帖子 845|积分 2535

点一下关注吧!!!非常感谢!!连续更新!!!

如今已经更新到了:



  • 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 实现了这种算法的变种
  • 当数据采样不均匀时,该算法变种可以得到更好的性能
代码实现

导入相关包

  1. # 全部行都能输出
  2. from IPython.core.interactiveshell import InteractiveShell
  3. InteractiveShell.ast_node_interactivity = "all"
  4. import numpy as np
  5. import pandas as pd
  6. import matplotlib.pyplot as plt
  7. # 解决坐标轴刻度负号乱码
  8. plt.rcParams['axes.unicode_minus'] = False
  9. # 解决中文乱码问题
  10. plt.rcParams['font.sans-serif'] = ['Simhei']
  11. plt.style.use('ggplot')
  12. # plt.figure(figsize=(2,3),dpi=720)
复制代码
执行结果如下:

构建已经分类好的原始数据集

起首随机设置十个样本表现十杯酒,这里去了部门样本点。
为了方便验证,使用 Python 的字典 dict 构建数据集,然后再将其转换为DataFrame 格式。
  1. rowdata = {
  2.     '颜色深度': [14.13,13.2,13.16,14.27,13.24,12.07,12.43,11.79,12.37,12.04],
  3.     '酒精浓度': [5.64,4.28,5.68,4.80,4.22,2.76,3.94,3.1,2.12,2.6],
  4.     '品种': [0,0,0,0,0,1,1,1,1,1]
  5. }
  6. # 0 代表 “黑皮诺”,1 代表 “赤霞珠”
  7. wine_data = pd.DataFrame(rowdata)
复制代码
执行结果如下图所示:

编写代码举行处理:
  1. X = np.array(wine_data.iloc[:,0:2]) #我们把特征(酒的属性)放在X
  2. y = np.array(wine_data.iloc[:,-1]) #把标签(酒的类别)放在Y
  3. #探索数据,假如我们给出新数据[12.03,4.1] ,你能猜出这杯红酒是什么类别么?
  4. new_data = np.array([12.03,4.1])
  5. plt.scatter(X[y==1,0], X[y==1,1], color='red', label='赤霞珠') #画出标签y为1
  6. 的、关于“赤霞珠”的散点
  7. plt.scatter(X[y==0,0], X[y==0,1], color='purple', label='黑皮诺') #画出标签y为0
  8. 的、关于“黑皮诺”的散点
  9. plt.scatter(new_data[0],new_data[1], color='yellow') # 新数据点
  10. new_data
  11. plt.xlabel('酒精浓度')
  12. plt.ylabel('颜色深度')
  13. plt.legend(loc='lower right')
  14. plt.savefig('葡萄酒样本.png')
复制代码
执行结果如下如下所示:

盘算已知种别数据会集的点与当前之间的距离

我们使用欧式距离公式,盘算新数据点 new_data 与现存的 X 数据集每一个点的距离:
  1. from math import sqrt
  2. distance = [sqrt(np.sum((x-new_data)**2)) for x in X ]
  3. distance
复制代码
执行结果如下:
  1. [2.6041505332833594,
  2. 1.1837651794169315,
  3. 1.9424983912477256,
  4. 2.3468276459936295,
  5. 1.2159358535712326,
  6. 1.3405968819895113,
  7. 0.4308131845707605,
  8. 1.0283968105745949,
  9. 2.0089798406156287,
  10. 1.500033332962971]
复制代码
运行结果如下所示:

将距离升序分列 选取距离最小的 K 个点

  1. sort_dist = np.argsort(distance)
  2. sort_dist
复制代码
执行结果如下所示:

以是,6、7、1 为最近的3个“数据点”的索引值,那么这些索引值对应的原数据的标签是什么?
  1. k = 3
  2. topK = [y[i] for i in sort_dist[:k]]
  3. topK
复制代码
执行结果如下所示:

确定前k个点地点种别的计数

  1. pd.Series(topK).value_counts().index[0]
复制代码
执行结果如下所示:

封装函数

将数据的过程封装成一个函数:
  1. def KNN(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]
  2. )    return result
复制代码
测试函数的运行结果:
  1. new_data=np.array([12.03,4.1])
  2. k = 3
  3. KNN(new_data,wine_data,k)
复制代码
执行结果如下所示:


免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

悠扬随风

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表