KNN分类器
监督学习
knn:通过样本和样本之间的距离来进行分类
样本属于临近样本中大多数样本的归属类
- 1.基于python 设计knn分类器
- 2.数据获取:txt、csv、xlsx
- 3.测试算法
- 4.使用算法
注: 若是各特征之间的数据级差距过大,将会影响分类效果,所以分类之前要进行数据处理
1. knn核心算法(python)
## knn.py
import numpy as np
import operator
def knn(X, dataSet, label, k):
## 分类器:knn分类算法的python实现
## X:一待分类样本的特征集;dataSet:模型的训练集;k:k类
diff = np.tile(X, (dataSet.shape[0], 1)) - dataSet
d = (diff**2).sum(axis=1)**0.5
sortd1 = d.argsort()
classCount = {}
for i in range(k):
votell = label[sortd1[i]]
classCount[votell] = classCount.get(votell, 0)+1
sortedClassCount = sorted(classCount.items(), key=operator.itemgetter(1), reverse=True)
return sortedClassCount[0][0]
2. 数据归一化
## normalization.py
import numpy as np
def normalization(dataSet):
## 归一化
minValues = dataSet.min(0)
maxValues = dataSet.max(0)
max_min = maxValues - minValues
normalizationDataSet = dataSet-np.tile(minValues,(dataSet.shape[0],1))
normalizationDataSet = normalizationDataSet/np.tile(max_min,(dataSet.shape[0],1))
return normalizationDataSet,minValues,max_min
3. 读取txt文件
## open_file.py
import numpy as np
def str_float(value):
# 列表中字符串转化浮点数(读取txt文本可能存在空行,自定义避免报错)
try:
return float(value)
except:
return None
def open_file(filename):
# 读取txt文件 返回分类特征集和类别集
fr = open(filename, encoding='utf-8')
arrayOLines = fr.readlines()
numberOfLines = len(arrayOLines)
returnMat = np.zeros((numberOfLines, 3)) # 创建一个行*3的0矩阵
classLabelVector = []
index = 0
for line in arrayOLines:
line = line.strip() # 去除每一行的空格或换行符
listFromLine = line.split("\t") # 按照回车分割每一行为每一个数组
returnMat[index, :] = list(map(str_float, listFromLine[0:3])) # 把每一行数据添加到之前创建的0矩阵之中
classLabelVector.append((listFromLine[-1]))
index += 1
for label in range(len(classLabelVector)):
if (classLabelVector[label] == '种类a'):
classLabelVector[label] = 1
elif (classLabelVector[label] == '种类b'):
classLabelVector[label] = 2
elif (classLabelVector[label] == '种类c'):
classLabelVector[label] = 3
return returnMat, classLabelVector
4. 运行 测试knn算法
import sys
sys.path.append(r"E:\daima\pythonexpert\algorithm")
import normalization
import knn
import open_file
def datingClassTest():
## 测试knn算法准确率
hoRatio = 0.3 #测试集占数据集比例
sys.path.append(r"C:\Users\myname\Desktop\学习\算法代码\算法数据")
datingDataMat,datingLabels = knn_cs.open_file("knn.txt") ##调用读取文件的方法
normMat =normalization.normalization(datingDataMat) ## 调用标准化方法
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifierResult = knn.knn(normMat[i,:], normMat[numTestVecs:m,:], datingLabels[numTestVecs:m],3)
print( "分类器:%d, 实际:%d" %(classifierResult,datingLabels[i]))
if(classifierResult!=datingLabels[i]) :
errorCount += 1.0
print( "错误率是%f" %(errorCount/float(numTestVecs)))
datingClassTest()
分类器:3, 实际:3
分类器:3, 实际:2
分类器:1, 实际:1
错误率是0.333333
4. 运行 使用knn算法
import sys
sys.path.append(r"E:\daima\pythonexpert\algorithm")
import normalization
import knn
import open_file
def classifyPerson():
## 使用knn分类器
resultList = ["种类a", "种类b", "种类c"]
t1 = float(input("特征1:"))
t2 = float(input("特征2:"))
t3 = float(input("特征3:"))
datingDataMat, datingLabels = open_file.open_file("knn.txt")
normMat, minValues, max_min =normalization.normalization(datingDataMat)
inArr = np.array([t1, t2, t3])
inarr=(inArr-minValues)/max_min
classifierResult = knn.knn(inarr, normMat, datingLabels, 3)
print("样本为:%s"%(resultList[classifierResult-1]))
classifyPerson()
特征1:40920
特征2:8
特征3:1
样本为:种类c