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

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

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

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

Python 3.x

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

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

Q&A

4回答

2602閲覧

特徴量を掛け合わせることの有効性について

kururi10

総合スコア27

Python 2.7

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

Python 3.x

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

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

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

0グッド

0クリップ

投稿2018/12/15 12:29

機械学習の木系モデルを使う際の話なのですが、
特徴量の積は有効なのかあまり意味がないのか
お聞きしたくて投稿しました。

例えば特徴量がA,B,Cと3つあるとして、
これらは全てカテゴリ変数ではないものとします。
そして、モデルは木系のモデルを使うとします。

その際、
A×B=D
A×C=E
B×C=F
という風にA,B,Cの特徴量を掛け合わせた
新しい特徴量D,E,Fを作って追加して学習させることは
有効なのか、あまり意味がないことなのか
どちらなのでしょうか?

自分はまだあまり詳しくわかっていなくて
間違っているかもしれませんが、
例えば木系のモデルとしてランダムフォレストを使う場合
根っこからたどって
1つ目のノードで特徴量Aが選ばれ、2つ目のノードで特徴量Bが選ばれたとすると
イメージ的にAかつBのように判断されているのではないかと思い
それは新たにA×B=Dという特徴量を追加しなくても
ちゃんと考慮されてるんじゃないかなと
なんとなく思っていますが・・・。

試しに特徴量同士の積を新たな特徴量として
実際にやってみたらいいのですが、
今やっている問題は特徴量の数が5000ぐらいあるので
そもそも意味があるものなのか
一般論としてお聞きしたいなと思いました。

ご回答のほど宜しくお願い致します。

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

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

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

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

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

guest

回答4

0

シンプルに、決定木モデルは分岐点の候補が多ければ多いほど機械側は嬉しいです。
使える特徴量かどうかは機械側が判断します。

仮に決定木モデルはゴミを投げても、特徴量の重要度を下げ使わない判断をしてくれますのでその点は安心です。
そのため特徴量を掛け合わせたり、足したりといったこともテクニックとしてありますし、多少有効に働くことが多いです。

もちろんGolden Feature(問題空間をよく表す最適な特徴)を与えるのが理想です。

投稿2018/12/23 09:29

amo

総合スコア33

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

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

kururi10

2018/12/23 13:19 編集

maro_amoebaさん、ご回答いただきありがとうございます! LightGBMの解説動画か何かをみていたときに 精度に寄与しないデータもたくさん入っていたけど 下がりはしなかったというのを聞いたことがあったので 決定木モデルはそのあたりが安心なのですね。 分岐が多いほど機械側は嬉しいというのも お聞きして良かったです! 1つ気になっていたのが 例えば特徴量Aと特徴量Bがあったとき それらを掛け合わせた特徴量Cを追加する場合 A=0.1 B=0.5 のとき C=0.1×0.5=0.05 A=0.5 B=0.1 のとき C=0.5×0.1=0.05 となり どちらもC=0.05となるので これだとあまり意味がない選択肢が増えて逆に迷うんじゃ・・・ と思っていました。 このケースだとCは単純に 重要ではないと判断されて捨てられるか、 内部的にAとCの組み合わせやBとCの組み合わせが 試されるということになる といった理解でいいのでしょうか?
amo

2018/12/23 14:32 編集

そうですね、内部的にAとC、BとCなどの組み合わせは試されるでしょうから そのように機械が試した上で、重要でなければモデルに貢献しない特徴量になると思います! ちなみにこの単純なテクニックは昔私がやったときは本当に少ししか精度が上がらなかったです。 一応その中でも特徴量重要度の上位の者同士だと効果は高めだったと思います。。汗
kururi10

2018/12/23 15:22

maro_amoebaさんが以前試された時は 少ししか上がらなかったのですね・・・。 内部的にはやはりAとCやBとCも試されている感じなんですね。 ランダムフォレストの概要を見ていると、 最初のノードでAが選ばれ次のノードでBが選ばれる というように、 「Aが選ばれて分けられた後、分けられたデータに対してBで判定される」(ランダムなので1つの例) という理解でいます。 ただこれは、 Aがこうなって、かつBがこうなっている という判断を「1つのノードで」行われていない気がしてですね。 少ししか精度が上がらなかったということは、 明示的に掛け合わせなくても 内部的にA×Bが実行されている と見ていいんでしょうか・・・ Aで分けられて次のノードへ進み⇒分けられたデータに対してBで分けられる というのと AとBを考慮して分けられて⇒次のノードへと進む のとでは 違うような気がしていて混乱しています^^;
amo

