当前位置: 首页 > news >正文

python示例程序演示_以Python代码实例展示kNN算法的实际运用

邻近算法,或者说K最近邻(kNN,k-NearestNeighbor)分类算法是数据挖掘分类技术中最简单的方法之一。所谓K最近邻,就是k个最近的邻居的意思,说的是每个样本都可以用它最接近的k个邻居来代表。

kNN算法的核心思想是如果一个样本在特征空间中的k个最相邻的样本中的大多数属于某一个类别,则该样本也属于这个类别,并具有这个类别上样本的特性。该方法在确定分类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 kNN方法在类别决策时,只与极少量的相邻样本有关。由于kNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,kNN方法较其他方法更为适合。

上图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

K最近邻(k-Nearest Neighbor,KNN)分类算法,是一个理论上比较成熟的方法,也是最简单的机器学习算法之一。该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。KNN算法中,所选择的邻居都是已经正确分类的对象。该方法在定类决策上只依据最邻近的一个或者几个样本的类别来决定待分样本所属的类别。 KNN方法虽然从原理上也依赖于极限定理,但在类别决策时,只与极少量的相邻样本有关。由于KNN方法主要靠周围有限的邻近的样本,而不是靠判别类域的方法来确定所属类别的,因此对于类域的交叉或重叠较多的待分样本集来说,KNN方法较其他方法更为适合。

KNN算法不仅可以用于分类,还可以用于回归。通过找出一个样本的k个最近邻居,将这些邻居的属性的平均值赋给该样本,就可以得到该样本的属性。更有用的方法是将不同距离的邻居对该样本产生的影响给予不同的权值(weight),如权值与距离成反比。

用 kNN 算法预测豆瓣电影用户的性别

摘要

本文认为不同性别的人偏好的电影类型会有所不同,因此进行了此实验。利用较为活跃的274位豆瓣用户最近观看的100部电影,对其类型进行统计,以得到的37种电影类型作为属性特征,以用户性别作为标签构建样本集。使用kNN算法构建豆瓣电影用户性别分类器,使用样本中的90%作为训练样本,10%作为测试样本,准确率可以达到81.48%。

实验数据

本次实验所用数据为豆瓣用户标记的看过的电影,选取了274位豆瓣用户最近看过的100部电影。对每个用户的电影类型进行统计。本次实验所用数据中共有37个电影类型,因此将这37个类型作为用户的属性特征,各特征的值即为用户100部电影中该类型电影的数量。用户的标签为其性别,由于豆瓣没有用户性别信息,因此均为人工标注。

数据格式如下所示:

X1,1,X1,2,X1,3,X1,4……X1,36,X1,37,Y1

X2,1,X2,2,X2,3,X2,4……X2,36,X2,37,Y2

…………

X274,1,X274,2,X274,3,X274,4……X274,36,X274,37,Y274

示例:

0,0,0,3,1,34,5,0,0,0,11,31,0,0,38,40,0,0,15,8,3,9,14,2,3,0,4,1,1,15,0,0,1,13,0,0,1,1 0,1,0,2,2,24,8,0,0,0,10,37,0,0,44,34,0,0,3,0,4,10,15,5,3,0,0,7,2,13,0,0,2,12,0,0,0,0

像这样的数据一共有274行,表示274个样本。每一个的前37个数据是该样本的37个特征值,最后一个数据为标签,即性别:0表示男性,1表示女性。

在此次试验中取样本的前10%作为测试样本,其余作为训练样本。

首先对所有数据归一化。对矩阵中的每一列求取最大值(max_j)、最小值(min_j),对矩阵中的数据X_j,

X_j=(X_j-min_j)/(max_j-min_j) 。

然后对于每一条测试样本,计算其与所有训练样本的欧氏距离。测试样本i与训练样本j之间的距离为:

distance_i_j=sqrt((Xi,1-Xj,1)^2+(Xi,2-Xj,2)^2+……+(Xi,37-Xj,37)^2) ,

对样本i的所有距离从小到大排序,在前k个中选择出现次数最多的标签,即为样本i的预测值。

实验结果

首先选择一个合适的k值。 对于k=1,3,5,7,均使用同一个测试样本和训练样本,测试其正确率,结果如下表所示。

选取不同k值的正确率表

由上述结果可知,在k=3时,测试的平均正确率最高,为74.07%,最高可以达到81.48%。

上述不同的测试集均来自同一样本集中,为随机选取所得。

Python代码

这段代码并非原创,来自《机器学习实战》(Peter Harrington,2013),并有所改动。

#coding:utf-8

from numpy import *

import operator

def classify0(inX, dataSet, labels, k):

dataSetSize = dataSet.shape[0]

diffMat = tile(inX, (dataSetSize,1)) - dataSet

sqDiffMat = diffMat**2

sqDistances = sqDiffMat.sum(axis=1)

distances = sqDistances**0.5

sortedDistIndicies = distances.argsort()

classCount={}

for i in range(k):

voteIlabel = labels[sortedDistIndicies[i]]

classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1

sortedClassCount = sorted(classCount.iteritems(), key=operator.itemgetter(1), reverse=True)

return sortedClassCount[0][0]

def autoNorm(dataSet):

minVals = dataSet.min(0)

