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

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

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

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

統計

統計は、集団現象を数量で把握することです。また、調査で得られた性質や傾向を数量的に表したデータのことをいいます。

Q&A

解決済

2回答

1901閲覧

1次元ではないデータ同士の相関を知る方法

dendenmushi

総合スコア98

NumPy

NumPyはPythonのプログラミング言語の科学的と数学的なコンピューティングに関する拡張モジュールです。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

統計

統計は、集団現象を数量で把握することです。また、調査で得られた性質や傾向を数量的に表したデータのことをいいます。

0グッド

0クリップ

投稿2020/03/20 22:41

編集2020/03/20 23:11

前提・実現したいこと

あるアンケートの選択肢3つ(A,B,C)のうち、どれを選んだか、回答者の性別と年齢、その他のデータ、結果何を選んだのかデータがあらかじめあるとき、新しい人が何を選択するのか予想したい。

ID性別年齢・・・・・・・・・選択した肢
1131Aを選択
1246Cを選択
455132?

試したアプローチ方法

人物のデータの1行ごとに特徴量を出して、新しい人と最も相関している人物の結果を参考にする方法。
つまり、すべての要素をone-hotで表してから、ベクトル(1次元変換)にしてからベクトル相関を求める方法になります。

python

1import numpy as np 2results = np.corrcoef(arr6) 3print("相関係数を出力") 4print(results)

発生している問題・エラーメッセージ

python

1arr4 = [[1.], [1.], [0.], [1.]] 2arr3 = [[1.], [1.], [0.], [0.]]

これらの2次元配列ですと1次元ベクトルではないためエラーになります。
これらの相関係数を知るにはどうしたらよいのでしょうか。

python

1arr4 = [[1.], 1., [0.], [1.,0.]] 2arr3 = [[1.], 1., [0.], [0.,1.]]

また、このようなときに1次元の要素,2次元の要素がある場合の2つのデータの相関を知りたい場合はどのようにすればよいのでしょうか。

試した方法

これらを1次元のベクトルに変換も考えましたが、reshape(-1,)でも変換できませんでした。
そもそも2次元要素をもっていたためです。

他アプローチ

one-hotに拘らず、性別男は1、女は2、趣味が手芸なら1、ボクシングなら2…読書なら72などのように数値に変換してしまえば、1次元のベクトルになるとも考えました。これでベクトルを作り、あとはcorrcoefで比較し出す相関係数は結果参考にするには正しい考え方でしょうか。アドバイスどなたか頂けないでしょうか。よろしくお願い致します。

補足

win10
python3.7

2020/03/21追記(8:11訂正)

ごめんなさい間違えました。1次元には変換はできてもリスト型になってしまって、その後の相関係数を求める際に、リストが入っているのでだめですよと言われてしまうエラーでした。

python

1import numpy as np 2d_float_y = np.array([ 3 [0.],1.,0. 4 ]) 5e_float_y = np.array([ 6 [1.],1.,0. 7 ]) 8print(d_float_y.flatten()) # 1次元に3つあるものを1次元K個にreshapeできる 9print(e_float_y.flatten()) 10arr6 = [] 11import numpy as np 12arr6.append(d_float_y) 13arr6.append(e_float_y) 14print(arr6) 15results = np.corrcoef(arr6) 16print("相関係数を出力") 17print(results)

↓結果

python

