見出し画像

LightGBMをはじめてさわってみよう!


こんにちは。
株式会社SHIFT 、アプリケーション開発テクノロジーグループ所属の竹内です。主にPythonを使った開発をしているバックエンドエンジニアです。

今回は、機械学習の世界で非常に人気のあるライブラリ「LightGBM」について紹介します。

LightGBMは、特に大規模なデータセットを扱う際に非常に強力なツールです。この記事では、LightGBMとは何か、そしてどのように使うのかについて説明します。

LightGBMとは?


LightGBM(Light Gradient Boosting Machine)は、Microsoftが開発した機械学習フレームワークです。Kaggleなどでも人気があり使いやすいです。LightGBMは以下の特徴を持っています。

  • 高速なトレーニング速度と高い効率性:大規模なデータセットでも高速に学習できます。

  • 低メモリ使用量:メモリ効率が良く、大規模データでも扱いやすいです。

  • 高い精度:他の勾配ブースティングライブラリと比較しても高い精度を誇ります。

  • 並列・分散・GPU学習のサポート:複数のCPUやGPUを使って学習を高速化できます。

LightGBMのインストール


まずはLightGBMをインストールしましょう。Pythonのパッケージ管理システムであるpipを使って簡単にインストールできます。

pip install lightgbm

LightGBMの基本的な使い方


ここでは、LightGBMを使った基本的なモデルのトレーニングと予測の流れを紹介します。例として、Irisデータセットを使います。
※Irisデータセットは、機械学習や統計学の分野で広く使用されているデータセットの一つです。このデータセットは、アヤメ(Iris)という花の3つの異なる品種(Setosa、Versicolor、Virginica)を分類するためのデータを含んでいます。

1. 必要なライブラリのインポート

import lightgbm as lgb
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

まずは必要なライブラリをインポートします。インポートしているLightGBM以外のライブラリについては、以下を参照ください。

  • Scikit-learn (sklearn)
    Pythonで機械学習を行うためのライブラリです。分類、回帰、クラスタリング、次元削減、モデル選択、前処理など、さまざまな機械学習アルゴリズムとツールを提供しています。Scikit-learnは、使いやすさと一貫性を重視して設計されており、機械学習の初心者から専門家まで幅広く利用されています。

  • load_iris(Scikit-learnのデータセットモジュール)
    Irisデータセットを読み込むための関数です。

  • train_test_split(Scikit-learnのモデル選択モジュール)
    データセットをトレーニングデータとテストデータに分割するための関数です。機械学習モデルの性能を評価するためには、データセットをトレーニングデータとテストデータに分けて、モデルの学習と評価を行うことが一般的です。この関数を使うことで、簡単にデータセットを分割することができます。

  • accuracy_score(Scikit-learnのメトリクスモジュール)
    分類モデルの予測精度を評価するための関数です。予測されたラベルと実際のラベルを比較して、正解率(accuracy)を計算します。正解率は、全ての予測のうち、正しく予測されたものの割合を示します。

2. データの準備

# Irisデータセットの読み込み
data = load_iris()
X = data.data
y = data.target

# トレーニングデータとテストデータに分割
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

Irisデータセットの読み込み

load_iris()で、Irisデータセットを読み込みます。 変数dataには、データセットの特徴量やターゲット変数、特徴量の名前、ターゲットの名前などが入ります。

Xは、Irisデータセットの特徴量(説明変数)を格納する変数です。data.dataは、Irisデータセットの特徴量を含むNumPy配列です。各行は1つのサンプルを表し、各列は1つの特徴量を表します。 特徴量:Irisデータセットには4つの特徴量があります。

  • Sepal Length(がく片の長さ)

  • Sepal Width(がく片の幅)

  • Petal Length(花弁の長さ)

  • Petal Width(花弁の幅)

yは、Irisデータセットのターゲット変数(目的変数、ラベル)を格納する変数です。data.targetは、各サンプルの品種を表すラベルを含むNumPy配列です。ラベルは0, 1, 2の整数値で、それぞれ以下の品種を表します。

  • 0:Setosa

  • 1:Versicolor

  • 2:Virginica

トレーニングデータとテストデータに分割

train_test_splitは、Scikit-learnのモデル選択モジュールに含まれる関数で、データセットをトレーニングデータとテストデータに分割します。この関数は、特徴量とターゲット変数を入力として受け取り、トレーニングデータとテストデータに分割された4つの配列を返します。

