纯python实现机器学习之kNN算法示例


Posted in Python onMarch 01, 2018

前面文章分别简单介绍了线性回归,逻辑回归,贝叶斯分类,并且用python简单实现。这篇文章介绍更简单的 knn, k-近邻算法(kNN,k-NearestNeighbor)。

k-近邻算法(kNN,k-NearestNeighbor),是最简单的机器学习分类算法之一,其核心思想在于用距离目标最近的k个样本数据的分类来代表目标的分类(这k个样本数据和目标数据最为相似)。

原理

kNN算法的核心思想是用距离最近(多种衡量距离的方式)的k个样本数据来代表目标数据的分类。

具体讲,存在训练样本集, 每个样本都包含数据特征和所属分类值。

输入新的数据,将该数据和训练样本集汇中每一个样本比较,找到距离最近的k个,在k个数据中,出现次数做多的那个分类,即可作为新数据的分类。

纯python实现机器学习之kNN算法示例

如上图:

需要判断绿色是什么形状。当k等于3时,属于三角。当k等于5是,属于方形。

因此该方法具有一下特点:

  1. 监督学习:训练样本集中含有分类信息
  2. 算法简单, 易于理解实现
  3. 结果收到k值的影响,k一般不超过20.
  4. 计算量大,需要计算与样本集中每个样本的距离。
  5. 训练样本集不平衡导致结果不准确问题

接下来用oython 做个简单实现, 并且尝试用于约会网站配对。

python简单实现

def classify(inX, dataSet, labels, k):
  """
  定义knn算法分类器函数
  :param inX: 测试数据
  :param dataSet: 训练数据
  :param labels: 分类类别
  :param k: k值
  :return: 所属分类
  """

  dataSetSize = dataSet.shape[0] #shape(m, n)m列n个特征
  diffMat = np.tile(inX, (dataSetSize, 1)) - dataSet
  sqDiffMat = diffMat ** 2
  sqDistances = sqDiffMat.sum(axis=1)
  distances = sqDistances ** 0.5 #欧式距离
  sortedDistIndicies = distances.argsort() #排序并返回index

  classCount = {}
  for i in range(k):
    voteIlabel = labels[sortedDistIndicies[i]]
    classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1 #default 0

  sortedClassCount = sorted(classCount.items(), key=lambda d:d[1], reverse=True)
  return sortedClassCount[0][0]

算法的步骤上面有详细的介绍,上面的计算是矩阵运算,下面一个函数是代数运算,做个比较理解。

def classify_two(inX, dataSet, labels, k):
  m, n = dataSet.shape  # shape(m, n)m列n个特征
  # 计算测试数据到每个点的欧式距离
  distances = []
  for i in range(m):
    sum = 0
    for j in range(n):
      sum += (inX[j] - dataSet[i][j]) ** 2
    distances.append(sum ** 0.5)

  sortDist = sorted(distances)

  # k 个最近的值所属的类别
  classCount = {}
  for i in range(k):
    voteLabel = labels[ distances.index(sortDist[i])]
    classCount[voteLabel] = classCount.get(voteLabel, 0) + 1 # 0:map default
  sortedClass = sorted(classCount.items(), key=lambda d:d[1], reverse=True)
  return sortedClass[0][0]

有了上面的分类器,下面进行最简单的实验来预测一下:

def createDataSet():
  group = np.array([[1, 1.1], [1, 1], [0, 0], [0, 0.1]])
  labels = ['A', 'A', 'B', 'B']
  return group, labels

上面是一个简单的训练样本集。

if __name__ == '__main__':
  dataSet, labels = createDataSet()
  r = classify_two([0, 0.2], dataSet, labels, 3)
  print(r)

执行上述函数:可以看到输出B, [0 ,0.2]应该归入b类。

上面就是一个最简单的kNN分类器,下面有个例子。

kNN用于判断婚恋网站中人的受欢迎程度

训练样本集中部分数据如下:

