ケーススタディー:自転車シェアリングサービスを成功させる
Googleデータアナリティクス プロフェッショナルのケーススタディーとして、
架空の自転車シェアリングサービスを成功させる=利潤を向上させる方法をデータ分析の手法を用いて提案しました。今回は前回の処理の仕方を見直し、以下の処理と分析の工程を加えました。
①year_monthという月ごとの分析に使うデータを追加
②乗車時間のデータ(ride_length)から負の値を排除したデータフレームを新しく作成する
③可視化資料として、以下の内容を共有する:
- 週ごとの利用車数(メンバー・カジュアルの比較)
- 週ごとの利用時間の平均
- 月ごとの利用車数
- 月ごとの利用時間の平均
- 車種ごとの利用車数
- 車種ごとの利用時間の平均
- 利用者数の折れ線グラフとその平滑化曲線
④可視化資料を基に、次の3点をメンバー・カジュアルの利用傾向の違いとして共有する:
- 週ごとの比較では、カジュアルユーザーは休日に利用者が増え逆に年間メンバーは平日に利用者が増える
- 月ごとに比較するとメンバー・カジュアルともに1年間に大きな季節性の変動があり、特にカジュアルユーザーは冬季の利用者が著しく減少する。折れ線グラフを平滑化するとよりこの傾向が明確になる
- 利用車種ごとに比較するとカジュアルユーザーは電動バイクの利用者が若干多く、利用時間自体も長い。特にドックド型自転車(利用終了時に関らず返却を要する)はその他の車種の4倍以上の利用時間となる
処理
データ処理の段階を改善し、新しく定性データの追加・バッドデータのクリーンアップを行う過程を加えました。この段階でデータの処理と分析にどのようなツールを使うか・データのクリーニングを完了しているかを確認します。12ヶ月分のデータを結合したデータフレームを作成する他、分析に用いる新しい指標と定性データを追加しています。
- divvy社の2022年3月 - 2023年2月までの自転車シェアリング事業のデータを1つのcsvファイルに統合
- 利用時間(ride_length)という定量データを追加(利用終了時間 - 利用開始時間を計測する)
- date, month, day, day_for_weekという日付に関係する定性データを追加(2022-03 ~ 2023-02)
- year_monthという月ごとの分析に使うデータを追加(2022-03 ~ 2023-02)
データを1つのデータフレームに纏める
library(lubridate) #時刻データを扱うメソッド
library(ggplot2) #可視化
setwd("C:\\Users\\user\\Desktop\\Data_Learning\\2023_share_cycling")
data_202203 <- read.csv("202203-divvy-tripdata.csv")
data_202204 <- read.csv("202204-divvy-tripdata.csv")
data_202205 <- read.csv("202205-divvy-tripdata03.csv")
data_202206 <- read.csv("202206-divvy-tripdata.csv")
data_202207 <- read.csv("202207-divvy-tripdata.csv")
data_202208 <- read.csv("202208-divvy-tripdata.csv")
data_202209 <- read.csv("202209-divvy-publictripdata.csv")
data_202210 <- read.csv("202210-divvy-tripdata.csv")
data_202211 <- read.csv("202211-divvy-tripdata.csv")
data_202212 <- read.csv("202212-divvy-tripdata.csv")
data_202301 <- read.csv("202301-divvy-tripdata.csv")
data_202302 <- read.csv("202302-divvy-tripdata.csv")
#bind_rowsを使って12ヶ月分のデータを1つのデータフレームに纏める
data_all <- bind_rows(data_202203, data_202204, data_202205, data_202206, data_202207, data_202208, data_202209, data_202210, data_202211, data_202212, data_202301, data_202302)
View(data_all)
colnames(data_all)
str(data_all)
#自転車ID(ride_id)を文字列データに変換
data_all <- mutate(data_all, ride_id = as.character(ride_id))
#分析に使わないデータを削除する(start_lat, start_lng, end_lat, end_lng)
data_all <- data_all %>%
select(-c(start_lat, start_lng, end_lat, end_lng))
データのクリーンアップを開始
#データの内容を確認
colnames(data_all) #データのコラム名
nrow(data_all) #データフレームの行数
dim(data_all) #データフレームの次元数
head(data_all) #最初の5行を開始
str(data_all) #データコラムのデータ型を表示する
summary(data_all) #定量データの要約統計量を表示
# 時系列データをクリーンアップ・文字列→時刻に変換、新しい時刻データを追加
# https://www.statmethods.net/input/dates.html more on date formats in R found at that link
data_all$date <- as.Date(data_all$started_at) #The default format is yyyy-mm-dd
data_all$month <- format(as.Date(data_all$date), "%m")
data_all$day <- format(as.Date(data_all$date), "%d")
data_all$year <- format(as.Date(data_all$date), "%Y")
data_all$day_of_week <- format(as.Date(data_all$date), "%A")
#乗車時間のデータ(ride_length)を追加
data_all$ride_length <- difftime(data_all$ended_at, data_all$started_at)
#乗車時間のデータ(ride_length)を定量データに変換する
is.factor(data_all$ride_length)
data_all$ride_length <- as.numeric(as.character(data_all$ride_length))
is.numeric(data_all$ride_length)
#乗車時間のデータ(ride_length)から負の値を排除したデータフレームを新しく作成する。
#排除前のデータ列数 - 5829084
#排除後のデータ列数 - 5821120、排除データは7964個(全体の0.136%)
data_all_new <- filter(data_all, ride_length > 0)
data_all_bad <- filter(data_all, ride_length <= 0)
#新しい時刻データを追加
data_all_new$year_month <- format(as.Date(data_all_new$date), "%Y-%m")
バッドデータを除去すると、排除前のデータ列数は5829084・排除後のデータ列数は5821120、排除データは7964個となることが分かりました。これは 全体の0.136% に相当します。
分析
データの統計解析
mean(data_all_new$ride_length) #平均
median(data_all_new$ride_length) #中央値
max(data_all_new$ride_length) #最大値
min(data_all_new$ride_length) #最小値
#summary()で要約統計量を表示する
summary(data_all_new$ride_length)
# 年間ユーザー・カジュアルユーザーを比較する
aggregate(data_all_new$ride_length ~ data_all_new$member_casual, FUN = mean)
aggregate(data_all_new$ride_length ~ data_all_new$member_casual, FUN = median)
aggregate(data_all_new$ride_length ~ data_all_new$member_casual, FUN = max)
aggregate(data_all_new$ride_length ~ data_all_new$member_casual, FUN = min)
データの可視化
#週ごとの利用車数(メンバー・カジュアルの比較)を可視化する
data_all_new %>%
mutate(weekday = wday(started_at, label = TRUE)) %>%
group_by(member_casual, weekday) %>%
summarise(number_of_rides = n() ,average_duration = mean(ride_length)) %>%
arrange(member_casual, weekday) %>%
ggplot(aes(x = weekday, y = number_of_rides, fill = member_casual)) +
geom_col(position = "dodge")
#週ごとの利用時間の平均(メンバー・カジュアルの比較)を可視化する
data_all_new %>%
mutate(weekday = wday(started_at, label = TRUE)) %>%
group_by(member_casual, weekday) %>%
summarise(number_of_rides = n() ,average_duration = mean(ride_length)) %>%
arrange(member_casual, weekday) %>%
ggplot(aes(x = weekday, y = average_duration, fill = member_casual)) +
geom_col(position = "dodge")
#月ごとの利用車数(メンバー・カジュアルの比較)を可視化する
data_all_new %>%
group_by(member_casual, year_month) %>%
summarise(number_of_rides = n()) %>%
arrange(member_casual, year_month) %>%
ggplot(aes(x = year_month, y = number_of_rides, fill = member_casual)) +
geom_col(position = "dodge")
#月ごとの利用時間の平均(メンバー・カジュアルの比較)を可視化する
data_all_new %>%
group_by(member_casual, year_month) %>%
summarise(average_duration = mean(ride_length)) %>%
arrange(member_casual, year_month) %>%
ggplot(aes(x = year_month, y = average_duration, fill = member_casual)) +
geom_col(position = "dodge")
#車種ごとの利用車数(メンバー・カジュアルの比較)を可視化する
data_all_new %>%
group_by(member_casual, rideable_type) %>%
summarise(number_of_rides = n()) %>%
arrange(member_casual, rideable_type) %>%
ggplot(aes(x = member_casual, y = number_of_rides, fill = rideable_type)) +
geom_col(position = "dodge")
#車種ごとの利用時間の平均(メンバー・カジュアルの比較)を可視化する
data_all_new %>%
group_by(member_casual, rideable_type) %>%
summarise(average_duration = mean(ride_length)) %>%
arrange(member_casual, rideable_type) %>%
ggplot(aes(x = member_casual, y = average_duration, fill = rideable_type)) +
geom_col(position = "dodge")
#日付ごとの利用車数(メンバー・カジュアルの比較)を可視化、折れ線グラフとする
data_all_new %>%
group_by(member_casual, date) %>%
summarise(number_of_rides = n()) %>%
arrange(member_casual, date) %>%
ggplot(aes(x = date, y = number_of_rides, color = member_casual))+
geom_line() + facet_wrap(~member_casual)
#日付ごとの利用車数(メンバー・カジュアルの比較)を可視化、折れ線グラフとする
data_all_new %>%
group_by(member_casual, date) %>%
summarise(number_of_rides = n()) %>%
arrange(member_casual, date) %>%
ggplot(aes(x = date, y = number_of_rides, color = member_casual))+
geom_point(size = 1) +
stat_smooth(method = "loess", se = TRUE, size = 2) +
facet_wrap(~member_casual)
共有
データの可視化が完了したので、自転車シェアリングサービスに対するインサイトを考案します。今回は、①カジュアルユーザー・年間メンバーとで自転車の利用法に違いがあるか
という事業タスクに対して明確な答えを3点提案することを目指しました。
週ごとの利用者数・利用時間の違い
①年間メンバーの利用者数は、平日になるとカジュアルユーザーの1.5~2.0倍ほどの水準となります。利用者数に平日に利用者数が増えるか・減るかという利用法の違いがあります。利用時間に注目すると、カジュアルユーザーは年間メンバーに比べ利用時間の平均が2.0~3.0倍程となります。特に休日と月曜・金曜にこの傾向が高いようです。
月ごとの利用者数の違い
②月ごとの利用者数に着目すると季節性の変動があり、利用者数に大きな影響を与えます。特にカジュアルユーザーにおいて影響が顕著で、12月の利用者は同年7月の1/8以下まで下がります。利用者数の折れ線グラフを平滑化すると、この傾向が明確になります。
車種の利用者数・利用時間の違い
③車種ごとの利用数の違いに比較すると、カジュアルユーザーは電動バイクの利用者が若干多いことが分かります。利用時間自体も長く特にドックド型自転車(利用終了時に返却を要する)の場合、その他の車種の4倍以上の利用時間となります。