Statistics using R

Yevonnael Andrew

Bahan webinar “Statistics using R” - Yevonnael Andrew

Untuk pertanyaan dan koreksi mohon hubungi saya melalui LinkedIn: https://www.linkedin.com/in/yevonnael-andrew-3351b9a7/

Jalankan kode di bawah untuk melakukan instalasi library. Jika Anda sudah pernah melakukan instalasi library di bawah ini, maka kode ini bisa dilompati.

Note: hilangkan tanda # untuk menjalankan kode (instalasi library)

# install.packages("tidyverse")
# install.packages("skimr")
# install.packages("GGally")
# install.packages("corrplot")
# install.packages("moderndive")
# install.packages("MASS")
# install.packages("lmtest")

Introduction

Setelah melakukan instalasi, kita perlu untuk memuat library yang diperlukan.

library(tidyverse)
library(skimr)
library(GGally)
library(corrplot)
library(moderndive)
library(MASS)
library(lmtest)

File yang akan digunakan adalah data.csv

# Memuat data
data <- read.csv("data.csv")

Lakukan inspeksi terhadap data.

head(data)
##   Order.Date  Ship.Date      Ship.Mode Customer.ID   Segment      Product.ID
## 1 2016-11-08 2016-11-11   Second Class    CG-12520  Consumer FUR-BO-10001798
## 2 2016-11-08 2016-11-11   Second Class    CG-12520  Consumer FUR-CH-10000454
## 3 2016-06-12 2016-06-16   Second Class    DV-13045 Corporate OFF-LA-10000240
## 4 2015-10-11 2015-10-18 Standard Class    SO-20335  Consumer FUR-TA-10000577
## 5 2015-10-11 2015-10-18 Standard Class    SO-20335  Consumer OFF-ST-10000760
## 6 2014-06-09 2014-06-14 Standard Class    BH-11710  Consumer FUR-FU-10001487
##          Category Sub.Category
## 1       Furniture    Bookcases
## 2       Furniture       Chairs
## 3 Office Supplies       Labels
## 4       Furniture       Tables
## 5 Office Supplies      Storage
## 6       Furniture  Furnishings
##                                                       Product.Name    Sales
## 1                                Bush Somerset Collection Bookcase 261.9600
## 2      Hon Deluxe Fabric Upholstered Stacking Chairs, Rounded Back 731.9400
## 3        Self-Adhesive Address Labels for Typewriters by Universal  14.6200
## 4                    Bretford CR4500 Series Slim Rectangular Table 957.5775
## 5                                   Eldon Fold 'N Roll Cart System  22.3680
## 6 Eldon Expressions Wood and Plastic Desk Accessories, Cherry Wood  48.8600
##   Quantity Discount    Profit Ship.Duration    Month     Day IsWeekend
## 1        2     0.00   41.9136             3 November Tuesday   Weekday
## 2        3     0.00  219.5820             3 November Tuesday   Weekday
## 3        2     0.00    6.8714             4     June  Sunday   Weekend
## 4        5     0.45 -383.0310             7  October  Sunday   Weekend
## 5        2     0.20    2.5164             7  October  Sunday   Weekend
## 6        7     0.00   14.1694             5     June  Monday   Weekday

Melihat daftar kolom yang tersedia dan jenisnya.

