1 分类基本思想
1.1 引入例子
import matplotlib.pyplot as plt
fight=(3,2,1,101,99,98,18)
kiss=(104,100,81,10,5,2,90)
filmtype=(1,1,1,2,2,2,3) # 电影类型,爱情片用1表示,动作片2表示,未知类型用3 表示
plt.scatter(fight,kiss,c=filmtype)# scatter绘制散点图,c颜色,分别区分三种类型电影的颜色
1.2 分类概念
分类核心思想就是相似;
人以群分,物以类聚;
出现黑豆里的是黑豆概率比较大,同样出现在绿豆里的是绿豆的概率比较大;
2 KNN算法基本原理
2.1 最近邻算法 (NN)
距离,距离谁近,就大概属于谁;
最近邻算法——KNN,K近邻
2.2 K近邻算法思想
2.3 KNN算法步骤
2.4 KNN算法中的K
3 KNN算法实战
3.1 示例分析算法步骤
3.2 KNN程序 分步实现
mport numpy as np
import matplotlib.pyplot as plt
# 训练集,删去未知点(18,90)
fight=(3,2,1,101,99,98)
kiss=(104,100,81,10,5,2)
filmtype=(1,1,1,2,2,2) # 电影类型,爱情片用1表示,动作片2表示
plt.scatter(fight,kiss,c=filmtype)# c颜色,分别区分三种类型电影的颜色
x=np.array([fight,kiss]) #训练集,
x=x.T
y=np.array(filmtype)# 输出
print(x)
print(y)
这里的X,y表示一致样本x,未知样本y
距离及排序
xx=np.array([18,90])
dis=(((x-xx)**2).sum(1))**0.5
print(dis)
sortedDis=dis.argsort()#得到的是,索引排序
print(sortedDis)
k=4
classCount={}#建立一个空字典,存储电影类型出现的次数
for i in range(k):
votelabel=y[sortedDis[i]]#filmtype的类型y,作为投票标签;通过y的索引值 (排序的索引当作Y的索引),统计filmtype的类型
classCount[votelabel]=classCount.get(votelabel,0)+1 #原来的结果从0开始,每次在对应的类型统计上加1
print(classCount)
电影类型1被统计3次,类型2 被统计1次
maxType=0
maxCount=-1
for key ,value in classCount.items():
if value >maxCount:
maxType=key
maxCount=value
print(‘output’,maxType)
3.3 完整程序
import numpy as np
import matplotlib.pyplot as plt
# 1. 构建数据集
# 训练集,删去未知点(18,90)
fight=(3,2,1,101,99,98)
kiss=(104,100,81,10,5,2)
filmtype=(1,1,1,2,2,2) # 电影类型,爱情片用1表示,动作片2表示
plt.scatter(fight,kiss,c=filmtype)# c颜色,分别区分三种类型电影的颜色
x=np.array([fight,kiss]) #训练集,
x=x.T
y=np.array(filmtype)# 输出
print(x)
print(y)
# 2. 计算未知样本和每个训练集样本的距离
xx=np.array([18,90])
dis=(((x-xx)**2).sum(1))**0.5
print(dis)
# 3. 将距离升序排序
sortedDis=dis.argsort()#得到的是,索引排序
print(sortedDis)
# 4. 选取距未知样本最近的k个点,统计前k个点所在类别出现的次数
k=4
classCount={}#建立一个空字典,存储电影类型出现的次数
for i in range(k):
votelabel=y[sortedDis[i]]#filmtype的类型y,作为投票标签;通过y的索引值 (排序的索引当作Y的索引),统计filmtype的类型
classCount[votelabel]=classCount.get(votelabel,0)+1 #原来的结果从0开始,每次在对应的类型统计上加1
print(classCount)
# 5. 多数表决,输出结果
maxType=0
maxCount=-1
for key ,value in classCount.items():
if value >maxCount:
maxType=key
maxCount=value
print('output',maxType)
3.4 封装KNN函数
封装KNN函数
import numpy as np
def knn(inX,dataSet,labels,k):
# 计算未知样本和每个训练集样本的距离
dis=(((dataSet-inX)**2).sum(1))**0.5
sortedDis=dis.argsort() #将距离升序排序 ;得到的是,索引排序
#选取距未知样本最近的k个点,统计前k个点所在类别出现的次数
classCount={}#建立一个空字典,存储电影类型出现的次数
for i in range(k):
votelabel=labels[sortedDis[i]]#filmtype的类型labels作为投票标签;通过labels的索引值 (排序的索引当作labels的索引),统计filmtype的类型
classCount[votelabel]=classCount.get(votelabel,0)+1 #原来的结果从0开始,每次在对应的类型统计上加1
# 多数表决投票
maxType=0
maxCount=-1
for key ,value in classCount.items():
if value >maxCount:
maxType=key
maxCount=value
return maxType
调用KNN函数
import numpy as np
import matplotlib.pyplot as plt
import knn as K
# 1. 构建数据集
# 训练集,删去未知点(18,90)
fight=(3,2,1,101,99,98)
kiss=(104,100,81,10,5,2)
filmtype=(1,1,1,2,2,2) # 电影类型,爱情片用1表示,动作片2表示
plt.scatter(fight,kiss,c=filmtype)# c颜色,分别区分三种类型电影的颜色
x=np.array([fight,kiss]) #训练集,
x=x.T
y=np.array(filmtype)# 输出
print(x)
print(y)
# 2. 计算未知样本和每个训练集样本的距离
xx=np.array([18,90])
# 3.调用knn函数
type=K.knn(xx,x,y,4)
print('output',type)
4 实战案例
4.1 读取数据
def file2matrix(filename):
fr = open(filename)
numberOfLines = len(fr.readlines())
returnMat = np.zeros((numberOfLines,3))
classLabelVector = [] # 创建空的向量存放分类标签
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip() #删除每行头尾的空白字符
listFromLine = line.split('\t') # 每行的四个元素是以tab分开的,进行切片
returnMat[index,:] = listFromLine[0:3] #将前三列存储在Mat矩阵中
if listFromLine[-1] == 'didntLike':
classLabelVector.append(1)
elif listFromLine[-1] == 'smallDoses':
classLabelVector.append(2)
elif listFromLine[-1] == 'largeDoses':
classLabelVector.append(3)
index += 1
return returnMat,classLabelVector
datingDataMat,datingLabels = file2matrix('datingTestSet.txt')
print(datingDataMat)
print(datingLabels)
4.2 分析数据
里程数和游戏,数据特征
plt.scatter(datingDataMat[:,0],datingDataMat[:,1],c=datingLabels) # 第一列里程和第二列打游戏,散点图,用不同颜色标记三种标签
plt.show()
里程数和吃冰淇凌,数据特征
plt.scatter(datingDataMat[:,0],datingDataMat[:,2],c=datingLabels)
plt.show()
打游戏和吃冰淇凌,数据特征
plt.scatter(datingDataMat[:,1],datingDataMat[:,2],c=datingLabels)
plt.show()
4.3 数据归一化处理
# 数据归一化
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
normDataSet = np.zeros(dataSet.shape)
normDataSet = (dataSet-minVals)/(maxVals-minVals)
return normDataSet
datingDataMat,datingLabels = file2matrix('datingTestSet.txt')
dataSet=autoNorm(datingDataMat)
print(dataSet)
4.4 测试KNN分类器模型
#分类器模型训练集 测试集
m = 0.8 #设置训练集的比例
dataSize = dataSet.shape[0] #取数据的全部行
trainSize = int(m*dataSize)
testSize = int((1-m)*dataSize)+1 # 199.9999python向下取整,199,故加1
print('数据总行数 :',dataSize,' 训练集 :',trainSize,' 测试集 :',testSize)
k=5
result=[]
error=0
for i in range(testSize):
result=K.knn(dataSet[trainSize+i,:],dataSet[:trainSize,:],datingLabels[:trainSize],k)
if result != datingLabels[trainSize+i]:
error=+1
print('错误率 :',error/testSize)
4.5 完整程序
KNN 函数
def knn(inX,dataSet,labels,k):
# 计算未知样本和每个训练集样本的距离
dis=(((dataSet-inX)**2).sum(1))**0.5
sortedDis=dis.argsort() #将距离升序排序 ;得到的是,索引排序
#选取距未知样本最近的k个点,统计前k个点所在类别出现的次数
classCount={}#建立一个空字典,存储电影类型出现的次数
for i in range(k):
votelabel=labels[sortedDis[i]]#filmtype的类型labels作为投票标签;通过labels的索引值 (排序的索引当作labels的索引),统计filmtype的类型
classCount[votelabel]=classCount.get(votelabel,0)+1 #原来的结果从0开始,每次在对应的类型统计上加1
# 多数表决投票
maxType=0
maxCount=-1
for key ,value in classCount.items():
if value >maxCount:
maxType=key
maxCount=value
return maxType
数据处理(转为为矩阵),归一化,分类器模型训练集 测试集,调用
import numpy as np
import matplotlib.pyplot as plt
import knn as K
# 文件转矩阵处理
def file2matrix(filename):
fr = open(filename)
numberOfLines = len(fr.readlines())
returnMat = np.zeros((numberOfLines,3))
classLabelVector = [] # 创建空的向量存放分类标签
fr = open(filename)
index = 0
for line in fr.readlines():
line = line.strip() #删除每行头尾的空白字符
listFromLine = line.split('\t') # 每行的四个元素是以tab分开的,进行切片
returnMat[index,:] = listFromLine[0:3] #将前三列存储在Mat矩阵中
if listFromLine[-1] == 'didntLike':
classLabelVector.append(1)
elif listFromLine[-1] == 'smallDoses':
classLabelVector.append(2)
elif listFromLine[-1] == 'largeDoses':
classLabelVector.append(3)
index += 1
return returnMat,classLabelVector
# 数据归一化
def autoNorm(dataSet):
minVals = dataSet.min(0)
maxVals = dataSet.max(0)
normDataSet = np.zeros(dataSet.shape)
normDataSet = (dataSet-minVals)/(maxVals-minVals)
return normDataSet
datingDataMat,datingLabels = file2matrix('datingTestSet.txt')
dataSet=autoNorm(datingDataMat)
print(dataSet)
#分类器模型训练集 测试集
m = 0.8 #设置训练集的比例
dataSize = dataSet.shape[0] #取数据的全部行
trainSize = int(m*dataSize)
testSize = int((1-m)*dataSize)+1 # 199.9999python向下取整,199,故加1
print('数据总行数 :',dataSize,' 训练集 :',trainSize,' 测试集 :',testSize)
k=5
result=[]
error=0
for i in range(testSize):
result=K.knn(dataSet[trainSize+i,:],dataSet[:trainSize,:],datingLabels[:trainSize],k)
if result != datingLabels[trainSize+i]:
error=+1
print('错误率 :',error/testSize)
5 鸢尾花分类(练习)
6 KNN算法总结
为什么Y分类,KNN失效呢 ?