機械学習データ前処理入門

機械学習のためのデータ前処理:新しい特徴量を作り出す方法【Pandas入門】

Tags: 機械学習, データ前処理, 特徴量生成, Pandas, データ分析

はじめに

機械学習モデルの性能は、使用する「データ」の質に大きく左右されます。中でも、「特徴量」と呼ばれるモデルへの入力となるデータの項目は、モデルがデータを理解し、学習するための鍵となります。

これまで、このサイトでは欠損値の処理、カテゴリ変数の扱い、外れ値の検出、スケーリングなど、既存の特徴量を調整する様々なデータ前処理手法を解説してきました。しかし、時には既存の特徴量をそのまま使うだけでは、モデルがデータの持つ潜在的なパターンを十分に捉えきれないことがあります。

そこで重要になるのが、「特徴量生成(Feature Engineering)」です。これは、既存のデータ項目を組み合わせて新しい特徴量を作成したり、データから新たな情報を引き出したりするプロセスです。適切に生成された特徴量は、モデルの精度を飛躍的に向上させることがあります。

この記事では、プログラミングや機械学習の経験が少ない方にも分かりやすく、特徴量生成の基本的な考え方と、Pythonのデータ分析ライブラリであるPandasを使った具体的な手法をご紹介します。データからどのように新しい価値を引き出すのか、その第一歩を学びましょう。

特徴量生成とは何か、なぜ重要なのか

特徴量生成とは、文字通り「特徴量を新しく生み出すこと」です。元のデータセットに含まれる1つまたは複数のカラム(列)から、新たな意味を持つ情報を抽出したり、計算によって新しいカラムを作り出したりします。

なぜ特徴量生成が重要なのでしょうか。主な理由は以下の通りです。

特徴量生成は、決まった万能な手法があるわけではなく、扱うデータや解決したい課題に応じて、試行錯誤しながら進める創造的なプロセスです。

Pandasを使った特徴量生成の基本テクニック

ここでは、Pandasライブラリを使って行う基本的な特徴量生成のテクニックをいくつかご紹介します。簡単な例を用いて解説します。

例として、以下のような架空の顧客データを考えます。

| 顧客ID | 年齢 | 体重(kg) | 身長(cm) | 購入金額 | 購入日 | | :----- | :--- | :------- | :------- | :------- | :--------- | | 101 | 35 | 70 | 175 | 5000 | 2023-10-01 | | 102 | 28 | 55 | 160 | 12000 | 2023-10-05 | | 103 | 42 | 85 | 180 | 3000 | 2023-10-08 | | 104 | 19 | 60 | 168 | 8000 | 2023-10-10 | | 105 | 55 | 65 | 158 | 25000 | 2023-10-12 |

このデータをPandasのDataFrameとして読み込みます。

import pandas as pd
import io

data = """顧客ID,年齢,体重(kg),身長(cm),購入金額,購入日
101,35,70,175,5000,2023-10-01
102,28,55,160,12000,2023-10-05
103,42,85,180,3000,2023-10-08
104,19,60,168,8000,2023-10-10
105,55,65,158,25000,2023-10-12
"""

df = pd.read_csv(io.StringIO(data))

# 購入日をdatetime型に変換しておきます
df['購入日'] = pd.to_datetime(df['購入日'])

print(df)
   顧客ID  年齢  体重(kg)  身長(cm)  購入金額        購入日
0   101  35      70     175  5000 2023-10-01
1   102  28      55     160 12000 2023-10-05
2   103  42      85     180  3000 2023-10-08
3   104  19      60     168  8000 2023-10-10
4   105  55      65     158 25000 2023-10-12

1. 既存の数値特徴量からの四則演算

複数の数値カラムから、計算によって新しい特徴量を作成する最も基本的な方法です。例えば、「体重(kg)」と「身長(cm)」からBMI(体格指数)を計算するカラムを追加してみましょう。BMIは「体重(kg) / (身長(m) * 身長(m))」で計算されます。身長がcmで与えられているので、mに変換するために100で割る必要があります。

# 身長をメートルに変換し、BMIを計算する
df['身長(m)'] = df['身長(cm)'] / 100
df['BMI'] = df['体重(kg)'] / (df['身長(m)'] ** 2)

# 元の身長(cm)と新しく作った身長(m)を表示
print(df[['身長(cm)', '身長(m)', 'BMI']])
   身長(cm)  身長(m)        BMI
0     175   1.75  22.857143
1     160   1.60  21.484375
2     180   1.80  26.234568
3     168   1.68  21.258611
4     158   1.58  26.030629

このように、既存のカラムを使って新しい計算結果をDataFrameの新しいカラムとして簡単に追加できます。

2. 条件に基づく新しい特徴量(カテゴリ化)

数値や他のカラムの値に基づいて、条件分けをして新しいカテゴリを示す特徴量を作成することもよく行われます。例えば、「年齢」から「年代」や「年齢層」といったカテゴリカルな特徴量を作成してみましょう。

