Python实现KNN算法

**

一.KNN算法介绍

**
K最近邻(k-Nearest Neighbor,KNN)分类算法,是机器学习算法之一。

该方法的思路是:如果一个样本在特征空间中的k个最相似(即特征空间中最邻近)的样本中的大多数属于某一个类别,则该样本也属于这个类别。

KNN算法用于分类和回归。

**

二.KNN算法原理

**

存在一个样本数据集合,即训练样本集,并且样本集中每个数据都存在标签,即我们知道样本集中每一个数据与所属分类的对应关系。

输入没有标签的新数据后,将新的数据的每个特征与样本集中数据对应的特征进行比较,然后算法提取样本最相似数据(最近邻)的分类标签。

一般来说,我们只选择样本数据集中前k个最相似的数据,这就是k-近邻算法中k的出处,通常k是不大于20的整数。

最后,选择k个最相似数据中出现次数最多的分类,作为新数据的分类。

注:这里的Python主要针对KNN分类问题

**

三.KNN算法实现流程

**

收集数据:可以使用爬虫进行数据的收集,也可以使用第三方提供的免费或收费的数据。

一般来讲,数据放在txt文本文件中,按照一定的格式进行存储,便于解析及处理。

准备数据:使用Python解析、预处理数据。

分析数据:可以使用很多方法对数据进行分析,例如使用Matplotlib将数据可视化。

测试算法:计算错误率。

使用算法:错误率在可接受范围内,就可以运行k-近邻算法进行分类。

注:在下面的程序中,我们直接创建模拟数据

**

四.主要代码

**

在这里,我们使用Python代码来实现一个KNN算法的二分类问题。


(1)创建模拟数据:


# 生成模拟数据(data generation)# 二分类(0/1)# 随机种子

np.random.seed(271)# 数据集1:点的数量

data_size_1 = 300

# 特征1

x1_1 = np.random.normal(loc=5.0,scale=1.0,size=data_size_1)

# 特征2

x2_1 = np.random.normal(loc=4.0,scale=1.0,size=data_size_1)

# 类别值:0

y_1 = [0 for _ in range(data_size_1)]



# 数据集2:点的数量

data_size_2 = 400

# 特征1

x1_2 = np.random.normal(loc=10.0,scale=2.0,size=data_size_2)

# 特征2

x2_2 = np.random.normal(loc=8.0,scale=2.0,size=data_size_2)

# 类别值:1

y_2 = [1 for _ in range(data_size_2)] # 合并

x1 = np.concatenate((x1_1,x1_2),axis=0)

x2 = np.concatenate((x2_1,x2_2),axis=0)x = np.hstack((x1.reshape(-1,1),x2.reshape(-1,1)))

y = np.concatenate((y_1,y_2),axis=0)

(2)打乱两组模拟数据集,进行分组

# 洗牌后的数据(即打乱所有的数据)dat



a_size_all = data_size_1 + data_size_2# numpy.random.permutation():随机排列序列

# 得到一个0-699的索引数组

shuffled_index = np.random.permutation(data_size_all)

x = x[shuffled_index]

y = y[shuffled_index]



# 切分成两组,一组训练,一组测试

split_index = int(data_size_all * 0.7)

# 训练集0-split_index

x_train = x[:split_index]

y_train = y[:split_index]

# 测试集split_index-(data_size_all-1)

x_test = x[split_index:]

y_test = y[split_index:]

(3)展示数据


# 展示数据visualize data

# 训练集

plt.scatter(x_train[:,0],x_train[:,1],c=y_train,marker='.')

plt.show()

# 测试集

plt.scatter(x_test[:,0],x_test[:,1],c=y_test,marker='.')

plt.show()

(4)归一化


# data preprocessing归一化x_train = (x_train - np.min(x_train,axis=0)) / (np.max(x_train,axis=0) - np.min(x_train,axis=0))x_test = (x_test - np.min(x_test,axis=0)) /  (np.max(x_test,axis=0) - np.min(x_test,axis=0))

(5)knn.py


import numpy as npimport operator# 类KNN

class KNN(object):

    # 函数1

    def __init__(self, k=3):

        self.k = k



    # 把x,y传进去

    def fit(self, x, y):

        self.x = x

        self.y = y



    # 计算任意两点的距离的平方

    def _square_distance(self, v1, v2):

        return np.sum(np.square(v1-v2))



    # 投票机制

    def _vote_(self, ys):

        # 取ys得唯一值

        ys_unique = np.unique(ys)

        # 字典

        vote_dict = {}

        for y in ys:

            if y not in vote_dict.keys():

                vote_dict[y] = 1

            else:

                vote_dict[y] += 1

         sorted_vote_dict = sorted(vote_dict.items(),key=operator.itemgetter(1), reverse=True)

        # 返回最大的值

        return sorted_vote_dict[0][0]



    def predict(self, x):

        y_pred = []

        for i in range(len(x)):

            # 当前x[i]和所有训练样点的平方距离,保存在dist_arr数组中

            dist_arr = [self._square_distance(x[i], self.x[j]) for j   in range(len(self.x))]

            sorted_index = np.argsort(dist_arr)

            # 提取从开始到self.k的索引数组,保存在top_k_index数组中

            top_k_index = sorted_index[:self.k]

            y_pred.append(self._vote_(ys=self.y[top_k_index]))

        return np.array(y_pred)

    # 计算精度

    def score(self, y_true=None, y_pred=None):

        if y_true is None or y_pred is None:

            y_pred = self.predict(self.x)

            y_true = self.y

        score = 0.0

        for i in range(len(y_true)):

            if y_true[i] == y_pred[i]:

                score += 1

        # 计算正确率

        score /= len(y_true)

        return score

(6)创建分类器


# knn classifier# 建立分类器

clf = KNN(k=3)

# 把x_train,y_train传进去

clf.fit(x_train,y_train)

# 得到训练集的精度

score_train = clf.score()

# 保留三位小数输出

print('train accuracy:{:.3}'.format(score_train))



# 传入测试集,与训练集进行比较,得到其预测值

y_test_pred = clf.predict(x_test)

# 得到测试集的精度,并保留三位小数

print('test accuracy:   {:.3}'.format(clf.score(y_test,y_test_pred)))

 

注:完整代码及注释见源程序
五.运行结果
训练集:

在这里插入图片描述

测试集:
在这里插入图片描述

在这里插入图片描述

六.个人总结

这次的作业是用Python程序实现KNN算法,我个人觉得还是挺难的。主要是因为刚接触到机器学习,常用库里面的一些函数弄不清楚,似懂非懂的很模糊,理解起来也比较难。

所以,我们首先要好好理解KNN算法的原理,能解决的问题。

在这里,我写的程序是一个KNN二分类问题。实现过程比较容易的是模拟数据的创建,难点为推测,主要通过距离公式以及数学运算。

要注意的问题有k值的选择,k值较小,容易发生过拟合;k值较大,容易

发生欠拟合。另外,如果我们没有考虑每个特征的量纲问题,则计算距离的时候可能会出现误差,这是,我们就需要用到归一化,来解决不同的数据在不同列数据的数量级相差过大的话,计算起来大数的变化会掩盖掉小数的变化。在这里,我们用到归一化形式中的min-max标准化(也称为离差标准化,是对原始数据的线性变换,使结果值映射到[0 - 1]之间):

总的来说,这次的作业让我们更加深刻的理解了KNN算法,进入了机器学习的大门。机器学习是一门很深的课程,需要我们不断去理解、探索,也需要我们去不断地实践。

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值