数据科学—K 最邻近算法实践

问题描述

  • 现要将目标分为四类,分别记为第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')#获取训练集data1
data2 = np.loadtxt('data2.txt')#获取训练集data2
data3 = np.loadtxt('data3.txt')#获取训练集data3
data4 = np.loadtxt('data4.txt')#获取训练集data4
objdata = np.loadtxt('objdata.txt')#获取目标集

#训练集,目标集,标签,k值
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]#k设置的为17 ,得到第17个距离
        sum1=0
        sum2=0
        sum3=0
        sum4=0
        for index,i in enumerate(dis):#对得到的距离进行遍历
              if i<threshold:#如果某个距离小于第10个距离,则是需要近似目标点的估计点
                  #判断该估计点属于哪一类
                  if ttarget1[index]==1:
                         sum1+=1
                  elif ttarget1[index]==2:
                         sum2+=1
                  elif ttarget1[index]==3:
                         sum3+=1
                  else:
                         sum4+=1
      
        #输出该目标点的所有估计点的每个类型总和
        #print('1类估计点的数量:',sum1)
        #print('2类估计点的数量:',sum2)
        #print('3类估计点的数量:',sum3)
        #print('4类估计点的数量:',sum4)

        #sum1,sum2,sum3,sum4进行比较,得出目标点属于的类别
             #sum1,sum2,sum3,sum4进行比较,得出目标点属于的类别
        if sum1>=max(sum2,sum3,sum4):
            #print("the class is",1)
            list1.append(1)
        elif sum2>=max(sum1,sum4,sum3):
            #print("the class is",2)
            list1.append(2)
        elif sum3>=max(sum1,sum2,sum3):
            #print("the class is",3)
            list1.append(3)
        elif sum4>=max(sum1,sum2,sum3):
            #print("the class is",4)
            list1.append(4)
    #print('目标集所属类别为:',list1)
    return(list1)
       

#k值的确定
#第一类
 
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))])

#对每个k的精度进行计算
number=0
accuracy=[]
for m in range(1,51):
    #调用分类函数(训练集,目标集,标签,k值)
    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))
#找出最大精度对应的k值
p=1
p_list=[]#k值不是唯一确定的
for u in accuracy:
    if u==max(accuracy):
        p_list.append(p)
    p+=1
print('最优精度值对应的k值为:',p_list)

        
#利用上述计算出的最优k值,进行目标集的分类
trains=np.vstack([data1,data2,data3,data4])#将四个训练集拼接
#print(trains)#输出总训练集
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))])
#print(ttarget)#输出所有标签
    
#调用分类函数(训练集,目标集,标签,k值)
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值

在这里插入图片描述

目标集分类

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值