Memakai Local Regression Di R
08 November 2014 1 Komentar
Pada artikel sebelumnya, Memakai Linear Regression Di R, saya mencoba menerapkan linear regression di R. Saya menyebutnya klasik karena teknik tersebut sudah ada sejak lama dan dapat dihitung secara manual. Seiring dengan penggunaan komputer pada bidang statistika, muncul pula berbagai teknik baru yang menawarkan akurasi yang lebih baik. Salah satunya adalah local regression yang memakai algoritma k-Nearest-Neighbor sehingga memperhitungkan titik disekitar saat menghitung posisi sebuah titik. Karena perhitungan ini harus dilakukan pada setiap titik, satu-per-satu sepanjang grafis, local regression boleh dibilang mustahil diproses secara manual tanpa melibatkan komputer.
Sebagai contoh, saya akan memakai data pendapatan dan pengeluaran yang saya baca dengan perintah seperti berikut ini:
> data <- read.csv('finance.csv') > names(data) [1] "tgl" "pendapatan" "pengeluaran" > ggplot(data, aes(tgl)) + + geom_line(aes(tgl, pendapatan, color='Pendapatan'), size=1) + + geom_line(aes(tgl, pengeluaran, color='Pengeluaran'), alpha=0.3) + + theme(legend.title=element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), axis.title.y = element_blank()) + + scale_color_manual(values=c('Pengeluaran'='red', 'Pendapatan'='blue'))
Saya akan mencoba mencari persamaan yang paling mendekati untuk memetakan data pendapatan berdasarkan tanggal. Bila memakai simple linear regression, saya akan memperoleh hasil seperti berikut ini:
> grafis <- ggplot(data, aes(tgl,pendapatan)) + theme(legend.title=element_blank(), axis.text.y = element_blank(), axis.ticks.y = element_blank(), axis.title.y = element_blank()) > grafis + geom_line() + geom_smooth(method='lm')
Sekarang, bandingkan grafis di atas dengan versi polynomial regression yang saya buat dengan perintah berikut ini:
> grafis + geom_line() + geom_smooth(method='lm', formula=y~poly(x,5))
Versi yang memakai polynomial regression terlihat lebih baik, bukan? Agar lebih yakin, saya akan berusaha membuktikannya secara numeris. Walaupun polynomial regression tidak lagi linear, ia masih berbasis model linear sehingga teknik pada model linear masih dapat saya gunakan. Oleh sebab itu, saya melakukan perbandingan dengan memberikan perintah berikut ini:
> summary(lm(pendapatan ~ tgl, data=data)) Call: lm(formula = pendapatan ~ tgl, data = data) Residuals: Min 1Q Median 3Q Max -3217705 -1000690 -85050 1097801 3938758 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 14408908.7 8270127.5 1.742 0.084 . tgl -652.6 520.4 -1.254 0.212 --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 1452000 on 122 degrees of freedom Multiple R-squared: 0.01273, Adjusted R-squared: 0.004635 F-statistic: 1.573 on 1 and 122 DF, p-value: 0.2122 > summary(lm(pendapatan ~ poly(tgl,5), data=data)) Call: lm(formula = pendapatan ~ poly(tgl, 5), data = data) Residuals: Min 1Q Median 3Q Max -2950460 -740133 -158111 612332 2881061 Coefficients: Estimate Std. Error t value Pr(>|t|) (Intercept) 4038452 99700 40.506 < 2e-16 *** poly(tgl, 5)1 -1820799 1110207 -1.640 0.104 poly(tgl, 5)2 -9361247 1110207 -8.432 9.73e-14 *** poly(tgl, 5)3 -682886 1110207 -0.615 0.540 poly(tgl, 5)4 1404591 1110207 1.265 0.208 poly(tgl, 5)5 4652563 1110207 4.191 5.40e-05 *** --- Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 Residual standard error: 1110000 on 118 degrees of freedom Multiple R-squared: 0.4416, Adjusted R-squared: 0.418 F-statistic: 18.67 on 5 and 118 DF, p-value: 1.247e-13
Pada hasil di atas, terlihat bahwa versi yang memakai simple linear regression memiliki nilai R-squared hanya sebesar 1,2%. Sementara itu, versi yang memakai polynomial regression memiliki nilai R-squared sebesar 41,8%. Ini adalah perbedaan yang cukup besar!
Tentu saja saya tidak bisa begitu saja memprediksi pendapatan berdasarkan tanggal (terlihat dari p-value). Hal ini ditambah lagi dengan penggunaan persamaan polynomial yang bisa membisa memberikan hasil yang tak terduga. Misalnya, prediksi pendapatan untuk bulan Desember adalah:
> cbind(predict(f,data.frame(tgl=c(seq(as.Date('2014/12/01'), as.Date('2014/12/10'), 'day'))))) [,1] 1 10171185 2 10307194 3 10444780 4 10583953 5 10724726 6 10867108 7 11011112 8 11156748 9 11304028 10 11452963
Wow, pendapatan meningkat secara drastis! Tapi saya tidak bisa bahagia karena ini kemungkinan besar disebabkan oleh kesalahan model (atau memang efek akhir tahun, ya? 🙂 )
Sekarang, saya akan menggunakan teknik local regression pada data yang sama. Grafis berikut ini memperlihatkan geom_smooth()
yang menggunakan method loess
:
> grafis + geom_line() + geom_smooth(method='loess')
Sebagai informasi, method geom_smooth()
dari package ggplot2
secara otomatis akan memakai method loess
bila n < 1000. Berdasarkan Wikipedia, LOESS adalah semacam singkatan dari “LOcal regrESSIon”. Grafis yang dihasilkan terlihat lebih lembut bila dibandingkan dengan versi yang memakai polynomial regression. Pada local regression, terdapat nilai alpha yang disebut sebagai smoothing parameter. Grafis di atas memakai dengan nilai default alpha berupa 0.75. Saya dapat menggunakan nilai alpha yang berbeda dengan perintah seperti berikut ini:
> grafis + geom_point() + geom_smooth(method='loess', span=0.25)
Saya dapat melakukan fitting yang memakai local regression dengan perintah seperti berikut ini:
> f <- loess(pendapatan ~ as.numeric(tgl), data, span=0.25)
Pada perintah di atas, saya perlu menggunakan as.numeric()
untuk menerjemahkan Date
menjadi angka agar dapat dihitung. Btw, pada saat memakai geom_smooth()
dalam menampilkan grafis, saya tidak perlu melakukan konversi karena hal ini telah dilakukan secara otomatis dimana tanggal diterjemahkan menjadi angka pada sumbu X.
Local regression tidak mengenal nilai seperti R-squared karena ia lebih berguna sebagai model untuk explorasi ketimbang sebagai model prediksi. Hal ini cukup masuk akal karena local regression sangat bergantung pada titik-titik yang sudah disekitarnya. Cara yang paling efektif untuk melihat keakuratan local regression adalah dengan mengamati grafis yang dihasilkan olehnya secara seksama. Walaupun ada function predict()
untuk local regression, saya hanya bisa menggunakannya untuk nilai tgl yang sudah ada dan bukan untuk tgl di-luar sampel:
> x.prediksi <- as.numeric(seq(as.Date('2014/12/01'), as.Date('2014/12/10'), 'day')) > cbind(predict(f, data.frame(tgl=x.prediksi))) [,1] 1 NA 2 NA 3 NA 4 NA 5 NA 6 NA 7 NA 8 NA 9 NA 10 NA > x.prediksi <- as.numeric(seq(as.Date('2013/12/01'), as.Date('2013/12/10'), 'day')) > cbind(predict(f, data.frame(tgl=x.prediksi))) [,1] 1 5617313 2 5627744 3 5637711 4 5647098 5 5655790 6 5663674 7 5670634 8 5676556 9 5681326 10 5684828
Dengan demikian, local regression lebih tepat dipakai untuk mempelajari hubungan antar-variabel dimana hubungan tersebut sangat kompleks dan tidak dapat dijelaskan oleh model yang sudah ada.
Ping-balik: Melakukan Unsupervised Learning Dengan R | The Solid Snake