データ分析学習の進捗【2/7】

前書き

「データ分析100本ノック」と「東京大学データサイエンティスト育成講座」を使って勉強を進めます。

melheaven.hatenadiary.jp

こちらの本の一部の問題・コードを自分なりに改変して載せています。
「全て載せてください!」という方はご購入を。おすすめです。

データ分析100本ノック3章

今回は顧客リストデータと顧客の利用履歴データを用いて、データ分析していきます。
お題は顧客の退会リストと退会した顧客の利用履歴・特性を抽出することです。

f:id:electric-city:20210208140845p:plain:w600:h200

入会日付と退会日付

Start_dateは入会、End_dateは退会日付です。
このように複数の要素で構成されているデータの場合、GroupByで要素別にデータ数を取得できます。

print(customer_end.groupby('gender').count()['customer_id'])
print(customer_end.groupby('class_name').count()['customer_id'])
print(customer_end.groupby('campaign_name').count()['customer_id'])
print(customer_end.groupby('is_deleted').count()['customer_id'])

gender
F    1400
M    1553
Name: customer_id, dtype: int64
class_name
オールタイム    1444
デイタイム      696
ナイト        813
Name: customer_id, dtype: int64
campaign_name
入会費半額     311
入会費無料     242
通常       2400
Name: customer_id, dtype: int64
is_deleted
0    2842
1     111
Name: customer_id, dtype: int64

利用履歴データの分析

各月の平均利用回数/1人

usedateには顧客(customer_id)が利用した履歴年月(usedate)が取得できす。
年月ごとに各顧客が利用した回数を以下のように算出します。

uselog2 = uselog2.groupby(['usedate', 'customer_id'], as_index=False).count()
uselog2.rename(columns={'log_id':'count'}, inplace=True)

as_indexではgroupbyにより生成した表データにindexを新たに振り分けません。
次のrenameのオプションにて指定しているinplace=Trueによりrenameが元のデータに反映されることを意味します。

f:id:electric-city:20210208141519p:plain:h300

各月の利用回数に関する統計量

上記で算出した各月の平均利用回数/1人に関する統計量をaggを使って算出します。
以下のサイトにてaggの記述方法が書かれています。

note.nkmk.me

uselog2 = uselog2.groupby('customer_id', as_index=False).agg(['mean', 'max', 'min', 'median'])['count']

曜日ごとに集計

この辺からオリジナリティを加えていきます。(曜日の集計をしていたので、何曜日が最も定期利用されているかの確認)

  1. 曜日ごとに顧客の利用履歴を集計する。
  2. 各顧客が各月で4回以上利用している曜日を取得する。
  3. 4回以上利用している曜日について、値"freq_flag"を1にする。
  4. 値"freq_flag"が1である曜日が最も多いのは?

→「 6: 3714 」。つまり土曜日に定期利用しているのですね。

uselog['weekday'] = uselog['usedate'].dt.weekday
uselog_freq = uselog4.groupby(['customer_id', 'month_year', 'weekday'], as_index=False).count()[['customer_id', 'month_year', 'weekday', 'log_id']]
uselog_freq.rename(columns={'log_id':'count'}, inplace=True)

selog_freq2 = uselog_freq.groupby('customer_id', as_index=False).max()[['customer_id','weekday','count']]
uselog_freq2['freq_flag'] = 0
uselog_freq2['freq_flag'] = uselog_freq2['freq_flag'].where(uselog_freq2['count']<4, 1)
week_freq = uselog_freq2.groupby('weekday').count()['freq_flag']
print(week_freq)

weekday
0      12
1      24
2      24
3      43
4      76
5     299
6    3714

relativedeltaで日付計算

日付データをdatetime型に変換したのちに、開始時間'start_date'と終了時間'end_date'をrelativedeltaで差計算することで経過時間を取得できます。以下では各行において経過月数を'membership_period'に格納しています。
今まで行指定にloc(=条件指定)を使っていましたが、行番号指定ではilocを使いますので、覚えておきましょう。

from dateutil.relativedelta import relativedelta

for i in range(len(customer_join_merge)):
    delta = relativedelta(customer_join['end_date'].iloc[i], customer_join['start_date'].iloc[i])
    customer_join['membership_period'][i] = delta.years*12+delta.months

他勉強

  • システム企画〜システム戦略
  • 統計検定(平均値の検定)

参考文献

qiita.com