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

機械学習データ前処理:データを「グループ化」して分析の切り口を見つける方法【Pandas入門】

Tags: 機械学習, データ前処理, Pandas, データ分析, groupby

機械学習モデルを構築する際には、その基盤となるデータの質が非常に重要です。生データはそのままでは分析やモデル学習に適していないことが多く、様々な前処理が必要となります。本記事では、数あるデータ前処理の中でも、データを特定の条件でまとめ、分析の切り口を見つけるための強力な手法である「グループ化」について解説します。

データを「グループ化」するとは?

データにおける「グループ化」とは、特定の列(または複数の列)の値に基づいて、データをいくつかのまとまりに分ける処理を指します。例えば、顧客ごとの購入履歴データがある場合に、顧客IDでグループ化すれば、各顧客の全購入履歴をまとめて扱うことができます。

この操作は、Excelを使ったデータ分析の経験がある方であれば、「ピボットテーブル」をイメージすると分かりやすいかもしれません。ピボットテーブルでは、特定の項目(行ラベルや列ラベル)でデータを集計しますが、これも広い意味でのグループ化と集計の組み合わせと言えます。

なぜデータ前処理でグループ化が重要なのか

機械学習の文脈において、グループ化は以下のような目的で重要な前処理となります。

  1. 傾向の把握と分析:

    • データをグループ化することで、特定の属性(例: 顧客、地域、商品カテゴリ)ごとの合計値、平均値、個数などを簡単に計算できます。これにより、データ全体の傾向や、グループ間の比較を通じてビジネス上の重要な洞察を得ることができます。
    • 例えば、「商品カテゴリごとの売上合計」や「地域ごとの平均購入金額」などを算出できます。
  2. 新しい「特徴量」の生成:

    • グループ化とそれに続く集計は、機械学習モデルの入力となる新しい特徴量(説明変数)を生み出す強力な手段です。
    • 例えば、顧客ごとの購入履歴データから、「顧客ごとの購入回数」「顧客ごとの合計購入金額」「顧客が最後に購入してからの日数」などを集計することで、顧客の購買行動を表す特徴量を作成できます。これらの特徴量は、顧客の将来の購買確率予測などに役立つ可能性があります。
  3. データの粒度の調整:

    • データの粒度が高すぎる(細かすぎる)場合、グループ化によってデータを集約し、分析に適した粒度に変更することができます。

このように、グループ化は単にデータを整理するだけでなく、分析の質を高めたり、モデルの性能向上に繋がる新しい情報を引き出したりするための、非常に価値のある前処理手法です。

