最近邻算法(KNN)Python实现

实验要求

第一个实验

数据集:Iris也称鸢尾花卉数据集,是一类多重变量分析的数据集。该数据集是4个最流行的机器学习数据集之一。通过花萼长度,花萼宽度,花瓣长度,花瓣宽度4个属性预测鸢尾花卉属于(Setosa,Versicolour,Virginica)三个种类中的哪一类。

实验要求:

  1. 读入Iris.csv数据,并将数据的70%做为训练数据,30%做为测试数据;
  2. 根据KNN算法思想,实现KNN算法,并使用训练数据训练KNN分类模型;
  3. 使用剩余30%数据对KNN分类模型进行测试,并计算出分类精度。(可考虑使用可视化界面进行分类效果分析)
  4. 可以直接用sklearn库中的neighbors.KNeighborsClassifier()

提示:

  1. from random import shuffle  --shuffle()
  2. 可视化模块

 

第二个实验

数据集dataSet..txt共1000个样本,包括以下三个特征:每年飞行的里程数、玩视频游戏所耗时间百分数,以及每周消费的冰淇淋公升数。希望根据上面三个特征,将上述人群分成1、2、3类。

实验要求:

  1. 读取数据
  2. 归一化特征值
  3. 实现KNN算法

根据数据集提供的类别,计算误差比例,并统计各类别数量

数据:

dataSet.txt

iris.csv

1. 实验基本原理及目的

最近邻算法(k-NearestNeighbor-KNN)

图中,绿色圆要被决定赋予哪个类,是红色三角形还是蓝色四方形?

如果K=3,由于红色三角形所占比例为2/3,绿色圆将被赋予红色三角

形那个类,如果K=5,由于蓝色四方形比例为3/5,因此绿色圆被赋予蓝色四方形类。

由于没有事先学习出模型,KNN也称懒惰学习方法

输入:

   T   // 训练数据  K  //邻居数目   t  // 待分配元组

    输出:

    c     //元组t被分配的类别

  KNN算法:

    N = Φ;     //对于元组t发现的邻居集合N

    for each          do

       if |N| ≤ K, then

     

       else

        if such that sim(t,u) ≤ sim(t,d),then

          begin

             N = N-{u};

             N = N + {d}

          end

 c = class to which the most are classified.

2. 数据的准备及数据预处理

2.1实验1

将数据读入,按7:3分别分为训练集和测试集data_practice,data_predict,将字符串类型转换为数字类型对应为0,1,2。

2.2实验2

将数据读入,按330:670分别分为训练集和测试集data_practice,data_predict。

3. 实验过程

3.1实验1

1. 函数介绍:

read(datafile):数据预处理函数,datafile为文件所在位置,返回值为data_practice,data_predict,分别为训练集,预测集。

knn(practice_x,practice_y,predict_x):KNN函数,训练数据的数据和标签,practice_x为数据,practice_y为标签, predict_x为预测数据的的数据,返回值为predict_y,为分的标签。

transfer(a):将字符串数组转化为数字。

cm_plot(t1,output):画图函数,画出混淆矩阵,t1为数据的真实标签,output为预测标签。

2.源码:

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier 

#读取文件函数,数据预处理,70%做训练集,30%做预测集
def read(datafile):
    data=pd.read_csv(datafile)
    #打乱顺序
    data=data.sample(frac=1).reset_index(drop=True)
    length=len(data) 
    #70%做训练集,剩下的为预测集
    data_practice=data[0:int(length*0.7)]
    data_predict=data[int(length*0.7):]
    return data_practice,data_predict

#KNN预测函数
def knn(practice_x,practice_y,predict_x):
    #测试精度参数为n_neighbors
    neigh=KNeighborsClassifier(n_neighbors=5)  
    neigh.fit(practice_x, practice_y)
    predict_y=neigh.predict(predict_x)
    return predict_y

