赞
踩
import numpy as np
import pandas as pd
#读取鸢尾花数据集,header参数来指定标题的行,默认为0,如果没有标题,则使用None data=pd.read_csv(r"F:\数据集\Iris数据集\iris.csv",header=0) #data 默认显示全部行 中间用省略号 #data.head()只显示头5行(默认) #data.head(n)显示头n行 #data.tail()默认显示后5行 #data.tail(n)显示后n行 #data.sample()默认随机抽取一行显示 #data.sample(n)随机抽取n条样本 data.sample(10) #将Species这一列的各种值映射为相应的数值 data["Species"]=data["Species"].map({"versicolor":0,"setosa":1,"virginica":2}) #data #删除不需要的 Unnamed: 0列 axis=1表示删除列 默认为0,表示删除行 #data=data.drop("Unnamed",axis=1)与下面这行等价 data.drop("Unnamed: 0",axis=1,inplace=True) #判断数据集中是否有重复的值, 只要有一个重复则返回true,否则返回false data.duplicated().any() #输出原有鸢尾花记录数:150条 len(data) #删除重复记录,加上inplace=True使其在原有的数据集上操作,而不是在其副本上操作 data.drop_duplicates(inplace=True) #删除重复记录后:149条 len(data) #查看各个类别的鸢尾花具有多少条记录 data["Species"].value_counts()
1 50
0 50
2 49
Name: Species, dtype: int64
class KNN: """ 使用python语言实现K近邻算法。(实现分类)""" #定义初始化方法(init两边是两杠) def __init__(self,k): """ 初始化方法 paramters -------- k:int 邻居的个数. """ self.k=k #定义fit(训练)方法 def fit(self,X,y): """训练方法 Parameters ------- X:类数组类型,形状为:[样本数量,特征数量] 待训练的样本特征 y:类数组类型,形状为:[样本数量] 每个样本的目标值(标签) """ #为了统一处理list和dataFrame,将X转化为ndarray数组形式,若X本身就是ndarray类型则什么都不做 self.X=np.asarray(X) #同理转换y self.y=np.asarray(y) #定义预测方法 参数X是测试集的样本,没有考虑权重 def predict(self,X): """根据参数传递的样本,对样本数据进行预测 Parameters --------- X:类数组类型,形状为:[样本数量,特征数量] 待训练的样本特征 Return: -------- result:数组类型 预测的结果 """ X=np.asarray(X) result=[] #对ndarray数组进行遍历,每次取数组中的一行(一个样本)。 # self.X是训练集的样本 这里用欧式距离 #注意,x是一行,self.X是多行,在做减法是先会对x进行扩展,使其行数和self.X 一样,再对应元素想减 for x in X: #axis=1 指定按行的方式求和,否则是将数组所有的值求和成一个数值 #对于测试集中的每一个样本,一次与训练集中的所有样本求距离 dis=np.sqrt(np.sum((x-self.X)**2,axis=1)) #返回数组排序后每个元素在原数组中的索引(原数组:排序之前的数组) index=dis.argsort() #进行截断,只取前k个元素【取距离最近的k个元素的索引】 index=index[:self.k] #找到距离最近的k个节点的标签 index不论是list还是ndarray都行(都返回对应位置的标签) #self.y[index] #返回数组中每个元素(0、1、2.。。数据最大值 等出现的次数)出现的次数,但元素必须是非负的整数 count=np.bincount(self.y[index]) #返回ndarray数组中,值最大的元素对应的索引,就是出现次数最多的元素的索引,该索引就是我们判定的类别 #count.argmax() #将判定的类别加到结果中 result.append(count.argmax()) #写成np.array(result)也行(用result创建ndarray数组) #这里写成np.asarray(result)是将result转化为ndarray数组 return np.asarray(result) #定义预测方法2 参数X是测试集的样本,考虑权重 def predict2(self,X): """根据参数传递的样本,对样本数据进行预测(考虑权重,使用距离的倒数使用权重) Parameters --------- X:类数组类型,形状为:[样本数量,特征数量] 待训练的样本特征 Return: -------- result:数组类型 预测的结果 """ X=np.asarray(X) result=[] #对ndarray数组进行遍历,每次取数组中的一行(一个样本)。 # self.X是训练集的样本 这里用欧式距离 #注意,x是一行,self.X是多行,在做减法是先会对x进行扩展,使其行数和self.X 一样,再对应元素想减 for x in X: #axis=1 指定按行的方式求和,否则是将数组所有的值求和成一个数值 #对于测试集中的每一个样本,一次与训练集中的所有样本求距离 dis=np.sqrt(np.sum((x-self.X)**2,axis=1)) #返回数组排序后每个元素在原数组中的索引(原数组:排序之前的数组) index=dis.argsort() #进行截断,只取前k个元素【取距离最近的k个元素的索引】 index=index[:self.k] #找到距离最近的k个节点的标签 index不论是list还是ndarray都行(都返回对应位置的标签) #self.y[index] #返回数组中每个元素(0、1、2.。。数据最大值 等出现的次数)出现的次数,但元素必须是非负的整数 #[使用weights考虑权重,权重为距离的倒数] count=np.bincount(self.y[index],weights=1/dis[index]) #返回ndarray数组中,值最大的元素对应的索引,就是出现次数最多的元素的索引,该索引就是我们判定的类别 #count.argmax() #将判定的类别加到结果中 result.append(count.argmax()) #写成np.array(result)也行(用result创建ndarray数组) #这里写成np.asarray(result)是将result转化为ndarray数组 return np.asarray(result)
#提取出每个类别的鸢尾花数据 t0=data[data["Species"]==0] t1=data[data["Species"]==1] t2=data[data["Species"]==2] #对每个类别数据进行洗牌,参数random_state指定随机种子,相同的值使每次随机洗牌的结果都一样 t0=t0.sample(len(t0),random_state=0) t1=t1.sample(len(t1),random_state=0) t2=t2.sample(len(t2),random_state=0) #构建训练集和测试集 axix=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.predict1(test_X) result=knn.predict2(test_X) #display(result) #display(test_y) display(np.sum(result==test_y)) #display(len(result)) display((np.sum(result==test_y))/len(result))
28
0.9655172413793104
import matplotlib as mpl
import matplotlib.pyplot as plt
#默认情况下matplotlib不支持中文显示,我们需要设置一下,使其支持 #设置字体为黑体,以支持中文显示 mpl.rcParams["font.family"]="SimHei" #设置在中文字体是,能正常显示负号(-) mpl.rcParams["axes.unicode_minus"]=False #{"versicolor":0,"setosa":1,"virginica":2} # 设置画布的大小 plt.figure(figsize=(8,8)) #绘制训练集数据散点图 选择花瓣、花萼长度这两个维度 注意:不要将label写成lable了 plt.scatter(x=t0["Sepal.Length"][:40],y=t0["Petal.Length"][:40],color="r",label="versicolor") plt.scatter(x=t1["Sepal.Length"][:40],y=t1["Petal.Length"][:40],color="g",label="setosa") plt.scatter(x=t2["Sepal.Length"][:40],y=t2["Petal.Length"][:40],color="b",label="virginica") #绘制测试集数据 返回数组给right 和 wrong right=test_X[result==test_y] wrong=test_X[result!=test_y] plt.scatter(x=right["Sepal.Length"],y=right["Petal.Length"],color="c",marker="x",label="right") plt.scatter(x=wrong["Sepal.Length"],y=wrong["Petal.Length"],color="m",marker=">",label="wrong") plt.xlabel("花萼长度") plt.ylabel("花瓣长度") plt.title("KNN分类结果显示") # 设置图例显示位置 默认best 最合适的地方 plt.legend(loc="best") #显示图形 plt.show()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。