質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

2回答

6725閲覧

pythonでのSOM 自己組織化マップ

kaErita_E

総合スコア14

Python 2.7

Python 2.7は2.xシリーズでは最後のメジャーバージョンです。Python3.1にある機能の多くが含まれています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

1クリップ

投稿2018/01/12 02:30

編集2018/01/12 05:00

pythonで下図のようなファイルを基にSOMを作成したいと考えています.

イメージ説明
参考:https://qiita.com/T_Shinaji/items/609fe9aabd99c287b389

python

1import numpy as np 2from matplotlib import pyplot as plt 3 4class SOM(): 5 6 def __init__(self, teachers, N, seed=None): 7 self.teachers = np.array(teachers) 8 self.n_teacher = self.teachers.shape[0] 9 self.N = N 10 if not seed is None: 11 np.random.seed(seed) 12 13 x, y = np.meshgrid(range(self.N), range(self.N)) 14 self.c = np.hstack((y.flatten()[:, np.newaxis], 15 x.flatten()[:, np.newaxis])) 16 self.nodes = np.random.rand(self.N*self.N, 17 self.teachers.shape[1]) 18 19 def train(self): 20 for i, teacher in enumerate(self.teachers): 21 bmu = self._best_matching_unit(teacher) 22 d = np.linalg.norm(self.c - bmu, axis=1) 23 L = self._learning_ratio(i) 24 S = self._learning_radius(i, d) 25 self.nodes += L * S[:, np.newaxis] * (teacher - self.nodes) 26 return self.nodes 27 28 def _best_matching_unit(self, teacher): 29 #compute all norms (square) 30 norms = np.linalg.norm(self.nodes - teacher, axis=1) 31 bmu = np.argmin(norms) #argment with minimum element 32 return np.unravel_index(bmu,(self.N, self.N)) 33 34 def _neighbourhood(self, t):#neighbourhood radious 35 halflife = float(self.n_teacher/4) #for testing 36 initial = float(self.N/2) 37 return initial*np.exp(-t/halflife) 38 39 def _learning_ratio(self, t): 40 halflife = float(self.n_teacher/4) #for testing 41 initial = 0.1 42 return initial*np.exp(-t/halflife) 43 44 def _learning_radius(self, t, d): 45 # d is distance from BMU 46 s = self._neighbourhood(t) 47 return np.exp(-d**2/(2*s**2)) 48 49 50N = 20 51//このteachersにコレクションとして図のようなふぁい 52teachers = np.random.rand(10000, 3) 53som = SOM(teachers, N=N, seed=10) 54 55# Initial map 56plt.imshow(som.nodes.reshape((N, N, 3)), 57 interpolation='none') 58plt.show() 59 60# Train 61som.train() 62 63# Trained MAP 64plt.imshow(som.nodes.reshape((N, N, 3)), 65 interpolation='none') 66plt.show()

//追記
申し訳ございません途中で送信してしまいました.
続きを追記させていただきます.

上記のプログラムのteachers部分に図のようなコレクションを挿入したく下記のようなプログラムに書き直しました.

python

1import numpy as np 2import csv 3data = [] 4 5with open("data.csv","rb") as f: 6 reader = csv.reader(f) 7 header = next(reader) 8 9 for row in reader: 10 data.append(row) 11 12from matplotlib import pyplot as plt 13 14class SOM(): 15 16 def __init__(self, teachers, N, seed=None): 17 self.teachers = np.array(teachers) 18 self.n_teacher = self.teachers.shape[0] 19 self.N = N 20 if not seed is None: 21 np.random.seed(seed) 22 23 x, y = np.meshgrid(range(self.N), range(self.N)) 24 self.c = np.hstack((y.flatten()[:, np.newaxis], 25 x.flatten()[:, np.newaxis])) 26 self.nodes = np.random.rand(self.N*self.N, 27 self.teachers.shape[1]) 28 29 def train(self): 30 for i, teacher in enumerate(self.teachers): 31 bmu = self._best_matching_unit(teacher) 32 d = np.linalg.norm(self.c - bmu, axis=1) 33 L = self._learning_ratio(i) 34 S = self._learning_radius(i, d) 35 self.nodes += L * S[:, np.newaxis] * (teacher - self.nodes) 36 return self.nodes 37 38 def _best_matching_unit(self, teacher): 39 #compute all norms (square) 40 norms = np.linalg.norm(self.nodes - teacher, axis=1) 41 bmu = np.argmin(norms) #argment with minimum element 42 return np.unravel_index(bmu,(self.N, self.N)) 43 44 def _neighbourhood(self, t):#neighbourhood radious 45 halflife = float(self.n_teacher/4) #for testing 46 initial = float(self.N/2) 47 return initial*np.exp(-t/halflife) 48 49 def _learning_ratio(self, t): 50 halflife = float(self.n_teacher/4) #for testing 51 initial = 0.1 52 return initial*np.exp(-t/halflife) 53 54 def _learning_radius(self, t, d): 55 # d is distance from BMU 56 s = self._neighbourhood(t) 57 return np.exp(-d**2/(2*s**2)) 58 59 60N = 20 61teachers = data 62som = SOM(teachers, N=N, seed=10) 63 64# Initial map 65plt.imshow(som.nodes.reshape((N, N, 3)),interpolation='none') 66plt.show() 67 68# Train 69som.train() 70 71# Trained MAP 72plt.imshow(som.nodes.reshape((N, N, 3)), 73 interpolation='none') 74plt.show()

