k-近邻算法(kNN)完整代码
2024-09-06 02:31:46
from numpy import *#科学计算包
from numpy import tile
from numpy import zeros
import operator #运算符模块
import importlib
import sys
importlib.reload(sys) def createDataSet():
group = array([[1.0,1.1],[1.0,1.0],[0,0],[0,0.1]])
labels = ['A','A','B','B']
return group,labels def classify0(inX, dataSet, labels, k):
dataSetSize = dataSet.shape[0]
#距离计算
diffMat = tile(inX, (dataSetSize,1)) - dataSet
sqDiffMat = diffMat**2 #平方
sqDistances = sqDiffMat.sum(axis=1) #根号下平方相加
distances = sqDistances**0.5 #根号
sortedDistIndicies = distances.argsort() #排序
classCount={}
#选择距离最小的k个点
for i in range(k):
voteIlabel = labels[sortedDistIndicies[i]]
classCount[voteIlabel] = classCount.get(voteIlabel,0) + 1
#排序,将classCount字典分解为元祖列表,导入itemgeeter方法,按照第二个元素的次序对元祖进行排序
#此处排序为逆序,即从大到小排序,最后返回发生频率最高的元素标签。
sortedClassCount = sorted(classCount.items(),key=operator.itemgetter(1),reverse=True)
return sortedClassCount[0][0]
# 为预测数据所在分类:kNN.classify0([0,0], group, labels, 3) # mat()函数可以将数组(array)转化为矩阵(matrix)
# randMat = mat(random.rand(4,4))
# 求逆矩阵:randMat.I
# 存储逆矩阵:invRandMat = randMat.I
# 矩阵乘法:randMat*invRandMat
# 求误差值:myEye = randMat*invRandMat
#myEye - eye(4)
#eye(4)创建4*4的单位矩阵
# 使用createDataSet()函数,创建数据集和标签
# 创建变量group和labels:group,labels = kNN.createDataSet()
# labels包含的元素个数 = group矩阵的行数
# 输入变量名字检验是否正确:group和labels
#
#
# 准备数据:从文本文件中解析数据
# 在kNN.py中创建名为file2matrix的函数,处理输入格式问题
# 该函数的输入为文件名字符串,输出为训练样本矩阵和类标签向量
# 将文本记录到转换Numpy的解析程序
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() #使用line.strip()截取掉所有的回车字符
listFromLine = line.split('\t') #使用tab字符\t将上一步得到的整行数据分割成一个元素列表
returnMat[index,:] = listFromLine[0:3] #选取前三个元素,存储到特征矩阵中
classLabelVector.append(int(listFromLine[-1])) #-1表示列表中的最后一列元素,存储到向量classLabelVector中
index += 1
return returnMat,classLabelVector #准备数据:归一化数值
def autoNorm(dataSet): #autoNorm()函数可以自动将数字特征值转换为0到1的区间
minVals = dataSet.min(0)
maxVals = dataSet.max(0) #ddataSet.max(0)中的参数0使得函数可以从列中选取最小值
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
#newValue = (oldValue-min)/(max-min),该公式可以将任意取值范围的特征值转换为0到1区间内的值
#tile()函数将变量内容复制成输入矩阵同样大小的矩阵(具体特征值相除)
#在numpy库中,矩阵除法需要使用函数linalg.solve(matA,matB)
normDataSet = dataSet - tile(minVals, (m,1))
normDataSet = normDataSet/tile(ranges, (m,1))
return normDataSet, ranges, minVals #测试算法:作为完整程序验证分类器
def datingClassTest():
hoRatio = 0.10 #设置测试集比重,前10%作为测试集,后90%作为训练集
datingDataMat,datingLabels = file2matrix('datingTestSet.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0] #得到样本数量m
numTestVecs = int(m*hoRatio) #得到测试集最后一个样本的位置
errorCount = 0.0 #初始化定义错误个数为0
for i in range(numTestVecs):
#测试集中元素逐一放进分类器测试,k = 3
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],datingLabels[numTestVecs:m],3)
#输出分类结果与实际label
print("the classifier came back with: %d, the real answer is: %d"% (classifierResult, datingLabels[i]))
#若预测结果与实际label不同,则errorCount+1
if (classifierResult !=datingLabels[i]): errorCount += 1.0
#输出错误率 = 错误的个数 / 总样本个数
print("the total error rate is: %f" % (errorCount/float(numTestVecs))) #约会网站预测数据
def classifyPersion():
resultList = ['not at all','in small doses','in large doses']
#input()函数允许用户输入文本行命令并返回用户所输入的命令
percentTats = float(input("percentage of time spent playing video games?"))
ffMiles = float(input("frequent year?"))
iceCream = float(input("liters years?"))
datingDataMat,datingLabels = file2matrix('datingTestSet2.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
inArr = array([ffMiles,percentTats, iceCream])
classifierResult = classify0((inArr-minVals)/ranges,normMat,datingLabels,3)
print("you like person:",resultList[classifierResult - 1]) #准备数据:将图像转换为测试向量
#img2vector函数,将图像转换为向量:该函数创建1*2014的numpy数组,
#然后打开给定的文件,循环读出文件的前32行,并将每行的头32个字符值存储在numpy数组中,最后返回数组
def img2vector(filename):
returnVect = zeros((1,1024))
fr = open(filename)
for i in range(32):
lineStr = fr.readline()
for j in range(32):
returnVect[0,32*i+j] = int(lineStr[j])
return returnVect #测试算法:识别手写数字
def handwritingClassTest():
hwLabels = []
trainingFileList = os.listdir('trainingDigits')
m = len(trainingFileList)
trainingMat = zeros((m,1024))
#文件名下划线_左边的数字是标签
for i in range(m):
fileNameStr = trainingFileList[i]
fileStr = fileNameStr.split(".")[0]
classNumStr = int(fileStr.split('_')[0])
hwLabels.append(classNumStr)
trainingMat[i,:] = img2vector('trainingDigits/%s' % fileNameStr)
testFileList = os.listdir('trainingDigits')
errorCount = 0.0
mTest = len(testFileList)
for i in range(mTest):
fileNameStr = testFileList[i]
fileStr = fileNameStr.split('.')[0] # take off .txt
classNumStr = int(fileStr.split('_')[0])
vectorUnderTest = img2vector('digits/testDigits/%s' % fileNameStr)
classifierResult = classify0(vectorUnderTest, trainingMat, hwLabels, 3)
print("the classifier came back with: %d, the real answer is: %d" % (classifierResult, classNumStr))
if (classifierResult != classNumStr): errorCount += 1.0
print("the total number of errors is: %d" % errorCount)
print("the total error rate is: %f" % (errorCount / float(mTest)))
最新文章
- FragmentPagerAdapter加载fragment并使用setUserVisibleHint()处理预加载时遇到的坑,给textview赋值时出现的空指针异常
- The median of multi ascending array
- BIOS设置教程
- 在FireFox中安装Selenium IDE
- 异步fifo的设计
- PHP访问数据,增删改
- TreeSet介绍
- orm fluentdata使用相关文章
- 获取contenteditable的内容 对html进行处理 兼容 chrome、IE、Firefox
- smarty 中时间格式化的用法
- Win7下unetbootin-windows-585工具制作Ubuntu12.04 U盘启动盘
- AngularJS创建新指令 - 基本功能
- 原生js二级联动
- 《Java从入门到放弃》JavaSE入门篇:面向对象语法一(入门版)
- 前端HTML介绍
- .Net Core小技巧 - 使用Swagger上传文件
- Android技术分享-文字转语音并朗读
- iOS9关键字的简单使用
- 关于想通过ros的dstnat实现公网IP nat 公网IP的情况
- .NET手记-Autofac进阶(传递注册参数 Passing Parameters to Register)
热门文章
- Window 相关命令
- 【大前端攻城狮之路·二】Javascript&;QA⼯程师
- 获取jQuery DataTables 的checked选中行
- 学习ECMAScript标准和具体实现-JavaScript
- 《JAVA设计模式》之观察者模式(Observer)
- composer 版本号前置~与^符号的区别
- k3 cloud移动审批提示实体类型BD_TaxRate中不存在名为AmountDigits属性
- combox系列问题集
- 前端 ----- 初探ES6 Promise
- C# DataTable、实体相互转换