机器学习实战学习笔记(一)分类—kNN算法(python3实现)
来源:互联网 发布:java office转换成pdf 编辑:程序博客网 时间:2024/06/06 02:56
概述
算法采用测量不同特征值之间的距离的方法进行分类。优点是该算法精度高、对异常值不敏感,无数据输入的各种假定;缺点是计算复杂度和空间复杂度都比较高。算法适用的数据类型主要是数值型和标称型。
工作原理
存在一个样本数据集合,也称训练样本集,样本集中的数据都存在标签。在输入没有标签的新数据后,将新数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本集中特征最相似数据的分类标签。一般来说我们选择样本数据集中前k个最相似的数据。从k个最相似数据中出现次数最多的分类,作为新数据的分类。算法基本流程
a. 计算已知类别数据集中的点与当前点之间的距离
b. 按照距离递增次序排序
c. 选取与当前点距离最小的k个点
d. 确定前k个点所在类别的出现频率
e. 返回前k个点出现频率最高的类别作为当前点的预测分类贴上核心代码
"""kNN核心分类器输入inX:用于分类的输入向量dataSet:训练集labels:类别标签向量k:选择邻居的个数"""def classify0(inX,dataSet,labels,k): #得到训练集的第一纬度的长度(有几行) dataSetSize=dataSet.shape[0] #得到特征值之间的差,计算欧式距离 #将输入向量沿行扩展得到差矩阵 diffMat=np.tile(inX,(dataSetSize,1))-dataSet #差矩阵各个元素乘二次方 sqDiffMat=diffMat**2 #求每一行元素的和并开方得到欧式距离矩阵 sqDistances=sqDiffMat.sum(axis=1) distances=sqDistances**0.5 #将欧氏距离排序,argsort返回数组值从小到大的索引值 sortedDistIndicies=distances.argsort() #得到前k个中出现次数最多的类别标签 classCount={} for i in range(k): voteLabel=labels[sortedDistIndicies[i]] #给不同的voteLabel计数 classCount[voteLabel]=classCount.get(voteLabel,0)+1 #sorted第一个参数是一个迭代器,对于字典排序,返回结果是一个元素为元组的列表 #operator模块提供的itemgetter函数用于获取对象的哪些维的数据 sortedClassCount=sorted(classCount.items(), key=operator.itemgetter(1),reverse=True) #返回出现次数最多的voteLabel return sortedClassCount[0][0]
示例:使用kNN改进约会网站配对效果
分析并处理数据集
样本数据中主要包含三个不同的特征,每年获得的飞行常客里程数,玩视频游戏所耗时间的百分比,每周消费的冰激凌公升数以及标签信息,我们通下面的函数将文本信息转换为python可以分析处理的训练样本矩阵和类标签向量,代码如下“"""文本数据转换为矩阵数据输入:文件路径输出:训练样本矩阵和类标签向量"""def file2matrix(filename): fr=open(filename) #得到样本数据的行数 arrayOfLines=fr.readlines() numberOfLines=len(arrayOfLines) #初始化一个0矩阵用于存放样本数据 returnMat=np.zeros((numberOfLines,3)) #定义一个向量用于存放标签 classLabelVector=[] index=0 #解析数据到矩阵和向量中去 for line in arrayOfLines: #删除开头和结尾的空白符(包括回车,回车换行和制表符) line=line.strip() #根据制表符切割每一行的数据 listFromLine=line.split('\t') #将列表写到矩阵中 returnMat[index,:]=listFromLine[0:3] #每一行最后一个是标签 classLabelVector.append(int(listFromLine[-1])) #到下一行 index+=1 return returnMat,classLabelVector
归一化数值
我们计算的距离的时候,要求每个特征对结果的影响的贡献权值接近,然而飞行里程数远大于另外两个特征,导致其对结果的贡献权值更大,我们利用下述公式处理三个特征值:
NewValue=(oleValue-min)/(max-min)
这样我们将数据转换到了0和1之间,代码如下:
"""归一化特征值输入:原始特征矩阵输出:元素值属于[0,1]区间的新的特征矩阵"""def autoNorm(dataSet): #从列选取最值 minVals=dataSet.min(0) maxVals=dataSet.max(0) ranges=maxVals-minVals #初始化一个0矩阵 normDataSet=np.zeros(np.shape(dataSet)) #列数 m=dataSet.shape[0] normDataSet=dataSet-np.tile(minVals,(m,1)) normDataSet=normDataSet/np.tile(ranges,(m,1)) return normDataSet,ranges,minVals
测试
我们将数据经过上述出来后,计算测试向量的数量,将数据分为测试集合训练集两部分,将其输入到上面的kNN核心分类器中,计算错误率并返回结果,代码如下:
"""测试代码"""def dataingTest(): hoRatio=0.10 datingSet,datainglabels=file2matrix("datingTestSet2.txt") normMat,ranges,minVals=autoNorm((datingSet)) m=normMat.shape[0] numTestVecs=int(m*hoRatio) errorCount=0.0 for i in range(numTestVecs): classifierResult=classify0(normMat[i,:],normMat[numTestVecs:m,:],datainglabels[numTestVecs:m],3) print("result is %d, answer is %d"%(classifierResult,datainglabels[i])) if(classifierResult!=datainglabels[i]): errorCount+=1.0 print("error rate is %f"%(errorCount/float(numTestVecs)))
然后我们可以写一个主函数,允许用户自己输入三个特征值来进行判断,本文略去
小结
优点:
1.简单好用,容易理解,精度高,理论成熟,既可以用来做分类也可以用来做回归;
2.可用于数值型数据和离散型数据;
3.训练时间复杂度为O(n);无数据输入假定;
4.对异常值不敏感
缺点:
1.计算复杂性高;空间复杂性高;
2.样本不平衡问题(即有些类别的样本数量很多,而其它样本的数量很少;
3.一般数值很大的时候不用这个,计算量太大。但是单个样本又不能太少 否则容易发生误分。
4.最大的缺点是无法给出数据的内在含义。
所以笔者认为在数据明确而且相对适中的时候,kNN算法进行分类效果很好
学习资料github链接- 机器学习实战学习笔记(一)分类—kNN算法(python3实现)
- 机器学习实战 笔记一:kNN分类算法
- 《机器学习实战》学习笔记——K-近邻算法(KNN)(一)分类器的简单实现
- 机器学习实战学习笔记(二)分类—ID3决策树算法(python3实现)
- 机器学习实战—笔记-kNN算法
- Python机器学习实战kNN分类算法
- 机器学习实战读书笔记-kNN分类算法
- 机器学习实战学习笔记(六)分类—利用AdaBoost元算法提高分类性能(python3实现)
- 《机器学习实战》——KNN分类算法
- 机器学习实战学习笔记-KNN算法
- 《机器学习实战》(一)knn算法
- 【机器学习实战-kNN:约会网站约友分类】python3实现-书本知识【2】
- 《机器学习实战》学习笔记——kNN算法
- 机器学习实战学习笔记1——KNN算法
- 机器学习实战--KNN 算法 笔记
- 机器学习实战笔记(一):KNN
- 机器学习实战学习笔记(三)分类—朴素贝叶斯(python3实现)
- 机器学习实战学习笔记(四)分类—Logistic回归(python3实现)
- jquery each中包含switch标签判断错误跳过each循环
- Target-specific Variable Values
- 大整数类模版(部分)
- Leetcode654. Maximum Binary Tree
- CodeForces
- 机器学习实战学习笔记(一)分类—kNN算法(python3实现)
- 利用集合模拟斗地主(2)
- Type interface com.mybatis.mapper.StudentMapper is not known to the MapperRegistry
- 你必须知道的261个Java语言问题笔记- Java流和文件操作2
- Linux 出现-bash: grunt: command not found 错误解决
- mysql5.7安装之后,mysqladmin无法设置root密码
- Codeforces Round #408 Div.2 A B C D
- js中的事件onchange案例
- Hadoop(4-2)-MapReduce程序案例-WordCount(Intellij Idea环境)