maxVals = dataSet.max(0)

ranges = maxVals - minVals

normDataSet = zeros(shape(dataSet))

m = dataSet.shape[0]

normDataSet = dataSet - tile(minVals, (m,1))

normDataSet = normDataSet/tile(ranges, (m,1)) #element wise divide

return normDataSet, ranges, minVals

def file2matrix(filename):

fr = open(filename)

numberOfLines = len(fr.readlines()) #get the number of lines in the file

returnMat = zeros((numberOfLines,37)) #prepare matrix to return

classLabelVector = [] #prepare labels return

fr = open(filename)

index = 0

for line in fr.readlines():

line = line.strip()

listFromLine = line.split(',')

returnMat[index,:] = listFromLine[0:37]

classLabelVector.append(int(listFromLine[-1]))

index += 1

fr.close()

return returnMat,classLabelVector

def genderClassTest():

hoRatio = 0.10 #hold out 10%

datingDataMat,datingLabels = file2matrix('doubanMovieDataSet.txt') #load data setfrom file

normMat,ranges,minVals=autoNorm(datingDataMat)

m = normMat.shape[0]

numTestVecs = int(m*hoRatio)

testMat=normMat[0:numTestVecs,:]

trainMat=normMat[numTestVecs:m,:]

trainLabels=datingLabels[numTestVecs:m]

k=3

errorCount = 0.0

for i in range(numTestVecs):

classifierResult = classify0(testMat[i,:],trainMat,trainLabels,k)

print "the classifier came back with: %d, the real answer is: %d" % (classifierResult, datingLabels[i])

if (classifierResult != datingLabels[i]):

errorCount += 1.0

print "Total errors:%d" %errorCount

print "The total accuracy rate is %f" %(1.0-errorCount/float(numTestVecs))

相关文章:

  • python 自动下载脚本_Python脚本自动下载小说
  • jdbc封装工具类代码_[22]-JDBC 工具类优化
  • jpg转dwg格式转换器_如何将PDF或者JPG转CAD格式(dwg格式)?
  • python多线程实现生产者消费者_使用Python多线程实现生产者与消费者模型
  • layui框架和vue哪个好_目前流行的9大前端框架
  • python xlwings筛选_使用Python和xlwings在Excel中查找活动/选定单元格的范围
  • stream distinct去重_会了这些 Stream 操作,再学 Flink 真的简单的不得了
  • ubuntu vscode安装_Visual Studio Code软件的安装和开发环境搭建
  • 只显示小方格_展位设计中的小空间如何运用使空间看上去更大(上)
  • oa系统登录后几分钟自动退出_你知道系统登录有多少种方式吗?
  • python 怕网页_Python解救论文拖延狗
  • xilinx bd修改后sdk如何刷新bsp_如何使用Theos对iOS应用程序进行注入
  • mysql 统计查询总数_详解慢查询日志分析工具mysqlsla--概念、选型、安装及实例说明...
  • python去除注释语句_Python文件去除注释的方法
  • qtdesigner 如何清空输入框_如何进行开发需求分解?
  • $translatePartialLoader加载失败及解决方式
  • [译] 怎样写一个基础的编译器
  • 10个最佳ES6特性 ES7与ES8的特性
  • 2017 前端面试准备 - 收藏集 - 掘金
  • 230. Kth Smallest Element in a BST
  • Docker容器管理
  • Github访问慢解决办法
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • mysql innodb 索引使用指南
  • 闭包--闭包作用之保存(一)
  • 关键词挖掘技术哪家强(一)基于node.js技术开发一个关键字查询工具
  • 看域名解析域名安全对SEO的影响
  • 通过git安装npm私有模块
  • 优化 Vue 项目编译文件大小
  • 中文输入法与React文本输入框的问题与解决方案
  • NLPIR智能语义技术让大数据挖掘更简单
  • ​LeetCode解法汇总2670. 找出不同元素数目差数组
  • ​软考-高级-信息系统项目管理师教程 第四版【第23章-组织通用管理-思维导图】​
  • #、%和$符号在OGNL表达式中经常出现
  • #pragma 指令
  • #基础#使用Jupyter进行Notebook的转换 .ipynb文件导出为.md文件
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • $.ajax()
  • (javascript)再说document.body.scrollTop的使用问题
  • (二十三)Flask之高频面试点
  • (分布式缓存)Redis分片集群
  • (一)ClickHouse 中的 `MaterializedMySQL` 数据库引擎的使用方法、设置、特性和限制。
  • (转)Sublime Text3配置Lua运行环境
  • (自适应手机端)响应式新闻博客知识类pbootcms网站模板 自媒体运营博客网站源码下载
  • **PHP二维数组遍历时同时赋值
  • .net mvc actionresult 返回字符串_.NET架构师知识普及
  • .NET Windows:删除文件夹后立即判断,有可能依然存在
  • .NET/C# 获取一个正在运行的进程的命令行参数
  • [BUG] Authentication Error
  • [CF226E]Noble Knight's Path
  • [codeforces]Checkpoints
  • [Django 0-1] Core.Email 模块
  • [hive] posexplode函数
  • [HNOI2006]鬼谷子的钱袋
  • [iOS]iOS获取设备信息经常用法