機械学習
記事内に商品プロモーションを含む場合があります

機械学習の前処理・特徴量エンジニアリングの手法を解説【Python】

tadanori

この記事では、機械学習においてLightGBMやXGBoostなどで使える前処理・特徴量エンジニアリングの基本的な手法やテクニックを紹介します。精度向上に悩んでいる場合は、ここで紹介されているテクニックを読んで、自分の課題に適用してみてください。

この記事は以下の様な人におすすめです
  • 機械学習の前処理特徴量エンジニアリングの手法について知りたい方
  • 精度向上のためのアイデアを探している方

前処理(特徴量エンジニアリング)の重要性

データの前処理とは

機械学習のアルゴリズム(lightGBMなど)に入力する前に、与えられたデータに何らかの加工を行うことをデータの前処理と呼びます。

特徴量エンジニアリングは、与えられたデータから新しい特徴量を作成するものです。

この前処理と特徴量エンジニアリングは、機械学習モデルの性能向上に欠かせません。

例えば、スケーリングなどによりデータを整形することで、モデルが学習しやすくすることができます。

特徴量エンジニアリングでは、入力データから有益な情報を抽出し、新たな特徴量としてモデルに入力することで、精度と汎化性能を向上させることができます。

特にkaggleなどの機械学習のコンテストでは、特徴エンジニアリングの差が順位の差として現れることも珍しくありません。

とにかく、データの前処理(特徴量エンジニアリング)は、精度向上のための重要な手法となります。

特徴量エンジニアリングは「データから新しい特徴量を作成する」ものなので、前処理とは異なるものと捉えることがありますが、ここでは、前処理と特徴量エンジニアリングを区別せずに説明します

様々な前処理

スケール変換とセンタリング

入力されたデータの中心値と、幅を変換する処理です。代表的な手法として、正規化(Normalization)と、標準化(Standarization)があります

正規化(Normalization)

データを「最小値=0最大値=1」の集合にまとめる操作です(別名Min-Max Scalingと呼ばれます)。

具体的には、以下のような計算式になります。

x_dash = (X - min(x))/(max(x) - min(x))

以下は、-100~100の範囲のデータを0~1に正規化する例です。

x = np.random.randint(-100, 100, 1000)
x_dash = (x - np.min(x))/(np.max(x) - np.min(x))

fig = plt.figure()

ax1 = fig.add_subplot(1,2,1)
ax1.hist(x)

ax2 = fig.add_subplot(1,2,2)
ax2.hist(x_dash)

plt.show()
正規化サンプル
(左)元データ (右)正規化後のデータ

標準化(Standarization)

データを「平均値=0標準偏差=1」の集合にまとめる操作です(標準偏差=1は分散=1と表現することもあります)。

具体的には、以下の計算式になります。

x_dash = (x - mean(x))/std(x)

以下は、-100~100の範囲のデータを標準化する例です。

x = np.random.randint(-100, 100, 1000)
x_dash = (x - np.min(x))/(np.max(x) - np.min(x))

fig = plt.figure()

ax1 = fig.add_subplot(1,2,1)
ax1.hist(x)

ax2 = fig.add_subplot(1,2,2)
ax2.hist(x_dash)

plt.show()
標準化サンプル
(左)元データ (右)標準化後のデータ

標準化の利点は、外れ値がある場合です。正規化では、極端に大きな値や小さな値がある場合、すごく狭い値の範囲にデータが集中してしまいます。

わたしの場合は、データにもよりますが、どちらかというと標準化を使うことが多いです。

正則化について

正規化、標準化とは別に、正則化という言葉も聞いたことがあるかと思います。

正規化と標準化はデータのスケール変換の手法のことで、正則化はモデルの複雑さを制御し、過学習を防ぐ手法のことです(ラッソとかリッジ回帰などが有名)

ごっちゃにならない様に注意しましょう。

分布を正規分布に近づける技法

データの分布を正規分布に近づける技法もあります。これについては、以下の記事を参考にしてください。

SMOTE:不均衡データをオーバーサンプリングして数を揃える手法
SMOTE:不均衡データをオーバーサンプリングして数を揃える手法

主成分分析

主成分分析(PCA, principal component analysis)は、次元を数を削減する次元圧縮処理として良く利用されますが、データの前処理でも利用することができます。

データの前処理で利用する目的は、「説明変数同士を無相関にする」ことです。

PCAは、scikit-learnに組み込まれているので、それを利用して簡単に利用することができます。

以下は、PCAの呼び出しの例です。

from sklearn.decomposition import PCA 
from sklearn import datasets         
import pandas as pd
import seaborn as sns 


wine = datasets.load_wine() 
df =  pd.DataFrame(wine.data)

pca = PCA(n_components=len(df.columns)) 
x_dash = pca.fit_transform(df)  
print(pca.explained_variance_ratio_)

pca.explained_variance_ratio_に寄与率が戻ってくるので、これを見ながら何次元までを特徴量として加えるかを調整します。

