机器学习实战笔记一:K-近邻算法在约会网站上的应用
K-近邻算法概述
简单的说,K-近邻算法采用不同特征值之间的距离方法进行分类
K-近邻算法
优点:精度高、对异常值不敏感、无数据输入假定。
缺点:计算复杂度高、空间复杂度高。
适用范围:数值型和标称型。
k-近邻算法的一般流程
- 收集数据:可使用任何方法
- 准备数据:距离计算所需要的数值,最好是结构化的数据格式。
- 分析数据:可以使用任何方法。
- 训练算法:此步骤不适用于K-近邻算法
- 使用算法:首先需要输入样本数据和节后话的输出结果,然后运行k-近邻算法判定输入数据分别属于哪个分类,最后应用对计算出的分类执行后续的处理
#kNN分类器
def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0] #得到数据总量
diffMat = tile(inX,(dataSetSize,1)) - dataSet #将输入数据扩充成与数据集同样大小的矩阵并作差
sqDiffMat = diffMat**2
sqDistances = sqDiffMat.sum(axis=1) #axis = 1 参数是维度参数等于1在此处表示将一个矩阵的每一行向量相加
distances = sqDistances** 0.5
sortedDistancesIndicies = distances .argsort() #将列表值进行对比返回一个按照数值升序的下标值
classCount={}
for i in range(k):
voteIlabel = labels[sortedDistancesIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0)+1
#dict.get("key") 返回value dict.get("key",default= None)如果能找到就返回对应的value找不到返回默认值
sortedClassCount = sorted(classCount.items(),key = operator.itemgetter(1),reverse=True)
#sorted 返回一个list operator.itemgetter(x,y)表示根据x+1维度的第y+1维度
return sortedClassCount[0][0]
K-近邻算法在约会网站改进的应用
在约会网站上使用K-近邻算法
(1)收集数据:提供文本文件。
(2)准备数据:使用python解析文本文件。
(3)分析数据:使用Matplotlib绘画二维扩展图。
(4)训练算法:此步骤不适用于K-近邻算法。
(5)测试算法:使用提供的部分数据作为测试样本。
测试样本和非测试样本的区别在于:测试样本是已经完成分类的数据,如果预测分类与实际不同,则标记为一个错误。
(6)使用方法:产生简单的命令行程序,然后可以输入一些特征数据以判断对方是否为自己喜欢的类型
准备数据:从文本文件中解析数据
提供的文本文件datingTestSet2.txt中,每个样本数据占一行,总共有1000行。主要包括以下特征:
1.每年获得的飞行常客里程数
2.玩视频游戏所耗时间百分比
3.每周消费的冰淇淋公升数
将上述特征数据输入到分类器前,必须将待处理数据的格式改变为分类器可以接受的格式。创建名为file2matrix的函数,以此来处理格式问题。函数的输入为文件名,输出为训练样本和类标签向量。
# Author:Thomas Wang
from numpy import *
def file2matrix(filename):
with open(filename,'r') as fr:
arrayOLines = fr.readlines()
numberOfLines = len(arrayOLines)#存储文件数据数目
returnMat = zeros((numberOfLines,3))#准备接收数据的numpy数组
classLabelVector = []#准备接收标签向量的数组python列表
index = 0
for line in arrayOLines:
line = line.strip() #截去每行的回车
listFromLine = line.split('\t')#以‘\t’为分隔符将字符串截取成字符串数组
returnMat[index,:] = listFromLine[0:3] #[index,:] = [index][:] 将字符串数组赋值给numpy数组自动转换为浮点型
classLabelVector.append(int(listFromLine[-1]))
index +=1
return returnMat,classLabelVector
需要注意的是:
1、numpy数组中[index,:] 与python 列表中[index][:] 作用相同
2、numpy函数库可以自动解决变量值问题,而python并不可以必须明确告诉解释器才可以处理
通过以下命令查看数据内容
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
print(datingDataMat)
print(datingLabels[0:20])
[[4.0920000e+04 8.3269760e+00 9.5395200e-01]
[1.4488000e+04 7.1534690e+00 1.6739040e+00]
[2.6052000e+04 1.4418710e+00 8.0512400e-01]
...
[2.6575000e+04 1.0650102e+01 8.6662700e-01]
[4.8111000e+04 9.1345280e+00 7.2804500e-01]
[4.3757000e+04 7.8826010e+00 1.3324460e+00]]
[3, 2, 1, 1, 1, 1, 3, 3, 1, 3, 1, 1, 2, 1, 1, 1, 1, 1, 2, 3]
分析数据:使用Matplotlib创建散点图
我们借助Matplotlib可以让我们对我们得到的数据更加直接的展示在我们的面前(具体的Matplotlib可以根据需要进行了解学习)
import matplotlib
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot()
ax.scatter(datingDataMat[:,],datingDataMat[:,],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show()

准备数据:归一化数值
| 玩视频游戏所耗时间百分比 | 每年获得的飞行常客里程数 | 每周消费的冰激凌公升数 | 样本分类 | |
| 1 | 0.8 | 400 | 0.5 | 1 |
| 2 | 12 | 134000 | 0.9 | 3 |
| 3 | 0 | 20000 | 1.1 | 2 |
| 4 | 67 | 32000 | 0.1 | 2 |
根据上表中样本3和样本4的数据,计算样本3和样本4之间的距离:
\[\sqrt {{{(0 - 67)}^2} + {{(20000 - 32000)}^2} + {{(1.1 - 0.1)}^2}} \]
我们可以发现,上面方程中数字差值最大的属性对计算结果的影响最大,其中飞行常客里程数对计算结果的影响将远远大于其他两个特征值。所以,作为三个等权重的特征值之一,飞行常客里程数不应该
如此严重的影响计算结果。
解决这种去不同范围的特征值是,我们常常采用的方法是将数值归一化,如将取值范围处理为0到1或者-1到1之间。我们可以用下式将任意取值范围的特征值转化到0到1区间内的值:
newValue = (oldValue - min)/(max - min)
其中min和max是数据集中最小特征值和最大特征值。我们可以通过构造函数autoNorm()自动将数字特征函数转化到0到1之间。
def autoNorm(dataSet):
minVals = dataSet.min() #Return the minimum along a given axis.
maxVals = dataSet.max() #Return the maximum along a given axis.
ranges = maxVals - minVals #取到特征值最大最小值之间的范围
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[] #取到数据量
normDataSet = dataSet - tile(minVals,(m,))
normDataSet = normDataSet/tile(ranges,(m,))
return normDataSet,ranges,minVals
测试算法:作为完整程序验证分类器
使用错误率来检测分类器的性能,对于分类器来说,错误率就是分类器给出错误结果的次数初一测试数据的总数数值处于0到1之间。代码中需要定义一个计数器变量,每次分类器错误的分类数据,计数器
就加1,程序执行完成之后计数器的结果初一数据点总数即是错误率。需要注意的是训练数据和测试数据都是按比例随机取得。
#完整程序验证分类器
def datingClassTest():
hoRatio = 0.1 #测试数据比例
datingDataMat, datingLabels = file2matrix('datingTestSet2.txt') #文本文件转换成可以处理的矩阵
normDataSet, ranges, minVals = autoNorm(datingDataMat) #将数据进行归一化
m = normDataSet.shape[0] #获取数据总量
numTestVecs = int(m * hoRatio) #获取测试数据数量
errorCount = 0.0 #错误数据个数计数器
for i in range(numTestVecs):
#对每个测试数据利用KNN算法进行分类
classifierResult = classify0(normDataSet[i,:],normDataSet[numTestVecs:m,:],datingLabels[numTestVecs:m],4)
#打印预测结果与实际结果
print("分类器结果:%s,真实结果:%s"%(classifierResult,datingLabels[i]))
#计算总错误个数并计算错误率
if (classifierResult != datingLabels[i]): errorCount+=1.0
print("the total error rate is: %f"%(errorCount/float(numTestVecs)))
datingClassTest()
分类器结果:,真实结果:
分类器结果:,真实结果:
分类器结果:,真实结果:
......
分类器结果:,真实结果:
分类器结果:,真实结果:
分类器结果:,真实结果:
the total error rate is: 0.040000
我们可以改变datingClassTest内变量hoRatio和变量K的值,洁厕错误率是否会随着变量的增加而增加。取决于分类算法、数据集和程序设计,分类器的输出结果可能会有很大的不同。
使用算法:构建完整可用系统
数据已经在分类器上进行了测试,我们将给用户一段小程序,通过用户输入的信息。程序会给出符合用户的预测值。
#完整可用系统
def classifyPerson():
resultList = ['not at all','in small does','in large does']
percetTats = float(input("玩视频游戏所耗时间百分比:"))
ffMiles = float(input("每年获取的飞行常客里程数:"))
iceCream = float(input("每年消耗冰淇淋的公升数:"))
datingDataMat,datingLabels = file2matrix("datingTestSet2.txt")
normMat,ranges,minVals = autoNorm(datingDataMat)
inArr = array([ffMiles,percetTats,iceCream])
classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,4)
print("You probably like this person:",resultList[classifierResult-1])
这样一个简单可用的针对约会网站的完整可用系统就完成了,代码理解并不是很困难。
总结
第一篇博客内容不会很详尽,希望大家留言指导改进。本篇博客通过一个简单的约会网站预测实例入手,论述了一个机器学习算法实践从无到有的过程:准备数据--->分析数据--->准备数据:归一化数值--->
测试算法--->使用算法。
机器学习实战笔记一:K-近邻算法在约会网站上的应用的更多相关文章
- 使用K近邻算法改进约会网站的配对效果
1 定义数据集导入函数 import numpy as np """ 函数说明:打开并解析文件,对数据进行分类:1 代表不喜欢,2 代表魅力一般,3 代表极具魅力 Par ...
- 机器学习(1)——K近邻算法
KNN的函数写法 import numpy as np from math import sqrt from collections import Counter def KNN_classify(k ...
- SIGAI机器学习第七集 k近邻算法
讲授K近邻思想,kNN的预测算法,距离函数,距离度量学习,kNN算法的实际应用. KNN是有监督机器学习算法,K-means是一个聚类算法,都依赖于距离函数.没有训练过程,只有预测过程. 大纲: k近 ...
- 机器学习实战笔记-11-Apriori与FP-Growth算法
Apriori算法 优点:易编码实现:缺点:大数据集上较慢:适用于:数值型或标称型数据. 关联分析:寻找频繁项集(经常出现在一起的物品的集合)或关联规则(两种物品之间的关联关系). 概念:支持度:数据 ...
- 机器学习实战笔记(1)——k-近邻算法
机器学习实战笔记(1) 1. 写在前面 近来感觉机器学习,深度学习神马的是越来越火了,从AlphaGo到Master,所谓的人工智能越来越NB,而我又是一个热爱新潮事物的人,于是也来凑个热闹学习学习. ...
- 机器学习实战 - python3 学习笔记(一) - k近邻算法
一. 使用k近邻算法改进约会网站的配对效果 k-近邻算法的一般流程: 收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据.一般来讲,数据放在txt文本文件中,按照一定的格式进 ...
- 机器学习实战笔记--k近邻算法
#encoding:utf-8 from numpy import * import operator import matplotlib import matplotlib.pyplot as pl ...
- 机器学习实战笔记(Python实现)-01-K近邻算法(KNN)
--------------------------------------------------------------------------------------- 本系列文章为<机器 ...
- 02机器学习实战之K近邻算法
第2章 k-近邻算法 KNN 概述 k-近邻(kNN, k-NearestNeighbor)算法是一种基本分类与回归方法,我们这里只讨论分类问题中的 k-近邻算法. 一句话总结:近朱者赤近墨者黑! k ...
随机推荐
- mongodb3.4.0复制集的搭建
本次主要介绍一下我们项目中关于mongodb复制集的搭建过程. 部署三台mongodb,分别是在69,70,71上面.71上面是主节点,69和70是从节点.使用mongodb3.4.0版本. 先看一安 ...
- 学习笔记(2)centos7 下安装mysql
centos7安装mysql 本文通过yum方式安装mysql 1.添加mysql yum 仓库 去mysql开发者中心(http://dev.mysql.com/downloads/repo/yum ...
- MySql is marked as crashed and should be repaired问题
在一次电脑不知道为什么重启之后数据库某表出现了 is marked as crashed and should be repaired这个错误,百度了一下,很多都是去找什么工具然后输入命令之类的,因为 ...
- JavaScript基础部分经典案例
再复杂的程序都是由一个个简单的部分组成. 001案例 - 交换两个变量的值 方法01 - 使用临时变量 var n1 = 5; var n2 = 6; // 创建一个临时中介变量 tmp var tm ...
- 开源框架:DBUtils使用详解
一.先熟悉DBUtils的API: 简介:DbUtils是一个为简化JDBC操作的小类库. (一)整个dbutils总共才3个包: 1.包org.apache.commons.dbutils 接 ...
- Java 序列化与反序列化(Serialization)
一.什么是?为什么需要? 序列化(Serialization)是将对象的状态信息转化为可以存储或者传输的形式的过程,反序列化则为其逆过程. 内存的易失性:传输需要:一些应用场景中需要将对象持久化下来, ...
- Java性能优化的50个细节
在JAVA程序中,性能问题的大部分原因并不在于JAVA语言,而是程序本身.养成良好的编码习惯非常重要,能够显著地提升程序性能. 1. 尽量在合适的场合使用单例 使用单例可以减轻加载的负担,缩短加载的时 ...
- openssl windows平台编译库
首先感谢http://blog.csdn.net/YAOJINGKAO/article/details/53041165?locationNum=10&fps=1和https://www.cn ...
- golang使用rabbitMQ入门代码
package main import ( "github.com/streadway/amqp" "log" "time" ) func ...
- vim 版本更新
sudo add-apt-repository ppa:jonathonf/vim sudo apt update sudo apt install vim 如果您想要卸载它, 请使用如下命令 sud ...