summary(data)
##   Order.Date         Ship.Date          Ship.Mode         Customer.ID       
##  Length:9994        Length:9994        Length:9994        Length:9994       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##    Segment           Product.ID          Category         Sub.Category      
##  Length:9994        Length:9994        Length:9994        Length:9994       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Product.Name           Sales              Quantity        Discount     
##  Length:9994        Min.   :    0.444   Min.   : 1.00   Min.   :0.0000  
##  Class :character   1st Qu.:   17.280   1st Qu.: 2.00   1st Qu.:0.0000  
##  Mode  :character   Median :   54.490   Median : 3.00   Median :0.2000  
##                     Mean   :  229.858   Mean   : 3.79   Mean   :0.1562  
##                     3rd Qu.:  209.940   3rd Qu.: 5.00   3rd Qu.:0.2000  
##                     Max.   :22638.480   Max.   :14.00   Max.   :0.8000  
##      Profit          Ship.Duration      Month               Day           
##  Min.   :-6599.978   Min.   :0.000   Length:9994        Length:9994       
##  1st Qu.:    1.729   1st Qu.:3.000   Class :character   Class :character  
##  Median :    8.666   Median :4.000   Mode  :character   Mode  :character  
##  Mean   :   28.657   Mean   :3.958                                        
##  3rd Qu.:   29.364   3rd Qu.:5.000                                        
##  Max.   : 8399.976   Max.   :7.000                                        
##   IsWeekend        
##  Length:9994       
##  Class :character  
##  Mode  :character  
##                    
##                    
## 

Format data belum tepat, maka kita perlu melakukan konversi jenis suatu variabel. * Konversi Order.Date dan Ship.Date menjadi jenis yang sesuai dengan as.Date * Konversi Customer.ID dan Product.Name menjadi jenis yang sesuai dengan as.Character

data[,1:2] <- lapply(data[,1:2], as.Date)
data[,c("Customer.ID", "Product.Name")] <- lapply(data[, c("Customer.ID", "Product.Name")],
                                                  as.character)

Mengecek ulang data.

summary(data)
##    Order.Date           Ship.Date           Ship.Mode        
##  Min.   :2014-01-03   Min.   :2014-01-07   Length:9994       
##  1st Qu.:2015-05-23   1st Qu.:2015-05-27   Class :character  
##  Median :2016-06-26   Median :2016-06-29   Mode  :character  
##  Mean   :2016-04-30   Mean   :2016-05-03                     
##  3rd Qu.:2017-05-14   3rd Qu.:2017-05-18                     
##  Max.   :2017-12-30   Max.   :2018-01-05                     
##  Customer.ID          Segment           Product.ID          Category        
##  Length:9994        Length:9994        Length:9994        Length:9994       
##  Class :character   Class :character   Class :character   Class :character  
##  Mode  :character   Mode  :character   Mode  :character   Mode  :character  
##                                                                             
##                                                                             
##                                                                             
##  Sub.Category       Product.Name           Sales              Quantity    
##  Length:9994        Length:9994        Min.   :    0.444   Min.   : 1.00  
##  Class :character   Class :character   1st Qu.:   17.280   1st Qu.: 2.00  
##  Mode  :character   Mode  :character   Median :   54.490   Median : 3.00  
##                                        Mean   :  229.858   Mean   : 3.79  
##                                        3rd Qu.:  209.940   3rd Qu.: 5.00  
##                                        Max.   :22638.480   Max.   :14.00  
##     Discount          Profit          Ship.Duration      Month          
##  Min.   :0.0000   Min.   :-6599.978   Min.   :0.000   Length:9994       
##  1st Qu.:0.0000   1st Qu.:    1.729   1st Qu.:3.000   Class :character  
##  Median :0.2000   Median :    8.666   Median :4.000   Mode  :character  
##  Mean   :0.1562   Mean   :   28.657   Mean   :3.958                     
##  3rd Qu.:0.2000   3rd Qu.:   29.364   3rd Qu.:5.000                     
##  Max.   :0.8000   Max.   : 8399.976   Max.   :7.000                     
##      Day             IsWeekend        
##  Length:9994        Length:9994       
##  Class :character   Class :character  
##  Mode  :character   Mode  :character  
##                                       
##                                       
## 

Statistik Deskriptif

Dalam sesi kali ini, kita akan membahas bagaimana mencari dan membandingkan ukuran sentral (mean, median, modus), variansi, dan bentuk distribusi data kita (apakah terdistribusi normal atau tidak)

1. Mencari rata-rata

sum(data$Profit)/length(data$Profit)
## [1] 28.6569
mean(data$Profit)
## [1] 28.6569

2. Mencari median

length(data$Profit) 
## [1] 9994

Karena jumlah data kita genap, maka median adalah data ke 0.5*((N/2) + (N/2 + 1))

