This report analyzes the Netflix Customer Churn dataset using descriptive statistics and 95% confidence intervals. The analysis focuses on customer churn status, watch hours, and days since the last login.
library(readxl)
netflix <- read_excel("netflix_customer_churn.xlsx")
head(netflix)
## # A tibble: 6 × 14
## customer_id age gender subscription_type watch_hours last_login_days region
## <chr> <dbl> <chr> <chr> <dbl> <dbl> <chr>
## 1 a9b75100-82… 51 Other Basic 14.7 29 Africa
## 2 49a5dfd9-7e… 47 Other Standard 0.7 19 Europe
## 3 4d71f6ce-fc… 27 Female Standard 16.3 10 Asia
## 4 d3c72c38-63… 53 Other Premium 4.51 12 Ocean…
## 5 4e265c34-10… 56 Other Standard 1.89 13 Africa
## 6 d8079475-5b… 58 Female Standard 13.8 26 Ocean…
## # ℹ 7 more variables: device <chr>, monthly_fee <dbl>, churned <dbl>,
## # payment_method <chr>, number_of_profiles <dbl>,
## # avg_watch_time_per_day <dbl>, favorite_genre <chr>
str(netflix)
## tibble [5,000 × 14] (S3: tbl_df/tbl/data.frame)
## $ customer_id : chr [1:5000] "a9b75100-82a8-427a-a208-72f24052884a" "49a5dfd9-7e69-4022-a6ad-0a1b9767fb5b" "4d71f6ce-fca9-4ff7-8afa-197ac24de14b" "d3c72c38-631b-4f9e-8a0e-de103cad1a7d" ...
## $ age : num [1:5000] 51 47 27 53 56 58 48 51 45 32 ...
## $ gender : chr [1:5000] "Other" "Other" "Female" "Other" ...
## $ subscription_type : chr [1:5000] "Basic" "Standard" "Standard" "Premium" ...
## $ watch_hours : num [1:5000] 14.73 0.7 16.32 4.51 1.89 ...
## $ last_login_days : num [1:5000] 29 19 10 12 13 26 20 56 10 34 ...
## $ region : chr [1:5000] "Africa" "Europe" "Asia" "Oceania" ...
## $ device : chr [1:5000] "TV" "Mobile" "TV" "TV" ...
## $ monthly_fee : num [1:5000] 8.99 13.99 13.99 17.99 13.99 ...
## $ churned : num [1:5000] 1 1 0 1 1 0 0 1 0 1 ...
## $ payment_method : chr [1:5000] "Gift Card" "Gift Card" "Crypto" "Crypto" ...
## $ number_of_profiles : num [1:5000] 1 5 2 2 2 3 5 1 3 1 ...
## $ avg_watch_time_per_day: num [1:5000] 0.49 0.03 1.48 0.35 0.13 0.51 0.66 0.25 0.91 0.06 ...
## $ favorite_genre : chr [1:5000] "Action" "Sci-Fi" "Drama" "Horror" ...
churn_freq <- table(netflix$churned)
churn_freq
##
## 0 1
## 2485 2515
prop.table(churn_freq)
##
## 0 1
## 0.497 0.503
prop.table(churn_freq) * 100
##
## 0 1
## 49.7 50.3
barplot(churn_freq,
main = "Netflix Customer Churn Status",
xlab = "Churn Status (0 = Not Churned, 1 = Churned)",
ylab = "Number of Customers")
min(netflix$watch_hours)
## [1] 0.01
median(netflix$watch_hours)
## [1] 8
max(netflix$watch_hours)
## [1] 110.4
mean(netflix$watch_hours)
## [1] 11.64945
sd(netflix$watch_hours)
## [1] 12.01465
range(netflix$watch_hours)
## [1] 0.01 110.40
max(netflix$watch_hours) - min(netflix$watch_hours)
## [1] 110.39
hist(netflix$watch_hours,
main = "Distribution of Customer Watch Hours",
xlab = "Watch Hours",
ylab = "Frequency")
not_churned <- netflix$watch_hours[netflix$churned == 0]
min(not_churned)
## [1] 0.01
median(not_churned)
## [1] 13.86
max(not_churned)
## [1] 110.4
mean(not_churned)
## [1] 17.44959
sd(not_churned)
## [1] 13.92395
max(not_churned) - min(not_churned)
## [1] 110.39
churned <- netflix$watch_hours[netflix$churned == 1]
min(churned)
## [1] 0.01
median(churned)
## [1] 4.06
max(churned)
## [1] 41.33
mean(churned)
## [1] 5.918497
sd(churned)
## [1] 5.418978
max(churned) - min(churned)
## [1] 41.32
t.test(netflix$watch_hours, conf.level = 0.95)
##
## One Sample t-test
##
## data: netflix$watch_hours
## t = 68.561, df = 4999, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 11.31635 11.98255
## sample estimates:
## mean of x
## 11.64945
t.test(netflix$last_login_days, conf.level = 0.95)
##
## One Sample t-test
##
## data: netflix$last_login_days
## t = 121.33, df = 4999, p-value < 2.2e-16
## alternative hypothesis: true mean is not equal to 0
## 95 percent confidence interval:
## 29.60362 30.57598
## sample estimates:
## mean of x
## 30.0898