こんばんは、Yuinaです🍵
本日は、前回の続きでデータ分析100本ノックの5章43本目から進めていきます。
よろしくお願いいたします!
ノック43本目:継続顧客データ作成しよう
42本目のノックでは退会データを作成したので、今度は継続顧客データを作成します。
conti_customer = customer.loc[customer["is_deleted"]==0]
is_deleted == 0 → 退会していない顧客を抽出して conti_customer に保存します。
conti_uselog = pd.merge(uselog, conti_customer, on=["customer_id"], how="left")
uselog(全ユーザーの利用履歴)と、退会していない顧客情報を customer_id で結合します。
conti_uselogの状態を確認します。

conti_uselog = conti_uselog.dropna(subset=["name"])
顧客が継続していれば各カラムの中に情報が付きますが、 NaN になっている(=退会済み)でconti_customer(=継続顧客)にいない人のログを削除して、継続顧客だけを残します。(退会している人には name
などが NaN
になります。)

再度conti_uselogを確認してみると、データの件数が減ったことがわかります。
ログが削除されたことが確認できました。
print(conti_uselog["name"].isna().sum())
心配なので、上記のコードで欠損値の有無を確認します。
退会データが1104件で継続顧客のデータが27422件不均衡なデータになってしまうため、
サンプル数を調整していく必要があります。
ここからは、conti_uselog(継続顧客の利用ログ)から 「一人につき1件だけ」をランダムに抽出してる処理を行います。
conti_uselog = conti_uselog.sample(frac=1, random_state=0).reset_index(drop=True)
sample(frac=1) はデータをシャッフルし、
random_state=0 を指定することで、毎回同じシャッフル結果になります(再現性あり)
なおsample(frac=1, random_state=42)と書くと、データをランダムにシャッフルするけど毎回同じ順番になります(再現可能)
今回は、0でも42でも999でもなんでもいいみたいです。
reset_index(drop=True) は、インデックスを振り直しています。
conti_uselog = conti_uselog.drop_duplicates(subset="customer_id")
customer_id ごとに 重複を削除しています。
ノック44本目:予測する月の在籍期間を作成する
predict_data["period"] = 0
predict_data["now_date"] = pd.to_datetime(predict_data["年月"], format="%Y%m")
predict_dataにperiodという列を作って初期化しています。
「年月」列を datetime 型に変換し、「今の年月」として扱えるようにしています。
predict_data[“start_date”] = pd.to_datetime(predict_data[“start_date”])
入会日もdatetime型に変換し、now_dateと揃えています。
for i in range(len(predict_data)):
delta = relativedelta(predict_data.loc[i, "now_date"], predict_data.loc[i, "start_date"])
predict_data.loc[i, "period"] = int(delta.years*12 + delta.months)
relativedelta
を使って「今の年月」と「入会日」の差を取ります。
「年 * 12 + 月」で、在籍月数に変換します。

periodに在籍月数が表示されました。
<table cellpadding="0" cellspacing="0" border="0" style=" border:1px solid #ccc; /*width:300px;*/"><tbody><tr style="border-style:none;"><td style="vertical-align:top; border-style:none; padding:10px; width:87px;"><a href="https://rpx.a8.net/svt/ejp?a8mat=453FFM+DG1FLE+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00q0724.2bo11c45.g00q0724.2bo12179%2Fa25042272339_453FFM_DG1FLE_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Fbook%252F17143076%252F%26amp%3Bm%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fbook%252Fi%252F20661735%252F%26amp%3Brafcid%3Dwsc_i_is_33f72da33714639c415e592c9633ecd7" rel="nofollow"><img border="0" alt="" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/7278/9784798067278_1_4.jpg?_ex=64x64" /></a></td><td style="font-size:12px; vertical-align:middle; border-style:none; padding:10px;"><p style="padding:0; margin:0;"><a href="https://rpx.a8.net/svt/ejp?a8mat=453FFM+DG1FLE+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00q0724.2bo11c45.g00q0724.2bo12179%2Fa25042272339_453FFM_DG1FLE_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Fbook%252F17143076%252F%26amp%3Bm%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fbook%252Fi%252F20661735%252F%26amp%3Brafcid%3Dwsc_i_is_33f72da33714639c415e592c9633ecd7" rel="nofollow">Python 実践データ分析 100本ノック 第2版 [ 下山輝昌 ]</a></p><p style="color:#666; margin-top:5px line-height:1.5;">価格:<span style="font-size:14px; color:#C00; font-weight:bold;">2640円</span><br/><span style="font-size:10px; font-weight:normal;">(2025/5/6 12:09時点)</span><br/><span style="font-weight:bold;">感想(1件)</span></p></td></tr></tbody></table>
<img border="0" width="1" height="1" src="https://www13.a8.net/0.gif?a8mat=453FFM+DG1FLE+2HOM+BWGDT" alt="">
predict_data.isna().sum()で欠損値を確認します。

count_1に255件ありました。(end_dateとexit_dateは、ジム契約継続中の顧客の退会履歴がNULLになっているだけなのでそのままで大丈夫です)
count_1が欠損している(=前月にログがなかった)データだけ除外します。

end_dateとexit_dateにも欠損値があったみたいです。
<table cellpadding="0" cellspacing="0" border="0" style=" border:1px solid #ccc; /*width:300px;*/"><tbody><tr style="border-style:none;"><td style="vertical-align:top; border-style:none; padding:10px; width:150px;"><a href="https://rpx.a8.net/svt/ejp?a8mat=453FFM+DG1FLE+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00q0724.2bo11c45.g00q0724.2bo12179%2Fa25042272339_453FFM_DG1FLE_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Fbook%252F17143076%252F%26amp%3Bm%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fbook%252Fi%252F20661735%252F%26amp%3Brafcid%3Dwsc_i_is_33f72da33714639c415e592c9633ecd7" rel="nofollow"><img border="0" alt="" src="https://thumbnail.image.rakuten.co.jp/@0_mall/book/cabinet/7278/9784798067278_1_4.jpg?_ex=64x64" /></a></td><td style="font-size:12px; vertical-align:middle; border-style:none; padding:10px;"><p style="padding:0; margin:0;"><a href="https://rpx.a8.net/svt/ejp?a8mat=453FFM+DG1FLE+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00q0724.2bo11c45.g00q0724.2bo12179%2Fa25042272339_453FFM_DG1FLE_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Fbook%252F17143076%252F%26amp%3Bm%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fbook%252Fi%252F20661735%252F%26amp%3Brafcid%3Dwsc_i_is_33f72da33714639c415e592c9633ecd7" rel="nofollow">Python 実践データ分析 100本ノック 第2版 [ 下山輝昌 ]</a></p><p style="color:#666; margin-top:5px line-height:1.5;">価格:<span style="font-size:14px; color:#C00; font-weight:bold;">2640円</span><br/><span style="font-size:10px; font-weight:normal;">(2025/5/5 22:12時点)</span><br/><span style="font-weight:bold;">感想(1件)</span></p></td></tr></tbody></table>
<img border="0" width="1" height="1" src="https://www16.a8.net/0.gif?a8mat=453FFM+DG1FLE+2HOM+BWGDT" alt="">
まとめ
本日はノック43,44,45本目の解説を行いました。
重複しているデータや欠損値などは頻繁に確認するのが大切だと思いました。
ありがとうございました!
コメント