Untuk mencari median, data harus diurutkan dulu dari terkecil menjadi terbesar!

N = 9994
letakMedian_kiri = N/2
letakMedian_kanan = N/2+1
0.5*(sort(data$Profit)[letakMedian_kiri] + sort(data$Profit)[letakMedian_kanan])
## [1] 8.6665
median(data$Profit)
## [1] 8.6665

3. Mean vs Median

Dari profit yang kita hitung di atas, kita dapatkan dua jenis ukuran sentral, yaitu:

    1. Mean = 28.6569
    1. Median = 8.6665

Manakah ukuran yang lebih representatif?

Untuk membantu menjawab ini, mari kita pertimbangkan skenario lain yang lebih mudah dipahami.

Sekarang misalkan kita kumpulkan gaji 10 orang di sebuah perusahaan unicorn: (dalam juta rupiah)

gaji <- c(5, 6, 7, 5, 6, 7, 5, 6, 7, 7)
mean(gaji)
## [1] 6.1
median(gaji)
## [1] 6

Dari skenario di atas, besaran mean dan median dari sampel tersebut kurang lebih sama, sehingga apa yang kita pilih tidak terlalu masalah.

Sekarang misalkan data kita modifikasi sedikit, yaitu dengan mengikutsertakan gaji seorang CEO. Cukup satu orang saja!

gaji <- c(5, 6, 7, 5, 6, 7, 5, 6, 7, 7, 100) # misalkan gaji CEO 100 juta
mean(gaji)
## [1] 14.63636
median(gaji)
## [1] 6

Perhatikan bagaimana sekarang nilai mean melonjak tinggi, sedangkan nilai median TETAP SAMA.

Apa yang terjadi? Apakah kita adil dengan mengatakan bahwa gaji rata-rata di perusahaan unicorn ini 14.6 juta? Tentu tidak! Faktanya jika tidak menyertakan gaji CEO, gaji rata-rata hanyalah 6.1 juta-an!

Contoh di atas merupakan sebuah contoh bagaimana ukuran mean sangat sensitif terhadap outlier.

Sedangkan ukuran median tidak sensitif terhadap outlier. Untuk kasus di atas (seperti pengukuran gaji), maka nilai median lebih representatif. (Tentunya nanti bergantung kebutuhan kita apa)

Pesan moral: Berhati-hati ketika membaca berita yang melaporkan rata-rata, karena sangat berpotensi menimbulkan bias!

Mari kita tinjau kembali nilai mean dan median dari data kita.

mean(data$Profit)
## [1] 28.6569
median(data$Profit)
## [1] 8.6665

Di dalam statistika, ada modifikasi dari mean yang lebih tidak sensitif terhadap outlier, salah satu contohnya adalah Trimmed Mean. Dalam Trimmed Mean, kita akan membuang nilai ekstrim terbesar dan nilai ekstrim terkecil, atau dalam bahasa lain, kita hanya mengambil 95% yang berada di tengah-tengah data.

mean(data$Profit, trim = 0.05)
## [1] 19.16937

Angka yang dihasilkan Trimmed Mean tidak se-ekstrim mean biasa.

4. Modus (Mode)

Ukuran ini digunakan untuk variabel yang bersifat diskrit atau non-numerikal. Karena di R tidak ada fungsi bawaan untuk menghitung mode, maka kita perlu mendefinisikan fungsi kita sendiri.

getMode <- function(x) {
keys <- unique(x)
keys[which.max(tabulate(match(x, keys)))]
}
getMode(data$Month)
## [1] "November"

5. Menghitung simpanan baku dan variance

Simpangan baku dan variance menghitung sejauh mana nilai dalam distribusi berbeda satu sama lain. Dalam bahasa yang lebih sederhana: “seberapa menyimpang data ini dari nilai mean-nya”?

Jika data kita adalah populasi

variance = sum((data$Profit - mean(data$Profit))^2) / (length(data$Profit))
sd = sqrt(variance)
variance
## [1] 54872.31
sd
## [1] 234.2484

