KNN代码

%matplotlib inline
import numpy as np
import pandas as pd

#读取莺尾花数据集,head参数来指定标题的行。默认为0,如果没有标题则使用None。
data = pd.read_csv(r"iris.arff.csv", header=0)
#显示头几个数据
#data.head(5)
#显示尾部几个数据
#data.tail(5)
#随机抽取样本,默认抽取一条,可通过参数指定抽取样本数量
#data.sample(10)
#将类别文本映射成数值类型
data["class"]= data["class"].map({"Iris-virginica":0, "Iris-setosa":1, "Iris-versicolor":2})
#删除不需要的ID列
#data.drop("Id", axis=1, inplace=True)
#data.duplicated().any()
#len(data)
#删除重复数据
data.drop_duplicates(inplace=True)
len(data)
#查看各个类别的莺尾花各有多少个
data["class"].value_counts()

class KNN:
    """使用Python语言实现K邻近算法。(实现分类)"""
    def __init__(self, k):
        """初始化方法
        parameters:
        ------
        k:int 邻居的个数
        """
        self.k=k;
        
    def fit(self, X, y):
        """训练方法
        paremeters:
        ------
        X:类似数数组类型,形状[样本数量,特征数量]
           待训练的样本特征(属性)
        y:类似数组类型,形状[样本数量]
          每个样本的标签
        """
        #将X装换成np。array数组类型
        self.X=np.asarray(X)
        self.y=np.asarray(y)
        
    def predict(self, X):
        """根据参数传递的样本,对样本进行预测
        paremeters:
        ------
        X:类似数数组类型,形状[样本数量,特征数量]
           待训练的样本特征(属性)
        Return:
        ------
        result:数组类型
               预测的结果
        """
        X=np.asarray(X)
        result=[]
        #对np.array进行遍历,每次取数组的一行(一个样本)
        for x in X:
            #对于测试集的每一个样本,依次与训练集中的所有样本求距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #返回数组排序后,每个数据在原数组(未排序)中的索引
            index=dis.argsort()
            #进行截断,只取前k个数(取距离最近的k个元素的索引)
            index=index[:self.k]
            #返回数组中每个元素出现的次数,元素必须是非负的整数
            count=np.bincount(self.y[index])
            #返回np.array数组中,值最大的索引,该索引就是我们判断的类别
            #最大元素的索引,就是出现最多次数的元素
            result.append(count.argmax())
        return np.asarray(result)
    
    def predict2(self, X):
        """根据参数传递的样本,对样本进行预测(考虑权重)
        paremeters:
        ------
        X:类似数数组类型,形状[样本数量,特征数量]
           待训练的样本特征(属性)
        Return:
        ------
        result:数组类型
               预测的结果
        """
        X=np.asarray(X)
        result=[]
        #对np.array进行遍历,每次取数组的一行(一个样本)
        for x in X:
            #对于测试集的每一个样本,依次与训练集中的所有样本求距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #返回数组排序后,每个数据在原数组(未排序)中的索引
            index=dis.argsort()
            #进行截断,只取前k个数(取距离最近的k个元素的索引)
            index=index[:self.k]
            #返回数组中每个元素出现的次数,元素必须是非负的整数, 考虑权重为距离的倒数
            count=np.bincount(self.y[index], weights=1/dis[index])
            #返回np.array数组中,值最大的索引,该索引就是我们判断的类别
            #最大元素的索引,就是出现最多次数的元素
            result.append(count.argmax())
        return np.asarray(result)
        
#提取每个类别的莺尾花数据
t0=data[data["class"]==0]
t1=data[data["class"]==1]
t2=data[data["class"]==2]
#对每个类别数据进行洗牌
t0=t0.sample(len(t0), random_state=0)
t1=t1.sample(len(t1), random_state=0)
t2=t2.sample(len(t2), random_state=0)
#构建测试集和训练集
train_X=pd.concat([t0.iloc[:40, :-1], t1.iloc[:40, :-1], t2.iloc[:40, :-1]], axis=0)
train_y=pd.concat([t0.iloc[:40,-1], t1.iloc[:40,-1], t2.iloc[:40,-1]], axis=0)

test_X=pd.concat([t0.iloc[40:, :-1], t1.iloc[40:, :-1], t2.iloc[40:, :-1]], axis=0)
test_y=pd.concat([t0.iloc[40:,-1], t1.iloc[40:,-1], t2.iloc[40:,-1]], axis=0)

#创建KNN对象,进行训练和测试
knn=KNN(k=3)
#进行训练
knn.fit(train_X,train_y)
#进行测试,获得测试结果
result=knn.predict(test_X)
display(result)
display(test_y)
display(np.sum((result==test_y)))
display(len(result))

#考虑权重 进行测试
result2=knn.predict2(test_X)
display(np.sum((result==test_y)))

import matplotlib as mpl
import matplotlib.pyplot as plt

#默认情况下,matplotlib不支持中文显示,需要进行设置
#设置字体为黑体,以支持中文显示
mpl.rcParams["font.family"]="SimHei"
#设置在中文字体时,能够正常的显示负号(-)
mpl.rcParams["axes.unicode_minus"]=False

#"Iris-virginica":0, "Iris-setosa":1, "Iris-versicolor":2
#设置画布的大小
plt.figure(figsize=(10,10))
#绘制训练集的数据
plt.scatter(x=t0["sepallength"][:40], y=t0["petallength"][:40], color="r",label="Iris-virginica")
plt.scatter(x=t1["sepallength"][:40], y=t1["petallength"][:40], color="g",label="Iris-setosa")
plt.scatter(x=t2["sepallength"][:40], y=t2["petallength"][:40], color="b",label="Iris-versicolor")
#绘制测试机数据
right=test_X[result==test_y]
wrong=test_X[result!=test_y]
plt.scatter(x=right["sepallength"], y=right["petallength"], color='c', label="right", marker="x")
plt.scatter(x=wrong["sepallength"], y=wrong["petallength"], color='m', label="wrong", marker=">")
plt.xlabel("花萼长度")
plt.ylabel("花瓣长度")
plt.title("KNN分类结果")
plt.legend(loc="best")
plt.show()

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值