关于机器学习中的K_NN近邻算法的原理和总结 基于python

讲一下这个小项目的背景和缘由

情况是这样,前些天导师交给我一个小任务,给我了一段飞行器飞行中的高度,航速,仰角等数据随时间实时变化的视频,要求我通过图像处理的方法来把视频中的数据按照时间识别提取出来,最好能够导出来一个excel表格数据。*
我在刚接到这个事情的时候思路是这样,先把给的这个视频读取出来,用opencv模块把它按帧截取保存下来,然后跟据它的帧率,确定选择一个帧片来识别处处理,来达到每秒或者每0.5秒的一个数据变化,总体上来说,就是将视频处理转变为图片处理。那现在的问题就是如何对图片处理识别,在刚开始我的思路是利用图像轮廓学的算法对待处理图片,划定ROI感兴趣区,灰度化后进行二值化,然后对二值化后的ROI识别区数字数据的一个识别。但是我在这个过程中遇到一个问题,就是老师给的这个视频分辨率太低了,取帧后,再划定ROI区域后,肉眼可见的模糊,二值化后基本上看不到一个数字的轮廓了,通过膨胀一些操作也收获甚微。于是我转变思路,想通过细化操作,即便你分辨率再低,那主体框架应该还在吧,结果我还是高估了,细化后也是惨不忍睹。我寻思可能是我算法的问题,就换了一张清晰的图片,结果识别效果良好,基本没有错误案例。于是乎只好等到新的清晰数据视频再进行处理,但是在这个过程中,K_NN近邻分类这个算法,也是深度学习分类算法的基础算法,我有在学习,他是一个较为基础简单的一个算法,我想在这里总结归纳一下,各位大佬看着笑笑就好了,另外各位大佬如果有什么能够改变图像分辨率,特别是截取它的ROI区域,还有良好显示效果的方法,请大佬分享学习一下,感激不尽。

k_NN近邻分类算法的原理.

K__NN近邻算法(K Nearest Neighbor,)属于机器学习中的一种经典的分类识别算法,通过计算新数据与训练特征值之间的距离,然后选取K(K>=1个距离最近的邻居进行分类或者回归,如果K=1,那新数据就会给分配给离它的特征距离最近的类别)我的理解就是:原来的训练集不同类的特征分布肯定是一个聚类分布,聚集在某一区域分布,在这一区域内的都可以看成同一类,那K__NN近邻算法思想就是,在我们新的待判断识别的特征点它的周围找K个最近(特征距离最小)的特征点,然后找出这K个特征点分别属于哪个类,对他们分别所属的类进行一个投票,得到票数最高的那个类,就是我们的分类结果,最多能得K票。
K-NN近邻算法是一种有监督学习,当它用于分类时,每一个训练数据都有明确的label,也可以明确的判断出新数据的label

k_NN近邻分类算法的过程

1.选择一种距离计算方式。通过数据所有的特征计算新数据与已知类别数据集中数据点的距离
2.按照距离递增次序进行排序,选取与当前距离最小的K个点。
对于离散分类,返回k个点出现频率最多的类别作为预测分类;对于回归,返回k个点的加权值作为预测值

具体我们通过下面的算法一步一步搭建训练模型具体跑一下

基于python的K_NN近邻算法的训练模型实例搭建

import numpy as np
import matplotlib.pyplot as plt
import operator

# data generation 训练集与测试集的设置
np.random.seed(314)

#第一类设置特征点以(4,4)为中心的随机分布的100个点
data_size1 = 100
x1 = np.random.randn(data_size1, 2) + np.array([4, 4]) 
y1 = [0 for _ in range(data_size1)]

#第二类设置特征点以(10,10)为中心的随机分布的100个点
data_size2 = 100
x2 = np.random.randn(data_size2, 2) + np.array([10, 10])
y2 = [1 for _ in range(data_size2)]

# all sample data
x = np.concatenate((x1, x2), axis=0)
y = np.concatenate((y1, y2), axis=0)

data_size_all = data_size1 + data_size2
shuffled_index = np.random.permutation(data_size_all)
x = x[shuffled_index]
y = y[shuffled_index]

# split train test 选择70&的点作为训练集,剩下的点作为测试集
split_index = int(data_size_all * 0.7)
x_train = x[:split_index]
y_train = y[:split_index]
x_test = x[split_index:]
y_test = y[split_index:]

# plot data 画出训练集的特征点的分布
plt.scatter(x_train[:, 0], x_train[:, 1], c=y_train, marker='.')
plt.title("train data")
plt.show()

#画出测试集的特征点的分布
plt.scatter(x_test[:, 0], x_test[:, 1], c=y_test, marker='.')
plt.title("test data")
plt.show()

############# data test and function
#距离的计算函数,这个特征在二维上就用简单的二维平方距离计算
def knn_distance(v1, v2):
    return np.sum(np.square(v1 - v2))

#投票函数,把我们K个中的类别进行投票,返回票数最多的那个类别
def knn_vote(ys):
    method = 1
    # method = 1
    if method == 1:
        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=lambda x: x[1], \
                                  reverse=True)
        return sorted_vote_dict[0][0]

    # method 2
    if method == 2:
        maxv = 0
        maxk = 0

        vote_dict = {}
        for y in ys:
            if y not in vote_dict.keys():
                vote_dict[y] = 1
            else:
                vote_dict[y] += 1

        for y in np.unique(ys):
            if maxv < vote_dict[y]:
                maxv = vote_dict[y]
                maxk = y
        return maxk

#我们的预测函数,计算我们的特征点与已有的特征点的距离,形成分类数组,对数组中的类投票,返回投票结果
``def knn_predict(x, train_x, train_y, k=3):
    dist_arr = [knn_distance(x, train_x[j]) for j in range(len(train_x))]
    sorted_index = np.argsort(dist_arr)
    top_k_index = sorted_index[:k]
    ys = train_y[top_k_index]
    return knn_vote(ys)`

#用训练数据训练模型
y_train_est = [knn_predict(x_train[i], x_train, y_train) for i in range(len(x_train))]
#打印结果
print(y_train_est)

#correct complete
n_correct = 0
for i in range(len(x_train)):
    if y_train_est[i] == y_train[i]:
        n_correct += 1
accuracy = n_correct / len(x_train) * 100.0
print("Train Accuracy: %f%%" % accuracy)

#Test Accuracy
y_test_est = [knn_predict(x_test[i], x_train, y_train, 3) for i in range(len(x_test))]
n_correct = 0
for i in range(len(x_test)):
    if y_test_est[i] == y_test[i]:
        n_correct += 1
accuracy = n_correct / len(x_test) * 100.0
print("Test Accuracy: %f%%" % accuracy)
print(n_correct, len(x_test))

训练运行结果

训练集的特征数据的分布情况
上面是训练集的特征数据的分布情况
上面是测试集的特征数据的分布情况
上面是测试集的特征数据的分布情况

在这里插入图片描述
结果与训练集,测试集的结果输出。这里可以看出测试集准确率很高,看来我们划分的这两类特征点数据还是离的比较远的。

这是自己学习过程中的小总结,希望能巩固知识,梳理自己的思路。刚开始写博客还不是很熟练,接下来会常常通过写博客总结,希望自己的能力在这个过程中能够得到增强。加油!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值