Jika data kita adalah sampel

variance = sum((data$Profit - mean(data$Profit))^2) / (length(data$Profit)-1)
sd = sqrt(variance)
variance
## [1] 54877.8
sd
## [1] 234.2601

Menggunakan fungsi bawaan R

Secara default, R akan menghitung variance dan simpanan baku sebagai sampel.

var(data$Profit)
## [1] 54877.8
sd(data$Profit) # sqrt(var(data$Profit))
## [1] 234.2601

Pada data kita atas, apakah data ini populasi atau sampel ternyata tidak terlalu relevan. Hal ini disebabkan karena jumlah observasi di data kita adalah N = 9994. Menurut teori statistika, semakin banyak N, maka akan semakin mendekati populasi.

Sekarang misalkan kita menghitung menggunakan data gaji perusahaan unicorn:

# Jika data adalah populasi
gaji <- c(5, 6, 7, 8, 9, 10, 5, 6, 8)
variance = sum((gaji - mean(gaji))^2) / (length(gaji))
sd = sqrt(variance)
variance
## [1] 2.765432
sd
## [1] 1.662959
# Jika data adalah sampel
gaji <- c(5, 6, 7, 8, 9, 10, 5, 6, 8)
variance = sum((gaji - mean(gaji))^2) / (length(gaji) - 1)
sd = sqrt(variance)
variance
## [1] 3.111111
sd
## [1] 1.763834

Simpanan baku pada data sampel akan lebih besar dibandingkan dengan data populasi. Hal ini karena ada ketidakpastian dan galat yang terkandung dalam sampling.

Ketika tidak ada variabilitas dalam data, maka nilai variance dan simpanan baku adalah nol.

jumlahJam <- c(24, 24, 24, 24, 24, 24, 24)
var(jumlahJam)
## [1] 0
sd(jumlahJam)
## [1] 0

6. Menghitung range, IQR, quantile

Kita juga bisa menggunakan macam-macam ukuran statistik lainnya, misalnya: range, IQR, dan quantile. Ukuran-ukuran ini umumnya digunakan untuk menyusun boxplot.

min(data$Profit)
## [1] -6599.978
max(data$Profit)
## [1] 8399.976
range(data$Profit) # mengembalikkan min dan max sekaligus
## [1] -6599.978  8399.976

IQR (Interquantile Range) adalah selisih data Q3 dan Q1. Median adalah Q2.

  • Q1: 25% data
  • Q2: 50% data
  • Q3: 75% data
median(data$Profit)
## [1] 8.6665
as.numeric(quantile(data$Profit, 0.50))
## [1] 8.6665
IQR(data$Profit)
## [1] 27.63525
as.numeric(quantile(data$Profit, 0.75) - quantile(data$Profit, 0.25))
## [1] 27.63525

Meskipun kita dapat menggunakan quantile() untuk mendapatkan Q3 dan Q1 satu per satu, kedua angka ini juga disajikan bersama dengan kuratil ke-0 (min()), Q2 (median()), dan ke-100 (max()).

Satu set angka ini dinamakan five-number summary, yang dapat dipanggil menggunakan fungsi fivenum() atau summary()

fivenum(data$Profit)
## [1] -6599.9780     1.7280     8.6665    29.3640  8399.9760
# Five-number summary + mean
summary(data$Profit)
##      Min.   1st Qu.    Median      Mean   3rd Qu.      Max. 
## -6599.978     1.729     8.666    28.657    29.364  8399.976

Kita coba menggunakan variabel lain:

# Five-number summary + mean
summary(data$Ship.Duration)
##    Min. 1st Qu.  Median    Mean 3rd Qu.    Max. 
##   0.000   3.000   4.000   3.958   5.000   7.000

Five-number summary ini juga dapat disajikan dalam bentuk boxplot.

boxplot(data$Ship.Duration)

Exercise 1: Saham manakah yang tingkat volatilitasnya paling tinggi?

