機械学習におけるデータの前処理についてのメモです。
データ前処理の必要性
機械学習でモデルにデータを渡す際には、データの全てが数値であることが求められる。しかし現実のデータが全て綺麗な数字のみで構成されていることは稀であり、文字列が混入していたりデータに欠損があったりすることが多い。
機械学習で扱えるデータ
生年月日 | 年齢 | 経験年数 |
---|---|---|
2000/1/1 | 20 | 1 |
2001/1/1 | 21 | 2 |
2002/2/1 | 22 | 0 |
このままでは機械学習で扱えないデータ
生年月日 | 年齢 | 経験年数 |
---|---|---|
2000/1/1 | 20才 | 一年 |
2001/1/1 | 21才 | 半年 |
2002/2/1 | 22才 | (空白) |
そこで、機械学習モデルにデータを渡す前に、データを綺麗することを目的として行われるのがデータの前処理である。上記のような例以外にも、データを標準化したりすることも本作業の範囲となる。
データ前処理
文字列をダミー変数に変換
データの特徴量が文字列であるとき、個々のデータ(カテゴリ変数)をダミー変数に置き換える方法が用いられる。これを One-hot-Encoding という。
pandas の get_dummies メソッドを使用することで、文字列など数値ではないデータを列の項目として置き換え、1 or 0 の値で表示することができる。
import pandas as pd
# 元データ。要素として文字列が含まれている
data1 = pd.DataFrame({'職業':['教師', 'プログラマー', '公務員']})
print(data1)
# 文字列(カテゴリ変数)をダミー変数に変換
new_data1 = pd.get_dummies(data1)
print(new_data1)
データの初期状態
職業 | |
---|---|
0 | 教師 |
1 | プログラマー |
2 | 公務員 |
One-Hot-Encoding後
職業_プログラマー | 職業_公務員 | 職業_教師 | |
---|---|---|---|
0 | 0 | 0 | 1 |
1 | 1 | 0 | 0 |
2 | 0 | 1 | 0 |
欠損値をダミー変数に変換
欠損値の場合でも、上記で用いたOne-Hot-Encodingを用いることができる。
欠損値を扱うことを明示するため、上で使用した get_dummies 関数に、 dummy_na=True というオプションを付ける。
import numpy as np
# 2番目と4番目のデータが欠損しているデータ
data2 = pd.DataFrame({'職業':['教師', np.nan, 'プログラマー', np.nan]})
print(data2)
# 欠損値をダミー変数に置き換える
new_data2 = pd.get_dummies(data2, dummy_na=True)
print(new_data2)
データの初期状態
職業 | |
---|---|
0 | 教師 |
1 | NaN |
2 | プログラマー |
3 | NaN |
One-Hot-Encoding後
職業_プログラマー | 職業_教師 | 職業_nan | |
---|---|---|---|
0 | 0 | 1 | 0 |
1 | 0 | 0 | 1 |
2 | 1 | 0 | 0 |
3 | 0 | 0 | 1 |
平均値による欠損値の補完
上の例では文字列の欠損であったためOnehotEncodingが使用出来たが、数値データ中の欠損値などに対してはこの方法は望ましくない。
そのような場合には、欠損値を他のデータの平均値で置き換えるという手法をとる。
欠損値の平均値への変換には、 Imputer モデルを使用する。
Imputer では、オプションで変換元データの種別、変換先データの種別を指定して使用する。
from sklearn.preprocessing import Imputer
# 欠損値を含む数値データ群
data3 = pd.DataFrame({'年収':[3000000, 4000000, 5000000, np.nan]})
print(data3)
## 欠損値を平均値に置き換えるための処理
# 変換モデルImputerに対し、欠損値NaN を 平均値(mean) に変換することを明示
imp = Imputer(missing_values='NaN', strategy='mean')
# モデルImputerに欠損値を含むデータを学習させる
imp.fit(data3)
# 欠損値を平均値に置き換える
new_data3 = pd.DataFrame(imp.transform(data3), columns=data3.columns)
print(new_data3)
データの初期状態
年収 | |
---|---|
0 | 3000000.0 |
1 | 4000000.0 |
2 | 5000000.0 |
3 | NaN |
平均値による変換後
年収 | |
---|---|
0 | 3000000.0 |
1 | 4000000.0 |
2 | 5000000.0 |
3 | 4000000.0 |
データの標準化
扱う数値データが大きすぎるとき、その後の扱いが煩雑になる。
そのような場合には、前処理段階でデータを標準化してしまうのが望ましい。
データの標準化には、 StandardScaler モデルを使用する。
from sklearn.preprocessing import StandardScaler
# 規模の大きな数値データ群
data4 = pd.DataFrame({'大きな数値群':[100000000,120000000,140000000]})
print(data4)
## データの標準化を行う準備
# 標準化を行うモデル
std = StandardScaler()
# モデルにデータを学習させる
std.fit(data4)
# データを標準化する
new_data4 = pd.DataFrame(std.transform(data4), columns=data4.columns)
print(new_data4)
データの初期状態
大きな数値群 | |
---|---|
0 | 100000000 |
1 | 120000000 |
2 | 140000000 |
標準化処理後
大きな数値群 | |
---|---|
0 | -1.224745 |
1 | 0.000000 |
2 | 1.224745 |
以上。