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

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

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

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

Q&A

解決済

1回答

4370閲覧

Pythonで重み付き多数決について

gymgym

総合スコア97

Python

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

0グッド

0クリップ

投稿2018/01/12 09:57

7個のリストから重み係数つきの多数決を行って、その結果から1個のリストを作成したいと考えています。

a = [ 1 0 2 2 2 1 1 0 2 4 3 3 5 3 5 4 6 5 6 7 6 8 7 8 6 8 6 11 11 9 10 11 11 11 9 11] b = [ 1 0 2 2 2 1 1 0 2 5 4 5 5 5 4 4 4 4 6 4 4 8 4 8 7 8 6 9 11 9 11 9 11 10 9 11] c = [ 1 0 2 2 2 1 1 0 2 5 4 5 3 4 4 4 5 5 6 7 6 8 7 8 6 8 6 9 9 9 10 9 11 10 9 11] d = [ 1 0 2 2 2 1 1 0 2 5 5 5 3 3 5 5 5 3 6 7 6 8 6 8 6 8 6 9 9 10 10 9 10 9 9 11] e = [ 0 2 2 0 1 0 0 2 0 3 5 3 4 4 3 4 3 4 8 8 6 6 7 6 8 6 8 9 9 9 10 10 10 10 9 10] f = [ 1 0 2 2 2 1 1 2 2 5 5 5 3 3 5 5 5 5 6 7 6 8 7 8 6 8 6 9 9 10 10 9 11 10 9 11] g = [ 1 1 2 2 2 1 1 2 2 4 5 5 4 4 5 3 5 5 6 4 4 8 7 8 6 8 6 9 11 9 10 9 11 10 9 11] aの重み係数: w1 = 0.417 bの重み係数: w2 = 0.278 cの重み係数: w3 = 0.444 dの重み係数: w4 = 0.333 eの重み係数: w5 = 0.333 fの重み係数: w6 = 0.361 gの重み係数: w7 = 0.333

それぞれのリストの1〜リストの長さ番目までの要素でそれぞれ重み付き係数を利用して多数決を行いリストを作成することが目的です。

Python

1label_list = [a,b,c,d,e,f,g] 2weight = [w1, w2, w3, w4, w5, w6, w7] 3labels = [] 4N = len(label_list[0]) 5for n in range(N): 6 for i, w in zip(label_list, weight): 7 a, gu, ty, pa, = [], [], [], [] 8 if(i[n] % 3 == 0): 9 gu.append(w) 10 elif(i[n] % 3 == 1): 11 ty.append(w) 12 elif(i[n] % 3 == 2): 13 pa.append(w) 14 15 x = [sum(gu), sum(ty), sum(pa)] 16 x.sort() 17 if(x[0] == sum(gu)):

リストの要素の数字によって、3つのリストを作成して重み係数をラベルによって分けてリストの合計をそれぞれ算出して一番大きい数のリストに応じて、ラベルをつけていこうと考えたのですがコードで表現できなくて困っています。

以上の文章では、意図がわかりづらいと思います。うまく説明できなくてすみません。

もっとうまい方法がありましたら、参考にさせてもらいたいので教えていただきたいです。

よろしくお願い致します。

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

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

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

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

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

guest

回答1

0

ベストアンサー

7個のリストから重み係数つきの多数決を行って、その結果から1個のリストを作成したい

次のようにして実現できそうです。

Python

1def get_most_popular_topic(topics, num_of_topic, weights=None): 2 if weights is None: 3 weights = np.array([1] * topics.shape[0]) 4 5 topic_table = np.array([ 6 np.dot(weights.T, (topics==i).astype(int)) 7 for i in range(num_of_topic) 8 ]) 9 print(topic_table) 10 return np.argmax(topic_table, axis=0) 11 12 13best_topics = get_most_popular_topic( 14 np.vstack((a, b, c, d, e, f, g)), 12 15 np.array(w) 16)

考え方

簡単なデータで動作を確認してみましょう。

Python