2018/12/24 01:24 編集

決定木では説明変数の組み合わせは、内部はそれぞれのかけ算をしているわけではないかと思います。(LightGBMはそれすらもしてるかもしれないですが私はわからないです) こちらの木構造の可視化の部分を見ると、「組み合わせ」という意味が伝わるかもしれないです。 http://www.randpy.tokyo/entry/python_random_forest また、決定木、ランダムフォレスト、勾配ブースティング(LightGBMなど)が区別がついていないようですので、 時間のあるときに勉強するといいかもです。 参考に:決定木についての説明を丁寧にしてくれている動画があります(他の手法も解説してくれています) https://www.youtube.com/watch?v=irTbuevXauk&t=1214s
nouken

2018/12/24 03:28

AとBといった特徴量があった場合、C = A × B といった 新たな特徴を定義しなくても、例えば A > 10 で分岐し B > 5で分岐することで C で表現できる情報の一部を表現できますが、それはC > 50 で捉えられる情報の一部でしかない、という話ですかね。そのため、掛け合わせることで、それなしではできなかった分け方ができる可能性はあると思います。
kururi10

2018/12/24 05:46

>maro_amoebaさん うーん、 僕が上記のコメントで 「最初のノードでAが選ばれ次のノードでBが選ばれる」 と言ったのは、 教えていただいたページの 木構造の可視化の部分のノードのお話のことです。 教えていただいたページの例で言うと、 最初のノードでSexが選ばれ次のノードでPclassが左側に分岐されたものでは選ばれている という構造になっていますよね。 これは最初のノードでSexで情報利得が最大となって分割がされ、 次の左側ノードでPclassで情報利得が最大となって分割がされていますが これは1つのノードでSexとPclassの両方を考慮した分け方になっていない というのが上記のコメントで僕が言いたかったことです。 Sexがこの値でPclassがこの値の時に情報利得が最大となったので Sex>=○ かつ Pclass>=○ で分割しましょう という形になっていない。 にもかかわらず、 特徴量A×特徴量Bを計算した特徴量を追加しても maro_amoebaさんの時は少ししか精度が上がらなかったのは なぜだろうと・・・。 仮に Sex>=○ かつ Pclass>=○ で分割しましょう という形になっているんだったら、 特徴量A×特徴量Bの特徴量を追加しても 精度が少ししか上がらないのは分かるんですけどね。 純粋に、それはなぜなんだろうと。 内部的に特徴量A×特徴量Bの効果があるんかなと・・・。 全体で見ると確かに組み合わせではあるんですが、 分割の判断の際に組み合わせは考慮されていない という構造なんですよね。。。
kururi10

2018/12/24 05:55

>noukenさん C > 50 で捉えられる情報の一部でしかない というのの一部というのが どこなのかちょっとまだ良くわからないのですが、 X軸がAでY軸がBの平面を考えると A > 10 で分岐し B > 5 なら C > 50の領域となり 同じなような気もするし・・・。 A > 10 で分岐したときに、A <= 10は捨てられずに もうひとつの分岐に残ると考えると A > 10 で分岐し B > 5 の方がむしろ多くの情報が捉えられている気もするし。。。 うむう、難しい^^; 1個上のmaro_amoebaさんへのお返事でも書いた、 分割の判断の際に組み合わせは考慮されていない という所を考えてみると C > 50が有効とも捉えられますしね。 (Cが組み合わせたものなので、それを分岐の判断の際に使っている) どうなんでしょうね・・・。
kururi10

2018/12/24 06:04 編集

>noukenさん あ、平面上の話は違ったかもです。 A > 10 で分岐し B > 5で C > 50のとき 平面上の話は無関係ですね。 失礼しました^^;
guest

0

データ依存ですが、効くときは効きます。

たとえば底辺と高さがわかっている長方形の面積がしきい値を超えるかどうか、というタスクを考えます。

python

1import numpy as np 2from sklearn.tree import DecisionTreeClassifier as DTC, export_graphviz 3 4xy = np.random.rand(300, 2)*10 5label = (xy[:,0] * xy[:,1] > 20).astype(int) 6 7dtc = DTC() 8dtc.fit(xy, label) 9export_graphviz(dtc, "tree1.dot") 10 11xy2 = np.hstack([xy, (xy[:,0]*xy[:,1]).reshape(-1, 1)]) 12dtc = DTC() 13dtc.fit(xy2, label) 14export_graphviz(dtc, "tree2.dot") 15 16""" 17$ dot -Tpng tree1.dot -o tree1.png 18$ dot -Tpng tree2.dot -o tree2.png 19"""