Pandasを使ったデータのグループ化(groupby()

Pythonでデータ分析を行う際に広く使われるpandasライブラリには、データを効率的にグループ化するためのgroupby()メソッドが用意されています。groupby()は、以下の3つのステップで処理を行います。

  1. Split (分割): 指定したキー(列)の値に基づいて、DataFrameを複数のグループに分割します。
  2. Apply (適用): 各グループに対して、集計関数(合計、平均、個数など)や変換関数、フィルタリングなどを適用します。
  3. Combine (結合): 適用した結果を一つのDataFrameやSeriesとして結合します。

groupby()メソッドは、この「Split-Apply-Combine」のプロセスを効率的に実行します。

groupby()の基本的な使い方

簡単な例として、売上データを使って、商品カテゴリごとの合計売上を計算してみましょう。まずはサンプルデータを作成します。

import pandas as pd

# サンプルデータの作成
data = {
    '商品ID': ['A001', 'A002', 'B001', 'B002', 'A001', 'C001', 'B001', 'A002'],
    '商品カテゴリ': ['家電', '書籍', '衣料品', '家電', '家電', '食品', '衣料品', '書籍'],
    '売上金額': [10000, 3000, 5000, 12000, 9000, 2000, 6000, 3500]
}
df = pd.DataFrame(data)

print("元のデータ:")
print(df)
元のデータ:
   商品ID 商品カテゴリ  売上金額
0  A001      家電  10000
1  A002      書籍   3000
2  B001     衣料品   5000
3  B002      家電  12000
4  A001      家電   9000
5  C001      食品   2000
6  B001     衣料品   6000
7  A002      書籍   3500

このデータを使って、「商品カテゴリ」ごとに「売上金額」の合計を計算します。groupby()メソッドにグループ化したい列名を指定し、その後に集計したい列名と集計関数をドット(.)でつなげて記述します。

# '商品カテゴリ'でグループ化し、'売上金額'の合計を計算
category_sales = df.groupby('商品カテゴリ')['売上金額'].sum()

print("\n商品カテゴリごとの合計売上:")
print(category_sales)
商品カテゴリごとの合計売上:
商品カテゴリ
家電     31000
書籍      6500
衣料品    11000
食品      2000
Name: 売上金額, dtype: int64

コードの解説:

結果として、各商品カテゴリの合計売上が計算されたSeriesが得られます。このSeriesのインデックスはグループ化に使用した'商品カテゴリ'列の値となっています。

複数の列でグループ化する

複数の列を組み合わせてグループ化することも可能です。例えば、「商品カテゴリ」と「商品ID」の組み合わせごとの合計売上を見たい場合は、groupby()に列名のリストを指定します。

# '商品カテゴリ'と'商品ID'でグループ化し、'売上金額'の合計を計算
category_item_sales = df.groupby(['商品カテゴリ', '商品ID'])['売上金額'].sum()

print("\n商品カテゴリと商品IDの組み合わせごとの合計売上:")
print(category_item_sales)
商品カテゴリと商品IDの組み合わせごとの合計売上:
商品カテゴリ  商品ID
家電     A001    19000
       B002    12000
書籍     A002     6500
衣料品    B001    11000
食品     C001     2000
Name: 売上金額, dtype: int64

この場合、グループ化のキーが複数あるため、結果のSeriesのインデックスも複数のレベルを持つMultiIndexとなります。

複数の集計関数を適用する

同じグループに対して、複数の集計関数を一度に適用することもできます。例えば、「商品カテゴリ」ごとの合計売上だけでなく、平均売上も知りたい場合などです。これには、集計関数をリストとして.agg()メソッドに渡します。

# '商品カテゴリ'でグループ化し、'売上金額'の合計と平均を計算
category_agg_sales = df.groupby('商品カテゴリ')['売上金額'].agg(['sum', 'mean', 'count'])

print("\n商品カテゴリごとの合計・平均・件数:")
print(category_agg_sales)
商品カテゴリごとの合計・平均・件数:
          sum     mean  count
商品カテゴリ                      
家電      31000  10333.333333      3
書籍       6500   3250.000000      2
衣料品     11000   5500.000000      2
食品       2000   2000.000000      1

.agg(['sum', 'mean', 'count'])とすることで、指定した3つの集計関数が一度に適用され、結果はDataFrameとして返されます。列名には指定した集計関数の名前が使われます。

グループ化結果をDataFrameとして扱う(as_index=False

デフォルトでは、groupby()のキーは結果のDataFrame(またはSeries)のインデックスになります。これを通常の列として扱いたい場合は、groupby()の引数にas_index=Falseを指定します。

# '商品カテゴリ'でグループ化し、'売上金額'の合計を計算(キーを列として保持)
category_sales_df = df.groupby('商品カテゴリ', as_index=False)['売上金額'].sum()

print("\n商品カテゴリごとの合計売上(DataFrame形式、インデックスを列として保持):")
print(category_sales_df)
商品カテゴリごとの合計売上(DataFrame形式、インデックスを列として保持):
  商品カテゴリ  売上金額
0      家電  31000
1      書籍   6500
2     衣料品  11000
3      食品   2000

この形式で得られたDataFrameは、後続のデータ処理や、機械学習モデルへの入力としてそのまま使いやすい形となります。

特徴量生成への応用例:顧客ごとの集計特徴量

ビジネスデータの分析でよくあるシナリオとして、顧客レベルでの特徴量を作成するタスクがあります。例えば、各顧客がどれだけ購入しているかを数値で表現したい場合などです。先ほどの売上データに「顧客ID」列を追加して考えてみましょう。

import pandas as pd

# 顧客IDを追加したサンプルデータの作成
data_customer = {
    '注文ID': [1, 2, 3, 4, 5, 6, 7, 8],
    '顧客ID': ['C001', 'C002', 'C001', 'C003', 'C002', 'C001', 'C003', 'C002'],
    '商品カテゴリ': ['家電', '書籍', '衣料品', '家電', '家電', '食品', '衣料品', '書籍'],
    '売上金額': [10000, 3000, 5000, 12000, 9000, 2000, 6000, 3500],
    '購入日時': pd.to_datetime(['2023-01-10', '2023-01-15', '2023-01-20', '2023-02-01', '2023-02-05', '2023-02-10', '2023-02-15', '2023-02-20'])
}
df_customer = pd.DataFrame(data_customer)

print("顧客IDを含む元のデータ:")
print(df_customer)
顧客IDを含む元のデータ:
   注文ID  顧客ID 商品カテゴリ  売上金額       購入日時
0     1  C001      家電  10000 2023-01-10
1     2  C002      書籍   3000 2023-01-15
2     3  C001     衣料品   5000 2023-01-20
3     4  C003      家電  12000 2023-02-01
4     5  C002      家電   9000 2023-02-05
5     6  C001      食品   2000 2023-02-10
6     7  C003     衣料品   6000 2023-02-15
7     8  C002      書籍   3500 2023-02-20

このデータから、顧客ごとの「合計売上」「購入回数」「平均購入金額」といった特徴量を作成できます。

# '顧客ID'でグループ化し、複数の集計関数を適用して特徴量を作成
customer_features = df_customer.groupby('顧客ID').agg(
    合計売上=('売上金額', 'sum'),           # 合計売上
    購入回数=('注文ID', 'count'),         # 購入回数(注文IDの数)
    平均購入金額=('売上金額', 'mean')        # 平均購入金額
).reset_index() # インデックスを列に戻す

print("\n顧客ごとの集計特徴量:")
print(customer_features)
顧客ごとの集計特徴量:
   顧客ID  合計売上  購入回数    平均購入金額
0  C001  17000     3  5666.666667
1  C002  15500     3  5166.666667
2  C003  18000     2  9000.000000

コードの解説:

このように、groupby().agg()を組み合わせることで、ビジネス上意味のある顧客レベルの集計特徴量(合計売上、購入回数、平均購入金額など)を簡単に生成できます。これらの特徴量は、例えば顧客のLTV予測やセグメンテーションといった機械学習タスクにおいて、モデルの予測精度を向上させるために非常に有効です。

さらに応用すると、購入日時データを使って、各顧客の「最後に購入してからの日数」や「初回購入からの日数」といった時間に関連する特徴量も、グループ化と適切な集計・変換処理を組み合わせて作成することが可能です。(日付・時刻データの処理については、別の記事で詳しく解説します)。

まとめ

本記事では、機械学習のためのデータ前処理における「グループ化」の重要性と、PythonのPandasライブラリを使った具体的な実装方法を解説しました。

データを「グループ化」して様々な切り口から眺めたり、ビジネス上の意味を持つ集計値を作成したりすることは、データ分析の基礎であり、機械学習モデルの性能向上にも直結する重要なスキルです。ぜひご自身のデータで試してみてください。

データ前処理には様々な手法があり、グループ化もその一部です。他の重要な前処理手法についても、本サイトで体系的に学習を進めていただければ幸いです。