机器学习之K近邻算法
概述
AI不断的火起来了,作为工程化的码农,也得奔向国际化轨道了。至于机器学习是什么,不知道找百科。现在大多数机器学习都是采用监督学习形式。我们学习一下KNN算法。
KNN
KNN(K近邻)算法属于监督学习的分类问题,采用不同feature之间的距离方法进行分类。 1.优点:精度高、对异常值不敏感、无数据输入规定,不需要训练算法。 2.缺点:计算复杂度和空间复杂度高。 3.原理:依据训练样本集中的每个数据对应一个标签,每个数据集中每一个数据与分类一一对应关系,输入没有标签的数据后KNN算法将新数据的每个特征与样本集中数据对应的特征进行比较,然后提出样本集中特征醉相思的数据的分类标签。比如:依据花瓣、花蕊等features标记的类,对输入的测试数据进行最佳匹配。或者依据打斗镜头、接吻镜头等Features将电影分为爱情片、动作片等。
Demo
标量文本数字的KNN
比如对一个约会网站寻找自己的最适合的约会对象,比如将约会的人分类为:
- 不喜欢的人
- 魅力一般的人
- 极具魅力的人
周一至周五我一般会选择魅力一般的人,周末选择极具魅力的人。我手中大约有1000多个约会对象,每个约会对象具有以下三个特征
- 每年飞行常客里程数
- 玩视频游戏时间百分比
- 每周消费的冰淇淋公升数
我要将1000多个对象依据这三个features分为上述三类人。下面请看具体的流程
准备数据
数据是在<机器学习实战>中datingTestSet.txt,由于”每年飞行常客里程数”是一个非常大的整数,且”玩视频游戏时间百分比”和”每周消费的冰淇淋公升数”是一个非常小的数值,如果不经过归一化处理之后那么相似性的判断上主要取决于”每年飞行常客里程数”,所以需要经过归一化处理。每个特征的贡献度都是一样的,所以需要将每个特征值进行归一化处理。归一化处理有以下几部分: 0-1归一化,将数据映射到[0-1]范围内。
x^*=frac{x-min}{max-min}
0-均值规范化(标准差标准化),经过处理的数据的均值为0,标准差为1.
x^*=frac{x_i-x}{sigma}
小数定标准规范化
x^*=frac{x}{10^k}
import pandas as pd
data = pd.read(file)
#0-1归一化
t1=(data-data.min())/(data.max()-data.min())
#0-均值标准化
t2=(data-data.mean())/data.std()
#小数定标规范化
t3=data/10**np.ceil(np.log10(data.abs().max()))
我们看一下测试数据中的数据的格式,然后将“每年飞行常客里程数”0-1归一化,然后数据的格式进行处理即可。
# [每年飞行常客里程数 玩视频游戏时间百分比 每周消费的冰淇淋公升数 样本分类]
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
72993 10.141740 1.032955 1
35948 6.830792 1.213192 3
42666 13.276369 0.543880 3
67497 8.631577 0.749278 1
pandas走起,代码如下:
test = pd.read_table('./datingTestSet2.txt',names=['year','game','ice','class'])
In [99]: test[:3]
Out[99]:
year game ice class
0 40920 8.326976 0.953952 3
1 14488 7.153469 1.673904 2
2 26052 1.441871 0.805124 1
#归一化处理
In [102]: f = lambda x:(((x-x.min())/(x.max()-x.min())) if x.name!='class' else x)
In [103]: test=test.apply(f)
In [104]: test[:3]
Out[104]:
year game ice class
0 0.448325 0.398051 0.562334 3
1 0.158733 0.341955 0.987244 2
2 0.285429 0.068925 0.474496 1
下面我们来看一下完整的书写代码的两种方式第一种采用DataFrame结构,第二种采用numpy的array结构。
def class_knn(x,data,label,k=1):
#归一化处理函数
f = lambda x:(x-x.min())/(x.max()-x.min())
#构造一个数据集,并对数据采用同样的归一化
test = (DataFrame(x,index=data.index) - data.min())/(data.max()-data.min())
data = data.apply(f)
diff = ((test-data)**2).sum(axis=1)**0.5
indexs = diff.sort_values(axis=0,ascending=True)[:k].index
return label[indexs].values
if __name__ == "__main__":
test = pd.read_table('datingTestSet2.txt',names=['year','game','ice','class'])
data,label = test.ix[:,['year','game','ice']],test['class']
x = {'year':10000,'ice':0.5,'game':10}
print class_knn(x, data, label)
第二种,也就是机器学习实战中的代码片段。
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)
print sortedClassCount
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,3)) #prepare matrix to return
classLabelVector = [] #prepare labels return
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip()
listFromLine = line.split('t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(int(unicode(listFromLine[-1])))
index += 1
return returnMat,classLabelVector
你也可以对数据进行分析和可视化,由于博主只是学习算法的思想。对于计算相似性,不仅可以采用欧氏距离,还有很多计算相似性的重要方法。比如:Pearson相关系数和Spearman秩相关系数。
参考书籍
《机器学习实战》 《统计学习方法》
- WAMP配置虚拟主机
- linux开关端口问题
- Python 3.6实现单博主微博文本、图片及热评爬取
- 用Django实现一个可运行的区块链应用
- Python的dict实现原理及与Java的比较探究
- 关于位域如何节省内存(C++)
- mysql的小知识点(关于数据库的导入导出 对于windows)
- Python网络编程中的套接字名和DNS解析
- hdu 4009 Transfer water(最小型树图)
- NumPy二元运算的broadcasting机制
- md5算法原理一窥(其一)
- 实现属于自己的TensorFlow(一) - 计算图与前向传播
- 基于Sanic的微服务基础架构
- hdu 3038 How Many Answers Are Wrong ( 带 权 并 查 集 )
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- spring-boot项目优雅的http客户端工具,真香!
- 人人都可以学会生存分析(学徒数据挖掘)
- 谈谈const跟Object.freeze()
- Java String类源码阅读笔记
- 别再用JSON配置文件了
- 什么,你一定要基于FPKM标准化表达矩阵做单细胞差异分析
- Tomcat 9最新版安装与使用手册,tomcat更改端口号,tomcat控制台乱码问题解决方法
- Python 技术篇-读取遍历指定路径的文件,区分文件和文件夹
- MySQL蜜罐获取攻击者微信ID
- PyQt5 技巧篇-增加一个类级变量,类级变量的设置方法,类级"常量"设置方法
- PyQt5 技巧篇-按钮隐藏并保留位置,设置按钮的可见度,设置按钮透明度
- PyQt5 技巧篇-复选框绑定行内容,全选、清空、展示选中的内容功能实现演示,设置复选框选中,检查复选框选中状态
- PyQt5 技巧篇-QWidget、Dialog界面固定大小设置
- 力扣:地下城游戏,手把手教你做困难题
- RN布局