目录
一、准备数据:从文本文件中解析数据
1、首先下载数据集
本实例数据库是从sklearn库中下载下来的
2、读取数据
def file2matrix(filename):
fr = open(filename)
#读取文件所有内容
arrayOLines = fr.readlines()
#得到文件行数
numberOfLines = len(arrayOLines)
#返回的NumPy矩阵,解析完成的数据:numberOfLines行,3列
returnMat = np.zeros((numberOfLines,13))
#返回的分类标签向量
classLabelVector = []
#行的索引值
index = 0
for line in arrayOLines:
#s.strip(rm),当rm空时,默认删除空白符(包括'\n','\r','\t',' ')
line = line.strip()
#使用s.split(str="",num=string,cout(str))将字符串根据'\t'分隔符进行切片。
listFromLine = line.split('\t')
#将数据前三列提取出来,存放到returnMat的NumPy矩阵中,也就是特征矩阵
returnMat[index,:] = listFromLine[0:13]
if listFromLine[-1] == '0':
classLabelVector.append(0)
elif listFromLine[-1] == '1':
classLabelVector.append(1)
elif listFromLine[-1] == '2':
classLabelVector.append(2)
index += 1
return returnMat, classLabelVector
filename = 'C:\\Users\\87578\\Desktop\\机器学习\\KNNCPQ\\wine.txt'
datingDataMat, datingLabels = file2matrix(filename)
二、实施KNN分类算法
该分类算法采用的是欧几里得算法,计算两点之间的距离,选择距离最小的K个点然后返回分类结果。
def classify(inx,datingDataMat,datingLabels,k):
dataSetSize = datingDataMat.shape[0] #算出训练集的行数
distance = (((np.tile(inx,(dataSetSize,1)) - datingDataMat)**2).sum(axis=1))**0.5 #np.tile复制成跟训练集一样的形状,与训练集作差求出差值,然后平方相加开根号,欧几里得算出x与各个训练集中的点的距离
sortedDistIndices = distance.argsort()#用argsort对得出来得距离进行排序,返回的是数组值从小到大的索引值不会改变distance数组。
count = {}#用来记录K范围内各个类别的次数
for i in range(k):
label = datingLabels[sortedDistIndices[i]]#sortedDistIndices[i]取出的是该元素的索引值
count[label] = count.get(label,0)+1
#key=operator.itemgetter(1)根据字典的值进行排序,key=operator.itemgetter(0)根据字典的键进行排序
#reverse降序排序字典
sortedCount = sorted(count.items(),key=operator.itemgetter(1),reverse=True)
return sortedCount[0][0]
三、归一化数值
归一化主要的作用是防止有些特征差值过大,这些特征对计算结果的影响最大,导致结果不准确,而我们普遍认为每个特征都应该是同等重要的。为了避免这种情况,我们通常采用的方法是将数据归一化,将任意取值范围的特征值转化为0到1区间内的值。
def autoNorm(dataSet):
minVals = dataSet.min(0)#获得数据最小值
maxVals = dataSet.max(0)#获得数据最大值
ranges = maxVals - minVals#算出最大最小值范围
normDataSet = np.zeros(np.shape(dataSet))#返回dataSet的行数,并构造对应的值为0的矩阵
m = dataSet.shape[0]
normDataSet = dataSet - np.tile(minVals, (m, 1))#用原始的值减去最小值
normDataSet = normDataSet / np.tile(ranges, (m, 1))#除以最大和最小值的差,得到归一化数据
return normDataSet, ranges, minVals#返回归一化数据结果,数据范围和最小值
四、测试分类器
因为该数据集只有一百多个样例,所以这边选择取出数据的百分之三十
def datingClassTest(datingDataMat,datingLabels):
hoRatio = 0.3#取出所有数据的百分之三十
normMat,ranges,minVals = autoNorm(datingDataMat)#数据归一化,返回归一化后的矩阵、数据范围、数据最小值
m = normMat.shape[0]
numTestVecs = int(m * hoRatio)#百分之三十测试数据的个数
errorCount = 0.0#分类错误计数
for i in range(numTestVecs):
classfierResult = classify(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],5)
print("the classifier came back with:%d \t the real answer is:%d" % (classfierResult,datingLabels[i]))
if(classfierResult!=datingLabels[i]):
errorCount +=1.0
print("the total error rate is:%f%%" % (errorCount/float(numTestVecs)*100))
五、使用算法构建完整使用系统
def classifyPerson():
#输出结果
resultList = ['0','1','2']
#十三维特征用户输入
Alcohol = float(input("酒精:"))
MalicAcid = float(input("苹果酸:"))
Ash = float(input("灰:"))
AlcalinityOfAsh = float(input("灰分的碱度:"))
Mg = float(input("镁:"))
TotalPhenols = float(input("总酚:"))
Flavanoids = float(input("黄酮类化合物:"))
NonflavanoidPhenols = float(input("非黄烷类酚类:"))
Proanthocyanins = float(input("原花色素:"))
ColorIntensity = float(input("颜色强度"))
Hue = float(input("色调"))
ofdilutedwines = print(input("稀释葡萄酒的02800D315:"))
Proline = print(input("脯氨酸:"))
#打开的文件名
filename = 'C:\\Users\\87578\\Desktop\\机器学习\\KNNCPQ\\wine.txt'
#打开并处理数据
datingDataMat, datingLabels = file2matrix(filename)
#训练集归一化
normMat, ranges, minVals = autoNorm(datingDataMat)
inArr = np.array([Alcohol, MalicAcid, Ash,AlcalinityOfAsh,Mg,TotalPhenols,Flavanoids,NonflavanoidPhenols,Proanthocyanins,
ColorIntensity,Hue,ofdilutedwines,Proline])
#测试集归一化
norminArr = (inArr - minVals) / ranges
#返回分类结果
classifierResult = classify(norminArr, normMat, datingLabels, 3)
#打印结果
print("该酒是:" % (resultList[classifierResult-1]))
classifyPerson()
输入13.2 3.3 2.2 18.4 97 1.78 0.83 0.6 1.88 10.5 0.54 1.5 672测试数据
输出2 测试成功