ここでは、Pandasのcut関数を使うと、数値をビン(区間)に区切ってカテゴリに変換できます。

# 年齢を年代に区切る
# bins: 区間の境界値のリスト (例: [0, 10, 20, 30, 40, 50, 60, 100])
# labels: 各区間に割り当てるラベルのリスト (例: ['0代', '10代', '20代', ...])
# right=False: 区間を [a, b) と定義 (aは含む、bは含まない)。デフォルトは (a, b]。
bins = [0, 20, 30, 40, 50, 60, 100]
labels = ['10代未満・10代', '20代', '30代', '40代', '50代', '60代以上']

df['年代'] = pd.cut(df['年齢'], bins=bins, labels=labels, right=False)

print(df[['年齢', '年代']])
   年齢           年代
0  35         30代
1  28         20代
2  42         40代
3  19  10代未満・10代
4  55         50代

このように、数値データを業務上の意味を持つカテゴリに変換することで、モデルが年齢のような連続的な値ではなく、「〇〇代」という区分としてパターンを学習できるようになります。

別の例として、「購入金額」に応じて顧客をランク付けする「顧客ランク」という特徴量を作成してみましょう。

このような複数の条件に基づく分類には、numpy.select関数やPandasのapplyメソッドと組み合わせる方法などがあります。ここでは、シンプルにlocを使って順番に条件を適用していく方法を見てみましょう。

import numpy as np

# 初期値として'Bronze'を設定
df['顧客ランク'] = 'Bronze'

# 条件に基づいてランクを更新
df.loc[df['購入金額'] >= 5000, '顧客ランク'] = 'Silver'
df.loc[df['購入金額'] >= 10000, '顧客ランク'] = 'Gold'
df.loc[df['購入金額'] >= 20000, '顧客ランク'] = 'Platinum'

print(df[['購入金額', '顧客ランク']])
   購入金額 顧客ランク
0    5000   Silver
1   12000     Gold
2    3000   Bronze
3    8000   Silver
4   25000 Platinum

この例では、locを使って条件に合う行の「顧客ランク」カラムの値を更新しています。条件を順番に適用することで、段階的なランク付けが可能です。

3. 日付・時刻データからの特徴量抽出

「購入日」のような日付・時刻データからは、様々な周期性や時点に関する特徴量を抽出できます。例えば、曜日、月、年、特定の祝日からの日数、といった情報です。これらは購買行動やイベント発生のタイミングを捉えるのに役立ちます。

日付・時刻データを扱うには、まずカラムのデータ型がdatetime型になっている必要があります(上記の最初のコードで既に変換済みです)。Pandasのdatetime型は.dtアクセサを通じて様々な属性にアクセスできます。

# 購入日から「年」「月」「曜日」を抽出する
df['購入年'] = df['購入日'].dt.year
df['購入月'] = df['購入日'].dt.month
df['購入曜日'] = df['購入日'].dt.day_name() # 英語の曜日名を取得

print(df[['購入日', '購入年', '購入月', '購入曜日']])
        購入日  購入年  購入月 購入曜日
0 2023-10-01   2023   10  Sunday
1 2023-10-05   2023   10  Thursday
2 2023-10-08   2023   10  Sunday
3 2023-10-10   2023   10   Tuesday
4 2023-10-12   2023   10  Thursday

このように、日付データから年、月、曜日などを新しい特徴量として簡単に取り出せます。これにより、例えば「週末は購入金額が多い傾向があるか?」といった分析やモデル構築が可能になります。

まとめ

この記事では、機械学習のデータ前処理における重要なステップの一つである「特徴量生成」について解説しました。特徴量生成は、既存データから新しい意味を持つ情報を作り出すことで、モデルの精度や解釈性を向上させるための創造的なプロセスです。

Pandasを使った基本的な特徴量生成のテクニックとして、以下の3つを紹介しました。

  1. 既存の数値特徴量からの四則演算: 複数の数値カラムを計算して新しいカラムを作成(例: BMIの計算)。
  2. 条件に基づく新しい特徴量(カテゴリ化): 数値などを条件で区切ってカテゴリカルなカラムを作成(例: 年齢から年代、購入金額から顧客ランク)。
  3. 日付・時刻データからの特徴量抽出: 日付データから年、月、曜日などの情報を抽出(例: 購入日から購入曜日)。

これらは特徴量生成のほんの一例ですが、これらの基本的な考え方と手法を理解することで、お手持ちのデータから多様な新しい特徴量を生み出すことができるようになります。

特徴量生成はデータと課題への深い理解が求められることもありますが、様々な切り口でデータを見て、新しい情報を作り出す作業は、データ分析の面白さの一つでもあります。

次に学ぶステップとしては、生成したカテゴリカルな特徴量をモデルに入力できるように数値に変換する方法(例: ワンホットエンコーディング)や、より複雑な特徴量生成のパターンに進むことが考えられます。

データ前処理は機械学習モデル構築の土台です。特徴量生成のスキルを身につけ、より高性能なモデル開発を目指しましょう。