Ini adalah sebuah set data yang dibuat melalui proses penggabungan data generik. Data ini mencakup informasi tentang harga rumah di lingkungan perkotaan di Paris. Data ini telah disusun untuk digunakan dalam konteks pembelajaran Model Regresi Linear. Dalam penelitian kali ini, data ini akan digunakan untuk mengembangkan model regresi linear. Lebih tepatnya, penelitian ini bertujuan untuk melakukan prediksi harga rumah berdasarkan karakteristiknya.
Saya akan melakukan pembacaan data dan kemudian menyimpannya ke dalam variabel yang bernama “house”.
#> Rows: 10,000
#> Columns: 17
#> $ squareMeters <int> 75523, 80771, 55712, 32316, 70429, 39223, 58682, 869…
#> $ numberOfRooms <int> 3, 39, 58, 47, 19, 36, 10, 100, 3, 42, 21, 74, 31, 4…
#> $ hasYard <int> 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1…
#> $ hasPool <int> 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1…
#> $ floors <int> 63, 98, 19, 6, 90, 17, 99, 11, 61, 15, 90, 21, 5, 77…
#> $ cityCode <int> 9373, 39381, 34457, 27939, 38045, 39489, 6450, 98155…
#> $ cityPartRange <int> 3, 8, 6, 10, 3, 8, 10, 3, 8, 5, 6, 4, 2, 8, 10, 6, 3…
#> $ numPrevOwners <int> 8, 6, 8, 4, 7, 6, 9, 4, 3, 8, 8, 2, 9, 4, 5, 9, 9, 8…
#> $ made <int> 2005, 2015, 2021, 2012, 1990, 2012, 1995, 2003, 2012…
#> $ isNewBuilt <int> 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1…
#> $ hasStormProtector <int> 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1…
#> $ basement <int> 4313, 3653, 2937, 659, 8435, 2009, 5930, 6326, 632, …
#> $ attic <int> 9005, 2436, 8852, 7141, 2429, 4552, 9453, 4748, 5792…
#> $ garage <int> 956, 128, 135, 359, 292, 757, 848, 654, 807, 591, 68…
#> $ hasStorageRoom <int> 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1…
#> $ hasGuestRoom <int> 7, 2, 9, 3, 4, 1, 5, 10, 5, 3, 10, 9, 4, 0, 7, 5, 9,…
#> $ price <dbl> 7559082, 8085990, 5574642, 3232561, 7055052, 3926647…
#> squareMeters numberOfRooms hasYard hasPool
#> Min. : 89 Min. : 1.00 Min. :0.0000 Min. :0.0000
#> 1st Qu.:25099 1st Qu.: 25.00 1st Qu.:0.0000 1st Qu.:0.0000
#> Median :50106 Median : 50.00 Median :1.0000 Median :0.0000
#> Mean :49870 Mean : 50.36 Mean :0.5087 Mean :0.4968
#> 3rd Qu.:74610 3rd Qu.: 75.00 3rd Qu.:1.0000 3rd Qu.:1.0000
#> Max. :99999 Max. :100.00 Max. :1.0000 Max. :1.0000
#> floors cityCode cityPartRange numPrevOwners
#> Min. : 1.00 Min. : 3 Min. : 1.00 Min. : 1.000
#> 1st Qu.: 25.00 1st Qu.:24694 1st Qu.: 3.00 1st Qu.: 3.000
#> Median : 50.00 Median :50693 Median : 5.00 Median : 5.000
#> Mean : 50.28 Mean :50225 Mean : 5.51 Mean : 5.522
#> 3rd Qu.: 76.00 3rd Qu.:75683 3rd Qu.: 8.00 3rd Qu.: 8.000
#> Max. :100.00 Max. :99953 Max. :10.00 Max. :10.000
#> made isNewBuilt hasStormProtector basement
#> Min. :1990 Min. :0.0000 Min. :0.0000 Min. : 0
#> 1st Qu.:1997 1st Qu.:0.0000 1st Qu.:0.0000 1st Qu.: 2560
#> Median :2006 Median :0.0000 Median :0.0000 Median : 5092
#> Mean :2005 Mean :0.4991 Mean :0.4999 Mean : 5033
#> 3rd Qu.:2014 3rd Qu.:1.0000 3rd Qu.:1.0000 3rd Qu.: 7511
#> Max. :2021 Max. :1.0000 Max. :1.0000 Max. :10000
#> attic garage hasStorageRoom hasGuestRoom
#> Min. : 1 Min. : 100.0 Min. :0.000 Min. : 0.000
#> 1st Qu.: 2512 1st Qu.: 327.8 1st Qu.:0.000 1st Qu.: 2.000
#> Median : 5045 Median : 554.0 Median :1.000 Median : 5.000
#> Mean : 5028 Mean : 553.1 Mean :0.503 Mean : 4.995
#> 3rd Qu.: 7540 3rd Qu.: 777.2 3rd Qu.:1.000 3rd Qu.: 8.000
#> Max. :10000 Max. :1000.0 Max. :1.000 Max. :10.000
#> price
#> Min. : 10314
#> 1st Qu.: 2516402
#> Median : 5016180
#> Mean : 4993448
#> 3rd Qu.: 7469092
#> Max. :10006771
Selanjutnya saya akan mengubah data-data yang bersifat klasifikasi/dapat dikelompokkan, dengan menggunakan fungsi as.factor.
house <- house %>%
mutate(across(-c(squareMeters, numberOfRooms, floors, numPrevOwners, made, basement, attic, price, garage, cityCode, made, cityPartRange, hasGuestRoom), as.factor))
glimpse(house)#> Rows: 10,000
#> Columns: 17
#> $ squareMeters <int> 75523, 80771, 55712, 32316, 70429, 39223, 58682, 869…
#> $ numberOfRooms <int> 3, 39, 58, 47, 19, 36, 10, 100, 3, 42, 21, 74, 31, 4…
#> $ hasYard <fct> 0, 1, 0, 0, 1, 0, 1, 1, 0, 0, 0, 1, 1, 1, 0, 1, 0, 1…
#> $ hasPool <fct> 1, 1, 1, 0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 1…
#> $ floors <int> 63, 98, 19, 6, 90, 17, 99, 11, 61, 15, 90, 21, 5, 77…
#> $ cityCode <int> 9373, 39381, 34457, 27939, 38045, 39489, 6450, 98155…
#> $ cityPartRange <int> 3, 8, 6, 10, 3, 8, 10, 3, 8, 5, 6, 4, 2, 8, 10, 6, 3…
#> $ numPrevOwners <int> 8, 6, 8, 4, 7, 6, 9, 4, 3, 8, 8, 2, 9, 4, 5, 9, 9, 8…
#> $ made <int> 2005, 2015, 2021, 2012, 1990, 2012, 1995, 2003, 2012…
#> $ isNewBuilt <fct> 0, 1, 0, 0, 1, 0, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1…
#> $ hasStormProtector <fct> 1, 0, 0, 1, 0, 1, 1, 0, 1, 1, 0, 1, 0, 0, 1, 1, 1, 1…
#> $ basement <int> 4313, 3653, 2937, 659, 8435, 2009, 5930, 6326, 632, …
#> $ attic <int> 9005, 2436, 8852, 7141, 2429, 4552, 9453, 4748, 5792…
#> $ garage <int> 956, 128, 135, 359, 292, 757, 848, 654, 807, 591, 68…
#> $ hasStorageRoom <fct> 0, 1, 1, 0, 1, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 1, 0, 1…
#> $ hasGuestRoom <int> 7, 2, 9, 3, 4, 1, 5, 10, 5, 3, 10, 9, 4, 0, 7, 5, 9,…
#> $ price <dbl> 7559082, 8085990, 5574642, 3232561, 7055052, 3926647…
Pertama saya akan memisahkan data sebanyak 80% untuk digunakan dalam melatih model regresi linear, dan sisa 20% dari data tersebut akan digunakan untuk menguji prediksi model regresi linear yang kita buat nanti.
Dengan menggunakan fungsi dibawah berikut, kita akan melatih sebuah model regresi linear dan kemudian menyimpannya ke dalam variabel yang bernama h_lm, dalam kasus ini kita menggunakan semua prediktor untuk memprediksi “price”.
#>
#> Call:
#> lm(formula = price ~ ., data = h_train)
#>
#> Residuals:
#> Min 1Q Median 3Q Max
#> -7031.6 -1194.3 1.6 1191.3 6990.0
#>
#> Coefficients:
#> Estimate Std. Error t value Pr(>|t|)
#> (Intercept) 6953.4521859 4540.7738863 1.531 0.125726
#> squareMeters 99.9998839 0.0007353 135992.631 < 0.0000000000000002
#> numberOfRooms 0.5328421 0.7353334 0.725 0.468702
#> hasYard1 3005.3725485 42.3398658 70.982 < 0.0000000000000002
#> hasPool1 2998.6705863 42.3406384 70.823 < 0.0000000000000002
#> floors 54.3020806 0.7307869 74.306 < 0.0000000000000002
#> cityCode -0.0006563 0.0007314 -0.897 0.369529
#> cityPartRange 50.8214912 7.3430108 6.921 0.00000000000483
#> numPrevOwners -5.9822412 7.4195645 -0.806 0.420106
#> made -3.3549948 2.2635523 -1.482 0.138332
#> isNewBuilt1 163.0616419 42.3430254 3.851 0.000119
#> hasStormProtector1 164.9213734 42.3181557 3.897 0.00009811610644
#> basement -0.0021049 0.0073422 -0.287 0.774359
#> attic -0.0018719 0.0073149 -0.256 0.798037
#> garage 0.1266406 0.0807322 1.569 0.116769
#> hasStorageRoom1 53.2120427 42.3618250 1.256 0.209105
#> hasGuestRoom -2.6579644 6.6699515 -0.398 0.690274
#>
#> (Intercept)
#> squareMeters ***
#> numberOfRooms
#> hasYard1 ***
#> hasPool1 ***
#> floors ***
#> cityCode
#> cityPartRange ***
#> numPrevOwners
#> made
#> isNewBuilt1 ***
#> hasStormProtector1 ***
#> basement
#> attic
#> garage
#> hasStorageRoom1
#> hasGuestRoom
#> ---
#> Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
#>
#> Residual standard error: 1892 on 7983 degrees of freedom
#> Multiple R-squared: 1, Adjusted R-squared: 1
#> F-statistic: 1.158e+09 on 16 and 7983 DF, p-value: < 0.00000000000000022
Dari summary di atas, dapat kita lihat bahwa terdapat beberapa variable yang berkolerasi kuat, diantaranya yaitu squareMeters, hasYard, hasPool, floors, CityPartRange, made, isNewBuilt, dan hasStormProtector. sedangkan sisanya tidak memberikan efek yang terlalu signifikan. Dari summary di atas juga menunjukan Adjusted R Square sebesar 1, ini artinya model ini dapat menjelaskan “price” sebaik 100%, ini adalah fenomena yang disebut “perfect fit” dan akan sangat jarang dijumpai jika dilakukan pada data yang sebenarnya, namun karena data yang kita gunakan adalah data yang dibuat oleh mesin untuk tujuan pembelajaran, maka Adj. R Square sebesar 1 bukanlah tidak mungkin dan cukup wajar.
Melakukan prediksi menggunakan data test (h_test) kemudian disimpan ke variabel h_pred
Ini adalah RMSE pada data Train
#> [1] 1889.793
Ini adalah RMSE pada data Test.
#> [1] 1926.35
h_res <- data.frame(residual = h_lm$residuals, fitted = h_lm$fitted.values)
h_res %>% ggplot(aes(fitted, residual)) + geom_point() + geom_smooth() + geom_hline(aes(yintercept = 0)) +
theme(panel.grid = element_blank(), panel.background = element_blank())Dilihat dari plot di atas, model kita linear dengan sempurna.
#>
#> Shapiro-Wilk normality test
#>
#> data: h_lm$residuals[3:5000]
#> W = 0.99842, p-value = 0.00006679
Statistik W (0.99845): Nilai statistik W yang mendekati 1 menunjukkan bahwa distribusi dari data yang diuji cenderung mendekati distribusi normal. p-value (0.00008117): Nilai p-value yang sangat rendah menunjukkan bahwa data memiliki bukti statistik yang cukup kuat untuk menolak hipotesis nol. Dalam konteks ini, hipotesis nol adalah bahwa data yang diuji memiliki distribusi normal.
#> lag Autocorrelation D-W Statistic p-value
#> 1 0.008741072 1.982204 0.382
#> Alternative hypothesis: rho != 0
D-W Statistic: Nilai D-W Statistic adalah 2.014816. Nilai D-W Statistic berkisar antara 0 dan 4. Nilai 2 adalah nilai tengah yang mengindikasikan bahwa tidak ada otokorelasi dalam data.p-value: Nilai p-value adalah 0.486. P-value ini digunakan untuk menguji apakah ada otokorelasi yang signifikan dalam data. Dalam hal ini, p-value yang tinggi (0.486) menunjukkan bahwa tidak ada bukti yang cukup untuk menyatakan adanya otokorelasi yang signifikan dalam data.
#> squareMeters numberOfRooms hasYard hasPool
#> 1.001772 1.003064 1.001409 1.001781
#> floors cityCode cityPartRange numPrevOwners
#> 1.002002 1.000866 1.001002 1.002255
#> made isNewBuilt hasStormProtector basement
#> 1.000876 1.001829 1.000752 1.001605
#> attic garage hasStorageRoom hasGuestRoom
#> 1.001207 1.002788 1.002807 1.002945
Tidak ada vif yang bernilai di atas 10, artinya tidak ada hubungan yang kuat di antara variabel-variabel prediktor.
#>
#> studentized Breusch-Pagan test
#>
#> data: h_lm
#> BP = 1305.9, df = 16, p-value < 0.00000000000000022
Nilai BP yang tinggi (1354.9) menunjukkan adanya indikasi kuat bahwa heteroskedastisitas mungkin terjadi dalam model regresi linear. p-value yang sangat rendah (< 0.00000000000000022), hampir mendekati nol. Hal ini mengindikasikan bahwa model memiliki bukti statistik yang sangat kuat untuk menolak hipotesis nol, yang berarti bahwa heteroskedastisitas ada dalam model regresi ini.
Menggunakan Root Mean Squared Error (RMSE) untuk mengevaluasi kinerja model. RMSE pada data pelatihan adalah sekitar 1883.283, sementara RMSE pada data uji adalah sekitar 1953.94. RMSE yang lebih rendah di data pelatihan menunjukkan kinerja model yang baik dalam mengikuti data pelatihan. Namun, perbedaan antara RMSE data pelatihan dan uji mungkin mengindikasikan sedikit overfitting. Grafik residual menunjukkan bahwa model cukup linear dengan residual yang tersebar merata di sepanjang garis horizontal nol. Uji Shapiro-Wilk menunjukkan bahwa data residual memiliki distribusi yang mendekati normal dengan nilai W mendekati 1. P-value yang rendah menunjukkan bukti statistik yang kuat untuk menolak hipotesis bahwa data residual tidak berdistribusi normal. Uji Durbin-Watson menunjukkan bahwa tidak ada bukti yang cukup kuat untuk menyatakan adanya otokorelasi yang signifikan dalam data residual. Tidak ada vif (variance inflation factor) yang bernilai di atas 10, menunjukkan bahwa tidak ada hubungan kuat antara variabel prediktor. Uji Breusch-Pagan menunjukkan adanya indikasi kuat bahwa heteroskedastisitas mungkin terjadi dalam model regresi linear. P-value yang sangat rendah mengindikasikan adanya heteroskedastisitas dalam model.
Model regresi linear memiliki nilai RMSE yang rendah, namun perbedaan antara RMSE data pelatihan dan uji menunjukkan adanya sedikit overfitting. Model cukup linear, distribusi residual mendekati normal, tidak ada otokorelasi yang signifikan, dan tidak ada multicollinearity yang signifikan. Namun, heteroskedastisitas terdeteksi dalam model, yang mungkin perlu diperbaiki untuk meningkatkan kualitas prediksi.