1[list([0.0]) 1.0 0.0] 2[list([1.0]) 1.0 0.0] 3[array([list([0.0]), 1.0, 0.0], dtype=object), array([list([1.0]), 1.0, 0.0], dtype=object)] 4--------------------------------------------------------------------------- 5TypeError Traceback (most recent call last) 6<ipython-input-14-97f2f6639cde> in <module>() 7 13 arr6.append(e_float_y) 8 14 print(arr6) 9---> 15 results = np.corrcoef(arr6) 10 16 print("相関係数を出力") 11 17 print(results) 12 13<__array_function__ internals> in corrcoef(*args, **kwargs) 14 153 frames 16<__array_function__ internals> in cov(*args, **kwargs) 17 18<__array_function__ internals> in average(*args, **kwargs) 19 20/usr/local/lib/python3.6/dist-packages/numpy/core/_methods.py in _mean(a, axis, dtype, out, keepdims) 21 149 is_float16_result = True 22 150 23--> 151 ret = umr_sum(arr, axis, dtype, out, keepdims) 24 152 if isinstance(ret, mu.ndarray): 25 153 ret = um.true_divide( 26 27TypeError: can only concatenate list (not "float") to list

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

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

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

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

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

guest

回答2

0

ベストアンサー

one-hotに変換する部分のコードがありませんが、失敗している気がします。

そもそも本当にカテゴリ数が合っているのかも疑問ですが、[[1.], 1., [0.], [1.,0.]]なら[1., 1., 0., 1.,0.]のような配列を得るべきです。また、年齢のようなnumericalな特徴量があるなら、それはそのまま入れるしかないでしょう。

数値とダミー変数が混ざると、単純な相関ではかなり厳しくなるので、機械学習をおすすめします。

実際に前処理をどうやるべきか? ですが、scikit-learnで書くとこんな感じです。

6.1. Pipelines and composite estimators — scikit-learn 0.22.2 documentation
scikit-learnのColumnTransformerを使ってみる - 静かなる名辞(拙記事)

自分で書いても良いのですが、one-hot変換をちゃんと実装するのはけっこう面倒くさいです。特段の理由がなければscikit-learnを(あるいは他の機械学習ライブラリを)勧めます。


one-hotに拘らず、性別男は1、女は2、趣味が手芸なら1、ボクシングなら2…読書なら72などのように数値に変換してしまえば、1次元のベクトルになるとも考えました。これでベクトルを作り、あとはcorrcoefで比較し出す相関係数は結果参考にするには正しい考え方でしょうか。

名義尺度の数値になりますので、うまくいきません。たとえば、「趣味:手芸」は「趣味:読書」より「趣味:ボクシング」に近いと考えることは無意味ですが、数値にエンコードして距離とか相関を測ると、そういうことをやるのと同じ結果になります。

投稿2020/03/20 22:48

編集2020/03/20 22:57
hayataka2049

総合スコア30933

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

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

dendenmushi

2020/03/20 23:18

非常に参考になりそうなサイト記事ですね。じっくり読まさせて下さい。またすぐ経過報告します。ありがとうございます。
hayataka2049

2020/03/20 23:38

補足を見ているんですが、そもそもその形式のnumpy配列になっている時点でおかしいと感じます。一体どんなコードで生成したのでしょうか? 前段のコードの見直しが先です。 numpy配列は通常、一次元ならベクトル、二次元なら平面的な配列、三次元なら立方体のような形の配列を表します。[[1], [2,3], 4]みたいなものをnumpy配列に変換すると、仕方がないのでobject型の一次元(ベクトル)相当のものにしてくれます。これはpythonオブジェクトへのポインタを含んでいる配列で、この形式を使うメリットはあまりありません(たとえば、numpyの取り回しやすさとか、パフォーマンス面での恩恵なども受けられないと思ってください)。
dendenmushi

2020/03/20 23:54 編集

d_float_y = np.array([ [0.],1.,0. ]) これは要素がただの数値とone-hotのような2次元データが混ざってしまっているものを想定したテスト作成データでした。失礼しました。実際は以下のようになるとその際は考えていました。 性別 →男:[0,1] →女:[1,0] 年齢:31歳 趣味:手芸:1,ボクシング:2,読書:3 data = np.array([ [0.,1],31.,3. ]) でもまだ、サイト読み込み終わっていないですが、これらをベクトルのように特徴を出して、他のIDの特徴と相関していく考えは難しい(無理?難易度が高い?)ということなんでしょうかね。今日はこちら精読したいと思っております。 追記すみません。 本当にこれを実現するのであれば、全てを同じ要素数に合わせる data = np.array([ [0.,1…90個分まで0.を追加],[0.,0.,…31個目を1,0.,…90歳分まで0追加].,[0.,0.,3.,0…90個分まで0を追加] ])
hayataka2049

2020/03/20 23:52 編集

性別:男, 性別:女, 年齢, 趣味:手芸, 趣味:ボクシング, 趣味:読書 [0, 1, 31, 0, 0, 1] という感じで作れば、とりあえずnumpy配列にしてデータ分析とかに回すことができます。 ネストした構造にはしないです。 (なお、基本的には複数の行(個体)のデータをまとめて単一の配列に入れるので、データは2次元です。(サンプル数, 特徴量の次元数)のshapeになります)
dendenmushi

2020/03/21 00:01 編集

ネストはしないのですね…1次元として数値データとして分析することについてわかりました。ありがとうございます。 >性別:男, 性別:女, 年齢, 趣味:手芸, 趣味:ボクシング, 趣味:読書 >[0, 1, 31, 0, 0, 1] これはやり方としても簡単でわかりやすいですね。データじたいは2次元。あくまでひとつのIDがひとつの多次元ベクトルになり、そのベクトル同士を相関させていくということですね。ありがとうございます。
guest

0

ndarrayが2次元であることが問題で,1次元に変換したいのでしたら,flatten関数を使うことで,1次元の配列に変換できます.

追記

py:

1import numpy as np 2arr6 = [] 3arr4 = np.ravel([[1.], [1.], [0.], [1.]]) 4arr3 = np.ravel([[1.], [1.], [0.], [0.]]) 5print(arr4) 6print(arr3) 7results = np.corrcoef(arr4, arr3) 8print(results)

で実行できますがこれでやりたいことが実現できているでしょうか?
実行結果は

[1. 1. 0. 1.] [1. 1. 0. 0.] [[1. 0.57735027] [0.57735027 1. ]]

投稿2020/03/20 22:44

編集2020/03/20 23:01
dark-eater-kei

総合スコア1248

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

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

dendenmushi

2020/03/20 22:47

回答ありがとうございます。flattenとreshape(-1,)はほぼ同じで<元を変化させるかだけ>試したのですが、[]の中に、さらに[]があるとエラーになってしまいました。補足情報を本文に追加します。
dendenmushi

2020/03/20 23:27 編集

こんな方法があるのですね。勉強になりました。ありがとうございます。例えば、 arr4 = np.ravel([[1.], [1.], [0.,1.], [1.]]) arr3 = np.ravel([[1.], [1.], [0.,1.], [0.]]) のようなリストの要素が変わるものがあるときは、エラーがでるようです。 TypeError: unsupported operand type(s) for /: 'list' and 'int' このときは、すべての要素の数をあえて合わせた方がいいということですね。 例えば以下のように arr4 = np.ravel([[1.,0.], [1.,0.], [0.,1.], [1.,0.]]) arr3 = np.ravel([[1.,0.], [1.,0.], [0.,1.], [0.,0.]]) 強引に合わせてしまえば比較はできると考えていますがもし認識おかしければ教えて頂けないでしょうか。
dendenmushi

2020/03/21 02:18

どちらも非常に参考になりました。ありがとうございました。またよろしくお願い致します。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問