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

機械学習のためのデータ前処理:日付・時刻データを効果的に扱う方法【Pandas入門】

Tags: 機械学習, データ前処理, Pandas, Python, データ分析, 時系列データ

はじめに:日付・時刻データの重要性

データ分析や機械学習モデルの構築において、多くの場合、データには日付や時刻の情報が含まれています。商品の購入日時、Webサイトへのアクセス時間、イベントの発生時刻など、これらは単なる記録ではなく、重要なパターンや傾向を捉えるための鍵となる情報です。

しかし、日付や時刻データは、そのままの状態では機械学習モデルが直接扱うことが難しい形式であることがほとんどです。文字列として記録されていたり、数値に変換されていてもモデルにとって意味のある表現になっていなかったりします。

日付や時刻データを適切に「前処理」することで、モデルは時間的な要素を学習に利用できるようになり、予測精度や分析の質を大きく向上させることが期待できます。この記事では、Pythonのpandasライブラリを使った、日付・時刻データの基本的な扱い方と効果的な前処理手法について解説します。

pandasにおける日付・時刻データ(datetime型)

pandasでは、日付や時刻を扱うための専用のデータ型として datetime 型が用意されています。この datetime 型を用いることで、日付の計算や、年・月・日といった要素へのアクセスが容易になります。

元のデータが文字列や数値で日付・時刻情報を持っている場合、まずこの datetime 型に変換することが前処理の第一歩となります。

1. 文字列からdatetime型への変換

データが日付や時刻を表現する文字列(例: '2023-10-27', '2023/10/27 14:30:00')として格納されている場合、pandasの to_datetime 関数を使って datetime 型に変換できます。

データフレーム df の '購入日時' という列が文字列で記録されている場合を考えます。

import pandas as pd

# サンプルデータの作成 (実際はファイル読み込みなど)
data = {'購入ID': [1, 2, 3],
        '商品名': ['A', 'B', 'C'],
        '購入日時': ['2023-10-27 10:00:00', '2023-10-27 14:30:00', '2023-10-28 09:15:00']}
df = pd.DataFrame(data)

print("変換前のデータ型:")
print(df.info())

# '購入日時' 列をdatetime型に変換
df['購入日時'] = pd.to_datetime(df['購入日時'])

print("\n変換後のデータ型:")
print(df.info())
print("\n変換後のデータ:")
print(df)

pd.to_datetime 関数は非常に賢く、多くの一般的な日付文字列形式を自動的に認識して変換してくれます。もし特定の形式で文字列が記述されている場合は、format 引数を使って形式を指定することも可能です。

# 例: 'YYYY/MM/DD HH:MM:SS' 形式の場合
# df['購入日時'] = pd.to_datetime(df['購入日時'], format='%Y/%m/%d %H:%M:%S')

変換時にエラーが発生する場合(例えば、不正な日付文字列が含まれている場合)は、errors 引数を指定することで挙動を制御できます。errors='coerce' と指定すると、変換できなかった値を NaT (Not a Time) という欠損値に置き換えることができます。

2. 日付・時刻要素の抽出

datetime 型に変換することで、年、月、日、曜日、時間といった個別の要素を簡単に抽出できるようになります。これは、これらの要素自体が機械学習モデルにとって有用な特徴量となることが多いため、非常に重要な前処理ステップです。

datetime 型のSeries(データフレームの列)は .dt アクセサを持っており、これを通じて様々な属性にアクセスできます。

# 前のステップでdatetime型に変換したdfを使用
print("\n日付・時刻要素の抽出:")

df['購入年'] = df['購入日時'].dt.year
df['購入月'] = df['購入日時'].dt.month
df['購入日'] = df['購入日時'].dt.day
df['購入曜日'] = df['購入日時'].dt.dayofweek # 月曜日が0、日曜日が6
df['購入時間'] = df['購入日時'].dt.hour
df['購入分'] = df['購入日時'].dt.minute

print(df)

抽出した「購入年」「購入月」「購入日」「購入曜日」「購入時間」「購入分」といった新しい列は、そのまま数値特徴量としてモデルに入力したり、カテゴリ特徴量としてエンコーディングしたりすることができます。特に「曜日」や「月」などは、季節性や周期性を捉える上で有効な特徴量となります。

3. 日付・時刻間の計算(期間、差分)

日付・時刻データから、あるイベントから別のイベントまでの期間や、ある時点からの経過時間といった「差分」を計算することも、重要な特徴量エンジニアリングの手法です。

例えば、顧客の初回購入日時と最新購入日時の差から「顧客の利用期間」を計算したり、あるタスクの開始時刻と終了時刻の差から「タスクの所要時間」を計算したりすることが考えられます。

datetime 型のデータ同士の引き算は、自動的に期間を表す timedelta 型のデータになります。

# 例: 注文から発送までの時間を計算するシナリオを想定
data_diff = {'注文ID': [101, 102],
             '注文日時': ['2023-10-27 08:00:00', '2023-10-27 12:00:00'],
             '発送日時': ['2023-10-27 11:30:00', '2023-10-28 09:00:00']}
df_diff = pd.DataFrame(data_diff)

df_diff['注文日時'] = pd.to_datetime(df_diff['注文日時'])
df_diff['発送日時'] = pd.to_datetime(df_diff['発送日時'])

# 注文から発送までの時間を計算
df_diff['発送までの時間'] = df_diff['発送日時'] - df_diff['注文日時']

print("\n期間計算の例:")
print(df_diff)
print("\n発送までの時間のデータ型:")
print(df_diff['発送までの時間'].dtype)

timedelta 型のデータは、.dt アクセサを使って日 (.dt.days) や秒 (.dt.total_seconds()) などの単位で数値に変換できます。モデルに入力するには、数値形式に変換する必要があります。

# 発送までの時間を時間単位(小数点含む)で表現
df_diff['発送までの時間_hours'] = df_diff['発送までの時間'].dt.total_seconds() / 3600

print("\n期間を数値に変換した例:")
print(df_diff)

4. 時系列に特化した特徴量エンジニアリング

日付・時刻データは、単なる時刻情報だけでなく、その背後にある時間的なパターンや外部要因を示す情報を引き出すことができます。

これらの特徴量エンジニアリングは、ビジネスの知識やデータの特性に合わせて工夫することが重要です。どのような時間的な要素が分析対象の課題に関連があるのかを考慮して特徴量を設計します。

まとめ

日付・時刻データの前処理は、機械学習モデルが時間的な情報を効果的に活用するために不可欠なステップです。この記事では、以下の基本的な前処理フローを紹介しました。

  1. datetime型への変換: pandasの to_datetime を使用して、日付・時刻データを専用の datetime 型に変換します。
  2. 要素の抽出: .dt アクセサを使って、年、月、日、曜日、時間などの個別の要素を新しい特徴量として抽出します。
  3. 期間・差分の計算: datetime 型データの引き算で期間を計算し、必要に応じて数値形式に変換します。
  4. 時系列特化特徴量: 曜日・月サイクル、祝日フラグ、時間帯など、時間に関連するビジネス上の意味を持つ特徴量を検討・生成します。

これらのステップを通じて、元の単なる日付・時刻情報が、モデルが学習できる具体的な数値やカテゴリの特徴量へと生まれ変わります。データに含まれる時間的なパターンを捉えることで、より精度の高い機械学習モデルを構築できる可能性が高まります。

次回の記事では、別の重要なデータ前処理手法について解説する予定です。データ前処理のスキルを体系的に習得し、機械学習プロジェクトを成功に導きましょう。