[贸易源码]手把手教你用OpenCV完成机械进修最复杂的k-NN算法(附代码)

  • A+
所属分类:网络推广
摘要

小白源码资源站原题目:手把手教你用OpenCV完成机械进修最小白源码资源站最复杂的k-NN算法(附代码)导读:OpenCV的构建是为了供给计算机视觉的通用基础接口,现在曾经成为经典和最优良的计算机视觉和机械进修的综合算法对象集。作为一个开源项目,研究者、贸易

小白源码资源站http://www.526bt.com/account?__preferral=41b2453033.2042

原题目:手把手教你用OpenCV完成机械进修最小白源码资源站http://www.526bt.com/account?__preferral=41b2453033.2042最复杂的k-NN算法(附代码)

导读:OpenCV 的构建是为了供给计算机视觉的通用基础接口,现在曾经成为经典和最优良的计算机视觉和机械进修的综合算法对象集。作为一个开源项目,研究者、贸易用户和当局部分都可以轻松应用和修改现成的代码。

k-NN算法可以认为是最复杂的机械进修算法之一。本文教你应用OpenCV 和 Python 的基础常识,完成 k-NN算法。

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

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

01 应用分类模型猜测种别:后果的提出

假定在一个叫作随机镇的小镇,人们对他们的两个活动队随机城红队和随机城蓝队十分痴迷。红队汗青悠长,深受人们爱好。但随后一些外镇的百万财主离开小镇,买下红队中最出色的得分别,并末尾组建一支新的球队,蓝队。

除让大年夜局部红队球迷不满以外,阿谁最出色的得分别还是可以在蓝队中一步一步赢得冠军。固然还是会有一些永久没法谅解他早期职业选择的球迷不满,几年以后他照样会前去红队。

但不管若何,你可以发明红队球迷与蓝队球迷的关系并欠好。抱负上,这两队的球迷因为不愿与对方做邻居,连居处都是离开的。我乃至听到过这类故事,红队球迷在蓝队球迷搬到家左近时,会故意搬走到其他中央。这是真实的故事!

不管若何,我们一窍不通的进入这个小镇,测验测验挨家挨户卖给人们一些蓝队的货色。然则,时不时地会碰到一些热血的红队球迷会因为我们售卖蓝队的器械而对我们大年夜喊大年夜叫,并把我们驱逐出他们的草坪。十分不友好!假设可以防止这些房屋而仅仅访问那些蓝队球迷的家,压力将会更小,也能够更好地应用时间。

因为坚信可以学会猜测红队球迷寓居的中央,我们末尾记录每次的访问。假设碰到了一个红队球迷的家,就在手边的小镇地图上画一个白色三角形;否则,就画一个蓝色正方形。一阵子以后,我们就十分了解他们的寓居信息了。

▲随机镇的小镇地图

然则,现在我们到了地图中绿色圆圈标记的房子前了。应当敲门吗?我们测验测验着找到一些线索来肯定他们支撑哪个球队(或许在后阳台上插着球队的旗号),但没有找到。那若何知道敲门可否平安呢?

这个有些愚蠢的例子准确说清晰明了监督进修算法可以处理的一类后果。我们有一些不美观察信息(房屋、房屋的地点和他们支撑球队的色彩)构成了练习数据。可以应用这些数据来从经历里进修,如许当面对猜测新居子的主人支撑的球队色彩这一义务时,便可以有足够的信息做出评价。

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

这正是k-NN算法将要处理的后果。

02 了解 k-NN 算法

k-NN算法可以认为是最复杂的机械进修算法之一。启事是我们只需求存储练习数据集。接上去,为了对新数据点停止猜测,仅需求在练习数据集中找到它比来邻的点便可以了。

复杂而言,k-NN算法认为一个数据点很能够与它近邻的点属于统一个类。思考一下:假设我们的邻居是红队球迷,我们很能够也是红队球迷,否则我们能够很早之前就搬场到其他中央了。关于蓝队球迷而言也是如许。

