纯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 相关文章推荐
Python基于pillow判断图片完整性的方法
Sep 18 Python
python数据清洗系列之字符串处理详解
Feb 12 Python
pandas中的DataFrame按指定顺序输出所有列的方法
Apr 10 Python
推荐10款最受Python开发者欢迎的Python IDE
Sep 16 Python
python钉钉机器人运维脚本监控实例
Feb 20 Python
对YOLOv3模型调用时候的python接口详解
Aug 26 Python
python读取tif图片时保留其16bit的编码格式实例
Jan 13 Python
详解Python的三种拷贝方式
Feb 11 Python
Python ATM功能实现代码实例
Mar 19 Python
scrapy与selenium结合爬取数据(爬取动态网站)的示例代码
Sep 28 Python
Python OpenCV超详细讲解读取图像视频和网络摄像头
Apr 02 Python
4种方法python批量修改替换列表中元素
Apr 07 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
Yii框架上传图片用法总结
2016/03/28 PHP
PHP实现数组转JSon和JSon转数组的方法示例
2018/06/14 PHP
PHP使用phpunit进行单元测试示例
2019/09/23 PHP
php设计模式之组合模式实例详解【星际争霸游戏案例】
2020/03/27 PHP
this[] 指的是什么内容 讨论
2007/03/24 Javascript
javascript基本类型详解
2014/11/28 Javascript
JS中使用apply、bind实现为函数或者类传入动态个数的参数
2016/04/26 Javascript
jQuery插件pagination实现无刷新分页
2016/05/21 Javascript
js中window.open的参数及注意注意事项
2016/07/06 Javascript
AngularJS基础 ng-include 指令示例讲解
2016/08/01 Javascript
JS从数组中随机取出几个数组元素的方法
2016/08/02 Javascript
JS碰撞运动实现方法详解
2016/12/15 Javascript
jquery仿苹果的时间/日期选择效果
2017/03/08 Javascript
JavaScript引用类型之基本包装类型实例分析【Boolean、Number和String】
2018/08/09 Javascript
angularjs $http调用接口的方式详解
2018/08/13 Javascript
解决vue-cli webpack打包后加载资源的路径问题
2018/09/25 Javascript
浅析vue 函数配置项watch及函数 $watch 源码分享
2018/11/22 Javascript
小程序指纹验证的实现代码
2018/12/04 Javascript
使用apifm-wxapi快速开发小程序过程详解
2019/08/05 Javascript
layui多图上传实现删除功能的例子
2019/09/23 Javascript
[01:00:54]TI4正赛第二日开场
2014/07/20 DOTA
简述Python中的面向对象编程的概念
2015/04/27 Python
Python中矩阵库Numpy基本操作详解
2017/11/21 Python
解决Django一个表单对应多个按钮的问题
2019/07/18 Python
基于python二叉树的构造和打印例子
2019/08/09 Python
python分布式爬虫中消息队列知识点详解
2020/11/26 Python
解决pytorch 数据类型报错的问题
2021/03/03 Python
初中班主任评语
2014/04/24 职场文书
机械专业应届毕业生自荐书
2014/06/12 职场文书
2014审计局领导班子民主生活会对照检查材料思想汇报
2014/09/20 职场文书
2014年仓库工作总结
2014/11/20 职场文书
涉外离婚协议书怎么写
2014/11/20 职场文书
本溪水洞导游词
2015/02/11 职场文书
2019年个人工作总结范文
2019/03/25 职场文书
导游词之云南丽江-泸沽湖
2019/09/26 职场文书
Java 垃圾回收超详细讲解记忆集和卡表
2022/04/08 Java/Android