tree1.png
イメージ説明

tree2.png
イメージ説明

実データでここまで顕著なのはないと思いますが、少しでもこういう傾向を持っていれば効きます。掛け合わせ変数がより効果的な説明変数であれば木を浅くでき、汎化性能に影響することでしょう。

参考:
[入門]初心者の初心者による初心者のための決定木分析 - Qiita

投稿2018/12/24 14:38

hayataka2049

総合スコア30933

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

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

kururi10

2018/12/25 13:03 編集

hayataka2049さん、ご回答いただきありがとうございます! なるほど、シンプルな事例を挙げていただき 確かに浅い深さでもうまく判別できていますね! 下のmaro_amoebaさんとnoukenさんとのやり取りの中書いた、 決定木は 「分割の判断の際に特徴量の組み合わせは考慮されていない」 ように見えることについてなのですが、 これが考慮されていないから、あえて掛け合わせることに意味が出てくる場合がある と考えてもよろしいのでしょうか?
guest

0

ちょっと気になったのでbreast_cancerのデータセットで実際にやってみました。

python

1import numpy as np 2import pandas as pd 3import matplotlib.pyplot as plt 4import seaborn as sns 5%matplotlib inline 6 7from sklearn.tree import DecisionTreeClassifier 8from sklearn.datasets import load_breast_cancer 9from sklearn.model_selection import train_test_split 10from sklearn.metrics import accuracy_score 11 12# モデルの木構造の視覚化に必要なパッケージ 13from sklearn import tree 14import pydotplus as pdp 15 16breast_cancer = load_breast_cancer() 17df = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names) 18 19df['target'] = breast_cancer.target 20#一応シャッフル 21df = df.sample(frac=1, random_state=1) 22target = df['target'] 23df.drop('target', axis=1, inplace=True) 24 25x_train, x_val, y_train, y_val = train_test_split(df, target, test_size=0.25, random_state=1) 26x_train.shape, x_val.shape, y_train.shape, y_val.shape 27 28model = DecisionTreeClassifier(random_state=1) 29model.fit(x_train, y_train) 30y_pred = model.predict(x_val) 31print('acc: {}'.format(accuracy_score(y_val, y_pred))) 32 33importance_df = pd.DataFrame() 34importance_df['feature'] = breast_cancer.feature_names 35importance_df['importance'] = model.feature_importances_ 36importance_df = importance_df.sort_values(by='importance', ascending=False).head(10) 37sns.barplot(x='importance', y='feature', data=importance_df) 38 39#file_name = "./tree_visualization.png" 40#dot_data = tree.export_graphviz(model, out_file=None, filled=True, rounded=True, feature_names=df.columns, 41 #class_names=breast_cancer.target_names, special_characters=True) 42#graph = pdp.graph_from_dot_data(dot_data) 43#graph.write_png(file_name)

acc: 0.9370629370629371

python

1np.mean(cross_val_score(DecisionTreeClassifier(random_state=1), df, target, cv=5))

0.93674490188534043

python

1import numpy as np 2import pandas as pd 3import matplotlib.pyplot as plt 4import seaborn as sns 5%matplotlib inline 6 7from sklearn.tree import DecisionTreeClassifier 8from sklearn.datasets import load_breast_cancer 9from sklearn.model_selection import train_test_split 10from sklearn.metrics import accuracy_score 11 12# モデルの木構造の視覚化に必要なパッケージ 13from sklearn import tree 14import pydotplus as pdp 15import itertools 16 17breast_cancer = load_breast_cancer() 18df = pd.DataFrame(breast_cancer.data, columns=breast_cancer.feature_names) 19 20df['target'] = breast_cancer.target 21#一応シャッフル 22df = df.sample(frac=1, random_state=1) 23target = df['target'] 24df.drop('target', axis=1, inplace=True) 25 26#特徴量の掛け合わせ 27for f1, f2 in itertools.combinations(df.columns, 2): 28 df[f1+'*'+f2] = df[f1] * df[f2] 29 30x_train, x_val, y_train, y_val = train_test_split(df, target, test_size=0.25, random_state=1) 31x_train.shape, x_val.shape, y_train.shape, y_val.shape 32 33model = DecisionTreeClassifier(random_state=1) 34model.fit(x_train, y_train) 35y_pred = model.predict(x_val) 36print('acc: {}'.format(accuracy_score(y_val, y_pred))) 37 38importance_df = pd.DataFrame() 39importance_df['feature'] = df.columns 40importance_df['importance'] = model.feature_importances_ 41importance_df = importance_df.sort_values(by='importance', ascending=False).head(10) 42sns.barplot(x='importance', y='feature', data=importance_df) 43 44#file_name = "./tree_visualization.png" 45#dot_data = tree.export_graphviz(model, out_file=None, filled=True, rounded=True, feature_names=df.columns, 46 #class_names=breast_cancer.target_names, special_characters=True) 47#graph = pdp.graph_from_dot_data(dot_data) 48#graph.write_png(file_name)

