纯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 实现堆排序算法代码
Jun 05 Python
Python模块学习 datetime介绍
Aug 27 Python
Python中os和shutil模块实用方法集锦
May 13 Python
Python多线程编程(三):threading.Thread类的重要函数和方法
Apr 05 Python
详细介绍Ruby中的正则表达式
Apr 10 Python
python将字符串转换成json的方法小结
Jul 09 Python
对Python中小整数对象池和大整数对象池的使用详解
Jul 09 Python
python 判断字符串中是否含有汉字或非汉字的实例
Jul 15 Python
pytorch torch.nn.AdaptiveAvgPool2d()自适应平均池化函数详解
Jan 03 Python
python匿名函数lambda原理及实例解析
Feb 07 Python
Python中的sys.stdout.write实现打印刷新功能
Feb 21 Python
Django ORM 查询表中某列字段值的方法
Apr 30 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
通过html表格发电子邮件
2006/10/09 PHP
信用卡效验程序
2006/10/09 PHP
PHP安装攻略:常见问题解答(三)
2006/10/09 PHP
不要轻信 PHP_SELF的安全问题
2009/09/05 PHP
利用PHP实现短域名互转
2013/07/05 PHP
浅析51个PHP处理字符串的函数
2013/08/02 PHP
python进程与线程小结实例分析
2018/11/11 PHP
Laravel创建数据库表结构的例子
2019/10/09 PHP
fckeditor 获取文本框值的实现代码
2009/02/09 Javascript
sencha touch 模仿tabpanel导航栏TabBar的实例代码
2013/10/24 Javascript
使用jQuery jqPlot插件绘制柱状图
2014/12/18 Javascript
js实现拖拽效果
2015/02/12 Javascript
jQuery实现带滑动条的菜单效果代码
2015/08/26 Javascript
javascript特效实现——当前时间和倒计时效果的简单实例
2016/07/20 Javascript
解决拦截器对ajax请求的拦截实例详解
2016/12/21 Javascript
ajax实现加载页面、删除、查看详细信息 bootstrap美化页面!
2017/03/14 Javascript
原生JS+CSS实现炫酷重力模拟弹跳系统的登录页面
2017/11/01 Javascript
vscode中vue-cli项目es-lint的配置方法
2018/07/30 Javascript
详解webpack-dev-server使用方法
2018/09/14 Javascript
微信小程序实现下拉框功能
2019/07/16 Javascript
VsCode与Node.js知识点详解
2019/09/05 Javascript
Python使用迭代器打印螺旋矩阵的思路及代码示例
2016/07/02 Python
python实现图片批量压缩程序
2018/07/23 Python
libreoffice python 操作word及excel文档的方法
2019/07/04 Python
python内存管理机制原理详解
2019/08/12 Python
纯CSS3实现的井字棋游戏
2020/11/25 HTML / CSS
中国专业的音频分享平台:喜马拉雅
2019/05/24 全球购物
英国运动服、设备及配件网站:DW Sports
2019/12/04 全球购物
运动会广播稿200米(5篇)
2014/10/15 职场文书
学校食堂食品安全承诺书
2015/04/29 职场文书
搞笑结婚保证书
2015/05/08 职场文书
会计岗位工作总结
2015/08/12 职场文书
2019员工保密协议书(3篇)
2019/09/23 职场文书
PostgreSQL基于pgrouting的路径规划处理方法
2022/04/18 PostgreSQL
Python OpenGL基本配置方式
2022/05/20 Python
Java 中的 Lambda List 转 Map 的多种方法详解
2022/07/07 Java/Android