概要
機械学習において、データの前処理は非常に重要な作業です。
データサイエンスの分野では「Garbage In, Garbage Out(ゴミを入力すれば、ゴミか出力される)」という格言があり、データの前処理をきちんとしなければ精度の良いモデルを得ることは難しいです。
しかし、データ分析において「これをやっておけばOK!」といった、確実に学習モデルの精度を上げるような方法はありません。
じっくりデータとにらめっこして、一つ一つデータを整えていくしかないのです。
とはいいつつ、多くの場合で行われる前処理の常套手段もあります。
この記事では、Kaggleの「House price」コンペのデータを例に、データ前処理でよく用いられる処理をデモンストレーションしたいと思います。
ちなみに、使用するツールは「Excel」です。(情弱ぅ!)
pandasとかで処理しても良いのですが、Excelの方が慣れているので。
使用するデータセット
今回使用するデータセットは、Kaggleコンペティションの「House Prices - Advanced Regression Techniques」です。
コンペティションに参加し、CSVファイルをダウンロードします。
このデータセットは予測対象(Sale Price)含めて、80項目の変数で構成されています。
これらすべての変数の前処理を説明していると、途方もないので、
いくつかの変数をピックアップして、前処理の代表手法を説明しながら適応してきます。
データの前処理
それでは、データ前処理の代表的な方法を説明していきます。
なお、データ前処理は訓練(train)データとテスト(test)データの両方を同様に処理するのを忘れないでください。
①欠損値の補完・除外
まずは、欠損値の除外や補完を行います。
欠損値は「NULL」や「NAN」のようなデータが欠落しているものや、「0」や「999」といった数値が上限・下限を示しており、うまくデータ取得できていないものを指します。
ここでは、D列「LotFrontage」を代表して前処理します。
パッと見て、欠損値が散在していることがわかります。
訓練データとテストデータ合わせて(2919データ中)486個の欠損値があります。
除外する場合
欠損値に対して除外処置するのは、下記のようなパターンが想定されます。
- 同一データ項目内の欠損値が少ない場合(かつデータ数十分ある場合)、データの行ごと削除する
- 欠損値が多い場合、データの質として悪いので項目(データの列)ごと削除する
今回の「LotFrontage」も欠損値が多いため、データの質として悪いと判断して、データ列ごと除外します。
補完する場合
欠損値の補完が必要な場合は、下記のようなパターンが想定されます。
- データ数が少なく、できるだけ情報を残しておきたい場合
- 他の情報から欠損値の予測ができそうな場合
一番単純な補完方法は「平均補完」です。
データ列の平均値で補完させます。
また、「0で補完」して、一旦機械学習で取り扱えるようにすることもあります
他には、「他の情報から予測補完」する方法があります。
BK列「GarageArea」を例に見てみましょう。
このデータは訓練データに欠損はないのですが、テストデータに1件欠損データがあります。
訓練データであれば、データごと削除してもよかったのですが、今回はテストデータ=予測対象なので削除できません。
しかも、ガレージ関連の情報は欠損値が多い状況です。
ここで、ガレージタイプを見ると「Detchd」となっているので、ガレージ自体はありそうです。
(ガレージがない家はガレージタイプ「NA」となっています)
なので、ガレージタイプ=Detchdを対象にGarage Areaを平均した値=419.5で補完することにしました。
②異常値の除外・補完
異常値とは、データとしては取れているが、分布から大きく外れているデータです。
除外や補完の考え方は、欠損値と基本的には同じです。
ただし、欠損値と異なるポイントとして、
そのデータは本当に異常値かどうか判断する必要があることです。
例えば、下図のような例を見てみましょう。
点Aも点Bも、説明変数の分布的には離れた値を示しています。
ここで、点Aは予測変数との傾向的にも異常な値を示しており、このデータは異常値とみなしてよさそうです。
異常値は少数でも存在していると、誤った傾向学習をしてしまい、モデル精度を大きく損なう可能性があるので、可能な限り慎重に対処していくべきです。
しかし、点Bは予測対象との傾向的には順当な値を示しており、こちらは一概に異常値とは言えなさそうです。
このような場合に、異常値がどうか判断するには、この値があり得る値なのかといった知識が必要になりなす。
なので、データの前処理をするには、そもそものデータセットに対して十分な知識を持っている必要があります。
今回のhouse prize予測に関しては、私は住宅価格に関して詳しくないので、分布から外れていれば除外するようにしました。
ただし、なんでもかんでも除外してしまうと、データ数の減少やデータの多様性がなくなり、モデルの精度低下につながる懸念があるので、注意しましょう。
③カテゴリデータの数値化
機械学習は基本的には文字列をそのまま学習させられないので、カテゴリデータは数値化しましょう。
カテゴリデータの数値化にもいくつかパターンがあります。
どの手法を使うかは、トライ&エラーなことが多いです。
One-Hot エンコーディング
G列「Allay」を例に見てみます。
このデータは「Grvl」「Pave」「NA」の3種類のデータで構成されています。
One-Hotエンコーディングでは下記のように、カテゴリごとに列を作成し、0/1で数値化していきます。
データNo | Grvl | Pave | |
---|---|---|---|
001 | 1 | 0 | =Grvl |
002 | 0 | 1 | =Pave |
003 | 0 | 0 | =NA |
シンプルで余計な情報を含まないのがメリットなのですが、
カテゴリの種類が多くなると、データ数が多くなってしまうのが欠点です。
ラベルエンコーディング
次は、「MSZoning」を見てみましょう。
このデータは5種類のデータで構成されており、One-Hotコーディングではデータ数が多くなり大変そうです。
そんなときは、ラベルエンコーディングが良いです。
下図のように、各カテゴリに数字を割り振って、そのまま数値化します。
カテゴリ名 | 数値化 |
---|---|
C (all) | 1 |
FV | 2 |
RH | 3 |
RL | 4 |
RM | 5 |
ラベルエンコーディングでは、データ数を増やさずに数値化できるのがメリットですが、
数字自体に意味は無いため、傾向学習に悪影響を及ぼす可能性があります。
カウントエンコーディング
同じく、「MSZoning」を例に説明します。
カウントエンコーディングは、そのカテゴリごとのデータ数をそのまま数値化します。
カテゴリ名 | 数値化 |
---|---|
C (all) | 10 |
FV | 65 |
RH | 16 |
RL | 1151 |
RM | 218 |
この手法では、数字に意味を持たせることができるので、
ラベルエンコーディングに比べて傾向学習がうまくいく場合があります。
ターゲットエンコーディング
M列「Neighborhood」を例に見てみましょう。
このデータは25種類のデータで構成されています。
また、このデータとSale Prizeとの関係を見てみると下図のようになり、予測対象との関係も深そうです。
こういったデータでは、予測対象と関係のある数字(今回は、Sale Prizeの平均値)とすることで、傾向学習を行いやすくします。
数値化するときは下表のようなイメージです。
Neighborhood | 数値化(Sale Prize平均値) |
---|---|
MeadowV | 98576.47059 |
IDOTRR | 100123.7838 |
BrDale | 104493.75 |
・・・ | ・・・ |
(省略) | |
・・・ | ・・・ |
StoneBr | 310499 |
NridgHt | 316270.6234 |
NoRidge | 335295.3171 |
デメリットとして、数値に目的変数の情報を持ってしまっているため、
検証データの精度が過剰に高く見積もられてしまう(汎化性能の低下)ことがあります。
なので、交差検証などを行い、汎化性能が低下していないか、学習結果の評価に注意しましょう。
④データスケーリング
データスケーリングは、データセット全体の数値の大きさ(スケール)を揃える処理です。
各データ列に対して処理を行います。
例えば、E列「Lot Area」は数千~数万の数値レンジですが、R列「Overall Qual」は1桁の数値です。
これをこのまま学習に用いると、数値のスケールが影響して、正しく傾向学習ができない場合があります。
データスケーリングは主に下記の2パターンがあります。
どちらを用いるかは学習結果を評価しながら決定します。
正規化(Normalization)
正規化はデータの最大値=1、最小値=0として0~1の間にスケールを揃える手法です。
{x^{nomal}_i} = \frac{x_i-x_{min}}{x_{max}-x_{min}}
{x^{nomal}_i}・・・正規化後の数値
x_{max}・・・データ列の最大値
x_{min}・・・データ列の最小値
標準化(Standardization)
正規化はデータの平均値=0、標準偏差=1として、0を中心に標準偏差に従ってスケールを揃える手法です。
{x^{std}_i} = \frac{x_i-\mu}{\sigma}
{x^{std}_i}・・・標準化後の数値
\mu・・・データ列の平均値
\sigma・・・データ列の標準偏差
⑤新規データ項目の作成
ここは詳細説明はしません(できません)が、データセットに詳しい場合、データを組み合わせて、新たな変数を作成することもあります。
まずは、①~④の前処理を行い、モデル学習を行います。その結果を見て、より精度UPが必要な場合、新規データ項目の作成が有効な場合があります。
まとめ
いかがだったでしょうか。
この記事では、データ前処理でよく用いられる処理を紹介しました。
結局、このデータセット全体で3時間以上は前処理に時間がかかっています。
ここから、さらにモデル精度を上げようと思うと、さらに詳細にデータを分析して、前処理をやり直したりする必要があります。
要するに、トライ&エラーの泥臭い作業です。
データ前処理は非常に手間暇かかる作業ですが、この作業の良し悪しはモデル精度に直結するので、頑張りましょう。