Posted at

Python3(OpenCV)を使ってデータ分類(K近傍法)

今回はOpenCVを使ってデータを分類を行いたいと思います.

分類した結果をPython3のmatplotlibを使って可視化します.


matplotlibとは

matplotlibはPythonでグラフを描画するときなどに使われる標準的なライブラリです.

画像ファイルを作るばかりでなく,簡単なアニメーションやインタラクティブなグラフを作ることもできます.

実際の例はmatplotlibサイトのギャラリーで見ることができます.

https://matplotlib.org/gallery.html


準備

サンプルコードを動かす上で予めいくつかモジュールを読み込んでおきます.

import cv2

import numpy as np
import matplotlib.pyplot as plt


OpenCVとは

OpenCV(Open Source Computer Vision Library)は,コンピューターで画像や動画を処理するための機能がまとめて実装されている,オープンソースのライブラリです.

「OpenCV-Python Tutorials」というサイトで,様々な機能が紹介されていますので,ぜひ確認してみてください.

https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_imgproc/py_table_of_contents_imgproc/py_table_of_contents_imgproc.html

先では,import cv2 が必要と言いました.Python3からOpenCVを利用するには,

opencv-pythonライブラリをインストールします.

OpenCVは,いくつかの方法でインストールできますが,

pip3 install opencv-pythonでインストールするが最も簡単でおすすめです.

print(cv2.__version__) を使ってOpenCVのバージョンを確認することができます.

※「pip3」のバージョンによってpipの可能性があります.


K近傍法(KNN)


概要

K近傍法は,Yが未知のXのデータがあった時に,未知のYを推測する方法です.

K近傍法は,K個の「K」を自分で予め決めておいて,その地点に近い順のK個の地点の情報から,推測する方法です.

また,K近傍法は,データ全体ではなく,一部のデータだけを使いますので,YとXの関係を数式で表す事ができなくても,確からしい推測ができます.

局所的な推測に,有利な方法です.


計算

距離関数を使って,既知のX群の中のどの辺りにあるのかを調べます.

次に,結合関数を使って,近傍のk個のYから,未知のYの大きさを計算します.

距離関数や結合関数は自分で選べます.

EX. 距離関数は「ユークリッドの距離」,結合関数は「平均値」があります.


プログラム

import cv2

import numpy as np
import matplotlib.pyplot as plt

trainData = np.random.randint(0,100,(50,2)).astype(np.float32) #(1)
responses = np.random.randint(0,2,(50,1)).astype(np.float32) #(2)

red = trainData[responses.ravel() == 0] #(3)
plt.scatter(red[:,0], red[:,1], 80, "r", "^") #(3)

blue = trainData[responses.ravel() == 1] #(4)
plt.scatter(blue[:,0], blue[:,1], 80, "b", "s") #(4)

newdata = np.random.randint(0,100,(1,2)).astype(np.float32) #(5)
plt.scatter(newdata[:,0], newdata[:,1], 80, "g", "o") #(5)

knn = cv2.ml.KNearest_create() #(6)
knn.train(trainData, cv2.ml.ROW_SAMPLE, responses) #(6)
ret,results,neighbours,dist = knn.findNearest(newdata, 5) #(6)

print("result:\t{}".format(results))
print("neighbours:\t{}".format(neighbours))
print("distance:\t{}".format(dist))

plt.show()


コード解説

(1): (x,y)データを50個作る,大きさ0~100,50行2列

(2): 50個のデータについてランダムに0のクラスか1のクラスを割り振る,50行1列

(3): 0のデータは赤色の点,プロット

(4): 1のデータは青色の点,プロット

(5): 未分類データの出現(1つ)緑色の点,プロット

(6): KNNを実行します,K=5とします

ここで注意する点は (6)の1,2行目,

knn = cv2.KNearest()

knn.train(trainData,responses)


で書く人がいますが,これではエラーは出ます.

これは古いバージョンの書き方,上記の方は新しいバージョンの書き方です.

上のプログラムを実行して表示する図は以下のようになります.



図にすることによって視覚的に,緑色の点(未分類データ)は,1のデータのクラスに属していることがわかった.

今回のPython3(OpenCV)を使ってデータ分類(K近傍法)は以上で終わります.

読んでいただいてありがとうございます.