acc: 0.965034965034965

python

1np.mean(cross_val_score(DecisionTreeClassifier(random_state=1), df, target, cv=5))

0.95087341285109661

決定木の可視化にはgraphvizのinstallが必要ですが、それを見ると掛け合わせ特徴を用いた方が少ない枝分かれでより高い正解率を達成しています。もちろんデータにもよりますが、試してみる価値はあると思います。

投稿2018/12/23 01:57

nouken

総合スコア369

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

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

kururi10

2018/12/23 12:55

おおおおおおおお! DecisionTreeで見ると確かに違いが出ていますね~。 書いていただいたコードをRandomForestClassifierに変えると 同じになりましたが、 木1個単位では少ない枝分かれでより早く精度を上げている 感じになるのですね。 ご丁寧にコードまで書いてくださってありがとうございます^^
nouken

2018/12/23 13:19 編集

すいませんランダムフォレストで試してなかったんですが、確かにデフォルトパラメータのままだとクロスバリデーションスコアの差がほとんどなくなりますね。ただ、n_estimators=500にして、クロスバリデーションすると、1.2%ほど掛け合わせ特徴量を使った方が正解率が高くなりますね。 自分も勉強になりました!
kururi10

2018/12/23 13:38

おお、ランダムフォレストでも差が出ましたか! 試していただいてありがとうございます^^ ちなみにnoukenさんはランダムフォレストの計算式のような 数学的な部分も理解を進めながら使用されていますか? 僕は数学的な部分はさっぱりなもので・・・^^;
nouken

2018/12/23 14:38

機械学習の勉強始めた頃は難しいところは飛ばしてとりあえず使えたらいいか、っていう感じでしたが、勉強を進めるにつれやはり理論もある程度わかっていた方がいいと気づいたので、最近は理解しようと努力はしています。でもなかなか難しいですよね。。。
kururi10

2018/12/23 15:11

そうですよね・・・内部的にどんな動作をしているか ある程度分かっておいたほうがいいですよね・・・。 僕は株価の分析に機械学習を使っているのですが、 手法のどこを特徴量にすればいいかに頭を使っていて なかなか理論的なことが進められていないので 勉強していこうと思います。。。 難しい部分も多いですよね^^;
guest

0

randomforestにそのまま突っ込むよりも、明示的に掛け合わせた方がモデルにとって学習しやすいといったケースもあると思います。自分の経験上、やってみないとわかりませんが、効くこともあるといった感じでう。5000を全て掛けあわせるのは厳しいものがあると思うので、特徴量重要度上位の者同士であったり、ドメイン知識から考えて有効ではないかと考えられる組み合わせなどを試してみるのはどうでしょうか?

投稿2018/12/22 13:50

nouken

総合スコア369

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

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

kururi10

2018/12/22 17:06

noukenさん、ご回答いただきありがとうございます! なるほど、重要度が高いもの同士を掛け合わせるなどで 効率化してみるといいのではないかということなんですね。 モデルにとって学習しやすいというのは、 特に特徴的だった値同士が掛け合わせることによって さらに強力に色濃く特徴として出てくるので それをモデルが見分けやすくなる というイメージでしょうか?
nouken

2018/12/23 02:01

そのようなイメージで良いと思います。僕もそれほど専門的なことはわからないですが、モデルに「察して」もらうよりもこちらが「’示して」あげた方が分類しやすくなることもあるのかなぁというイメージです。
kururi10

2018/12/23 12:49

なるほど、なるほど。 察してもらうより、しっかりと示してあげたほうがいい というのは分かりやすい表現ですね^^
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問