目次
目的変数と説明変数と特徴量
機械学習における用語です。
目的変数とは、予測対象の変数のことです。
説明変数とは、目的変数を説明することができる変数のことです。
特徴量は説明変数のことです。
例えば、未来の売上げを予測したいとした場合。
目的変数になるのは「過去の売上データ」になるのは直観でもわかります。
そして、その売上に影響をあたえる可能性のある諸々・・例えば、曜日や気温、店舗周辺イベント、セールの有無、広告費、チラシ枚数などなど・・が説明変数/特徴量となります。
ただ、説明変数には、売り上げへの影響が強いものがあれば、弱いものもあります。
まったく関係なさそうなものもあります。
予測精度をあげようと思ったら、あたりまえですけど、売り上げへの影響が強いものにしぼって学習データを作る必要があります。
どの説明変数が使えそうか?
もしくは、どの説明変数がいらないか?
説明変数の中の値で予測精度をさげるようなイレギュラーな値(はずれ値)がはいっていないか?
そんなことを調べて、学習データの精度をあげてやる必要があります。
サンプルで使うデータとやること
以下の要領でCSVファイルを読み込んで「t」というDataFrameがある想定です。
こんなデータを例にします。
target列が目的変数です。
他の列は説明変数候補です。
説明変数として有効かどうかは、まだわからないので、説明変数候補に対して分析をかけて、使えそうかどうか「あたりをつける」作業をしてみようというわけです。
あたりをつけるとはどうするか?なのですが。
一番、理解しやすいのは出現率ではないかと思ってます。
つまり、目的変数である「target」が各値になるときに、ある説明変数の値がどれくらいの比率で出現しているか?ってことです。
出現率が高い値があるということは、目的変数の値を決定するのに影響が強い可能性が高いですし、逆なら弱い・・というのは考えやすいです。
まず、それをやってみます。
Pandasのcrosstabで出現率をみるサンプル
出現率をみるのに、Pandasの「crosstab」を使います。
コード例は、以下がインポートされている前提とします。
import pandas as pd
出現率計算1:crosstabでnormalize='columns'
例の「prl」列を説明変数に選んで、目的変数に対する各値の出現率を求めます。
pd.crosstab(index=train['target'], columns=train['brl'], margins=True, normalize='columns')
結果はこんな感じ。
brlが「0」の時、「1」の時に、各targetの値ごとの出現率が計算されてます。
各列の縦計は「概ね1.0・・つまり100%」です。
上記は列方向の計が100%になっています。
出現率2:crosstabでnormalize='index'
オプションを「normalize='index'」に変更すると、行方向の計が100%になります。
pd.crosstab(index=train['target'], columns=train['brl'], margins=True, normalize='index')
結果はこう変わります。
横計が概ね100%になります。
出現率3:indexとcolumnsを入れ替えてみる
上記はindexに目標変数、columnsに特徴変数を指定しています。
今度は、それを入れ替えてみます。
pd.crosstab(index=train['brl'],columns=train['target'],margins=True,normalize='index')
そうすると、以下のように横長になります。
ブログの画像にすると見づらいですが、実際には、たくさんの項目を並べて表示するので、このほうもよく使います。
出現率4:結果をheatmap(ヒートマップ)で視覚化
crosstabの出力を数字だけだと見づらいときには視覚化します。
出力をprintではなく、左辺のDataFrameに渡し、All列は邪魔なのでdropした後、seabornのheatmap()に渡して表示するだけですけど。
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
dfheat = pd.crosstab(index=train['target'], columns=train['prl'], margins=True, normalize='columns')
dfheat.drop(['All'], axis=1, inplace=True)
sns.heatmap(dfheat, annot=True)
plt.show()
すると、こういうグラフになって、視覚的に把握しやすい・・かどうかは好みですが・・カッコいいです。
はずれ値にあたりをつける
出現率以外に重要なのは「はずれ値」の把握です。
はずれ値は「他のデータからみて、極端に大きいか小さい値」のことです。
学習データとして使うには、これをみつけて「外れ値=異常値」なのか、「はずれ値だけど異常値ではない」のかを判断しないといけません。
外れ値に判定されたものは学習データからはぶいてやらないと、結果の精度がおちてしまうからです。
どの値がはずれ値なのかを判定する方法にはいくつかあります。
- スミルノフ・グラブス検定
- 四分位範囲(IQR)を利用した判定
等です。
今回はシンプルな後者の方法でやります。
四分位範囲(IQR)とは「第3四分位点 - 第1四分位点」で計算します。
それを使って
- 「第3四分位数から四分位範囲×1.5倍を足した値」以上
- 「第1四分位数から四分位範囲×1.5倍を引いた値」以下
を外れ値だと判定する方法です。
例にdescribe()で以下のような結果になった列を使います。
25%が第一四分位、75%が第三四分位にあたります。
なので、外れ値判定の基準値を求めるのは。
q1 = train['rnd'].describe()['25%']
q3 = train['rnd'].describe()['75%']
iqr = q3 - q1outlier_min = q1 - (iqr) * 1.5
outlier_max = q3 + (iqr) * 1.5
みたいな感じになります。
上記の例だとoutlier_minは「 -61.5」で、元データのminより小さいので基準値以下の外れ値はありません。
でも、outlier_maxは「142.5」で、maxより小さいので基準値以上の外れ値はあります。
あとは、以下のように基準値以上の外れ値の行を抽出したりして
outmax = train[train['rnd'] >= outlier_max]
あたりをつけ、必要に応じて置き換えたり、行を削除したりすれば、なんとかなりそうな気はします。
今回はこんなところで。
ではでは。