Introduction

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.

Part A: Descriptive Statistics

1. Churn Status

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

Churn Status Bar Chart

barplot(churn_freq,
        main = "Netflix Customer Churn Status",
        xlab = "Churn Status (0 = Not Churned, 1 = Churned)",
        ylab = "Number of Customers")

2. Watch Hours

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

Distribution of Watch Hours

hist(netflix$watch_hours,
     main = "Distribution of Customer Watch Hours",
     xlab = "Watch Hours",
     ylab = "Frequency")

3. Watch Hours By Churn Status

Customers Who Did Not Churn

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

Customers Who Churned

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

Part B: 95% Confidence Intervals

Confidence Interval for Mean Watch Hours

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

Confidence Interval for Mean Days Since Last Login

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