KNN算法分类算法--鸢尾花实例

import numpy as np
import pandas as pd

#读取数据集,header参数来指定参数标题的行,默认为0,第一行,如果没有标题使用None
data = pd.read_csv('iris.csv',header=0)
#对文本进行处理,将Species列的文本映射成数值类型
data['Species'] = data['Species'].map({'Iris-virginica':0,'Iris-setosa':1,'Iris-versicolor':2})
#data.head(20)
#显示末尾行数
# data.tail(20)
#随机显示,默认为1条
data.sample(10)
#删除不需要的列
data.drop("id",axis=1,inplace=True)
#重复值检查,any(),一旦有重复值,就返回True
data.duplicated().any()
#删除重复的数据
data.drop_duplicates(inplace=True)
#查看各类别的数据条数
data['Species'].value_counts()
data
#编写KNN类
class KNN:
    """使用python实现K近邻算法"""
    def __init__(self,k):
        """初始化方法
        
        Parameters:
        ----
        k:int
            邻居的个数
        """
        self.k = k
    
    def fit(self, X, y):
        """训练方法
        Parameters
        ----
            X:类似数组类型,list,ndarray……形状:[样本的数量,特征的数量]
            y:类似数组类型,形状为[样本数量]
                每个样本的目标值,也是就是标签
        """
        #将X转换成ndarray类型,如果X已经是ndarray则不进行转换
        self.X = np.asarray(X)
        self.y = np.asarray(y)
    
    def predict(self, X):
        """根据参数传递的样本,对样本数据进行预测,返回预测之后的结果
        
        Parameters
        ----
        X:类似数组类型,list,ndarray……形状:[样本的数量,特征的数量]
        
        Return
        ----
        result:数类型,预测的结果。
        """
        
        #将测试的X转换为ndarray结构
        X = np.asarray(X)
        result = []
        
        for x in X:
            #ndarray相减为对应元素相减,测试的X的每一行与self.X 相减
            #求欧氏距离:每个元素都取平方值
            dis = np.sqrt(np.sum((x - self.X) ** 2,axis = 1))
            #求最近的k个点的距离,sort()排序不适用,因为排序后打乱了顺序
            #argsort(),返回每个元素在排序之前原数组的索引
            index = dis.argsort()
            #取前k个元素,距离最近的k的元素
            index = index[:self.k]
            #返回数组中每个元素出现的次数,元素必须是非负整数
            count = np.bincount(self.y[index])
            #返回ndarray之最大的元素的索引,该索引就是我们判定的类别
            result.append(count.argmax())
        return np.asarray(result)
    
    def predict2(self, X):
        """根据参数传递的样本,对样本数据进行预测(考虑权重,使用距离的倒数作为权重),返回预测之后的结果
        
        Parameters
        ----
        X:类似数组类型,list,ndarray……形状:[样本的数量,特征的数量]
        
        Return
        ----
        result:数类型,预测的结果。
        """
        
        #将测试的X转换为ndarray结构
        X = np.asarray(X)
        result = []
        
        for x in X:
            #ndarray相减为对应元素相减,测试的X的每一行与self.X 相减
            #求欧氏距离:每个元素都取平方值
            dis = np.sqrt(np.sum((x - self.X) ** 2,axis = 1))
            #求最近的k个点的距离,sort()排序不适用,因为排序后打乱了顺序
            #argsort(),返回每个元素在排序之前原数组的索引
            index = dis.argsort()
            #取前k个元素,距离最近的k的元素
            index = index[:self.k]
            #返回数组中每个元素出现的次数,元素必须是非负整数,【使用weight考虑权重,权重为距离的倒数】
            count = np.bincount(self.y[index],weights=1/dis[index])
            #返回ndarray之最大的元素的索引,该索引就是我们判定的类别
            result.append(count.argmax())
        return np.asarray(result)
    
#数据集拆分成训练集和测试集
#1、提取每个类别鸢尾花的数量
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)
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(k=3)
#进行训练
knn.fit(train_X,train_Y)
#进行测试
result = knn.predict(test_X)
# display(result)
# display(test_Y)
#查看预测结果
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 #设置在中文字体是能够正常显示负号(“-”)

#设置画布大小
plt.figure(figsize=(10,10))
#挑选维度进行散点图显示
#绘制训练集的散点图'Iris-virginica':0,'Iris-setosa':1,'Iris-versicolor':2
plt.scatter(x=t0['SepalLengthCm'][:40],y=t0['PetalLengthCm'][:40],color='r',label='Iris-virginica')
plt.scatter(x=t1['SepalLengthCm'][:40],y=t1['PetalLengthCm'][:40],color='g',label='Iris-setosa')
plt.scatter(x=t2['SepalLengthCm'][:40],y=t2['PetalLengthCm'][:40],color='b',label='Iris-versicolor')

#绘制测试集数据,使用不同的图案显示预测正确和错误的结果
right = test_X[result == test_Y]
wrong = test_X[result != test_Y]
plt.scatter(x=right['SepalLengthCm'],y=right['PetalLengthCm'],color='c',marker='x',label='right')
plt.scatter(x=wrong['SepalLengthCm'],y=wrong['PetalLengthCm'],color='m',marker='>',label='wrong')

#显示额外信息
plt.xlabel("花萼长度")
plt.ylabel("花瓣长度")
plt.title("KNN分类显示结果")
plt.legend(loc="best")
plt.show()

KNN算法分类算法--鸢尾花实例_第1张图片

你可能感兴趣的:(机器学习算法)