Pythonで逐次型自己組織化マップ
自己組織化マップとはなにか
自己組織化マップ(Self Organizing Map)は、多次元の特徴ベクトルをベクトルの関係性を維持しながら任意の次元に写像する様に学習するニューラルネットワークの1つです。
難しい言い回しですね。
色の例を用いてざっくりと説明します。
まず、マス毎にランダムに色が塗られている方眼紙があるとします。
そして、スイッチを押すとランダムに色が出てくる変な機械があるとします。
誰が何の為にそんな機械があるかどうかは考えないでおきます。
SOMの学習は次のように行われます。
- スイッチを押して色を取得する
- 方眼紙の中から最も取得した色に近いマスを選択する
- そのマスの色と取得した色を混ぜあわせる
- ついでにそのマスの周りのマスにも少し色を混ぜあわせる
- 上記を繰り返す
学習終了後に方眼紙を眺めてみると、似た色同士が近い所に集まるように方眼紙が塗り分けられています。
(例)
色の説明だけだとSOMの用途が分かりにくいですよね。
SOMの主な用途はベクトル間の関係を壊さずに少ない次元に写像する事で、人間には分かりにくい多次元のデータの関係の可視化を行ったり、近傍関係を用いてクラスタリングに利用したりします。
Pythonによる逐次型自己組織化マップの実装
__author__ = 'emoson' #ユークリッド距離 dist = lambda vec1, vec2: (sum([(vec[0]-vec[1])**2 for vec in list(zip(vec1, vec2))]))**0.5 def near(map_vector, input_vector): """ input_vectorに対し、最近傍ユニットのラベルを返す :param map_vector: :param input_vector: :return: """ dist_vector = [dist(input_vector, m) for m in map_vector] return dist_vector.index(min(dist_vector)) def learning(input_vectors, map_width, map_height, vec_size, learning_count, area_size): """ 自己組織化マップの学習 :param input_vectors: :param map_width: :param map_height: :param vec_size 入力ベクトルの次元数(色の場合はrgbの3次元): :param learning_count: :param area_size: :return map_vector: """ import random map_vector = [[random.random() for v in range(vec_size)] for h in range(map_height) for w in range(map_width)] a = 1.0 a_size = area_size for t in range(learning_count): for input_vector in input_vectors: #近傍ユニットの探索 bmu = near(map_vector=map_vector, input_vector=input_vector) #重みの更新 for i in range(map_width * map_height): c = (a_size - dist([i // map_width, i % map_width], [bmu // map_width, bmu % map_width])) if c > 0: map_vector[i] = [mv+c*a*(iv-mv) for iv, mv in zip(input_vector, map_vector[i])] #学習係数、学習範囲の更新 a = (learning_count - t) / learning_count a_size = area_size * (learning_count - t) / learning_count return map_vector
次のように呼び出すと、学習されたSOMのmapが返って来ます。
width = 20 height = 20 import random input_vectors = [[random.random() for j in range(3)] for i in range(30)] som_map = learning(input_vectors=input_vectors, map_width=width, map_height=height, vec_size=3, learning_count=0, area_size=3)
学習回数毎にSOMのマップを可視化すると、次のようになります。
徐々にマップが学習されている様子が分かりますね。