#将字符类型数据转化为数字类型
def transfer(a):
    b=[]
    for i in a:
        if i=='Iris-setosa':
            b.append(0)
        elif i=='Iris-versicolor':
            b.append(1)
        else:
            b.append(2)
    return b
                
#混淆矩阵画图
def cm_plot(t1,output):
    from sklearn.metrics import confusion_matrix
    cm=confusion_matrix(t1,output)
#    print(cm)
#    print(len(cm))
    import matplotlib.pyplot as plt
    plt.matshow(cm,cmap=plt.cm.Greens)
    plt.colorbar()
    for x in range(len(cm)):
        for y in range(len(cm)):
            plt.annotate(cm[x,y],xy=(x,y),horizontalalignment='center',verticalalignment='center')
    plt.ylabel('True label')
    plt.xlabel('Predict label')
    return plt

#读取文件
datafile='D:/ProgramData/file5/iris.csv'
data_practice,data_predict=read(datafile)
#训练数据的数据和标签,practice_X为数据,practice_y为标签
practice_x=np.array(data_practice.iloc[0:,0:4])
practice_y=list(data_practice['class'])
#预测数据的结果和标签,predict_x为数据,predict_y为标签
predict_x=np.array(data_predict.iloc[0:,0:4])
predict_y=knn(practice_x,practice_y,predict_x)
#将预测的标签和数据真正的标签转化成数字类型,并画出混淆矩阵
true_y=transfer(list(data_predict['class']))
test_y=transfer(predict_y)
cm_plot(true_y,test_y).show()
#打印预测结果
print(predict_y)

3.2实验2

1. 函数介绍:

read(datafile):预处理函数,数据预处理函数,datafile为文件所在位置,将特征值进行归一化处理,返回值为归一化之后的数据。

knn(practice_x,practice_y,predict_x):KNN函数,同上个实验。

printf(true_y,predict_y):打印函数,打印结果,true_y为真实值,predict_y为预测值。

2.源码:

# -*- coding: utf-8 -*-
import numpy as np
import pandas as pd
from sklearn.neighbors import KNeighborsClassifier
#预处理函数
def read(datafile):   
    data=np.array(pd.read_table(datafile,sep="\t",header=-1))
    a=[0,0,0]
    for i in range(0,3):
        a[i]=max(data[:,i])-min(data[:,i])
    for i in range(0,3):
        data[:,i]=data[:,i]/a[i]
    return data

#KNN预测函数
def knn(practice_x,practice_y,predict_x):
    #测试精度参数为n_neighbors
    neigh=KNeighborsClassifier(n_neighbors=5)  
    neigh.fit(practice_x, practice_y)
    predict_y=neigh.predict(predict_x)
    return predict_y
#分类错误函数
def printf(true_y,predict_y):
    k=0
    number1=0
    number2=0
    number3=0
    for i in range(0,len(true_y)):
        if true_y[i]!=predict_y[i]:
            k+=1
        if true_y[i]==1:
            number1+=1
        elif true_y[i]==2:
            number2+=1
        else:
            number3+=1
            
    for i in range(0,len(true_y)):
        print('分类结果为:'+str(predict_y[i])+',实际结果为:'+str(true_y[i]))
    print('错误率为:'+str(k/len(true_y)))
    print('分类错误数:'+str(k)+',总样本数为:'+str(len(true_y)))
    print('第一类     第二类     第三类')
    print(str(number1)+'        '+str(number2)+'        '+str(number3))
    return
    
datafile='D:/ProgramData/file5/dataSet.txt'
data=read(datafile)
practice_x=data[0:330,0:2]
practice_y=data[0:330,3]
predict_x=data[330:len(data),0:2]
true_y=data[330:len(data),3]
predict_y=knn(practice_x,practice_y,predict_x)
printf(true_y,predict_y)


 

4. 实验结果分析

4.1实验1

当精度K取3时:

图像:

预测结果:

当精度K5时:

图像:

预测结果:

分析:对比K为3和5,5的精度更高。

4.2实验2

实验结果:

  • 4
    点赞
  • 44
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值