from numpy import *
import operator
import matplotlib
import matplotlib.pyplot as plt
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
#在上面的代码中 我们导入两个模块 第一个科学计算包Numpy 第二个是运算符模块
group,labels=creatDataSet()
print(group)
print(labels)
def classify0(inX,dataSet,labels,k):
#inX是你要输入的要分类的“坐标”,dataSet是上面createDataSet的array,就是已经有的,分类过的坐 标,label是相应分类的标签,k是KNN,k近邻里面的k
dataSetSize=dataSet.shape[0]#Numpy中shape
#dataSetSize是sataSet的行数,用上面的举例就是4行
diffMat=tile(inX,(dataSetSize,1))-dataSet
# 接下来要求inX和训练集dataSet的距离
# tile(inX,(dataSetSize,1))生成一个大小和dataSet一样的矩阵,只不过矩阵每行都是inX,再减去dataSet
#面用tile,把一行inX变成4行一模一样的(tile有重复的功能,dataSetSize是重复4遍,后面的1保证重复完了是4行,而不是一行里有四个一样的),然后再减去dataSet,是为了求两点的距离,先要坐标相减,这个就是坐标相减
sqDiffMat=diffMat**2 #上一行得到了坐标相减,然后这里要(x1-x2)^2,要求乘方
sqDistances=sqDiffMat.sum(axis=1) #axis=1是列相加,,这样得到了(x1-x2)^2+(y1-y2)^2
distances=sqDistances**0.5 #开根号,这个之后才是距离
sortedDistIndicies=distances.argsort() #argsort是排序,将元素按照由小到大的顺序返回下标,比如([3,1,2]),它返回的就是([1,2,0])
classCount={}
for i in range(k):#0,1,2
voteIlabel=labels[sortedDistIndicies[i]]#labels[sortedDistIndicies[0]]距离最小的数据样本的标签
classCount[voteIlabel]=classCount.get(voteIlabel,0)+1 #get是取字典里的元素,如果之前这个voteIlabel是有的,那么就返回字典里这个voteIlabel里的值,如果没有就返回0(后面写的),这行代码的意思就是算离目标点距离最近的k个点的类别,这个点是哪个类别哪个类别就加1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
#key=operator.itemgetter(1)的意思是按照字典里的第一个排序,{A:1,B:2},要按照第1个(AB是第0个),即‘1’‘2’排序。reverse=True是降序排序 items用于返回字典的键值对 key and value
return sortedClassCount[0][0] #返回类别最多的类别
print(classify0([0,0],group,labels,3))
'''
2,当tile(a,(1,1))时
结果是
array([[1, 2]])
tile(a,(1,1)).shape
结果是(1,2),说明是一个1X2的矩阵。
tile(a,(1,2))
结果是
array([[1, 2, 1, 2]])
>>> tile(a,(1,2)).shape
(1, 4)
结果是一个1X4的矩阵,说明tile里参数列表中元组的第二个参数是控制a重复次数的
>>> tile(a,(2,1))
array([[1, 2],
[1, 2]])
>>> tile(a,(2,1)).shape
(2, 2)
######说明参数列表的元组第一个是控制行数的
'''
#约会网站的配对效果
#将文本记录转换为Numpy的array
def file2matrix(filename): #输入为文件名字符串
fr=open(filename) #打开文件
arrayOLines=fr.readlines() #取得该文件的每行数据的列表
numberOfLines=len(arrayOLines) #计算该文件共有多少行(即共有多少个样本)
returnMat=zeros((numberOfLines, 3)) #创建返回的Numpy矩阵
classLabelVector=[]
index=0
for line in arrayOLines: #解析文件数据到列表
line=line.strip() #去掉首尾空白符
listFromLine=line.split('\t') #利用空格符分离字符串
returnMat[index, :]=listFromLine[0:3] #将每行样本数据的前3个数据输入返回样本矩阵中
classLabelVector.append(int(listFromLine[-1])) #将每行样本数据的最后一个数据加入类标签向量中
index+=1
return returnMat, classLabelVector #返回训练样本矩阵和类标签向量
datingDataMat,datingLabels=file2matrix('datingTestSet2.txt')#这里注意有个错误 datingTestSet 就产生错误
print(datingDataMat)
print(datingLabels)
fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*array(datingLabels),15.0*array(datingLabels))
plt.show()
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))
return normDataSet, ranges, minVals
def classifyPerson():
resultList = ['not at all','in small doses','in large doses']
percentTats = float(input("percentage of time spent playing video games?"))
ffMiles = float(input("frequent flier miles earned per year?"))
iceCream = float(input("liters of ice cream consumed per year?"))
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
normMat,ranges,minVals = autoNorm(datingDataMat)
inArr = array([ffMiles,percentTats,iceCream])
classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
#这边减1是由于最后分类的数据是1,2,3对应到数组中是0,1,2
print("You will probably like this person: ",resultList[classifierResult -1])
classifyPerson()
机器学习(一)-----K近邻算法
最新推荐文章于 2024-04-20 19:30:30 发布