saham.A <- c(9999, 10200, 10500, 9800, 9900, 10500, 10900, 11000, 11500, 10500)
saham.B <- c(10000, 9500, 9900, 11000, 12000, 9800, 11500, 10500, 11000, 11500)
saham.C <- c(10000, 10100, 10200, 10000, 9900, 10000, 9900, 10500, 10300, 10200)
plot(saham.B, type = "l", col = "green")
lines(saham.A, col = "red")
lines(saham.C, col = "blue")

7. Menghitung covariance dan correlation

Misalkan kita memilih dua sampel, X dan Y, yang berukuran sama, lalu kita bisa menghitung covariance-nya, yaitu bagaimana variasi dalam sampel X memiliki keterkaitan dengan variasi dalam sampel Y.

Metrik ini banyak digunakan dalam dunia keuangan, misalnya dalam memilih saham untuk sebuah portofolio.

sum((saham.A - mean(saham.A))*(saham.B - mean(saham.B)))/(length(saham.B)-1)
## [1] 26074.44
cov(saham.A, saham.B)
## [1] 26074.44

Untuk menghitung korelasi.

  • Nilai korelasi memiliki rentang -1 <= Cor(X,Y) <= 1
  • Cor(X,Y) = 0 artinya tidak ada korelasi sama sekali antara X dan Y
  • Cor(X,Y) = 1 atau -1 artinya ada korelasi sempurna antara X dan Y
cor(saham.A, saham.B)
## [1] 0.05685123
cor(saham.A, saham.C)
## [1] 0.6081219

Statistik Inferensial

https://id.wikipedia.org/wiki/Distribusi_normal https://id.wikipedia.org/wiki/Uji_hipotesis https://en.wikipedia.org/wiki/Standard_score

1. Menghitung nilai z

Nilai z adalah berapa standar deviasi skor tersebut dihitung dari mean. Distribusi data dianggap distribusi normal.

Contoh: Tinggi badan pria di Indonesia berdistribusi normal dengan rata-rata 160cm dan simpangan baku 7cm. Berapa peluang seorang pria yang dipilih secara acak lebih tinggi dari 175cm?

z <- (175-160)/7
pnorm(z, lower.tail = F)
## [1] 0.01606229

Jika rata-rata 160cm, maka berapa peluang seorang pria yang dipilih secara acak lebih tinggi dari 180cm?

z <- (180-160)/7
pnorm(z, lower.tail = F)
## [1] 0.002137367

Latihan: Misalkan kita memiliki rata-rata populasi 180cm dan simpangan baku 8cm, berapa probabilitas bahwa orang yang dipilih secara acak lebih pendek dari 174cm?

2. Menghitung interval kepercayaan

Pernah mendengar tingkat kepercayaan alfa = 0.05?

# Confidence interval 95%
qnorm(0.025)
## [1] -1.959964
# Confidence interval 99%
qnorm(0.005)
## [1] -2.575829

3. Uji Hipotesis dan p-value

Contoh: * a. Dari data sensus (populasi), misalkan pendapatan rata-rata per satu keluarga adalah 10 juta dengan simpanan baku 3 juta. * b. Sekarang kita melakukan sampling terhadap 30 keluarga, kita dapatkan rata-rata pendapatan per satu keluarga adalah 11 juta (sampel)

Pertanyaannya adalah: Apakah fluktuasi nilai pendapatan rata-rata yang ada di sampel kita ini hanya merupakan kebetulan (by chance karena randomness) atau memang keluarga ini berbeda dari keluarga pada umumnya?

Sekarang, kita asumsikan kita menggunakan tingkat kepercayaan 95%. Kita susun dulu hipotesis pengujian ini: * H0: mean sampel = mean sensus * H1: mean sampel TIDAK SAMA DENGAN mean sensus (two-sided test) * H1: mean sampel LEBIH KECIL atau LEBIH BESAR dari mean sensus (one-sided test)

z_stat <- (11 - 10) / (3 / sqrt(30))
z_stat
## [1] 1.825742
# P-value untuk uji two-sided
(1-pnorm(z_stat))*2
## [1] 0.06788915

Nilai z adalah 1.825. Nilai p-value 0.0679. Hasil TIDAK signifikan pada p < .05.

