这里写目录标题
KNN算法原理
KNN是最简单的分类算法之一,也是最常用的分类算法之一,KNN算法是有监督学习中的分类算法。
knn算法的基本法则是:相同类别的样本之间在特征空间中应当聚集在一起,也就是说当要预测一个新的值x的时候,根据它距离最近的K个点是什么类别来判断x属于哪个类别
如图所示:
图中绿色点为我们要预测的值,当k值等于三时,算法判断离绿色点最近的三个图形中哪一类图形最多就将新预测的点归为哪一类。
当k值改变时,预测的值也将发生变化,如上图所示,当k为5时,预测的值变为红色的圆,因此k值得选择对于knn算法来说非常重要
优点:
- 简单易用,相比其他算法,KNN算是比较简洁明了的算法。即使没有很高的数学基础也能搞清楚它的原理。
- 模型训练时间快。
- 预测效果好。
- 对异常值不敏感。
缺点:
- 对内存要求较高,因为该算法存储了所有训练数据
- 预测阶段可能很慢
- 对不相关的功能和数据规模敏感
案例实现(书上)
电影类别分类
代码
from numpy import *
import operator
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 file2metrix(filename):
fr = open(filename)
arrayOLines = fr.readlines()
numberOfLines = len(arrayOLines)
returnMat = zeros((numberOfLines,3))
classLabelVector = []
index = 0
for line in arrayOLines:
line = line.strip()
listFromLine = line.split('\t')
returnMat[index,:] = listFromLine[0:3]
classLabelVector.append(listFromLine[-1])
index += 1
return returnMat,classLabelVector
源码(分类器)
def datingClassTest():
hoRatio = 0.50
datingDataMat,datingLabels = file2metrix('datingTestSet.txt')
normMat, ranges, minVals = autoNorm(datingDataMat)
m = normMat.shape[0]
numTestVecs = int(m*hoRatio)
errorCount = 0.0
for i in range(numTestVecs):
classifierResult = classify0(normMat[i,:],normMat[numTestVecs:m,:],\
datingLabels[numTestVecs:m],3)
print ("the classifier came back with: %s, the real answer is: %s" \
% (classifierResult, datingLabels[i]))
if (classifierResult != datingLabels[i]): errorCount += 1.0
print( "the total error rate is: %f" % (errorCount/float(numTestVecs)))
结果
错误及解决方法
将 classLabelVector.append(int(listFromLine[-1]))
改为classLabelVector.append(listFromLine[-1])
可视化
源码
import knn
datingDataMat,datingLabels = knn.file2metrix('datingTestSet.txt')
import matplotlib.pyplot as plt
fig = plt.figure()
ax = fig.add_subplot(111)
ax.scatter(datingDataMat[:,1],datingDataMat[:,2])
<matplotlib.collections.PathCollection object at 0x0000017CCD9459A0>
plt.show()
结果
错误
输入import matplotlib
时出现以下错误
直接在设置中添加改包解决
出现找不到array
的错误
添加from numpy import *
后出现numpy.core._exceptions._UFuncNoLoopError: ufunc 'multiply' did not contain a loop with signature matching types (dtype('float64'), dtype('<U10')) -> None
错误
归一化
源码
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
ranges = maxVals - minVals
normDataSet = zeros(shape(dataSet))
m = dataSet.shape[0]
normDataSet = dataSet - tile(minVals, (m,1))
normDataSet = normDataSet/tile(ranges, (m,1)) #element wise divide
return normDataSet, ranges, minVals
结果
手写体识别
见博客一
案例实现(课外)
根据身高、体重、鞋子尺码,预测性别
import numpy as np
import pandas as pd
from pandas import DataFrame,Series
feature = np.array([[170,65,41],[166,55,38],[177,80,39],[179,80,43],[170,60,40],[170,60,38]])
target = np.array(['男','女','女','男','女','女'])
from sklearn.neighbors import KNeighborsClassifier #k邻近算法模型
#实例k邻近模型,指定k值=3
knn = KNeighborsClassifier(n_neighbors=3)
#训练数据
knn.fit(feature,target)
#模型评分
knn.score(feature,target)
#预测
knn.predict(np.array([[176,71,38]]))
print('预测分类:', knn.predict(np.array([[176,71,38]])))