考研对信息的获取至关重要,此公众号会发表计算机考研(初复试信息)、夏令营等资料,方便考研人对信息的获取,节约自身查找资料的时间
1.KNN算法
import numpy as np
import operator
def createDataset():
group=np.array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]]);
labels = ['A','A','B','B'];
return group,labels;
#knn
def classify0(inX, dataSet, labels, k):
"""
inX:用于分类的输入向量
dataSet:输入的训练样本集
lables:标签向量
k:表示用于选择最近邻居的数目
预测数据所在分类可在输入下列命令
kNN.classify0([0,0], group, labels, 3)
"""
# array的shape函数返回指定维度的大小,如dataset为n*m的矩阵,
# 则dataset.shape[0]返回n,dataset.shape[1]返回m,dataset.shape返回n,m
dataSetSize = dataSet.shape[0]
# tile函数简单的理解,它的功能是重复某个数组。比如tile(A,n),功能是将数组A重复n次,构成一个新的数组
# 所以此处tile(inX,(dataSetSize,1))的作用是将inX重复复制dataSetSize次,以便与训练样本集的样本个数一致
# 减去dataSet就是求出其差值,所以diffMat为一个差值矩阵
diffmat = np.tile(inX, (dataSetSize, 1)) - dataSet
# 距离度量,度量公式为欧氏距离,每行的分量计算平方
sqdiffmat = diffmat ** 2
# 将矩阵的每一行相加,axis用于控制是行相加还是列相加,axis=0为列相加
sqdistances = sqdiffmat.sum(axis=1)
# 开方
distances = sqdistances ** 0.5
# 根据距离排序从小到大的排序,返回对应的索引位置
'''
numpy.argsort(a, axis=-1, kind=’quicksort’, order = None)
返回的是数组值从小到大的索引值
参数:
a为要排序的数组
axis:按哪一维进行排序
kind:排序算法的选择,有quicksort,mergesort,heapsort对于一维数组
'''
sortedDistIndicies = distances.argsort()
# 选择距离最小的k个点
classcount = {}
for i in range(k):
# 找到该样本标签的类型
voteIlabel = labels[sortedDistIndicies[i]]
# 字典的get方法,list.get(k,d) 其中 get相当于一条if...else...语句,参数k在字典中,字典将返回list[k];如果参数k不在字典中则返回参数d
classcount[voteIlabel] = classcount.get(voteIlabel, 0) + 1
# 字典的 items() 方法,以列表返回可遍历的(键,值)元组数组。
# sorted 中的第2个参数 key=operator.itemgetter(1) 这个参数的意思是先比较第几个元素
sortedClasscount = sorted(classcount.items(), key=operator.itemgetter(1), reverse=True)
# 返回最符合的标签
return sortedClasscount[0][0]
if __name__ == '__main__':
#创建数据集
group, labels = createDataset()
#测试集
test = [0,0]
#kNN分类
test_class = classify0(test, group, labels, 3)
#打印分类结果
print(test_class)
2.准备数据:从文本文件中解析数据
def file2matrix(filename):
#打开文件
fr = open(filename)
#print(fr)
#读取文件所有内容:['40920\t8.326976\t0.953952\tlargeDoses\n', '14488\t7.153469\t1.673904\tsmallDoses\n',......
arrayOLines = fr.readlines()
#print(arrayOLines)
#得到文件行数
numberOfLines = len(arrayOLines)
#返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列
'''
np.zeros函数的作用
返回来一个给定形状和类型的用0填充的数组;
zeros(shape, dtype=float, order=‘C’)
shape:形状
dtype:数据类型,可选参数,默认numpy.float64
order:可选参数,c代表与c语言类似,行优先;F代表列优先
'''
returnMat = np.zeros((numberOfLines,3))
#返回的分类标签向量
classLabelVector = []
#行的索引值
index = 0
for line in arrayOLines:
#s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ')
'''
Python strip() 方法用于移除字符串头尾指定的字符(默认为空格或换行符)或字符序列。
注意:该方法只能删除开头或是结尾的字符,不能删除中间部分的字符。
'''
line = line.strip()
#使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。
#str -- 分隔符,默认为所有的空字符,包括空格、换行(\n)、制表符(\t)等。
#num -- 分割次数。默认为 -1, 即分隔所有。
listFromLine = line.split('\t')
#将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵
returnMat[index,:] = listFromLine[0:3]
#根据文本中标记的喜欢的程度进行分类,1代表不喜欢,2代表魅力一般,3代表极具魅力
if listFromLine[-1] == 'didntLike':
classLabelVector.append(1)
elif listFromLine[-1] == 'smallDoses':
classLabelVector.append(2)
elif listFromLine[-1] == 'largeDoses':
classLabelVector.append(3)
index += 1
return returnMat, classLabelVector
3.分析数据:使用Matplotlib创建散点图
import matplotlib.pyplot as plt
from KNN.约会网站实例 import kNN2
import numpy as np
datingDataMat,datingLabels= kNN2.file2matrix('datingTestSet.txt')
fig=plt.figure()#figure() 函数会产生一个指定编号为 num 的图:plt.figure(num)这里,figure(1) 其实是可以省略的,因为默认情况下 plt 会自动产生一幅图像。
ax=fig.add_subplot(1,1,1)
#分别取第2列和第三列的全部元素,需记住这种写法.scatter()绘制散点图
ax.scatter(datingDataMat[:,1],datingDataMat[:,2],15.0*np.array(datingLabels),15.0*np.array(datingLabels))
plt.show()
4.准备数据:归一化数值
#归一化特征。由于特征值的取值范围差别很大,我们认为每个特征应该同等重要,所以要做归一化操作
def autoNorm(dataSet):
if __name__ == '__main__':
minVal=dataSet.min(0)#数组,将每列的最小值放到minVal中
#print(minVal)
maxVal=dataSet.max(0)
ranges=maxVal-minVal
normDataSet=np.zeros(np.shape(dataSet))
m=dataSet.shape[0]
#print(np.tile(minVal,(m,1)))
normDataSet=dataSet-np.tile(minVal,(m,1))#tile(minVals, (m,1)) 的功能是将数组 minVals 按(m,1)数组的维度叠加(即叠加m行,1列)。
normDataSet=normDataSet/np.tile(ranges,(m,1))
return normDataSet,ranges,minVal
5.测试算法:算法评估,验证分类器效果
'''测试算法分类器'''
def datingclassTest():
hoRatio = 0.10 #拿样本10%的数据测试
datingDataMat,datingLabels = file2matrix('datingTestSet.txt')
normMat,ranges,minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)#测试数据量
errorCount = 0.0
for i in range(numTestVecs):
'''normMat[i,:],normMat[numTestVecs:m,:] 前10%作为测试集,后m-numtestvecs个作为训练集'''
classifierResult = kNN.classify0(normMat[i,:],normMat[numTestVecs:m,:],
datingLabels[numTestVecs:m],3)
print('the classifier came back with: %d,the real answer is: %d'\
%(classifierResult,datingLabels[i]))
if(classifierResult !=datingLabels[i]):
errorCount += 1.0
print('the total error rate is: %f'%(errorCount/float(numTestVecs)))
print(errorCount)
6.使用算法:构建完整程序,用户输入数据进行分类判断
'''约会预测函数'''
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('datingTestSet.txt')
normMat,ranges,minVals = autoNorm(datingDataMat)
inArr = np.array([ffMiles,percentTats,iceCream])#测试数组
#对输入的数据做归一化
classifierResult = kNN.classify0((inArr-minVals)/ranges,normMat,datingLabels,4)
print('You will probably like this person:',resultList[classifierResult - 1])