KNN分类算法学习——机器学习实战学习
K-近邻算法:
1.计算样本数据集中的点与分类点的距离
2.按距离递增排序数据集中的点
3.选取距离最近的K个近邻点
4.确定前K个点所在类别的出现频率
5.频率最高的类别作为当前点的预测分类
python代码实现:
import numpy
from numpy import *
import operator
def creatDataSet():#创建数据集和标签集
group =array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])#数据集
labels=['A','A','B','B']#与数据集对应的标签集
return group,labels
#k近邻算法分类器
def classify0(inX,dataSet,labels,k):#四个参数:用于分类的输入向量inX,训练样本集dataSet,标签集labels,最近邻居数K
dataSetSize=dataSet.shape[0] #shape方法求训练样本集第一维维度
diffMat=tile(inX,(dataSetSize,1))-dataSet#tile函数将矩阵inX纵向复制dataSet个
sqDiffMat=diffMat**2 #按照欧式空间求距离
sqDistance=sqDiffMat.sum(axis=1)#按行求和
distances=sqDistance**0.5
sortedDistIndicies=distances.argsort()#argsort方法返回的是数组排序后的索引值
classCount={} #字典存储排序后的前K个键值(训练样本集和标签集)
for i in range (k): #找到距离最近的前三个值
voteIlabel=labels[sortedDistIndicies[i]]
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1#get方法返回字典中键对应值,如果没有则进行初始化
sortedClassCount=sorted(classCount.items(),#返回迭代
key=operator.itemgetter(1),
reverse=True)#倒序
return sortedClassCount[0][0]
#改进约会网站的配对效果
#转换文本记录为numpy,将待处理的数据改为分类器可接受的格式
def file2matrix(filename):
fr=open(filename) #open函数打开文件
arrayOLines=fr.readlines()#readlines方法返回list,list中的每个元素是每一行的字符串
numberOfLines=len(arrayOLines)#文件的行数
returnMat=zeros((numberOfLines,3))#zeros函数创建矩阵并初始化为0
classLabelVector=[]#解析文件数据到列表
index=0
for line in arrayOLines:
line=line.strip()#删除字符串头尾指定的字符,默认为空格或者换行符
listFromLine=line.split('\t')#利用分隔符对字符串进行切片
returnMat[index,:]=listFromLine[0:3]#选择前三个元素存在特征矩阵中
classLabelVector.append(int(listFromLine[-1]))
index += 1
return returnMat,classLabelVector
#归一化特征值
#公式:newvalue=(oldvalue-min)/(max-min)
def autoNorm(dataSet):
minVals=dataSet.min(0)#每列的最小值,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))#这里是具体的特征值相除而不是矩阵除法datingDataMat[:,1]
return normDataSet,ranges,minVals
#测试算法定义一个计数器变量,每次分类器错误的分类数据,计数器加1
#错误率=计数的结果/数据点总数
def datingClassTest():
hoRatio=0.10
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')#调用file2matrix函数读取数据
normMat,ranges,minVals=autoNorm(datingDataMat)#调用autoNorm函数归一化数据
m=normMat.shape[0]
numTestVecs=int(m*hoRatio)
errorCount=0.0
for i in range(numTestVecs):
classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],\
datingLabels[numTestVecs:m],3)
print('the classfier came back with :%d,the real anser is :%d'\
%(classifierResult,datingLabels[i]))
if (classifierResult!=datingLabels[i]):
errorCount+=1
print('the total error rate is :%f'%(errorCount/float(numTestVecs)))
#使用分类器具体进行分类
#在约会网站找到某个人并输入他的信息,分类器会给出喜欢程度的预测
def classifyPerson():
resultList=['not at all','in small doses','in large doses']
percentTats=float( input (\
"percentage of time spent playing games?"))
ffMiles=float(input("frequent flier miles earned per year ?"))
iceCream=float(input ("liters of ice cream consumed per year?"))
datingDataMat,datingLabels=file2matrix('datingTestMat')
normMat,ranges,minVals=autoNorm(datingDataMat)
inArr=array([ffMiles,percentTats,iceCream])
classifierResult = classify0((inArr-\
minVals)/ranges,normMat,datingLabels,3)
print ("you will probably like this person :",\
resultList[classifierResult-1])
测试代码:
import kNN
import numpy
from numpy import *
import matplotlib#matplotlib是python的第三方2D绘图库
import matplotlib.pyplot as plt#提供一个类似matlab的绘图框架
group,labels=kNN.creatDataSet()
print(group)
print(labels)
#调用kNN分类器对[0,0]进行分类
print(kNN.classify0([0,0],group,labels,3))
#准备数据:调用kNN中的文件处理函数,对datingTestSet2处理成可以分类器使用的格式
datingDataMat,datingLabels=kNN.file2matrix('datingTestSet2.txt')#对文件进行处理
print(datingDataMat)#查看训练样本集
print(datingLabels[0:20])#查看样本集对应的标签集的前20个标签
# #分析数据:对数据进行图形化,使用datingDataMat矩阵的第二第三列数据
fig = plt.figure()
ax=fig.add_subplot(111)#add_subplot 方法的作用是图像在画板上的第一行第一列从左到右自上到下第一个位置
ax.scatter(datingDataMat[:,0],datingDataMat[:,1],#scatter函数绘制散点图,由样本集矩阵datingDataMat的列数据作为x,y值
15.0 * array(datingLabels), 15.0 * array(datingLabels))#利用datingLabels的类标
# 签属性给散点图绘上了不同颜色,大小的点
plt.show()
#准备数据:归一化数值,因为在计算k近邻距离时数字差值最大的属性对计算结果的影响最大
#处理不同取值范围的特征值时,通常采用将数值归一化的方法,将数值处理到0-1或-1-1之间
normMat,ranges,minVals=kNN.autoNorm(datingDataMat)
print(normMat)
print(ranges)
print(minVals)
#测试分类器
print(kNN.datingClassTest())