こんにちは、クラウドデータ研究所です。
今回は「ロジスティック回帰」というものを見てみます。
難しそうな名前ですが、実は身近なところでよく使われている手法です。
AIや機械学習には大きく分けて「教師あり学習」と「教師なし学習」があります。
- 教師あり学習 → 正解付きのデータで学ぶ(例:「この人は買った/買わなかった」という履歴がある)
- 教師なし学習 → 正解がないデータでグループを探す(例:クラスタリングで似た人をまとめる)
今回は「教師あり学習」の代表例であるロジスティック回帰について見ていきましょう。
Table of Contents
銀行預金に申し込むかどうか?
それでは、実際に問題を見ていきましょう。
「銀行がマーケティング電話をかけて、お客さんが定期預金に申し込むかどうか(target=yes/no)?」という問いに対して、ロジスティック回帰の機械学習を使用して考えていきましょう。
教師あり学習の際に、説明変数として下記の情報を使用していきます。
1. 基本情報(顧客属性)
- age(年齢):数値。若い人・高齢の人で金融商品の興味に違いがあるか?
- job(職業):文字データ(例:management, student, unemployed)。社会的立場によって申し込みやすさが違う。
- marital(婚姻状況):divorced, married, single など。ライフステージが金融行動に影響。
- education(学歴):basic, high.school, university など。金融リテラシーの proxy(代替指標)。
2. 信用・経済状況
- default(債務不履行):yes/no。過去に返済延滞があればリスクが高い。
- balance(平均残高):数値。顧客の経済力の指標。
- housing(住宅ローンの有無):yes/no。既存のローン有無が預金行動に影響。
- loan(個人ローンの有無):yes/no。同上。
3. 連絡に関する情報
- contact(連絡手段):cellular, telephone。携帯電話の方が反応率高いか?
- day(最後の接触日):1〜31。曜日やタイミングの影響。
- month(最後の接触月):jan〜dec。年末や夏前など、季節性がある可能性。
- duration(最後の通話時間・秒数):重要だが注意点あり。
- 通話が長いほど申し込み率が高い(強い予測因子)。
- ただし「予測の時点ではわからない未来情報」なので、現実的なモデルからは除外するのが推奨。
4. 過去キャンペーン情報
- campaign(このキャンペーンでの通話回数):数値。しつこく電話すると逆効果か?
- pdays(前回からの経過日数):数値。999=未接触。
- previous(過去の接触回数):数値。過去の経験が効果に影響。
- poutcome(前回キャンペーンの結果):success, failure, nonexistent。過去の反応が予測因子になる。
実際にやっている処理を見ていきましょう!
1. SparkSession
(セッションの作成)
PySparkでは、まず最初に「作業する部屋」を用意します。これが SparkSession です。
すべての処理はこの部屋の中で行われます。
from pyspark.sql import SparkSession
spark = SparkSession.builder.master("local").appName("logistic_regression").getOrCreate()
2. データを読み込む
CSVファイルを読み込んで、データフレーム(表形式データ)にします。
data = spark.read.csv("./bank-full.csv", header=True, inferSchema=True, sep=";")
header=True
→ 1行目を列名にするinferSchema=True
→ 数字は数字、文字は文字として自動判別sep=";"
→ 区切り文字がセミコロン;
3. StringIndexer
(文字を数字に変える)
機械学習は文字のままだと理解できません。
そこで「文字(例:default=’yes’)」を数字(例:1や0)に変換します。
from pyspark.ml.feature import StringIndexer
default_index = StringIndexer(inputCol="default", outputCol="default_index")
4. VectorAssembler
(特徴量をまとめる)
年齢、残高、ローンの有無など、たくさんの列を「特徴量」と呼びます。
これを1本の「まとめカラム(features)」に集めるのが VectorAssembler です。
from pyspark.ml.feature import VectorAssembler
assemble = VectorAssembler(
inputCols=["age","balance","duration","campaign","previous","default_index"],
outputCol="features"
)
5. StandardScaler
(標準化)
身長が「150cm〜190cm」、年齢が「20〜70歳」など、スケールがバラバラだと計算が偏ってしまいます。
そこで全部を「平均0・標準偏差1」に揃える処理が StandardScaler。
from pyspark.ml.feature import StandardScaler
scaler = StandardScaler(inputCol="features", outputCol="scaled_features")
6. LogisticRegression
(ロジスティック回帰モデル)
このアルゴリズムは「この人がYesになる確率は何%」と予測してくれる先生です。
from pyspark.ml.classification import LogisticRegression
logistic_regression = LogisticRegression(featuresCol="scaled_features", labelCol="y1")
7. Pipeline
(処理の流れをまとめる)
上で紹介した「文字を数字に変える→まとめる→揃える→予測する」流れを Pipeline に一気にまとめられます。
from pyspark.ml import Pipeline
pipeline = Pipeline(stages=[default_index, assemble, scaler, logistic_regression])
学習と予測
学習(train)とテスト(test)に分ける
train_df, test_df = df.randomSplit([0.7, 0.3], seed=1234)
fit_model = pipeline.fit(train_df)
結果を確認
rawPrediction
→ モデルが計算したスコアprobability
→ Yesになる確率(0〜1の数値)
pred_train = fit_model.transform(train_df)
pred_train.select("rawPrediction", "probability").show()
例:
probability=[0.94, 0.05] → Yesの確率 94%、Noの確率 5%
まとめ
- ロジスティック回帰は Yes/No を予測するシンプルな手法
- PySparkでは
- データを数字に変える(StringIndexer)
- 特徴量をまとめる(VectorAssembler)
- スケールを揃える(StandardScaler)
- モデルを当てはめる(LogisticRegression)
を Pipelineで一括実行できる
- 難しそうに見えるけど、実際は「先生に過去データを見せて、未来を当てさせる」イメージ