しかし下記のようなエラーがでてしまいます.
実際のコレクションは33×500の行列なので,(N, N, 3)部分を(N, N, 33)にしたりしてみましたがうまくいきませんでした.

Traceback (most recent call last): File "soms.py", line 65, in <module> plt.imshow(som.nodes.reshape((N, N, 3)),interpolation='none') ValueError: cannot reshape array of size 13200 into shape (20,20,3)

python初学者のため,根本的な話なのかもしれませんがどうかご教授いただけると幸いです.

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fuzzball

2018/01/12 03:48

csvファイルを読み込んで、それをコレクションにしたいという質問でしょうか?そうであれば、そういう質問に書き換えた方が良いと思います。(SOMがどうとか全く関係ない)
kaErita_E

2018/01/12 05:01

コメントありがとうございます.誠に申し訳ございません,途中で送信してしまっていたようです.確認を怠り申し訳ございません.
fuzzball

2018/01/12 05:14

(33, 500)か(500, 33)ではないのでしょうか?なぜコードではN=20にしているのでしょうか?
kaErita_E

2018/01/12 05:31

コメントありがとうございます.N=20は競合層のニューロンの数ではないかとおもい,私も20に指定しました.
guest

回答2

0

こんにちは.

私もpythonで同じ分析を行おうとして,同じ問題に当たりました.
ちょうどそれについて検索をかけてどうにか解決できないかと探っていたところ, こちらにたどり着きました。

先ほど, 問題が解決できたので参考にしていただければと思います.

plt.imshow(som.nodes.reshape((N, N, 3)),interpolation='none')

の部分のsom.nodes.reshape((N, N, 3))について説明をします.

N=20 の意味は, プロットされるマスを20×20で表現することを意味しますので
あなたの適用したいデータを(500,33,3)とするような記述は正しくありません.
つまり, Nはあなたのデータを表現するものではなく, マップのマスを調整するものです.

重要な点はsom.nodes.reshape((N, N, 3))の3の部分です.
これは3次元の意味です.すなわち,SOMのマップを示すためには,あなたの用いたいデータを
3次元に圧縮する必要があるということです.

あなたのデータでいいますと観測変数が33個ある場合は,
あなたのデータが33次元で表現されていることを意味します.

つまり,33次元を3次元に圧縮する必要があるということです.

次元圧縮をする方法としては,主成分分析,カーネル主成分分析などがあります.

あなたのデータをSOMに適用するためには,この分析にかけた後に出力されるデータを
適用する必要があります.

投稿2018/03/23 18:14

Jancat

総合スコア17

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

SOMとしては33次元の特徴を受け入れることは可能です.
som.nodes.reshape((N, N, 3))
は縦横で20x20のノード(マップの各要素)がRGBの3次元の特徴を持っているため
このように処理して色の並びを可視化した次第です.

33次元の場合はノードが33次元の特徴を持っているため,
トレーニング後のマップの並びを色で表現することができません.
そのため,エラーが発生しています.
Chinatsu様のご回答のように,前処理で3次元に圧縮したり,
トレーニング後のノードの特徴量を3次元に圧縮することで色として並びを確認できます.

しかし,33次元のデータを類似した順に並べたいのであれば,次元圧縮をしたくないと思われます.
そのため,33次元の場合は

# target_dataは1行33列のnumpy array coordinate = som._best_matching_unit(target_data)

とすることで,target_dataに近い要素2次元マップ上の座標が得られます.
このようにして,2次元マップ上のどこに割り当てられたかをそれぞれのデータで確認することで
SOMによって類似した順で2次元平面上に並べた結果がどのようになったかを確認できます.

サンプルが色を並べたデータであるため混乱を生じさせて申し訳ありません.
SOMは3次元以上の特徴を2次元平面上に並べることは可能です.

後日Qiitaの記事を更新します.

投稿2018/05/10 08:41

TShinaji

総合スコア12

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問