固然,有些社区能够稍微复杂一些。在这类状况下,我们将不只仅思考我们比来邻的种别(即k=1),而是思考k个比来邻的种别。关于前面提到的例子,假设我们是红队球迷,我们能够不会搬到邻居大年夜局部都是蓝队球迷的中央。

这就是它的全部了。

03 应用 OpenCV 完成 k-NN

应用OpenCV,可以很轻松地经过cv2.ml.KNearest_create()函数来创立一个k-NN模型。然后停止以下几步:

生成一些练习数据。
指定k值,创立一个k-NN对象。
找到想要分类的新数据点的k个比来邻的点。
应用少数投票来分派新数据点的类标签。
画出结果图。

起首引入一切必须的模块:应用k-NN算法的OpenCV、处理数据的NumPy、用于画图的Matplotlib。假设应用Jupyter Notebook,别忘了调用%matplotlib inline魔法敕令。

In [ 1]: importnumpy asnp

... importcv2

... importmatplotlib.pyplot asplt

... %matplotlib inline

In [ 2]: plt.style.use( 'ggplot')

1. 生成练习数据

第一步是生成一些练习数据。我们将应用NumPy的随机数生成器来完成这个操作。我们将固定随机数生成器的种子值,如许从新运转脚本将总可以生成相反的值。

