问题描述
- 现要将目标分为四类,分别记为第1类、第2类、
第3类和第4类。
目标
数据集
- 训练集 data1.txt 包含了第1类顾客及其特征向量
data2.txt 包含了第2类顾客及其特征向量
data3.txt 包含了第3类顾客及其特征向量
data4.txt 包含了第4类顾客及其特征向量 - 目标集 objdata.txt 包含需要分类的目标顾客
分析
- 据以上对问题的分析,已知训练集有四类数据类型,同时要对目标集数据(未知类型)进行分类。
- 分析可得,使用KNN(k-近邻)算法实现目标集数据的分类。KNN算法主要解决的是在训练样本集中的每个样本的分类标签为已知的条件下,如何为一个新增数据给出对应的分类标签。
算法阐述
- 首先,K值的确定是根据将每个训练集分为10(作为测试集)+40(作为训练集),则共有四个数据集,即共有测试集40个数据,训练集160个数据。
- 其次,已知测试集的数据类别,利用测试集与训练集进行训练,得出测试集的分类类型,将得出的分类类型与已知测试集数据类型,进行精度计算得出最优精度,来确定最优k值。
- 再次,在这个过程中,程序的每一次进程,测试集和训练集的选取都是随机打乱,使得数据更具有代表性。
代码实现
from matplotlib import pyplot as plt
import numpy as np
import os
data1 = np.loadtxt('data1.txt')
data2 = np.loadtxt('data2.txt')
data3 = np.loadtxt('data3.txt')
data4 = np.loadtxt('data4.txt')
objdata = np.loadtxt('objdata.txt')
def fun(trains1,objdata1,ttarget1,k1):
list1=[]
for j in objdata1:
dis=np.linalg.norm(trains1-j,axis=1)
v=np.sort(dis)
threshold=v[k1]
sum1=0
sum2=0
sum3=0
sum4=0
for index,i in enumerate(dis):
if i<threshold:
if ttarget1[index]==1:
sum1+=1
elif ttarget1[index]==2:
sum2+=1
elif ttarget1[index]==3:
sum3+=1
else:
sum4+=1
if sum1>=max(sum2,sum3,sum4):
list1.append(1)
elif sum2>=max(sum1,sum4,sum3):
list1.append(2)
elif sum3>=max(sum1,sum2,sum3):
list1.append(3)
elif sum4>=max(sum1,sum2,sum3):
list1.append(4)
return(list1)
np.random.shuffle(data1)
data_1=data1[0:10,:]
data_11=data1[10:50,:]
np.random.shuffle(data2)
data_2=data2[0:10,:]
data_22=data2[10:50,:]
np.random.shuffle(data3)
data_3=data3[0:10,:]
data_33=data3[10:50,:]
np.random.shuffle(data4)
data_4=data4[0:10,:]
data_44=data4[10:50,:]
trains_1=np.vstack([data_1,data_2,data_3,data_4])
ttarget_1=np.vstack([np.ones((10,1)),2*np.ones((10,1)),3*np.ones((10,1)),4*np.ones((10,1))])
trains_11=np.vstack([data_11,data_22,data_33,data_44])
ttarget_11=np.vstack([np.ones((40,1)),2*np.ones((40,1)),3*np.ones((40,1)),4*np.ones((40,1))])
number=0
accuracy=[]
for m in range(1,51):
list3=fun(trains_11,trains_1,ttarget_11,m)
print('k=',m)
print(list3)
print('********************************************************************************')
for n in range(len(list3)):
if list3[n]==ttarget_1[n]:
number+=1
accuracy.append(number/(len(list3)))
number=0
print('k对应的各个精度值:',accuracy)
print('最优精度值为:',max(accuracy))
p=1
p_list=[]
for u in accuracy:
if u==max(accuracy):
p_list.append(p)
p+=1
print('最优精度值对应的k值为:',p_list)
trains=np.vstack([data1,data2,data3,data4])
os.system("python loaddatafun2.py")
ttarget=np.vstack([np.ones((50,1)),2*np.ones((50,1)),3*np.ones((50,1)),4*np.ones((50,1))])
list2=fun(trains,objdata,ttarget,p_list[0])
print('目标集的分类结果',list2)
y=1
z=0
for x in list2:
if x==1:
plt.scatter(objdata[z:y,0],objdata[z:y,1],color='r')
elif x==2:
plt.scatter(objdata[z:y,0],objdata[z:y,1],color='g')
elif x==3:
plt.scatter(objdata[z:y,0],objdata[z:y,1],color='b')
else:
plt.scatter(objdata[z:y,0],objdata[z:y,1],color='k')
y=y+1
z=z+1
plt.show()
结果
训练集
测试集的精度计算,确定最优k值
目标集分类