カテゴリ変数(one-hot-encodding)

データセットに男、女などのカテゴリ変数がある場合はone-hot-encodingを行います。

LightGBMなどでは、カテゴリ変数は指定することで自動的に処理してくれますので、最近は自身でやることは少ないかもしれません

one-hot-encodingとは、例えば以下のようなデータに対して性別の列を、男・女の列に分けて0,1で表現する方法です。

カテゴリ変数とone-hot-encoding

one-hot-encodingを行うと、列がカテゴリ種の数だけ増加します。

from sklearn import preprocessing
import numpy as np
import pandas as pd

df = pd.DataFrame( ['男','女','女','男'] )
enc = preprocessing.OneHotEncoder(sparse=False)
print( enc.fit_transform( df ) )
[[0. 1.]
 [1. 0.]
 [1. 0.]
 [0. 1.]]

時間データの処理

何時何分などのデータの場合、周期性を考慮したいことがあります。そのまま0時0分〜23時59分という形で扱うと、23:59と0:0の間が不連続になってしまいます。

これを防ぐために、時間データを極座標に変換して利用することがあります。

これにより、24時間の周期性を明示的に捉えやすくなります。

この変換は、例えば以下の様な関数で実現できます。

import math

def time_to_polar_coordinates(h, m):
    # 時間を角度に変換
    angle = ((h % 24) + m / 60) * 360 / 24
    
    # ラジアンに変換
    angle_rad = math.radians(angle)
    
    # 極座標(x, y)に変換
    x = math.cos(angle_rad)
    y = math.sin(angle_rad)
    
    return x, y
θとx,yの関係

特徴量エンジニアリングのテクニック

ここでは、kaggleなどで利用されている、少し高度な特徴量エンジニアリングについて説明します。

外れ値除去(欠損値)

欠損値の取り扱いについては、以下の記事を参考にしてください。

あわせて読みたい
欠損値(NaN)取り扱い方法を解説 | 機械学習におけるデータ予測精度向上のための手法
欠損値(NaN)取り扱い方法を解説 | 機械学習におけるデータ予測精度向上のための手法

列が多い場合や、複数のデータがある場合は、欠損値を予測する予測器を別途作り、欠損値を埋めるという方法も考えられます。特に大量の欠損値データが利用できる場合には効果があるかもしれません。

カテゴリ変数を使った集約

テーブル内で、カテゴリ変数が同じもの同士で統計量をとることで、新しい特徴量を作る手法。統計量としては、mean, min, max, stdなどが考えられる。

カテゴリ毎に平均などで新しい特徴量を作る

タイムスタンプなどがあるデータの場合は、一定の時間範囲で統計量を計算するという方法も考えられます

テーブル集約(複数テーブルをまとめる)平均、分散など

複数テーブルをまとめる場合にも、統計量を使った集約をおこなうことができます。例えば、片方のテーブルにはID1つにつき1行が割り当てられていて、もう1つのテーブルにはID1つにつき複数行が割り当てられている場合、複数行の方をIDごとに統計量を計算し、1行1IDのテーブルに追加できます。

イメージとしては、片方のテーブルが顧客のデータベース、もう1つが商品の売上データ(商品ごとにだれが購入したかのデータ)などが考えられます。

四則演算を行う

勾配ブースティングを使う手法(lightGBM, XGBoost, CatBoostなど)では、差や比を直接表現することができません。

このため、四則演算を行なった結果を特徴量に加えることで精度向上できることがあります。

例えば、身長と体重の比率などを新たな特徴量とすることも考えられます。

また、集約した特徴量との差、例えば平均身長からの差などを新たな特徴量とすることも考えられます。

四則演算を行なった結果の解釈性も重要だと思います

例えば、身長と体重の比などは、太り具合と解釈できそうです

他の予測器で作成した結果を特徴量として使う

他の予測器で予測した結果を特徴量に追加するなども考えられます。

例えばMLPやディープラーニング等を用いて予測した結果を勾配ブースティングの特徴量として入力するなども考えられます。

画像データがある場合は、CNNを使って画像特徴量を抽出し、縮退して列に追加するという方法も考えらます。

画像や音声などのデータは、深層学習モデルを使って特徴量に変換すればlightGBMなどの列として入力することができます(実際やってみると、効果があったり、なかったりで悩ましいですが)。

おすすめ書籍(PR)

私自身、kaggleの参加で特徴量エンジニアリングの手法と重要性について学びました。

前処理・特徴量エンジニアリングの学習には、kaggleに勝つデータ分析技術について書かれた、以下の書籍がおすすめです。

まとめ

機械学習の前処理・特徴量エンジニアリングの手法を解説しました。

特徴量エンジニアリングは性能改善にかなり重要な部分です。

今後も、気づいたものがあればここに追加していきます。

kaggleコンペに出るたびに、取り組みや上位の解法から気づきがあります。汎用的に使えそうなものがあればここにメモ代わりに追加していく予定です。

おすすめ書籍

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

記事URLをコピーしました