引数については以下のとおりです。

  • X
    特徴量の配列。ここでは、Irisデータセットの特徴量を含むXを指定します。

  • y
    ターゲット変数の配列。ここでは、Irisデータセットのターゲット変数を含むyを指定します。

  • test_size=0.2
    テストデータの割合を指定します。ここでは、データセットの20%をテストデータとして使用することを指定しています。残りの80%はトレーニングデータとして使用されます。

  • random_state=42
    乱数シードを指定します。これにより、データの分割が再現可能になります。任意の整数値を指定できますが、同じ値を指定すると同じ分割結果が得られます。

返り値については、以下のとおりです。

  • X_train
    トレーニングデータの特徴量を含む配列。

  • X_test
    テストデータの特徴量を含む配列。

  • y_train
    トレーニングデータのターゲット変数を含む配列。

  • y_test
    テストデータのターゲット変数を含む配列。

これにより、元のデータセットがトレーニングデータとテストデータに分割され、モデルの学習と評価に使用できるようになります。トレーニングデータはモデルの学習に使用され、テストデータは学習したモデルの性能を評価するために使用されます。

3. データセットの作成

LightGBMは独自のデータセット形式を使用します。これを作成します。

train_data = lgb.Dataset(X_train, label=y_train)
test_data = lgb.Dataset(X_test, label=y_test, reference=train_data)

まず各関数と変数については以下のとおりです。

  • lgb.Datasetは、LightGBMのデータセットを作成するためのクラスです。LightGBMは独自のデータセット形式を使用しており、このクラスを使ってデータをLightGBMが扱える形式に変換します。lgb.Datasetは、トレーニングデータや検証データを作成するために使用されます。

  • train_dataは、トレーニングデータを格納する変数です。lgb.Datasetクラスを使って、トレーニングデータの特徴量とターゲット変数を指定して作成します。

  • test_dataは、テストデータ(または検証データ)を格納する変数です。lgb.Datasetクラスを使って、テストデータの特徴量とターゲット変数を指定して作成します。

引数は以下のとおりです。

  • X_train
    トレーニングデータの特徴量を含む配列。train_test_split関数で分割されたトレーニングデータの特徴量を指定します。

  • y_train
    トレーニングデータのターゲット変数を含む配列。train_test_split関数で分割されたトレーニングデータのターゲット変数を指定します。

  • X_test
    テストデータの特徴量を含む配列。train_test_split関数で分割されたテストデータの特徴量を指定します。

  • y_test
    テストデータのターゲット変数を含む配列。train_test_split関数で分割されたテストデータのターゲット変数を指定します。

  • reference=train_data
    テストデータセットの作成時に使用されるオプションの引数です。reference引数は、テストデータセットがトレーニングデータセットに関連していることを示します。これにより、LightGBMはトレーニングデータセットのメタデータ(例えば、特徴量の名前やカテゴリカル特徴量の情報など)をテストデータセットに引き継ぐことができます。

上記を踏まえて、コードの処理の流れは以下のとおりです。

トレーニングデータセットの作成

X_train(トレーニングデータの特徴量)とy_train(トレーニングデータのターゲット変数)を使って、LightGBMのトレーニングデータセットを作成します。このデータセットは、LightGBMのモデルをトレーニングするために使用されます。

テストデータセットの作成

X_test(テストデータの特徴量)とy_test(テストデータのターゲット変数)を使って、LightGBMのテストデータセットを作成します。reference=train_dataを指定することで、テストデータセットがトレーニングデータセットに関連していることを示します。これにより、LightGBMはトレーニングデータセットのメタデータをテストデータセットに引き継ぎます。

まとめると、トレーニングデータとテストデータをLightGBMが扱える形式に変換するための処理になります。lgb.Datasetクラスを使って、トレーニングデータとテストデータのデータセットを作成し、reference引数を使ってテストデータセットがトレーニングデータセットに関連していることを示します。これにより、LightGBMは効率的にデータを扱い、モデルのトレーニングと評価を行うことができます。

4. モデルのトレーニング

次に、モデルをトレーニングします。ここでは、基本的なパラメータを設定します。

params = {
    'objective': 'multiclass',
    'num_class': 3,
    'metric': 'multi_logloss',
    'boosting_type': 'gbdt',
    'num_leaves': 31,
    'learning_rate': 0.05,
    'feature_fraction': 0.9
}