40920 8.326976 0.953952 3
14488 7.153469 1.673904 2
26052 1.441871 0.805124 1
75136 13.147394 0.428964 1
38344 1.669788 0.134296 1

第一列表示每年获得的飞行常客里程数, 第二列表示玩视频游戏所耗时间百分比, 第三类表示每周消费的冰淇淋公升数。第四列表示分类结果,1, 2, 3 分别是 不喜欢,魅力一般,极具魅力。

将数据转换成numpy。

# 文本转换成numpy
def file2matrix(filepath="datingSet.csv"):
  dataSet = np.loadtxt(filepath)
  returnMat = dataSet[:, 0:-1]
  classlabelVector = dataSet[:, -1:]
  return returnMat, classlabelVector

首先对数据有个感知,知道是哪些特征影响分类,进行可视化数据分析。

# 2, 3列数据进行分析
def show_2_3_fig():
  data, cls = file2matrix()
  fig = plt.figure()
  ax = fig.add_subplot(111)
  ax.scatter(data[:, 1], data[: ,2], c=cls)
  plt.xlabel("playing game")
  plt.ylabel("Icm Cream")
  plt.show()

纯python实现机器学习之kNN算法示例

如上图可以看到并无明显的分类。

纯python实现机器学习之kNN算法示例

纯python实现机器学习之kNN算法示例

可以看到不同的人根据特征有明显的区分。因此可以使用kNN算法来进行分类和预测。

由于后面要用到距离比较,因此数据之前的影响较大, 比如飞机里程和冰淇淋数目之间的差距太大。因此需要对数据进行归一化处理。

# 数据归一化
def autoNorm(dataSet):
  minVal = dataSet.min(0)
  maxVal = dataSet.max(0)
  ranges = maxVal - minVal

  normDataSet = np.zeros(dataSet.shape)
  m, n = dataSet.shape # 行, 特征
  normDataSet = dataSet - minVal
  normDataSet = normDataSet / ranges
  return normDataSet, ranges, minVal

衡量算法的准确性

knn算法可以用正确率或者错误率来衡量。错误率为0,表示分类很好。

因此可以将训练样本中的10%用于测试,90%用于训练。

# 定义测试算法的函数
def datingClassTest(h=0.1):
  hoRatio = h
  datingDataMat, datingLabels = file2matrix()
  normMat, ranges, minVals = autoNorm(datingDataMat)
  m, n = normMat.shape
  numTestVecs = int(m * hoRatio) #测试数据行数
  errorCount = 0 # 错误分类数


  # 用前10%的数据做测试
  for i in range(numTestVecs):
    classifierResult = classify(normMat[i, :], normMat[numTestVecs:m, :], datingLabels[numTestVecs:m], 3)
    # print('the classifier came back with: %d,the real answer is: %d' % (int(classifierResult), int(datingLabels[i])))
    if classifierResult != datingLabels[i]:
      errorCount += 1
  print("the total error rate is: %f" % (errorCount / float(numTestVecs)))

调整不同的测试比例,对比结果。

使用knn进行预测。

有了训练样本和分类器,对新数据可以进行预测。模拟数据并进行预测如下:

# 简单进行预测
def classifypersion():
  resultList = ["none", 'not at all','in small doses','in large doses']
  # 模拟数据
  ffmiles = 15360
  playing_game = 8.545204
  ice_name = 1.340429

  datingDataMat, datingLabels = file2matrix()
  normMat, ranges, minVals = autoNorm(datingDataMat)
  inArr = np.array([ffmiles, playing_game, ice_name])
  # 预测数据归一化
  inArr = (inArr - minVals) / ranges
  classifierResult = classify(inArr, normMat, datingLabels, 3)
  print(resultList[int(classifierResult)])

可以看到基本的得到所属的分类。

完成代码和数据请参考:

github:kNN

