两种方法:利用sklearn和不使用sklearn,自己编写KNN程序对鸢尾花数据进行分类

利用sklearn,KNN对鸢尾花数据进行分类

import numpy as np
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

iris=load_iris()
#从sklearn数据集中获取鸢尾花数据
iris_feature=iris.data
iris_label=iris.target
#将数据划分为训练集和测试集
#test_size=0.3表示测试集占0.3,训练集占0.7
# random_state相当于随机数种子random.seed()
x_train,x_test,y_train,y_test=train_test_split(iris_feature,iris_label,test_size=0.3,random_state=30)
knn = KNeighborsClassifier(n_neighbors=5, algorithm='auto', weights='distance', n_jobs=1)
knn.fit(x_train,y_train)
predict=knn.predict(x_test)
#预测结果
print(predict)
#原本测试数据
print(y_test)
#准确性
print(accuracy_score(predict,y_test))

在这里插入图片描述
  在实验过程发现了一个特殊的情况, 当我把random_state设置为40或者42这两个数字时,准确率都达到了1.0。

查阅资料了解random_state的含义

  • random_state可以保证程序每次运行都分割一样的训练集合测试集。即当我把random_state=一个数时,每次运行程序划分的数据集相同。
  • 否则,如果不设置值,每次构建的模型,数据集是不同的,导致每次运行程序得到的结果都不相同。

  因为模型的构建、数据集的生成、数据集的拆分都是一个随机的过程,random_state相当于一个随机种子。random_state取值不同,生成数据集就会不相同。

  经过查阅资料,上面提到的准确率达到1.0这个问题还是没有得到解决,如果大家有想法,欢迎讨论。

不使用sklearn,自己编写KNN程序对鸢尾花数据进行分类

  因为最开始np.sqrt(np.sum(matrixtemp2, axis=1))可以来计算向量每行的和,因此最开始采用了相对来说繁杂的计算欧式距离方法。下面将把两种方式附在下面:

方式一:

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import collections as co
#计算两点之间的欧式距离
def exp(i,j):
    return np.sqrt(np.sum(abs(i-j)**2))
def knn(k,predictpoint,x_train,y_train):
    dist=[]
    for train_data in x_train:
        distance=exp(predictpoint,train_data)
        dist.append(distance)
    sortindex=np.argsort(dist)
    sortlabel=y_train[sortindex]
    return co.Counter(sortlabel[0:k]).most_common(1)[0][0]
if __name__ == '__main__':
    iris = load_iris()
    iris_feature = iris.data
    iris_label = iris.target
    k=5
    x_train, x_test, y_train, y_test = train_test_split(iris_feature, iris_label, test_size=0.3, random_state=30)
    count=0
    predict=[]
    for predictpoint in x_test:
        result=knn(k,predictpoint,x_train,y_train)
        predict.append(result)
    predict=np.array(predict)
    print(predict)
    print(y_test)
    print(np.sum((predict==y_test)/y_test.size))

方式二:

import numpy as np
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
import collections as co

def knn(k,predictpoint,x_train,y_train):
    # 计算xi-yi
    matrixtemp = (x_train - predictpoint)
    # 计算(xi-yi)的平方
    matrixtemp2 = np.square(matrixtemp)
    # 计算欧式距离, 此处一定要设置axis=1,它表示按行的方向相加,返回每个行的值;
    # axis=0按列相加,返回每个列的值;如果不写则返回的是所有值相加的结构
    distance = np.sqrt(np.sum(matrixtemp2, axis=1))
    # 对distance的集合元素冲销到大排序,返回的是下表 np.sort()只是把集合里面的内容进行排序
    sortindex = np.argsort(distance)
    # 用排序的sortindex来操作lable集合
    sortlabel = y_train[sortindex]
    # 返回前k个中出现最多次数的标签值
    return co.Counter(sortlabel[0:k]).most_common(1)[0][0]
if __name__ == '__main__':
    iris = load_iris()
    iris_feature = iris.data
    iris_label = iris.target
    k=5
    x_train, x_test, y_train, y_test = train_test_split(iris_feature, iris_label, test_size=0.3, random_state=30)
    count=0
    predict=[]
    for predictpoint in x_test:
        result=knn(k,predictpoint,x_train,y_train)
        predict.append(result)
    predict=np.array(predict)
    print(predict)
    print(y_test)
    print(np.sum((predict==y_test)/y_test.size))

两种方式最后得到的结果都是一致的.
在这里插入图片描述

对于上述提到的问题,如果大家有什么好的想法,欢迎指正。

  • 6
    点赞
  • 31
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值