Pythonでbatch型SOM
この記事に書かれていること
Pythonによるbatch型自己組織化マップの実装
Batch型SOMって何?
前回、Pythonによる逐次型自己組織化マップをPythonで実装しました。
Pythonで逐次型自己組織化マップ - 理系大学生がPythonで色々頑張るブログ
逐次型の自己組織化マップは、学習の際に与えられる入力ベクトルの順番によって、学習結果が大きく異る性質が有ります。
この性質は、研究対象としてとても有意義なものですが、クラスタリングやデータの可視化に用いる場合には再現性に疑問が残ります。
対し、Batch型の自己組織化マップは、重みベクトルの更新タイミングを全てのベクトルを処理した後にまとめて行う事で、入力ベクトルの順番の影響をなくしています。
PythonによるBatch型SOMの実装
__author__ = 'emoson' import math 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 batch_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_size = area_size for t in range(learning_count): w = [[[0 for v in range(vec_size)] for i in range(2)] for h in range(map_height) for w in range(map_width)] 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: w[i][0] = [w[i][0][j] + c*input_vector[j] for j in range(vec_size)] w[i][1] = [w[i][1][j] + c for j in range(vec_size)] #学習の更新 for i in range(map_width * map_height): map_vector[i] = [w[i][0][j]/w[i][1][j] if w[i][1][j] is not 0 else map_vector[i][j] for j in range(vec_size)] a_size = area_size * (learning_count - t) / learning_count return map_vector
前回と同様のパラメータで実行した際のマップは次のようになります。
比較の為に逐次型SOMの結果も載せておきます。
逐次型SOM
Batch型SOM