KNN算法(自己实现)鸢尾花数据集
一.题目描述
- 题目:自己实现knn算法(用鸢尾花数据集)
- Knn算法描述:在训练集中数据和标签已知的情况下,输入测试数据,将测试数据的特征与训练集中对应的特征进行相互比较,找到训练集中与之最为相似的前K个数据,则该测试数据对应的类别就是K个数据中出现次数最多的那个分类
二. 算法构造
Knn算法通过计算对象间距离来作为各个对象之间的非相似性指标,在这里距离一般使用欧氏距离或曼哈顿距离:
算法描述为:
1)计算测试数据与各个训练数据之间的距离;
2)按照距离的递增关系进行排序;
3)选取距离最小的K个点;
4)确定前K个点所在类别的出现频率;
5)返回前K个点中出现频率最高的类别作为测试数据的预测分类。
程序流程图:
算法流程图:
三.代码实现
import pandas as pd
import numpy as np
from math import sqrt
from collections import Counter
class knnClass:
def __init__(self,k):
'''初始化'''
assert k>=1,"k必须是有效的"
self.k=k
self._x=None
self._y=None
def fit(self,x,y):
assert x.shape[0] == y.shape[0]
assert self.k<=x.shape[0] ,"k 必须是有效的"
self._x=x
self._y=y
return self
def predict(self,xP):
'''给定待预测数剧集,给出预测结果向量'''
assert self._x is not None and self._y is not None
assert xP.shape[1]==self._x.shape[1]
yP=[self._predict(x) for x in xP]
return np.array(yP)
def _predict(self,x):
'''给定单个数据,返回预测类别'''
assert x.shape[0]==self._x.shape[1],"必须相同"
'''计算距离'''
distances=[sqrt(np.sum((x_t-x)**2)) for x_t in self._x]
nearest=np.argsort(distances)
topk_y=[self._y[i] for i in nearest[:self.k]]
votes=Counter(topk_y)
return votes.most_common(1)[0][0]
def knnRatio(self,yN,yP):
n = 0
assert yN.shape[0] == yP.shape[0]
for i in range(40):
if yN[i] != yP[i]:
n=n+1
return (40-n)/40
def _repr_(self):
return "kNN(k=%d)"%self.k
"训练集"
knn_cl=knnClass(k=6)
mydata_csv=pd.read_csv('iris.csv')
mydata_csv.columns=['sepal_len','sepal_width','petal_len','petal_width','class']
mydata_csv['class'] = mydata_csv['class'].apply(lambda x: x.split('-')[1])
x = mydata_csv[['sepal_len', 'sepal_width','petal_len', 'petal_width']]
y = mydata_csv['class']
"print(x)"
x=np.array(x)
y=np.array(y)
knn_cl.fit(x,y)
"测试集"
mydata_csv2=pd.read_csv('iris0.csv')
mydata_csv2.columns=['sepal_len','sepal_width','petal_len','petal_width','class']
mydata_csv2['class'] = mydata_csv2['class'].apply(lambda x: x.split('-')[1])
x_new = mydata_csv2[['sepal_len', 'sepal_width','petal_len', 'petal_width']].values
y_new = mydata_csv2['class'].values
"print(x_new)"
print("测试集结果")
print(y_new)
y_predict=knn_cl.predict(x_new)
print("预测结果")
print(y_predict)
r=knn_cl.knnRatio(y_new,y_predict)
print('测试集的正确率为:',r)
四.实验总结
- 对knn算法的认识:knn就是根据“新数据的分类取决于它的邻居”进行的,算法的目的就是根据新数据和训练集的距离,找出它的邻居,然后分析这几位邻居大多数的分类,新数据类型就是它几位邻居的大多数类型。
- 实现算法过程出现的问题:
(1)第一次用的数据集是xlsl格式,出现下面问题,格式不正确,目前没有解决这个格式错误问题,最后换成了CSV格式。
(2)测试集和训练集数据匹配问题,但是输出都是4,莫名其妙的问题,最后发现自己调用错函数,一组数据应该调用的是_predict()函数,调用成了predict()函数
鸢尾花数据集下载:http://archive.ics.uci.edu/ml/datasets/Iris
测试集自己可以写,或者从下载的数据集随机选40组
测试集文件iris0.csv,数据集文件iris.csv,这两个文档自己准备
运行的结果截图: