【Python実践データ分析100本ノック】ノック26-30

python実践データ分析100本ノック解説 python データ分析
スポンサーリンク

本記事では学習のアウトプットとして、『Python実践データ分析100本ノック』に書かれている各ノックのコードのうち、難解と思われる部分の意味を解説していきます。 「本に書かれている解説だけでは理解が難しい(;一_一)」と感じた方、この記事を読んで理解の一助となれば幸いです。

Python実戦データ分析100本ノックは、データの集計や分析のためのpandasや、グラフ描画に使用するmatplotlib、機械学習を行うためのscikit-learnなど、データ分析に欠かせない要素を実際に自分で手を動かしながら学ぶことができる本です。

今回は第6回として、ノック26-30をやっていきます。

 

追記現在第二版が2022年6月に出版されています

本記事は第1版の内容の解説です

第二版の解説記事もいずれ書かせていただこうと思っていますので今しばしお待ちください!

スポンサーリンク

第3章 顧客の全体像を把握するノック10本

ノック26:利用履歴データから定期利用フラグを作成しよう

#dt.weekdayメソッドは月曜=0,日曜=6の整数値を得ることができます。
uselog["weekday"] = uselog["usedate"].dt.weekday

#ノック8と同様にcustomer_id、年月、weekdayごとにprice(売上)とlog_idで集計します。
#結果をuselog_weekdayに格納します。
#dt.weekdayを使って、曜日に数字をふったのは下の一文や次のブロックの文で集計しやすくするためです。
#uselog_weekdayの意味は、どの顧客が、どの年のどの月にどの曜日に何回来たかを集計しています。
uselog_weekday = uselog.groupby(["customer_id","年月","weekday"], as_index=False).count()[["customer_id","年月", "weekday","log_id"]]

#ノック8と同様にrename()で今回はlog_idをcountという名前に書き替えます。
uselog_weekday.rename(columns={"log_id":"count"}, inplace=True)
uselog_weekday.head()

 

#uselog_weekdayをさらに集計します。
#customer_idごとにcustomer_idとcountで集計し、最大値を取得します。
#つまり、どの顧客がどの年のどの月に最も利用したのかを示す回数(count)です。
uselog_weekday = uselog_weekday.groupby("customer_id",as_index=False).max()[["customer_id", "count"]]

#フラグを示す列を作成します。初期値は0です、
uselog_weekday["routine_flg"] = 0

#where()メソッドはwhere(条件,Falseとなる場合の処理)という意味です。
#Trueの場合は値を変更せず、Falseの時に()の右側にしていた値を代入できます。
#最大利用回数が4以下の場合は0のまま、4以上であれば1にroutine_flgを変更します。
uselog_weekday["routine_flg"] = uselog_weekday["routine_flg"].where(uselog_weekday["count"]<4, 1)
uselog_weekday.head()

  

利用者のうち、定期的に同じ曜日で毎週来ている顧客のフラグを1とすることができました。

ノック27:顧客データと利用履歴データを結合しよう

#customer_id をキーとして、顧客データと利用履歴データをマージしてcustomer_joinとしています。
customer_join = pd.merge(customer_join, uselog_customer, on="customer_id", how="left")

#customer_id をキーとして、customer_joinをベースにuselog_weekdayのcustomer_id列とroutine_flg列をマージしています。
customer_join = pd.merge(customer_join, uselog_weekday[["customer_id", "routine_flg"]], on="customer_id", how="left")
customer_join.head()

  

ノック26で集計したuselog_weekdayの一部のデータを顧客データに結合できました。

ノック28:会員期間を計算しよう

ここからは、relativedeltaというライブラリを用いて月の計算を行います。

#relativedeltaのライブラリインポートを行います。
from dateutil.relativedelta import relativedelta
customer_join["calc_date"] = customer_join["end_date"]

#calc_dateに欠損値があるときdatetime型の20190430を代入します。
customer_join["calc_date"] = customer_join["calc_date"].fillna(pd.to_datetime("20190430"))
customer_join["membership_period"] = 0

#customer_joinの要素数の数だけcustomer_join内の集計動作を繰り返します。
for i in range(len(customer_join)):

#ilocというlocに似たものがでてきました。
#locはスライス表記含めて行や列の'ラベル名'を指定できます(例えば、loc["列名"])。
#ilocは行や列の'番号'を指定できます(例えば、0(番目))。
#ループ変数のように変数内の数字が変わっていく場合には、番号を指定するとループの中で自動的に変数内の数字を指定できます。
#i行目のcalc_dateとstart_dateの月の単位の長さの差分をrelativedeltaを使って計算し、deltaに格納しています。
delta = relativedelta(customer_join["calc_date"].iloc[i], customer_join["start_date"].iloc[i])

#relativedeltaは.yearや.monthsでそのデータの年や月の部分を自動で抽出してくれます。
#先ほど算出したdeltaの内、年数に12を掛け、月数はそのままとして二つの和をとります。
#つまり、会員期間(membership_period)をrelativedeltaをつかって月の長さの単位で算出し、membership_period列に格納しています。
customer_join["membership_period"].iloc[i] = delta.years*12 + delta.months
customer_join.head()

  

ご参考までに、relativedeltaの基本的な使い方はこちらの記事で解説しています。

会員期間を算出し、新しい列として追加できました。

ノック29:顧客行動の各種統計量を把握しよう

#各列の主要な統計量を一度に取得したい場合はdescribe()メソッドを使います。
#aggで処理を表す文字列やオブジェクトのリストを指定するより簡単に集計できます。
customer_join[["mean", "median", "max", "min"]].describe()
customer_join.groupby("routine_flg").count()["customer_id"]

 

#ノック10と同様にmatplotlibを用いてグラフを描いていきます。
import matplotlib.pyplot as plt
%matplotlib inline

#hist()で指定したデータのヒストグラムを作成します。横軸に会員期間を、縦軸には会員数を設定します。
plt.hist(customer_join["membership_period"])

  

会員の月別利用回数の各種統計量を集計し、会員期間を横軸、会員数を縦軸にしてヒストグラムを作成できました。

ノック30:退会ユーザーと継続ユーザーの違いを把握しよう

#describeでis_deleted=1 の退会している会員と is_deleted=0 の継続中の会員の集計をしていきます。
customer_end = customer_join.loc[customer_join["is_deleted"]==1]customer_end.describe()
customer_stay = customer_join.loc[customer_join["is_deleted"]==0]customer_stay.describe()

#完成したcustomer_joinをcsvファイルにダンプします。
customer_join.to_csv("customer_join.csv", index=False)

  

退会したユーザーと継続中の会員の集計をdescribe()メソッドを用いて簡単に実行できました。

ここまでで、ノック26-30は完了です。お疲れ様でした。 今回は機械学習といいつつ、その下準備となる集計処理を行いました。データの概要を集計結果から把握しておくことで、機械学習の際にどんなデータを学習させるかを検討しておくことは重要です。次回はいよいよ機械学習を行う第4章に入ります。引き続きよろしくお願いいたします(^^)/。