In [ 3]: np.random.seed( 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_point

Out[ 4]: array([ 51, 92])

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

In [ 5]: single_label=np.random.randint( 0, 2)

... single_label

Out[ 5]: 0

结果表现这个数据点的种别是0,我们把它算作一个蓝色的正方形。

把这个过程包装成函数,输入是要生成的数据点的个数(即num_sample)和每个数据点的特点数(即num_features)。

In [ 6]: defgenerate_data(num_samples, num_features=2):

"""随机生成一些数据点"""

因为在这个例子中特点的数量是2,应用默许的参数值是没有后果的。在这类调用函数时不显式指定num_features值的状况下,这个参数会被主动分派为2。置信你曾经了解了这个常识点。

我们想要创立的数据矩阵应当有num_samples行、num_features列,个中每个元素都应当是[0, 100]范围内的一个随机整数。

... data_size=(num_samples, num_features)

... train_data=np.random.randint( 0, 100, size=data_size)

异样,我们想要创立一个一切样本在[0, 2]范围内的随机整数标签值的向量:

... labels_size=(num_samples, 1)

... labels=np.random.randint( 0, 2, size=labels_size)

别忘了让函数前去生成的数据:

... returntrain_data.astype(np.float32), labels

Tips:OpenCV关于数据类型有些过分的考究,因此确保总是把数据点的类型转换为np.float32!

接上去对函数停止测试,师长教师成任意数量的数据点,比如说11个数据点,并随机选择它们的坐标:

In [ 7]: train_data, labels=generate_data( 11)

... train_data

Out[ 7]: array([[ 71., 60.],

[ 20., 82.],

[ 86., 74.],

[ 74., 87.],

[ 99., 23.],

[ 2., 21.],

[ 52., 1.],

[ 87., 29.],

[ 37., 1.],

[ 63., 59.],

[ 20., 32.]], dtype=float32)

可以从下面的输入结果看到,train_data变量是一个11x2的数组,每行表现一个独自的数据点。可以经过应用数组的索引获得第一个数据和它对应的标签:

In [ 8]: train_data[ 0], labels[ 0]

Out[ 8]: (array([ 71., 60.], dtype=float32), array([ 1]))

这个结果通知我们第一个数据点是一个蓝色的正方形(因为它的种别是0),它在小镇地图的坐标位置是(x, y)=(71, 60)。假设想要的话,可以应用Matplotlib在小镇地图上画出这个数据点:

In [ 9]: plt.plot(train_data[ 0, 0], train_data[ 0, 1], 'sb')

... plt.xlabel( 'x coordinate')

... plt.ylabel( 'y coordinate')

Out[ 9]:

但假设想要一次就显示一切的练习数据集呢?可以写一个函数。这个函数的输入应当是一个一切都是蓝色正方形的数据点的列表(all_blue)和一个一切都是白色三角形的数据点的列表(all_red):

In [ 10]: defplot_data(all_blue, all_red):

接上去函数应当可以把一切蓝色数据点用蓝色正方形画出来(应用色彩'b'和标记's'),可以应用Matplotlib中的scatter函数完成这个义务。在应用这个函数时,需求把蓝色数据点算作N×2的数组来传入,个中N是样本的数量。接着all_blue[:,0]包罗了一切蓝色数据点的x坐标,all_blue[:, 1]包罗了一切蓝色数据点的y坐标:

... plt.scatter(all_blue[:, 0], all_blue[:, 1], c='b', marker='s', s=180)

同理,关于一切的白色数据点也能够这么做:

... plt.scatter(all_red[:, 0], all_red[:, 1], c='r', marker='^', s=180)

最后,设置画图的标签:

... plt.xlabel( 'x coordinate (feature 1)')

... plt.ylabel( 'y coordinate (feature 2)')

在我们的数据集上测试一下这个函数吧!起首需求把一切的数据点分红白色数据集和蓝色数据集。可以应用下面的敕令(个中ravel将平面化数组)快速选择前面创立的labels数组中一切等于0的元素:

In [ 11]: labels.ravel()==0

Out[ 11]: array([ False, False, False, True, False, True, True, True, True,

True, False], dtype=bool)

前面创立的train_data中对应标签为0的那些行就是一切蓝色的数据点:

In [ 12]: blue=train_data[labels.ravel()==0]

关于一切的白色数据点也能够异样操作:

In [ 13]: red=train_data[labels.ravel()==1]

最后,让我们画出一切的数据点:

In [ 14]: plot_data(blue, red)

这将会创立以下所示的图:

▲全部练习数据集的可视化

2. 练习分类器

现在是时分练习分类器了。

和其他一切的机械进修函数一样,k-NN分类器也是OpenCV 3.1 中ml模块的一局部。可以应用下面的敕令来创立一个新的分类器:

In [ 15]: knn=cv2.ml.KNearest_create()

Tips:在OpenCV的旧版本中,这个函数能够叫作cv2.KNearest()。

接上去把练习数据传入到train方法中:

In [ 16]: knn.train(train_data, cv2.ml.ROW_SAMPLE, labels)

Out[ 16]: True

这里,必须通知knn我们的数据是一个 N×2 的数组(即每行都是一个数据点)。这个函数会在履行胜利后前去True。

3. 猜测新数据点的种别

knn供给的另外一个十分有效的方法叫作findNearest。它可以依据比来邻数据点的标签来猜测新数据点的标签。

因为有generate_data函数,我们可以十分轻易地生成一个新的数据点!可以把新数据点算作只要一个数据的数据集。

In [ 17]: newcomer, _=generate_data( 1)

Out[ 17]: newcomer

函数也前去一个随机的种别,但我们对它不感兴味。相反,我们想要应用我们练习的模型对它停止猜测!可以经过一个下划线(_)让Python疏忽输入值。

回到我们的小镇地图,我们要像之前一样把练习数据集画出来,并将新的数据点参与,用绿色的圆圈表现(因为我们现在还不知道它应当是一个蓝色的正方形照样一个白色的三角形)。

In [ 18]: plot_data(blue, red)

... plt.plot(newcomer[ 0, 0], newcomer[ 0, 1], 'go', markersize=14);

Tips:可以在plt.plot函数前面添加一个分号以抑制输入,与Matlab一样。

下面的代码将生成下面这幅图(不包罗圆环):

▲全部练习数据集,加上一个有待肯定标签的新数据点(绿色)

假设要你依据它的邻近点猜想,你会给新的数据点分派甚么标签,蓝色照样白色呢?

其实,这也看状况,不是吗?假设看离它比来的房子(阿谁位置大年夜致在(x, y)=(85,75),上图中点圆外面的房子),能够会把新的数据点异样分派一个白色的三角形。这也确实是在k=1的状况下我们的分类器猜测的结果。

In [ 19]: ret, results, neighbor, dist=knn.findNearest(newcomer, 1)

... print( "Predicted label:t", results)

... print( "Neighbors label:t", neighbor)

... print( "Distance to neighbor:t", dist)

Out[ 19]: Predicted label: [[ 1.]]

... Neighbors label: [[ 1.]]

... Distance to neighbor: [[ 250.]]

这里,knn申报说比来邻的点有250个单位远,其种别是1(我们说过1对应的是白色三角形),因此新的数据点种别应当也是1。假设设置k=2比来邻和k=3比来邻,结果也是一样的。

但要当心不要选择任意偶数的k值。为甚么呢?其实,可以从下面的图中看出来(虚线圆),在虚线圆外面的6个比来邻点中,有3个蓝色正方形和3个白色三角形—这是个平局!

Tips:在这类平局的状况下,OpenCV的k-NN完成将会选择到数据点全部距离更近的邻居。

最后,假设十分大年夜地扩大搜刮窗口,依据k=7比来邻来对新数据点分类(在前面的图中是实线圆),会爆发甚么呢?

经过调用findNearest方法并设置k=7,可以看到结果:

In [ 20]: ret, results, neighbor, dist=knn.findNearest(newcomer, 7)

... print( "Predicted label:t", results)

... print( "Neighbors label:t", neighbor)

... print( "Distance to neighbor:t", dist)

Out[ 20]: Predicted label: [[ 0.]]

Neighbors label: [[ 1.1.0.0.0.1.0.]]

Distance to neighbor: [[ 250.401.784.916.1073.1360.4885.]]

突然之间,猜测的标签变成0(蓝色正方形)。启事是现在实线圆内有四个邻居是蓝色正方形(标签0),而只要三个是白色三角形(标签1)。因此少数投票建议猜测新来者也是一个蓝色正方形。

正如所看到的,k-NN的输入结果会随着k的变更而变更。然则,大年夜少数状况下是没法提早知道k为何值时是最适宜的。关于这个后果最复杂的处理方法是测验测验一组k值,其实不美观察哪个的结果最好。

关于作者:Michael Beyeler,华盛顿大年夜学神经工程和数据迷信专业的博士后,主攻仿生视觉计算模型,用认为瞽者植入人工视网膜(仿生眼睛),改良瞽者的视觉体验。 他的任务属于神经迷信、计算机工程、计算机视觉和机械进修的交叉范围。同时他也是多个开源项目标积极贡献者。

本文摘编自《机械进修:应用OpenCV和Python停止智能图象处理》,经出版方授权宣布。

延长浏览《机械进修》

点击上图了解及购置

转载请联系微信:DoctorData

引荐语:OpenCV是一个综合了经典和先辈计算机视觉、机械进修算法的开源库。经过与Python Anaconda版本联合,你便可以获得你所需求的一切开源计算库。本书起首引见分类和回归等统计进修的基本概念,然后具体讲处理策树、支撑向量机和贝叶斯收集等算法,和若何把它们与其他OpenCV函数联合。

Q:你经常使用哪些机械进修算法?

转载 / 投稿请联系:baiyu@hzbook.com

义务编辑:

分享当前页面将至少获得10%佣金,点此获取推广链接(规则说明)。

本站VIP源码资源永久免费下载!持续更新!www.526bt.com

加入999永久VIP会员带做项目包赚钱!教引流包搭建,社群资源共享!

新项目更新通知QQ群:767688774 站长技术交流QQ群:552760713

点击这里给我发消息

  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin
第三方支付通道申请/支付宝支付申请/微信支付代申请/QQ钱包支付-T0实时到账
PHP源码安装ASP源码HTML源码安装服务
支付通道搭建、支付接口搭建、承接各种支付项目
网站漏洞修复 网站木马清理 漏洞修复 漏洞检测 服务器安全维护

发表评论

您必须才能发表评论!