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

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

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

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

Q&A

解決済

2回答

2538閲覧

Scikit-Learnでのデータ分析の前処理について

flow_engine

総合スコア5

Python 3.x

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

pandas

Pandasは、PythonでRにおけるデータフレームに似た型を持たせることができるライブラリです。 行列計算の負担が大幅に軽減されるため、Rで行っていた集計作業をPythonでも比較的簡単に行えます。 データ構造を変更したりデータ分析したりするときにも便利です。

0グッド

0クリップ

投稿2018/05/12 17:05

編集2018/05/12 17:07

前提・実現したいこと

scikit-learnを用いたデータ分析の前処理
私は現在scikit-learnを用いてデータ分析の学習をしています。現在はSIGNATEのプラクティスコンペティションで学習しています。
元データのサイト
元データは規約上貼れないことをお許しください。
また、この問題は分類問題です。

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

現在はニューラルネットワークを用いて学習させたところ0.7前後の精度となっています。そこで、前処理としてpreprocessingクラスにあるMinMaxScalerとStandaerdScalerを使用したところ精度が0.7を割る値になりました。

該当のソースコード

Python3

1import pandas as pd 2import sklearn 3 4#csvからの読み込み 5train = pd.read_csv('./train.csv', index_col=0) 6test = pd.read_csv('./test.csv', index_col=0) 7 8#欠損値を文字列からNoneへと変換 9dict_none = {'unknown': None} 10train = train.replace(dict_none) 11test = test.replace(dict_none) 12 13#テストデータに対するダミー変数 14dummy = pd.get_dummies(train["job"], prefix="job") 15train = train.drop("job", axis=1).join(dummy) 16dummies = pd.get_dummies(train["marital"], prefix="marital") 17train = train.drop("marital", axis=1).join(dummies) 18dummies = pd.get_dummies(train["education"], prefix="edu") 19train = train.drop("education", axis=1).join(dummies) 20dummies = pd.get_dummies(train["default"], prefix="default") 21train = train.drop("default", axis=1).join(dummies) 22dummies = pd.get_dummies(train["housing"], prefix="housing") 23train = train.drop("housing", axis=1).join(dummies) 24dummies = pd.get_dummies(train["loan"], prefix="loan") 25train = train.drop("loan", axis=1).join(dummies) 26dummies = pd.get_dummies(train["contact"], prefix="contact") 27train = train.drop("contact", axis=1).join(dummies) 28dummies = pd.get_dummies(train["poutcome"], prefix="poutcome") 29train = train.drop("poutcome", axis=1).join(dummies) 30dict_week = {"jan": 1, "feb": 2, "mar": 3, "apr": 4, "may": 5, "jun": 6, "jul": 7, "aug": 8, "sep": 9, "oct": 10, "dec": 11, "nov": 12} 31train["month"] = train["month"].replace(dict_week) 32 33#テストデータに対するダミー変数 34dummy = pd.get_dummies(test["job"], prefix="job") 35test = test.drop("job", axis=1).join(dummy) 36dummies = pd.get_dummies(test["marital"], prefix="marital") 37test = test.drop("marital", axis=1).join(dummies) 38dummies = pd.get_dummies(test["education"], prefix="edu") 39test = test.drop("education", axis=1).join(dummies) 40dummies = pd.get_dummies(test["default"], prefix="default") 41test = test.drop("default", axis=1).join(dummies) 42dummies = pd.get_dummies(test["housing"], prefix="housing") 43test = test.drop("housing", axis=1).join(dummies) 44dummies = pd.get_dummies(test["loan"], prefix="loan") 45test = test.drop("loan", axis=1).join(dummies) 46dummies = pd.get_dummies(test["contact"], prefix="contact") 47test = test.drop("contact", axis=1).join(dummies) 48dummies = pd.get_dummies(test["poutcome"], prefix="poutcome") 49test = test.drop("poutcome", axis=1).join(dummies) 50dict_week = {"jan": 1, "feb": 2, "mar": 3, "apr": 4, "may": 5, "jun": 6, "jul": 7, "aug": 8, "sep": 9, "oct": 10, "dec": 11, "nov": 12} 51test["month"] = test["month"].replace(dict_week) 52 53from sklearn.preprocessing import MinMaxScaler 54ms = MinMaxScaler() 55 56X = ms.fit_transform(train.drop('y', axis=1)) 57y = train['y'].values 58 59from sklearn.neural_network import MLPClassifier 60clf = MLPClassifier() 61clf.fit(X, y) 62 63X = ms.fit_transform(test) 64p = clf.predict(X) 65pd.DataFrame(p, index=test.index).to_csv('./output.csv', header=False) 66