# モデルのトレーニング

bst = lgb.train(
    params,
    train_data,
    valid_sets=[test_data],
    num_boost_round=100,
    callbacks=[
        lgb.early_stopping(stopping_rounds=10, verbose=True),
        lgb.log_evaluation(period=100)
    ]
)

パラメータ

各パラメータについて説明します。このパラメータは、モデルの挙動や性能に大きな影響を与えます。

  • objective
    モデルの目的関数を指定します。ここでは、'multiclass'を指定しており、多クラス分類問題を解くための設定です。

  • num_class
    クラスの数を指定します。Irisデータセットには3つのクラス(Setosa, Versicolor, Virginica)があるため、3を指定しています。

  • metric
    評価指標を指定します。ここでは、'multi_logloss'を指定しており、多クラス分類のロス(損失)を評価指標として使用します。

  • boosting_type
    ブースティングの種類を指定します。ここでは、'gbdt'(Gradient Boosting Decision Tree)を指定しています。これは、勾配ブースティング決定木を使用する設定です。

  • num_leaves
    1つの決定木の葉の数を指定します。大きな値を指定するとモデルが複雑になり、過学習のリスクが高まります。

  • learning_rate
    学習率を指定します。小さな値を指定すると学習が遅くなりますが、精度が向上する可能性があります。

  • feature_fraction
    各決定木の学習に使用する特徴量の割合を指定します。過学習を防ぐために使用します。

モデルのトレーニング

lgb.trainは、LightGBMのモデルをトレーニングするための関数です。この関数は、指定されたパラメータとデータセットを使用してモデルをトレーニングし、トレーニングされたモデルを返します。

引数については、以下のとおりです。

  • params
    モデルのトレーニングに使用するパラメータを含む辞書。上記で設定したparamsを指定します。

  • train_data
    トレーニングデータセット。lgb.Datasetクラスを使って作成したトレーニングデータセットを指定します。

  • valid_sets
    検証データセットのリスト。ここでは、[test_data]を指定しており、テストデータセットを検証データとして使用します。これにより、トレーニング中にモデルの性能を評価するためにテストデータが使用されます。

  • num_boost_round
    ブースティングの反復回数(決定木の数)を指定します。ここでは、100を指定しています。モデルは最大で100回のブースティングを行います。

引数になっているcallback関数で指定している関数については、以下のとおりです。

  • lgb.early_stopping(stopping_rounds=10, verbose=True)
    early stoppingのためのコールバック関数。stopping_roundsは、早期停止のラウンド数を指定します。ここでは、10を指定しています。検証データセットの評価指標が10ラウンド連続で改善しない場合、トレーニングを早期に停止します。これにより、過学習を防ぐことができます。verbose=Trueに設定すると、early stoppingの情報が表示されます。

  • lgb.log_evaluation(period=100)
    評価結果を記録するためのコールバック関数。periodは、評価結果をログに記録する周期を指定します。最後のブースティングステージまたはearly_stoppingコールバックを使用して見つかったブースティングステージもログに記録されます。

ここでは、LightGBMのモデルをトレーニングするための一連の手順を示しています。まず、モデルのパラメータを設定し、次にlgb.train関数を使ってモデルをトレーニングします。トレーニング中に検証データセットを使用してモデルの性能を評価し、早期停止を行うことで過学習を防ぎます。

5. 予測と評価

トレーニングが完了したら、テストデータに対して予測を行い、精度を評価します。

y_pred = bst.predict(X_test, num_iteration=bst.best_iteration)
y_pred_max = [list(x).index(max(x)) for x in y_pred]

# 精度の計算
accuracy = accuracy_score(y_test, y_pred_max)
print(f'精度: {accuracy * 100:.2f}%')

クラスの予測

bst.predictは、トレーニング済みのLightGBMモデル(bst)を使って、新しいデータに対する予測を行うためのメソッドです。

引数については、以下のとおりです。

  • X_test
    テストデータの特徴量を含む配列。train_test_split関数で分割されたテストデータの特徴量を指定します。

  • num_iteration=bst.best_iteration
    予測に使用するブースティングの反復回数を指定します。ここでは、bst.best_iterationを指定しており、最適な反復回数(早期停止が適用された場合の最良の反復回数)を使用します。