# P-value untuk uji one-sided
(1-pnorm(z_stat))
## [1] 0.03394458

Nilai z adalah 2.11. Nilai p-value 0.0339. Hasil signifikan pada p < .05.

4. Uji T-Test

Umumnya, uji-z digunakan ketika kita memiliki ukuran sampel yang cukup besar (aturan praktisnya adalah n >= 30) dan ketika simpangan baku populasi diketahui. Jika kondisi di atas tidak terpenuhi, kita dapat menggunakan pengukuran statistik yang dikenal sebagai uji-t Student.

Contoh: Diketahui 10 gaji karyawan dari perusahaan unicorn. Kita tahu dari data resmi bahwa rata-rata gaji adalah 10 juta, tapi kita tidak ketahui simpangan bakunya.

gaji <- c(9,8,8,9,10,11,12,8,7,9)
mean(gaji)
## [1] 9.1
  • H0: mean gaji sampel SAMA dengan rata-rata data resmi
  • H1: mean gaji sampel LEBIH KECIL dari rata-rata data resmi (one-sided test)
t.test(gaji, mu=10, alternative="less")
## 
##  One Sample t-test
## 
## data:  gaji
## t = -1.8676, df = 9, p-value = 0.04733
## alternative hypothesis: true mean is less than 10
## 95 percent confidence interval:
##      -Inf 9.983367
## sample estimates:
## mean of x 
##       9.1
  • H0: mean gaji sampel SAMA dengan rata-rata data resmi
  • H1: mean gaji sampel TIDAK SAMA dari rata-rata data resmi (two-sided test)
t.test(gaji, mu=10, alternative = "two.sided")
## 
##  One Sample t-test
## 
## data:  gaji
## t = -1.8676, df = 9, p-value = 0.09466
## alternative hypothesis: true mean is not equal to 10
## 95 percent confidence interval:
##   8.009879 10.190121
## sample estimates:
## mean of x 
##       9.1

Jika nilai p kurang dari 0,05, kita menolak H0, maka kita bisa menyimpulkan bahwa memang ada perbedaan yang signifikan. Jika nilai p lebih besar dari 0,05, kita tidak dapat menyimpulkan bahwa ada perbedaan yang signifikan.

Extra Session

1. skim()

Secara pribadi, saya menyukai fungsi skim() dari paket skimr daripada glimpse() atau summary() karena memberikan informasi yang lebih rinci tentang data, termasuk missing data, jumlah data unik, jenis kolom dan untuk jenis numerik, skim() juga mengembalikan ringkasan lima angka dengan histogram kecil.

skim(data)
Data summary
Name data
Number of rows 9994
Number of columns 17
_______________________
Column type frequency:
character 10
Date 2
numeric 5
________________________
Group variables None

Variable type: character

skim_variable n_missing complete_rate min max empty n_unique whitespace
Ship.Mode 0 1 8 14 0 4 0
Customer.ID 0 1 8 8 0 793 0
Segment 0 1 8 11 0 3 0
Product.ID 0 1 15 15 0 1862 0
Category 0 1 9 15 0 3 0
Sub.Category 0 1 3 11 0 17 0
Product.Name 0 1 5 127 0 1850 0
Month 0 1 3 9 0 12 0
Day 0 1 6 9 0 7 0
IsWeekend 0 1 7 7 0 2 0

Variable type: Date

skim_variable n_missing complete_rate min max median n_unique
Order.Date 0 1 2014-01-03 2017-12-30 2016-06-26 1237
Ship.Date 0 1 2014-01-07 2018-01-05 2016-06-29 1334

Variable type: numeric

skim_variable n_missing complete_rate mean sd p0 p25 p50 p75 p100 hist
Sales 0 1 229.86 623.25 0.44 17.28 54.49 209.94 22638.48 ▇▁▁▁▁
Quantity 0 1 3.79 2.23 1.00 2.00 3.00 5.00 14.00 ▇▅▁▁▁
Discount 0 1 0.16 0.21 0.00 0.00 0.20 0.20 0.80 ▇▆▁▁▁
Profit 0 1 28.66 234.26 -6599.98 1.73 8.67 29.36 8399.98 ▁▁▇▁▁
Ship.Duration 0 1 3.96 1.75 0.00 3.00 4.00 5.00 7.00 ▂▃▇▅▃