試したこと

まずはじめに文字列の含まれる列を全てダミー変数へと置き換えました。その精度は0.7前後でした。そこで、Yes,Noの2値化出来る列を0,1に置き換えMinMaxScalerメソッドを施したところ精度は0.7を割り0.68前後となりました。
次に元データでは欠損値が'unknown'なのでNoneへと変換し欠損値をわかりやすくしました。その後、dropnaメソッドを用いて欠損値のある行を全て消去したところ精度は0.7未満となりました。
このように前処理を施すとどんどん精度が下がる結果となってしまっています。

補足情報(FW/ツールのバージョンなど)

Python 3.6.5
Scikit-Learn 0.19.1
Pandas 0.22.0

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

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

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

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

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

guest

回答2

0

ベストアンサー

「前処理すると性能が落ちる」というのは原理的にありえないほどの話ではないので、もしかしたら単に「そういう事例だった」という話かもしれませんが、

とりあえず掲示されているプログラムにはミスがあります。

python

1X = ms.fit_transform(train.drop('y', axis=1)) # trainのスケールをここでms内に保持している 2y = train['y'].values 3 4from sklearn.neural_network import MLPClassifier 5clf = MLPClassifier() 6clf.fit(X, y) 7 8X = ms.fit_transform(test) # fit_transformしたら保持したtrainのスケールが消えてtestだけのスケールになる(ので台無しになる)

testの方では単にtransformとするのが正解です。

なお、こういう場合、Pipelineを活用するとラクかつミスしないで書けるのでおすすめです。

sklearn.pipeline.Pipeline — scikit-learn 0.19.1 documentation

投稿2018/05/12 21:47

hayataka2049

総合スコア30933

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

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

flow_engine

2018/05/13 03:00

早朝から回答ありがとうございます。 回答の通り関数に対する勉強が不足していました。とりあえず結果だけを求めてしまいfit_transformすれば良いと考えていました。pipelineについてもしっかりと勉強させていただきます。 プログラムの結果ですが、fit_transformからtransformに変更いたしましたところ、精度の向上は起きませんでした。検証用データの一部をテストデータとして扱ったところ0.89と周りの人の結果よりも低いため、前処理が足りないと考えられるため頑張りたいと思います。 回答していただきありがとうございました。
hayataka2049

2018/05/13 03:25

前処理どうこうより、 MLPClassifierをデフォルトパラメタで使っているのがかなり不利な気がします。ちゃんと学習させられていないのではないでしょうか。 特に縛りがなければ、RandomForestClassifierなどがそこそこ手軽に性能を出せておすすめです。パラメタは細かくチューニングしなくてもたいていなんとかなりますが、n_estimatorを1000以上にすることと、並列化のオプションは計算速度のために指定してください(n_jobs=-1とすれば良い)
flow_engine

2018/05/13 15:32

回答ありがとうございます。Scikit-Learnの良いところであるライブラリの切り替えが容易なため分類問題に使用できる全ての手法を試しましたところニューラルネットワークが一番良い精度のため使用していました。メソッドについて調べず勉強もせず使用していたため引数に何を入れると良いのか調べていなかったためこのような不可解なコードとなってしまい申し訳ありません。 今回の問題に関しましてはpredictからpredict_probaへと変更しましたところ精度の良い結果となりました。出題サイトの求める回答を見ていなく0,1の結果で出力していたことが原因であったとされます。 お忙しい中回答していただいたにも関わらずこのような幼稚な間違いをしていたことをお許しください。回答していただきありがとうございました。アドバイスを肝に銘じ学習に励みたいと思います。
guest

0

結果としては確率を出力すべき問題でした。
そこを0,1の口座を開設したかどうかのみ出力していたため精度が上がることはなかった原因となっていました。
読んでくださった方々、回答をくださったhayataka様、幼稚な間違いで申し訳ありませんでした。

投稿2018/05/13 15:35

flow_engine

総合スコア5

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問