返り値については、以下のとおりです。

  • y_pred
    予測結果を含む配列。各サンプルに対して、各クラスの確率が含まれています。例えば、Irisデータセットの場合、各サンプルに対して3つの確率(Setosa, Versicolor, Virginicaの確率)が含まれます。

y_pred_maxは、予測されたクラスラベルを格納するリストです。y_predには各クラスの確率が含まれているため、最も高い確率を持つクラスを選択して、そのクラスラベルを取得します。

list(x).index(max(x))は、xは各サンプルに対するクラスの確率を含むリストです。max(x)は最も高い確率を取得し、list(x).index(max(x))はその確率に対応するクラスラベルのインデックスを取得します。

[list(x).index(max(x)) for x in y_pred]では、リスト内包表記を使って、y_predの各要素に対して上記の操作を行い、各サンプルに対する予測クラスラベルを取得します。

精度の計算

accuracy_scoreは、Scikit-learnのメトリクスモジュールに含まれる関数で、分類モデルの予測精度を計算します。

引数については、以下のとおりです。

  • y_test
    実際のクラスラベルを含む配列。train_test_split関数で分割されたテストデータのターゲット変数を指定します。

  • y_pred_max
    予測されたクラスラベルを含むリスト。上記で計算した予測クラスラベルを指定します。

返り値については、以下のとおりです。

  • accuracy
    予測精度を表すスコア。全ての予測のうち、正しく予測されたものの割合を示します。

ここでは、トレーニング済みのLightGBMモデルを使ってテストデータに対する予測を行い、予測されたクラスラベルを取得し、実際のクラスラベルと比較して予測精度を計算する一連の手順を示しています。各ステップを理解することで、モデルの性能を評価する方法を学ぶことができます。

応用:パラメータチューニング


LightGBMの性能を最大限に引き出すためには、パラメータのチューニングが重要です。以下に、いくつかの主要なパラメータとその役割を紹介します。

  • num_leaves:決定木の葉の数。大きくするとモデルが複雑になり、過学習のリスクが高まります。

  • learning_rate:学習率。小さくすると学習が遅くなりますが、精度が向上する可能性があります。

  • feature_fraction:各決定木の学習に使用する特徴量の割合。過学習を防ぐために使用します。

  • bagging_fraction:各決定木の学習に使用するデータの割合。過学習を防ぐために使用します。

パラメータのチューニングには、Grid SearchやRandom Searchなどの手法を使用することが一般的です。

LightGBMを実際に使ってみよう


LightGBMは色んな用途が考えられます。試しにご自身で試してみたいケースで使ってみてください。 例として、いくつかケースを挙げてみます。

  • 顧客の離脱予測
    【シナリオ】
    あなたはあるサブスクリプションサービスを提供する企業のデータアナリストです。顧客がサービスを解約する(離脱する)かどうかを予測したいと考えています。
    【データ】
    顧客の年齢、性別、利用履歴、サポートへの問い合わせ回数、過去の支払い履歴などの特徴量と、顧客が離脱したかどうかのラベル(0: 継続、1: 離脱)。
    【使い方】
    特徴量とラベルを用意し、トレーニングデータとテストデータに分割します。 LightGBMを使ってモデルをトレーニングし、顧客が離脱する確率を予測します。 予測結果を基に、離脱のリスクが高い顧客に対して特別なオファーを提供するなどの対策を講じることができます。

  • 商品の売上予測
    【シナリオ】
    あなたは小売業のデータアナリストで、特定の商品が次の月にどれだけ売れるかを予測したいと考えています。
    【データ】
    過去の売上データ、季節、プロモーション情報、価格、競合他社の価格などの特徴量と、次の月の売上数のラベル。
    【使い方】
    特徴量とラベルを用意し、トレーニングデータとテストデータに分割します。 LightGBMを使ってモデルをトレーニングし、次の月の売上数を予測します。 予測結果を基に、在庫管理やプロモーション戦略を最適化することができます。

  • スパムメールの分類
    【シナリオ】
    あなたはメールサービスのエンジニアで、受信したメールがスパムかどうかを自動的に分類したいと考えています。
    【データ】
    メールの内容、送信者の情報、件名、メールの長さ、リンクの数などの特徴量と、メールがスパムかどうかのラベル(0: スパムでない、1: スパム)。
    【使い方】
    特徴量とラベルを用意し、トレーニングデータとテストデータに分割します。 LightGBMを使ってモデルをトレーニングし、メールがスパムかどうかを予測します。 予測結果を基に、スパムメールを自動的にフィルタリングするシステムを構築することができます。

  • 住宅価格の予測
    【シナリオ】
    あなたは不動産業のデータアナリストで、特定の地域の住宅価格を予測したいと考えています。
    データ:住宅の面積、部屋数、築年数、所在地、近隣の学校の評価、交通アクセスなどの特徴量と、住宅の価格のラベル。
    使い方:
    特徴量とラベルを用意し、トレーニングデータとテストデータに分割します。 LightGBMを使ってモデルをトレーニングし、住宅価格を予測します。 予測結果を基に、価格設定や投資判断を行うことができます。

  • クレジットカードの不正利用検出
    【シナリオ】
    あなたは金融機関のデータアナリストで、クレジットカードの不正利用を検出したいと考えています。
    【データ】
    取引の金額、取引の場所、取引の時間、取引の種類、過去の取引履歴などの特徴量と、取引が不正かどうかのラベル(0: 正常、1: 不正)。
    【使い方】
    特徴量とラベルを用意し、トレーニングデータとテストデータに分割します。 LightGBMを使ってモデルをトレーニングし、取引が不正かどうかを予測します。 予測結果を基に、不正取引をリアルタイムで検出し、対策を講じることができます。