总结

  1. kNN
  2. 监督学习
  3. 数据可视化
  4. 数据归一化,不影响计算

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
用C++封装MySQL的API的教程
May 06 Python
Jupyter中直接显示Matplotlib的图形方法
May 24 Python
解决pandas.DataFrame.fillna 填充Nan失败的问题
Nov 06 Python
Python进程间通信Queue消息队列用法分析
May 22 Python
python自动化测试之如何解析excel文件
Jun 27 Python
python字典的常用方法总结
Jul 31 Python
Python 使用matplotlib模块模拟掷骰子
Aug 08 Python
用Python写一个自动木马程序
Sep 17 Python
利用Python代码实现一键抠背景功能
Dec 29 Python
tensorflow 限制显存大小的实现
Feb 03 Python
python多进程使用函数封装实例
May 02 Python
Python操作PostgreSql数据库的方法(基本的增删改查)
Dec 29 Python
用python与文件进行交互的方法
Mar 01 #Python
python爬虫爬取快手视频多线程下载功能
Feb 28 #Python
python爬取m3u8连接的视频
Feb 28 #Python
python实现m3u8格式转换为mp4视频格式
Feb 28 #Python
浅谈Python中的私有变量
Feb 28 #Python
python中logging包的使用总结
Feb 28 #Python
深入理解Python爬虫代理池服务
Feb 28 #Python
You might like
三个类概括PHP的五种设计模式
2012/09/05 PHP
基于jquery的一个简单的脚本验证插件
2010/04/05 Javascript
jQuery的实现原理的模拟代码 -2 数据部分
2010/08/01 Javascript
jquery选择checked在ie8普通模式下的问题
2014/02/12 Javascript
js写出遮罩层登陆框和对联广告并自动跟随滚动条滚动
2014/04/29 Javascript
javascript实例--教你实现扑克牌洗牌功能
2014/05/15 Javascript
jQuery插件datepicker 日期连续选择
2015/06/12 Javascript
在JavaScript的AngularJS库中进行单元测试的方法
2015/06/23 Javascript
js判断当前页面在移动设备还是在PC端中打开
2016/01/06 Javascript
利用JavaScript判断浏览器类型及版本
2016/08/23 Javascript
浅谈js函数的多种定义方法与区别
2016/11/29 Javascript
JS实现的系统调色板完整实例
2016/12/21 Javascript
简单实现js上传文件功能
2017/08/21 Javascript
Vue移动端右滑屏幕返回上一页附源码下载
2019/06/26 Javascript
如何在Express4.x中愉快地使用async的方法
2020/11/18 Javascript
[36:33]2018DOTA2亚洲邀请赛 4.3 突围赛 EG vs Newbee 第二场
2018/04/04 DOTA
python实现代码行数统计示例分享
2014/02/10 Python
Python编程语言的35个与众不同之处(语言特征和使用技巧)
2014/07/07 Python
python with statement 进行文件操作指南
2014/08/22 Python
使用Python制作获取网站目录的图形化程序
2015/05/04 Python
Python中的localtime()方法使用详解
2015/05/22 Python
python如何获取服务器硬件信息
2017/05/11 Python
详解python之heapq模块及排序操作
2019/04/04 Python
Django restful framework生成API文档过程详解
2020/11/12 Python
老生常谈CSS中的长度单位
2016/06/27 HTML / CSS
LivingSocial爱尔兰:爱尔兰本地优惠
2018/08/10 全球购物
澳洲网红粉泥面膜:Sand & Sky
2019/08/13 全球购物
.NET是怎么支持多种语言的
2015/02/24 面试题
高中教师考核方案
2014/05/18 职场文书
乡镇消防安全责任书
2014/07/23 职场文书
2014机关党员干部“正风肃纪”思想汇报
2014/09/15 职场文书
戒毒悔改检讨书
2014/09/21 职场文书
幼儿园感恩节活动方案2014
2014/10/11 职场文书
运动会开幕式主持词
2015/07/01 职场文书
python基于opencv批量生成验证码的示例
2021/04/28 Python
vue组件vue-esign实现电子签名
2022/04/21 Vue.js