2. ggpairs()

Dengan menggunakan ggpairs(), kita bisa membuat plot dari beberapa variabel sekaligus.

ggpairs(data[c('Sales','Profit','Quantity','Discount')])

3. Matriks Korelasi

Membuat matriks korelasi

cor_mat <- cor(data[c('Sales','Profit','Quantity','Discount')])
cor_mat
##                Sales      Profit   Quantity    Discount
## Sales     1.00000000  0.47906435 0.20079477 -0.02819012
## Profit    0.47906435  1.00000000 0.06625319 -0.21948746
## Quantity  0.20079477  0.06625319 1.00000000  0.00862297
## Discount -0.02819012 -0.21948746 0.00862297  1.00000000

Membuat plot dari matriks korelasi

corrplot(cor_mat, method="pie", type="lower", addCoef.col = "black")

4. Modelling

model_single <- lm(Profit ~ Sales, data=data)
get_regression_summaries(model_single)
## # A tibble: 1 x 9
##   r_squared adj_r_squared    mse  rmse sigma statistic p_value    df  nobs
##       <dbl>         <dbl>  <dbl> <dbl> <dbl>     <dbl>   <dbl> <dbl> <dbl>
## 1      0.23         0.229 42279.  206.  206.     2976.       0     1  9994

5. Menguji Asumsi Normalitas

Salah satu asumsi dalam regresi linier adalah bahwa residual berdistribusi normal. Sekarang kita akan memplot Studentized Residuals model kita.

srs <- studres(model_single)
hist(srs, freq=FALSE, 
     main="Distribution of Studentized Residuals",
     breaks=100)
xfit<-seq(min(srs),max(srs),length=40) 
yfit<-dnorm(xfit) 
lines(xfit, yfit)

Tampaknya data kita tidak berdistribusi normal dengan melihat grafik. Untuk memastikannya, kita harus menghitungnya secara statistik. Karena data kita melebihi 5000, kita harus menggunakan uji Kolmogorov-Smirnov.

ks.test(studres(model_single), data$Profit)
## Warning in ks.test(studres(model_single), data$Profit): p-value will be
## approximate in the presence of ties
## 
##  Two-sample Kolmogorov-Smirnov test
## 
## data:  studres(model_single) and data$Profit
## D = 0.76926, p-value < 2.2e-16
## alternative hypothesis: two-sided
  • H0: Data mengikuti distribusi yang ditentukan
  • HA: Data tidak mengikuti distribusi yang ditentukan

Karena p-value kita <0,5, maka H0 ditolak, sehingga data kita tidak terdistribusi normal.

6. Uji Heteroskedastisitas

Uji heteroskedastisitas bertujuan untuk menguji apakah dalam model regresi terjadi ketidaksamaan varian dari residual satu pengamatan ke pengamatan yang lain.

bptest(model_single)
## 
##  studentized Breusch-Pagan test
## 
## data:  model_single
## BP = 2723, df = 1, p-value < 2.2e-16
  • H0 : Residual bersifat Homoskedastisitas
  • HA : Residual bersifat Heteroskedastisitas

Karena p-value kita < 0,5, maka H0 ditolak, sehingga data error kita heteroskedastis, artinya data kita tidak terlalu cocok untuk menggunakan model regresi ini.

par(mfrow = c(2,2))
plot(model_single)

Ini adalah visualisasi dari residual model kita Dengan melihat Residuals vs Fitted, intinya terlihat seperti kipas, artinya semakin besar nilainya maka semakin besar pula residualnya. Kita harus mencoba untuk menormalkan mereka. Selain itu, dengan melihat Residuals vs Leverage, kita dapat melihat beberapa poin outlier yang akan kita lakukan analisis outlier.