機械学習のライブラリsklearnを用いて、
クラスタリングしてみたいです。
このような要望にお応えします。
sklearnは、様々な機械学習手法を簡単に使用することができるツールです。
そして、sklearnを用いることでクラスタリング手法を簡単に使用することができます。
クラスタリングは、教師なしデータ(ラベル付けがなされていないデータ)に対して、類似属性を持つデータをクラスタと呼ばれる部分集合としてグループ化します。
クラスタリングでは、対象をベクトルとして表現します。
コサイン類似度を指標として、データ間の距離(類似度)を計測することでデータを分類します。
今回は、果物画像の分類をしてみたいと思います。
データは画像ですので、これをベクトルに変換する必要があります。
本記事では、64*64 pixelのRGB画像をデータとして使用します。 そのため、画像をベクトル変換したとき、その次元数が画像を縦pixel数*横pixel数*カラーチャネル数となるようにします。
クラスタリング手法は、k-means法を用います。
ざっくりとk-means法について整理します。
k-means法は、以下の3つの手順を実施することによりクラスタリングを行います。
phase.1 初期値となる重心点をサンプルデータからクラスタ数だけ求める。
phase.2 各サンプルから最も近い距離にあるデータを計算によって求め、クラスタを構成する。
phase.3 phase.2を設定した回数分実行し、類似度に基づきデータを分類する。
クラスタリング分析手順を実装するにあたり、以下のライブラリを使用します。
・pandas
・numpy
・sklearn
・matplotlib
・Pillow
・opencv-python
・glob
ライブラリが存在しない場合は、以下のようにインストールしましょう。
1 2 3 4 5 6 |
pip install pandas pip install numpy pip install scikit-learn pip install matplotlib pip install Pillow pip install opencv-python |
環境としては、anaconda prompt経由でjupyter notebookを使用します。
ソースコードは、以下になります。
input dir->には、画像データを保存したフォルダを指定します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# coding: utf-8 from PIL import Image import cv2 import glob import matplotlib.pyplot as plt import numpy as np from sklearn.cluster import KMeans def fn_image_convert(dir_name): files = glob.glob(dir_name + '/*') # print(files) col = 10 row = int(len(files) / col) + 1 cols = 64 rows = 64 dpis = 100 fig = plt.figure(figsize=(cols, rows), dpi=dpis) index = 1 for f in files: try: img = Image.open(f) img_resize = img.resize((64, 64)) plt.subplot(row, col, index) plt.imshow(img_resize, cmap='gray') index += 1 except OSError as e: return features = np.array([cv2.cvtColor(cv2.resize(cv2.imread(f), (64, 64), cv2.INTER_CUBIC), cv2.COLOR_BGR2RGB) for f in files]) print(features.shape) train_data = features.reshape(features.shape[0], features.shape[1]*features.shape[2]*features.shape[3]).astype('float32') / 255.0 print(train_data.shape) # モデル定義 model = KMeans(n_clusters=9, init='k-means++', max_iter=5000, random_state=0) y_res = model.fit_predict(train_data) # 結果出力 fig = plt.figure(figsize=(cols, rows), dpi=dpis) index = 1 for label, p in zip(y_res, features): plt.subplot(row, col, index) plt.imshow(p, cmap='gray') plt.xlabel("cluster={}".format(label), fontsize=30) index += 1 if __name__ == '__main__': dir_name = input('input dir->') fn_image_convert(dir_name) |
出力結果は、以下のようになりました。
類似する果物画像が分類される傾向にあるようですが、誤分類もありますね。
色だけでなく、形状が類似する果物画像のベクトル距離が近くなるからでしょうか?
このように、sklearnを用いることで、様々なデータに対して機械学習の手法を適用できますので是非試してみましょう。