基礎編
データの見方と前処理
尺度水準、テーブルの粒度、欠損値と外れ値、スケーリングとエンコーディング。手間の大半はここにかかります。
この記事の要点
- 「1 行が何を表す表なのか」(粒度)を最初に決めます。ここが曖昧なまま結合すると、行が増えて静かに結果が狂います。
- 数値に見えても足し算に意味が無い列があります。尺度水準を取り違えると、モデルは無意味な大小関係を学びます。
- 欠損や外れ値は「消す」前に、なぜそうなっているかを見ます。欠けていること自体が情報のこともあります。
1 行が何を表す表なのか(粒度)
機械学習に渡すデータは、基本的に 1 枚の表です。まず決めるべきは1 行が何を表すかで、これを粒度と呼びます。 「1 行 = 1 人の顧客」なのか「1 行 = 1 回の購入」なのかで、 同じ売上データでもまったく別の表になります。
粒度が違う表をつなぐ(結合する)ときは注意が必要です。 1 対多で結合すると行が増え、気づかないうちに同じ観測を何度も数えてしまうことがあります。 結合の前後で行数を必ず確認してください。
数値に見えても数値ではない列がある
列の性質は、次の 4 つに分けて考えると扱いを間違えません(尺度水準)。
| 種類 | 性質 | 例 |
|---|---|---|
| 名義 | 区別だけ。大小も間隔も無い | 都道府県コード、コース名 |
| 順序 | 順番はあるが、間隔は等しくない | 満足度(不満・普通・満足)、学年、等級 |
| 間隔 | 差に意味があるが、0 が「無い」を意味しない | 気温、西暦 |
| 比率 | 差も比も意味がある | 金額、距離、所要時間 |
たとえば「コースの番号」は名義なのに、そのまま数値として渡すと モデルは「3 番コースは 1 番コースの 3 倍」という架空の大小関係を学びます。 こういう列は後述のエンコーディングで扱います。
欠損値は「なぜ欠けているか」で扱いが変わる
欠損(空欄)を平均値で埋める、という機械的な処理をよく見かけますが、 その前になぜ欠けているのかを確かめてください。
- たまたま欠けた(入力漏れ、通信エラー)… 埋める・落とすのどちらでも大きな害は出にくい
- そもそも存在しない(初回利用者に前回の記録は無い)… 欠けていること自体が「初回である」という情報。「欠損だった」ことを表すフラグ列を足すのが定石
- 値によって欠けやすい(都合の悪い数字ほど未報告)… 埋めると偏りを持ち込むので慎重に
外れ値・重複・表記の揺れ
極端に大きい・小さい値(外れ値)は、入力ミスのこともあれば、 本物の珍しい事象のこともあります。前者は直す対象ですが、後者を消すといちばん知りたい現象を自分で捨てることになります。 まずは分布を見て、どちらなのか判断します。
重複行、全角と半角の混在、単位の不一致(円と千円)といった地味な問題も、 ここで潰しておかないと後の集計がすべてずれます。
スケーリングとエンコーディング
- スケーリング… 正規化(0〜1 に収める)や標準化(平均 0・標準偏差 1 にする)で桁をそろえます。 必要になる理由はモデルによって違います。距離を測る手法(k 近傍法・SVM など)では必須で、 そろえないと桁の大きい列だけで「似ている」が決まってしまいます。線形モデルで効いてくるのは、正則化の罰則を列ごとに公平にかけたいときと、 最適化を安定させたいときです (罰則の無い線形回帰なら、桁が違っても係数がそのぶん変わるので予測は同じになります)。決定木系のモデルでは基本的に不要です。
- エンコーディング… 文字列のカテゴリを数値に直します。取りうる値が少なければ One-Hot(該当する列だけ 1 にする)、順序があるなら順序どおりの整数、 種類が非常に多い場合は出現頻度や統計量に置き換える方法もあります。 ただし目的変数(答え)の平均に置き換える方法は、 自分の答えを含んだ平均を自分の特徴量にしてしまうためデータリークそのものです。平均は必ず「その行を除いた」「その時点より前の」データで計算します (出現頻度への置き換えは答えを使わないので、この問題は起きません)。
作る前に、まず見る(EDA)
モデルを組む前に、分布・件数・時系列の推移・列同士の関係をひと通り眺めます (探索的データ分析、EDA)。ここで 「ある月から急に値が変わっている」「ある区分だけ件数が極端に少ない」 といった問題に気づけると、あとで原因不明の不調に悩まされずに済みます。
測り方が途中で変わったデータ、一部しか記録されていないデータは、 どんなに丁寧にモデルを組んでも直りません。データの出どころと作られ方を疑うのは、早いほど得です。