手把手教你用OpenCV实现机器学习最简单的k-NN算法(附代码)

本文介绍了如何使用OpenCV和Python基础知识实现机器学习中的k-NN算法。通过一个关于足球粉丝的例子,阐述了监督学习的问题,并详细讲解了k-NN算法的原理。文章还提供了使用OpenCV创建k-NN模型的步骤,包括生成训练数据、训练分类器和预测新数据点的类别。最后,讨论了k值选择对分类结果的影响。
摘要由CSDN通过智能技术生成

640?wx_fmt=gif

导读:OpenCV 的构建是为了提供计算机视觉的通用基础接口,现在已经成为经典和最优秀的计算机视觉和机器学习的综合算法工具集。作为一个开源项目,研究者、商业用户和政府部门都可以轻松利用和修改现成的代码。


k-NN算法可以认为是最简单的机器学习算法之一。本文教你利用OpenCV 和 Python 的基础知识,实现 k-NN算法。

 
 


作者:迈克尔·贝耶勒(Michael Beyeler)

如需转载请联系大数据(ID:hzdashuju)


640?wx_fmt=jpeg



01 使用分类模型预测类别:问题的提出


假设在一个叫作随机镇的小镇,人们对他们的两个运动队随机城红队和随机城蓝队非常痴迷。红队历史悠久,深受人们喜爱。但随后一些外镇的百万富翁来到小镇,买下红队中最出色的得分手,并开始组建一支新的球队,蓝队。


除了让大部分红队球迷不满之外,那个最出色的得分手依旧可以在蓝队中一步一步赢得冠军。尽管依旧会有一些永远无法原谅他早期职业选择的球迷不满,几年之后他还是会返回红队。


但无论如何,你可以发现红队球迷与蓝队球迷的关系并不好。事实上,这两队的球迷因为不愿与对方做邻居,连住所都是分开的。我甚至听到过这种故事,红队球迷在蓝队球迷搬到家附近时,会故意搬走到其他地方。这是真实的故事!


无论如何,我们一无所知的进入这个小镇,尝试挨家挨户卖给人们一些蓝队的货物。然而,时不时地会遇到一些热血的红队球迷会因为我们售卖蓝队的东西而对我们大喊大叫,并把我们驱赶出他们的草坪。非常不友好!如果可以避免这些房屋而仅仅访问那些蓝队球迷的家,压力将会更小,也可以更好地利用时间。


由于坚信可以学会预测红队球迷居住的地方,我们开始记录每次的访问。如果遇到了一个红队球迷的家,就在手边的小镇地图上画一个红色三角形;否则,就画一个蓝色正方形。一阵子之后,我们就非常了解他们的居住信息了。


640?wx_fmt=png

▲随机镇的小镇地图


然而,现在我们到了地图中绿色圆圈标记的房子前了。应该敲门吗?我们尝试着找到一些线索来确定他们支持哪个球队(也许在后阳台上插着球队的旗帜),但没有找到。那如何知道敲门是否安全呢?


这个有些愚蠢的例子准确说明了监督学习算法可以解决的一类问题。我们有一些观察信息(房屋、房屋的地点和他们支持球队的颜色)组成了训练数据。可以使用这些数据来从经验里学习,这样当面对预测新房子的主人支持的球队颜色这一任务时,就可以有足够的信息做出评估。


正如前面所说,红队的球迷对他们的球队非常狂热,因此他们绝不可能成为蓝队球迷的邻居。我们是否可以使用这个信息比对所有邻居的房屋,以此来查明居住在新房子中的是哪一队的球迷?


这正是k-NN算法将要处理的问题。



02 理解 k-NN 算法


k-NN算法可以认为是最简单的机器学习算法之一。原因是我们只需要存储训练数据集。接下来,为了对新数据点进行预测,仅需要在训练数据集中找到它最近邻的点就可以了。


简单而言,k-NN算法认为一个数据点很可能与它近邻的点属于同一个类。思考一下:如果我们的邻居是红队球迷,我们很可能也是红队球迷,否则我们可能很早之前就搬家到其他地方了。对于蓝队球迷而言也是这样。


当然,有些社区可能稍微复杂一些。在这种情况下,我们将不仅仅考虑我们最近邻的类别(即k=1),而是考虑k个最近邻的类别。对于前面提到的例子,如果我们是红队球迷,我们可能不会搬到邻居大部分都是蓝队球迷的地方。


这就是它的全部了。



03 使用 OpenCV 实现 k-NN


使用OpenCV,可以很轻松地通过cv2.ml.KNearest_create()函数来创建一个k-NN模型。然后进行以下几步:


  1. 生成一些训练数据。

  2. 指定k值,创建一个k-NN对象。

  3. 找到想要分类的新数据点的k个最近邻的点。

  4. 使用多数投票来分配新数据点的类标签。

  5. 画出结果图。


首先引入所有必需的模块:使用k-NN算法的OpenCV、处理数据的NumPy用于绘图的Matplotlib。如果使用Jupyter Notebook,别忘了调用%matplotlib inline魔法命令。


In [1]: import numpy as np...     import cv2...     import matplotlib.pyplot as plt...     %matplotlib inlineIn [2]: plt.style.use('ggplot')import numpy as np
...     import cv2
...     import matplotlib.pyplot as plt
...     %matplotlib inline
In [2]: plt.style.use('ggplot')


1. 生成训练数据


第一步是生成一些训练数据。我们将使用NumPy的随机数生成器来完成这个操作。我们将固定随机数生成器的种子值,这样重新运行脚本将总可以生成相同的值。


 
 
In [3]: np.random.seed(42)42)


好了,现在可以开始了。那么我们的训练数据到底应该是什么样子的呢?


在前面的例子中,数据点是小镇地图中的房子。每个数据点有两个特征(也就是,在小镇地图上的位置的x和y坐标)以及一个类别标签(也就是,如果是蓝队球迷居住的地方则是一个蓝色的正方形,如果是红队球迷居住的地方则是一个红色的三角形)。


单独数据点的特征可以用一个具有两个元素的向量表示,这个向量表示数据点在小镇地图上的x坐标和y坐标。相似的,如果标记是蓝色的正方形,则类别是数字0,如果是红色的三角形,则类别是数字1。


可以通过从地图上随机选择一个位置并随机分配一个标签(不是0就是1)就可以生成一个数据点。假设小镇地图的范围是0≤x<100和0≤y<100。那么可以使用下面的代码来生成一个随机数据点:


 
 
In [4]: single_data_point = np.random.randint(0, 100, 2)...     single_data_pointOut[4]: array([51, 92])01002)
...     single_data_point
Out[4]: array([5192])


正如上面的输出结果所示,这段代码将会从0到100之间获取两个随机的整数。我们将把第一个整数当作数据点在地图上的x坐标值,第二个整数当作数据点的y坐标值。同样,可以为这个数据点选择一个标签:


 
 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值