<参考>


個人的にLightGBMを使っているケースとして、競馬の予想があるので、少しだけ詳しく書きます。気になったら読んでみてください。

競馬の予想は、馬の過去の成績、騎手の情報、馬場状態、天候など多くの要因が関与する複雑な問題です。LightGBMを使ってこれらの要因を考慮し、レースの結果を予測することができます。

1.データの収集

まず、競馬の予想に必要なデータを収集します。以下のようなデータが考えられます:

  • 馬の情報:馬の名前、年齢、性別、過去の成績、調教師、馬主など

  • 騎手の情報:騎手の名前、過去の成績、騎乗経験など

  • レースの情報:レースの距離、馬場状態(芝、ダート)、天候、開催場所、賞金など

  • 過去のレース結果:各馬の過去のレースでの順位、タイム、出走頭数など

2.データの前処理

収集したデータを前処理します。具体的には、以下のような処理を行います。

欠損値の処理:欠損値がある場合は適切に補完します。 カテゴリカルデータのエンコーディング:馬の名前や騎手の名前などのカテゴリカルデータを数値に変換します(例えば、One-HotエンコーディングやLabelエンコーディング)。 特徴量のスケーリング:特徴量のスケーリングを行い、モデルが学習しやすいようにします。

3. 特徴量の選定

予測に使用する特徴量を選定します。例えば、以下のような特徴量が考えられます。

  • 馬の過去の成績(直近のレースでの順位、タイムなど)

  • 騎手の過去の成績

  • レースの距離

  • 馬場状態

  • 天候

4. データの分割

データをトレーニングデータとテストデータに分割します。これにより、モデルの性能を評価することができます。

競馬の予想にLightGBMを使うための基本的な手順を紹介しました。データの収集、前処理、特徴量の選定、データの分割、モデルのトレーニング、予測と評価の各ステップを通じて、競馬の予想モデルを構築することができます。実際のプロジェクトでは、データの質や量、特徴量の選定、パラメータのチューニングなどが重要な要素となりますので、これらを工夫しながらモデルの精度を向上させてください。

さいごに


LightGBMは、分類、回帰、ランキングなどのさまざまな機械学習タスクに適用できる強力なツールです。初心者でも、データの準備と基本的なパラメータ設定を行うことで、簡単に高性能なモデルを構築することができます。上記の具体的な例を参考に、ぜひLightGBMを活用してみてください。

参考


https://lightgbm.readthedocs.io/en/latest/Python-Intro.html


執筆者プロフィール:竹内 勇毅
2023年11月 から(株)SHIFT ITソリューション部 アプリケーション開発テクノロジーグループに所属。

SHIFTへのお問合せはお気軽に

SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/

SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/

SHIFTの導入事例
https://service.shiftinc.jp/case/

お役立ち資料はこちら
https://service.shiftinc.jp/resources/

SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/

PHOTO:UnsplashPietro Jeng