1topics = np.array([ 2 [0, 0, 0, 0, 1, 1, 1, 1], # w=1 3 [0, 0, 1, 1, 0, 0, 1, 1], # w=1 4 [0, 1, 0, 1, 0, 1, 0, 1] # w=2 5]) 6weights = np.array([1, 1, 2])

まず、トピック0についてマスクを作ります。
numpyを用いればこの処理は至って簡単です。

Python

1>>> topics==0 2array([[ True, True, True, True, False, False, False, False], 3 [ True, True, False, False, True, True, False, False], 4 [ True, False, True, False, True, False, True, False]], dtype=bool)

このままでは使いにくいので、Trueを1に、Falseを0と解釈しなおします。

Python

1>>> (topics==0).astype(int) 2array([[1, 1, 1, 1, 0, 0, 0, 0], 3 [1, 1, 0, 0, 1, 1, 0, 0], 4 [1, 0, 1, 0, 1, 0, 1, 0]])

重み付きの和が欲しいので、weightsを左からかけます。

Python

1>>> np.dot(weights.T, (topics==0).astype(int)) 2array([4, 2, 3, 1, 3, 1, 2, 0])

この出力は、『トピック0に関する重み』です。
実際に手で計算したときと同じ結果が得られます(当たり前ですが)。

それ以外の結果も連ねると、次のような結果になります。

Python

1[[4 2 3 1 3 1 2 0] # トピック0の重み 2 [0 2 1 3 1 3 2 4]] # トピック1の重み

このような表を作れば、ただの最大値の選択に話題を置き換えることが出来ます。
『最大値がどの行にあるか』が重要なので、np.argmaxを使います。

Python

1>>> topic_table 2array([[4, 2, 3, 1, 3, 1, 2, 0], 3 [0, 2, 1, 3, 1, 3, 2, 4]]) 4>>> np.argmax(topic_table, axis=0) 5array([0, 0, 0, 1, 0, 1, 0, 1], dtype=int64)

このようにして、『最も重い』トピックを選ぶことが出来ました。

なお、元のデータで試すと

Python

1a = [ 2 1, 0, 2, 2, 2, 1, 1, 0, 2, 4, 3, 3, 3 5, 3, 5, 4, 6, 5, 6, 7, 6, 8, 7, 8, 4 6, 8, 6, 11, 11, 9, 10, 11, 11, 11, 9, 11 5] 6b = [ 7 1, 0, 2, 2, 2, 1, 1, 0, 2, 5, 4, 5, 8 5, 5, 4, 4, 4, 4, 6, 4, 4, 8, 4, 8, 9 7, 8, 6, 9, 11, 9, 11, 9, 11, 10, 9, 11 10] 11c = [ 12 1, 0, 2, 2, 2, 1, 1, 0, 2, 5, 4, 5, 13 3, 4, 4, 4, 5, 5, 6, 7, 6, 8, 7, 8, 14 6, 8, 6, 9, 9, 9, 10, 9, 11, 10, 9, 11 15] 16d = [ 17 1, 0, 2, 2, 2, 1, 1, 0, 2, 5, 5, 5, 18 3, 3, 5, 5, 5, 3, 6, 7, 6, 8, 6, 8, 19 6, 8, 6, 9, 9, 10, 10, 9, 10, 9, 9, 11 20] 21e = [ 22 0, 2, 2, 0, 1, 0, 0, 2, 0, 3, 5, 3, 23 4, 4, 3, 4, 3, 4, 8, 8, 6, 6, 7, 6, 24 8, 6, 8, 9, 9, 9, 10, 10, 10, 10, 9, 10 25] 26f = [ 27 1, 0, 2, 2, 2, 1, 1, 2, 2, 5, 5, 5, 28 3, 3, 5, 5, 5, 5, 6, 7, 6, 8, 7, 8, 29 6, 8, 6, 9, 9, 10, 10, 9, 11, 10, 9, 11 30] 31g = [ 32 1, 1, 2, 2, 2, 1, 1, 2, 2, 4, 5, 5, 33 4, 4, 5, 3, 5, 5, 6, 4, 4, 8, 7, 8, 34 6, 8, 6, 9, 11, 9, 10, 9, 11, 10, 9, 11 35] 36 37w = [0.417, 0.278, 0.444, 0.333, 0.333, 0.361, 0.333] 38 39topics = np.vstack( 40 (a, b, c, d, e, f, g) 41) 42weights = np.array(w)

次のような結果になります。

[ 1 0 2 2 2 1 1 0 2 5 5 5 3 3 5 4 5 5 6 7 6 8 7 8 6 8 6 9 9 9 10 9 11 10 9 11]

ざっと見る限りまともに動いてそうに見えます
さすがに手計算をするのは手間なので、もし気になるようなら手元での確認をお願いします。

投稿2018/01/12 12:16

LouiS0616

総合スコア35660

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問