阿里云大学 笔记——KNN分类

1. 导入鸢尾花数据集

import numpy as np
import pandas as pd
from sklearn import datasets

#读取鸢尾花数据集,header参数制定标题的行,默认为0,没标题为None
data=pd.read_csv("data/iris.csv",header=0)
data.head()
#随机抽取样本,默认为1.
data.sample(10)
#将类别文本映射为数值类型
data["Name"]=data["Name"].map({"Iris-versicolor":0,
                              "Iris-virginica":1,
                              "Iris-setosa":2})

data.duplicated()#是否有重复,有重复为True
data.duplicated().any()#只要有一个重复就返回True(只返回一个True)
data.drop_duplicates(inplace=True)#删除重复记录
len(data)#查看数据集长度
#查看各种类型鸢尾花有多少条记录
data["Name"].value_counts()
0    50
1    49
2    48
Name: Name, dtype: int64
x=np.array([1,2,3])
y=np.array([[4,5,6],
           [7,8,9]])
x-y
np.sum(x-y)#算出来只有一个值
sum(x-y)
array([-9, -9, -9])

2. KNN分类

class KNN:
    def __init__(self,k):
        """初始化 """
        self.k=k
    def fit(self,X,y):
        """训练方法
        X:类数组类型(二维)  待训练的样本特征(属性)
        y:(一维)  样本的目标值(标签)"""
        self.X=np.asarray(X)#转化为ndarray数组类型
        self.y=np.asarray(y)
        
    def predict(self,X):
        X=np.asarray(X)
        result=[]
        for x in X:
            #对于测试集中的每一个样本,依次与训练集中的所有样本求距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #返回数组排序后的索引,也是每个元素在原数组(排序之前)中的索引
            index=dis.argsort()
            #只取前K个
            index=index[:self.k]
            #返回数组中每个元素出现的次数。元素必须是非负整数。
            count=np.bincount(self.y[index])
            #返回出现次数最多的元素的索引,该索引就是我们判断的类别.加入resul数组
            result.append(count.argmax())
            
        return np.asarray(result)

    def predict2(self,X):#考虑权重,权重为距离的倒数。
        X=np.asarray(X)
        result=[]
        for x in X:
            #对于测试集中的每一个样本,依次与训练集中的所有样本求距离
            dis=np.sqrt(np.sum((x-self.X)**2,axis=1))
            #返回数组排序后的索引,也是每个元素在原数组(排序之前)中的索引
            index=dis.argsort()
            #只取前K个
            index=index[:self.k]
            #返回数组中每个元素出现的次数。元素必须是非负整数。
            count=np.bincount(self.y[index],weights=1/dis[index])
            #返回出现次数最多的元素的索引,该索引就是我们判断的类别.加入resul数组
            result.append(count.argmax())
            
        return np.asarray(result)

3. train_test_split

#提取出每种类别的鸢尾花数据
t0=data[data["Name"]==0]
t1=data[data["Name"]==1]
t2=data[data["Name"]==2]
#打乱顺序(随机抽取样本)
t0=t0.sample(len(t0),random_state=666)
t1=t1.sample(len(t1),random_state=666)
t2=t2.sample(len(t2),random_state=666)
#进行切分,构建训练集与测试机
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)
#from sklearn.neighbors import KNeighborsClassifier
#knn=KNeighborsClassifier(n_neighbors=3)
#knn.fit(train_X,train_y)
#predict_y=knn.predict(test_X)
#sum(predict_y==test_y)/len(test_y)
#---------
#创建KNN对象,进行训练与测试
my_knn=KNN(k=3)
#进行训练
my_knn.fit(train_X,train_y)
#进行测试
result=my_knn.predict(test_X)
display(result)
display(test_y)
sum(result==test_y)/len(test_y)
array([0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 2, 2, 2,
       2, 2, 2, 2, 2], dtype=int64)



93     0
77     0
86     0
96     0
59     0
56     0
80     0
95     0
52     0
94     0
127    1
136    1
147    1
109    1
106    1
130    1
146    1
102    1
145    1
38     2
49     2
9      2
6      2
30     2
47     2
2      2
46     2
Name: Name, dtype: int64





0.9259259259259259
#考虑权重进行测试
result2=my_knn.predict2(test_X)
display(np.sum(result2==test_y))
display(sum(result2==test_y)/len(test_y))
25



0.9259259259259259

4. 可视化显示

import matplotlib as mpl
import matplotlib.pyplot as plt
# 默认不支持中文显示,需要进一步设置。

#设置字体为黑体,以支持中文显示。
mpl.rcParams["font.family"]="SimHei"
#设置在中文字体时,能够正常显示负号。
mpl.rcParams["axes.unicode_minus"]=False
data.sample(10)
SepalLengthSepalWidthPetalLengthPetalWidthName
485.33.71.50.22
766.82.84.81.40
1156.43.25.32.31
355.03.21.20.22
165.43.91.30.42
134.33.01.10.12
1307.42.86.11.91
1357.73.06.12.31
205.43.41.70.22
454.83.01.40.32
#{"Iris-versicolor":0,"Iris-virginica":1,"Iris-setosa":2}
#设置画布的大小
plt.figure(figsize=(20,10))
#绘制训练集数据
plt.scatter(x=t0["SepalLength"][:40],y=t0["PetalLength"][:40],color='r',label="Iris-versicolor")
plt.scatter(x=t1["SepalLength"][:40],y=t1["PetalLength"][:40],color='b',label="Iris-virginica")
plt.scatter(x=t2["SepalLength"][:40],y=t2["PetalLength"][:40],color='g',label="Iris-setosa")

#绘制测试集的训练数据
right=test_X[result==test_y]
wrong=test_X[result!=test_y]
plt.scatter(right["SepalLength"],right["PetalLength"],color='c',marker='x',label="right")
plt.scatter(wrong["SepalLength"],wrong["PetalLength"],color='m',marker='>',label="wrong")
plt.xlabel("花萼长度")
plt.ylabel("花瓣长度")
plt.title("KNN分类结果显示")
plt.legend(loc="best")#label:图例,必须要加plt.legend()才可以显示
plt.show()

在这里插入图片描述

np.bincount([1,0,0,1,1],weights=[0.3,0.1,0.2,0.2,0.4])
array([0.3, 0.9])
np.bincount([1,0,0,1,1])
array([2, 3], dtype=int64)
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值