pacman::p_load(tidyverse,
tidyquant,
tidyr,
caret,
leaflet,
rpart,
class,
DT,
timetk,
forcats,
plotly,
hrbrthemes,
corrplot,
tint,
tufte,
prettydoc,
rmdformats,
ggplot2,
tseries,
plotly)
data <- read_csv("house_data.csv")
## Rows: 21613 Columns: 21
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (20): id, price, bedrooms, bathrooms, sqft_living, sqft_lot, floors, wa...
## dttm (1): date
##
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(data, 5)
## # A tibble: 5 × 21
## id date price bedrooms bathrooms sqft_living sqft_lot
## <dbl> <dttm> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 7129300520 2014-10-13 00:00:00 221900 3 1 1180 5650
## 2 6414100192 2014-12-09 00:00:00 538000 3 2.25 2570 7242
## 3 5631500400 2015-02-25 00:00:00 180000 2 1 770 10000
## 4 2487200875 2014-12-09 00:00:00 604000 4 3 1960 5000
## 5 1954400510 2015-02-18 00:00:00 510000 3 2 1680 8080
## # ℹ 14 more variables: floors <dbl>, waterfront <dbl>, view <dbl>,
## # condition <dbl>, grade <dbl>, sqft_above <dbl>, sqft_basement <dbl>,
## # yr_built <dbl>, yr_renovated <dbl>, zipcode <dbl>, lat <dbl>, long <dbl>,
## # sqft_living15 <dbl>, sqft_lot15 <dbl>
str(data)
## spc_tbl_ [21,613 × 21] (S3: spec_tbl_df/tbl_df/tbl/data.frame)
## $ id : num [1:21613] 7.13e+09 6.41e+09 5.63e+09 2.49e+09 1.95e+09 ...
## $ date : POSIXct[1:21613], format: "2014-10-13" "2014-12-09" ...
## $ price : num [1:21613] 221900 538000 180000 604000 510000 ...
## $ bedrooms : num [1:21613] 3 3 2 4 3 4 3 3 3 3 ...
## $ bathrooms : num [1:21613] 1 2.25 1 3 2 4.5 2.25 1.5 1 2.5 ...
## $ sqft_living : num [1:21613] 1180 2570 770 1960 1680 ...
## $ sqft_lot : num [1:21613] 5650 7242 10000 5000 8080 ...
## $ floors : num [1:21613] 1 2 1 1 1 1 2 1 1 2 ...
## $ waterfront : num [1:21613] 0 0 0 0 0 0 0 0 0 0 ...
## $ view : num [1:21613] 0 0 0 0 0 0 0 0 0 0 ...
## $ condition : num [1:21613] 3 3 3 5 3 3 3 3 3 3 ...
## $ grade : num [1:21613] 7 7 6 7 8 11 7 7 7 7 ...
## $ sqft_above : num [1:21613] 1180 2170 770 1050 1680 ...
## $ sqft_basement: num [1:21613] 0 400 0 910 0 1530 0 0 730 0 ...
## $ yr_built : num [1:21613] 1955 1951 1933 1965 1987 ...
## $ yr_renovated : num [1:21613] 0 1991 0 0 0 ...
## $ zipcode : num [1:21613] 98178 98125 98028 98136 98074 ...
## $ lat : num [1:21613] 47.5 47.7 47.7 47.5 47.6 ...
## $ long : num [1:21613] -122 -122 -122 -122 -122 ...
## $ sqft_living15: num [1:21613] 1340 1690 2720 1360 1800 ...
## $ sqft_lot15 : num [1:21613] 5650 7639 8062 5000 7503 ...
## - attr(*, "spec")=
## .. cols(
## .. id = col_double(),
## .. date = col_datetime(format = ""),
## .. price = col_double(),
## .. bedrooms = col_double(),
## .. bathrooms = col_double(),
## .. sqft_living = col_double(),
## .. sqft_lot = col_double(),
## .. floors = col_double(),
## .. waterfront = col_double(),
## .. view = col_double(),
## .. condition = col_double(),
## .. grade = col_double(),
## .. sqft_above = col_double(),
## .. sqft_basement = col_double(),
## .. yr_built = col_double(),
## .. yr_renovated = col_double(),
## .. zipcode = col_double(),
## .. lat = col_double(),
## .. long = col_double(),
## .. sqft_living15 = col_double(),
## .. sqft_lot15 = col_double()
## .. )
## - attr(*, "problems")=<externalptr>
summary(data)
## id date price
## Min. :1.000e+06 Min. :2014-05-02 00:00:00.00 Min. : 75000
## 1st Qu.:2.123e+09 1st Qu.:2014-07-22 00:00:00.00 1st Qu.: 321950
## Median :3.905e+09 Median :2014-10-16 00:00:00.00 Median : 450000
## Mean :4.580e+09 Mean :2014-10-29 04:38:01.96 Mean : 540088
## 3rd Qu.:7.309e+09 3rd Qu.:2015-02-17 00:00:00.00 3rd Qu.: 645000
## Max. :9.900e+09 Max. :2015-05-27 00:00:00.00 Max. :7700000
## bedrooms bathrooms sqft_living sqft_lot
## Min. : 0.000 Min. :0.000 Min. : 290 Min. : 520
## 1st Qu.: 3.000 1st Qu.:1.750 1st Qu.: 1427 1st Qu.: 5040
## Median : 3.000 Median :2.250 Median : 1910 Median : 7618
## Mean : 3.371 Mean :2.115 Mean : 2080 Mean : 15107
## 3rd Qu.: 4.000 3rd Qu.:2.500 3rd Qu.: 2550 3rd Qu.: 10688
## Max. :33.000 Max. :8.000 Max. :13540 Max. :1651359
## floors waterfront view condition
## Min. :1.000 Min. :0.000000 Min. :0.0000 Min. :1.000
## 1st Qu.:1.000 1st Qu.:0.000000 1st Qu.:0.0000 1st Qu.:3.000
## Median :1.500 Median :0.000000 Median :0.0000 Median :3.000
## Mean :1.494 Mean :0.007542 Mean :0.2343 Mean :3.409
## 3rd Qu.:2.000 3rd Qu.:0.000000 3rd Qu.:0.0000 3rd Qu.:4.000
## Max. :3.500 Max. :1.000000 Max. :4.0000 Max. :5.000
## grade sqft_above sqft_basement yr_built
## Min. : 1.000 Min. : 290 Min. : 0.0 Min. :1900
## 1st Qu.: 7.000 1st Qu.:1190 1st Qu.: 0.0 1st Qu.:1951
## Median : 7.000 Median :1560 Median : 0.0 Median :1975
## Mean : 7.657 Mean :1788 Mean : 291.5 Mean :1971
## 3rd Qu.: 8.000 3rd Qu.:2210 3rd Qu.: 560.0 3rd Qu.:1997
## Max. :13.000 Max. :9410 Max. :4820.0 Max. :2015
## yr_renovated zipcode lat long
## Min. : 0.0 Min. :98001 Min. :47.16 Min. :-122.5
## 1st Qu.: 0.0 1st Qu.:98033 1st Qu.:47.47 1st Qu.:-122.3
## Median : 0.0 Median :98065 Median :47.57 Median :-122.2
## Mean : 84.4 Mean :98078 Mean :47.56 Mean :-122.2
## 3rd Qu.: 0.0 3rd Qu.:98118 3rd Qu.:47.68 3rd Qu.:-122.1
## Max. :2015.0 Max. :98199 Max. :47.78 Max. :-121.3
## sqft_living15 sqft_lot15
## Min. : 399 Min. : 651
## 1st Qu.:1490 1st Qu.: 5100
## Median :1840 Median : 7620
## Mean :1987 Mean : 12768
## 3rd Qu.:2360 3rd Qu.: 10083
## Max. :6210 Max. :871200
Informasi yang di dapat terdiri dari 21 variabel yang terdiri dari ID properti, tanggal penjualan, harga properti, jumlah kamar tidur, jumlah kamar mandi, luas ruang hidup, luas lahan, jumlah lantai, keberadaan waterfront (pantai atau tepi danau), pemandangan, kondisi properti, tingkat kualitas bangunan (grade), luas di atas tanah (sqft_above), luas di bawah tanah (sqft_basement), tahun pembangunan, tahun renovasi, kode pos, latitude dan longitude, serta luas ruang hidup (sqft_living15) dan luas lahan (sqft_lot15).
correlation_matrix <- cor(data %>% select(price, bedrooms, bathrooms, sqft_living, sqft_lot, floors, view, condition, grade, sqft_above, sqft_basement, yr_built, yr_renovated, lat, long, sqft_living15, sqft_lot15))
print(correlation_matrix)
## price bedrooms bathrooms sqft_living sqft_lot
## price 1.00000000 0.30834960 0.52513751 0.70203505 0.089660861
## bedrooms 0.30834960 1.00000000 0.51588364 0.57667069 0.031703243
## bathrooms 0.52513751 0.51588364 1.00000000 0.75466528 0.087739662
## sqft_living 0.70203505 0.57667069 0.75466528 1.00000000 0.172825661
## sqft_lot 0.08966086 0.03170324 0.08773966 0.17282566 1.000000000
## floors 0.25679389 0.17542894 0.50065317 0.35394929 -0.005200991
## view 0.39729349 0.07953185 0.18773702 0.28461119 0.074710106
## condition 0.03636179 0.02847210 -0.12498193 -0.05875259 -0.008958250
## grade 0.66743426 0.35696673 0.66498253 0.76270448 0.113621124
## sqft_above 0.60556730 0.47760016 0.68534248 0.87659660 0.183512281
## sqft_basement 0.32381602 0.30309338 0.28377003 0.43504297 0.015286202
## yr_built 0.05401153 0.15417807 0.50601944 0.31804877 0.053080367
## yr_renovated 0.12643379 0.01884082 0.05073898 0.05536293 0.007643505
## lat 0.30700348 -0.00893101 0.02457295 0.05252946 -0.085682788
## long 0.02162624 0.12947298 0.22304184 0.24022330 0.229520859
## sqft_living15 0.58537890 0.39163752 0.56863429 0.75642026 0.144608174
## sqft_lot15 0.08244715 0.02924422 0.08717536 0.18328555 0.718556752
## floors view condition grade sqft_above
## price 0.256793888 0.397293488 0.036361789 0.66743426 0.6055672984
## bedrooms 0.175428935 0.079531852 0.028472104 0.35696673 0.4776001614
## bathrooms 0.500653173 0.187737024 -0.124981933 0.66498253 0.6853424759
## sqft_living 0.353949290 0.284611186 -0.058752587 0.76270448 0.8765965987
## sqft_lot -0.005200991 0.074710106 -0.008958250 0.11362112 0.1835122809
## floors 1.000000000 0.029443820 -0.263767946 0.45818251 0.5238847103
## view 0.029443820 1.000000000 0.045989737 0.25132058 0.1676493441
## condition -0.263767946 0.045989737 1.000000000 -0.14467367 -0.1582136164
## grade 0.458182514 0.251320585 -0.144673671 1.00000000 0.7559229376
## sqft_above 0.523884710 0.167649344 -0.158213616 0.75592294 1.0000000000
## sqft_basement -0.245704542 0.276946579 0.174104914 0.16839182 -0.0519433068
## yr_built 0.489319425 -0.053439851 -0.361416562 0.44696320 0.4238983517
## yr_renovated 0.006338401 0.103917288 -0.060617787 0.01441428 0.0232846879
## lat 0.049614131 0.006156732 -0.014941006 0.11408406 -0.0008164986
## long 0.125419028 -0.078399712 -0.106500448 0.19837215 0.3438030175
## sqft_living15 0.279885265 0.280439082 -0.092824268 0.71320209 0.7318702924
## sqft_lot15 -0.011269187 0.072574568 -0.003405523 0.11924790 0.1940498619
## sqft_basement yr_built yr_renovated lat long
## price 0.32381602 0.05401153 0.126433793 0.3070034800 0.02162624
## bedrooms 0.30309338 0.15417807 0.018840823 -0.0089310097 0.12947298
## bathrooms 0.28377003 0.50601944 0.050738978 0.0245729528 0.22304184
## sqft_living 0.43504297 0.31804877 0.055362927 0.0525294622 0.24022330
## sqft_lot 0.01528620 0.05308037 0.007643505 -0.0856827882 0.22952086
## floors -0.24570454 0.48931942 0.006338401 0.0496141310 0.12541903
## view 0.27694658 -0.05343985 0.103917288 0.0061567321 -0.07839971
## condition 0.17410491 -0.36141656 -0.060617787 -0.0149410064 -0.10650045
## grade 0.16839182 0.44696320 0.014414281 0.1140840571 0.19837215
## sqft_above -0.05194331 0.42389835 0.023284688 -0.0008164986 0.34380302
## sqft_basement 1.00000000 -0.13312410 0.071322902 0.1105379580 -0.14476477
## yr_built -0.13312410 1.00000000 -0.224873518 -0.1481224021 0.40935620
## yr_renovated 0.07132290 -0.22487352 1.000000000 0.0293976092 -0.06837237
## lat 0.11053796 -0.14812240 0.029397609 1.0000000000 -0.13551178
## long -0.14476477 0.40935620 -0.068372369 -0.1355117836 1.00000000
## sqft_living15 0.20035498 0.32622890 -0.002672555 0.0488579321 0.33460498
## sqft_lot15 0.01727618 0.07095793 0.007853765 -0.0864188072 0.25445129
## sqft_living15 sqft_lot15
## price 0.585378904 0.082447153
## bedrooms 0.391637524 0.029244224
## bathrooms 0.568634290 0.087175361
## sqft_living 0.756420259 0.183285551
## sqft_lot 0.144608174 0.718556752
## floors 0.279885265 -0.011269187
## view 0.280439082 0.072574568
## condition -0.092824268 -0.003405523
## grade 0.713202093 0.119247897
## sqft_above 0.731870292 0.194049862
## sqft_basement 0.200354983 0.017276181
## yr_built 0.326228900 0.070957926
## yr_renovated -0.002672555 0.007853765
## lat 0.048857932 -0.086418807
## long 0.334604984 0.254451288
## sqft_living15 1.000000000 0.183191749
## sqft_lot15 0.183191749 1.000000000
corrplot::corrplot(correlation_matrix, method = "circle", type = "upper")
Variabel price memiliki korelasi yang kuat dengan sqft_living (0.585) dan bathrooms (0.569), menunjukkan bahwa ukuran ruang hidup dan jumlah kamar mandi merupakan faktor penting yang mempengaruhi harga properti. grade juga memiliki korelasi tinggi dengan price (0.713), menandakan bahwa kualitas properti juga berpengaruh saat penentuan harga. Variabel sqft_living15 memiliki korelasi moderat dengan price (0.200), menunjukkan hubungan dengan ukuran ruang hidup di properti sekitar. Dari plot ini bisa disimpulkan bisa melihat hubungan antara variabel.
ggplot(data, aes(x = price)) +
geom_histogram(binwidth = 50000, fill = "blue", color = "grey") +
labs(title = "Distribusi Harga", x = "Harga", y = "Frekuensi") +
theme_minimal()
Pembuatan gambaran distribusi harga properti menggunakan histogram menggambarkan cara harga-harga tersebut tersebar di dalam set data. Dengan melihat histogram ini, kita dapat mengetahui apakah distribusi harga properti cenderung normal, miring ke arah tertentu, atau apakah terdapat beberapa puncak (bimodal atau multimodal). Visualisasi ini memberikan gambaran awal mengenai variasi harga properti dalam set data dan membantu dalam mengidentifikasi kecenderungan atau pola tertentu yang mungkin perlu diteliti lebih lanjut untuk analisis yang lebih mendalam.
ggplot(data, aes(x = sqft_living, y = price)) +
geom_point(alpha = 0.5, color = "red") +
labs(title = "Harga vs Luas Rumah", x = "Luas Rumah", y = "Harga") +
theme_minimal()
Dari grafik, terlihat bahwa sebagian besar rumah memiliki luas di rentang 0 sampai 5000, dan dapat disimpulkan bahwa ada hubungan antara luas rumah dan harga. Ketika luas rumah meningkat, harga juga cenderung meningkat secara signifikan.
ggplot(data, aes(x = factor(bedrooms), y = price)) +
geom_boxplot(fill = "lightblue") +
labs(title = "Distribusi Harga Berdasarkan Jumlah Kamar Tidur", x = "Jumlah Kamar Tidur", y = "Harga") +
theme_minimal()
Dari grafik tersebut diketahui bahwa semakin banyak kamar, berpengaruh terhadap kenaikan harga rumah.
data$date <- as.Date(data$date)
monthly_avg_price <- data %>%
group_by(month = format(date, "%Y-%m")) %>%
summarise(avg_price = mean(price))
monthly_avg_price$month <- as.Date(paste0(monthly_avg_price$month, "-01"))
ggplot(monthly_avg_price, aes(x = month, y = avg_price)) +
geom_line(color = "blue") +
labs(title = "Tren Harga Rata-rata Bulanan Properti", x = "Bulan", y = "Harga Rata-rata") +
theme_minimal() +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Grafik di atas menunjukkan tren harga rumah, dengan terlihat adanya lonjakan harga pada bulan April 2015.
missing_data <- sapply(data, function(x) sum(is.na(x)))
print(missing_data)
## id date price bedrooms bathrooms
## 0 0 0 0 0
## sqft_living sqft_lot floors waterfront view
## 0 0 0 0 0
## condition grade sqft_above sqft_basement yr_built
## 0 0 0 0 0
## yr_renovated zipcode lat long sqft_living15
## 0 0 0 0 0
## sqft_lot15
## 0
Dari hasil di atas variabel-variabel di atas tidak memiliki nilai yang hilang (missing values). Artinya, data tersebut lengkap dan tidak ada data yang hilang sehingga tidak memerlukan tindakan untuk menangani data yang hilang. Hal ini menandakan bahwa dataset tersebut dapat digunakan untuk analisis lebih lanjut tanpa perlu melakukan imputasi atau penghapusan baris yang mengandung nilai yang hilang.
set.seed(123)
train_index <- createDataPartition(data$price, p = 0.8, list = FALSE)
train_data <- data[train_index, ]
test_data <- data[-train_index, ]
model1 <- train(price ~ ., data = train_data, method = "lm", trControl = trainControl(method = "cv", number = 10))
train_limited_model <- function(data, formula, method = "lm", max_features = 3) {
fit <- train(formula, data = data, method = method, trControl = trainControl(method = "cv", number = 10))
return(fit)
}
model2_formula <- as.formula("price ~ bedrooms + bathrooms + sqft_living")
model2 <- train_limited_model(train_data, model2_formula)
model3_formula <- as.formula("price ~ sqft_lot + floors + view")
model3 <- train_limited_model(train_data, model3_formula)
model4_formula <- as.formula("price ~ condition + grade + sqft_above")
model4 <- train_limited_model(train_data, model4_formula)
model5_formula <- as.formula("price ~ yr_built + yr_renovated + zipcode")
model5 <- train_limited_model(train_data, model5_formula)
results <- list(
model1 = model1,
model2 = model2,
model3 = model3,
model4 = model4,
model5 = model5
)
Koding ini mengembangkan lima model regresi linear untuk meramalkan harga properti berdasarkan data latihan yang dipisahkan dari dataset utama dengan rasio 80-20. Model pertama menggunakan semua variabel independen sebagai prediktor, sedangkan model-model berikutnya menggunakan kombinasi maksimal tiga variabel independen yang dianggap memiliki potensi pengaruh terhadap harga properti. Setiap model dilatih menggunakan validasi silang dengan 10 lipatan untuk mengevaluasi kinerja dan mencegah overfitting. Penelitian ini bertujuan untuk membandingkan performa model-model yang dibangun dengan berbagai kombinasi variabel dalam memprediksi harga properti, untuk menentukan model terbaik dalam hal akurasi dan kompleksitas.
results_df <- data.frame(
Model = c("Model 1", "Model 2", "Model 3", "Model 4", "Model 5"),
RMSE = c(199283.5, 256001.3, 319103.2, 257411.5, 358359.4),
Rsquared = c(0.6991357, 0.5026754, 0.2255492, 0.4967233, 0.02341441))
ggplot(results_df, aes(x = Model, y = RMSE, fill = Model)) +
geom_bar(stat = "identity", position = position_dodge()) +
labs(title = "Perbandingan RMSE Model", x = "Model", y = "RMSE") +
theme_minimal() +
scale_fill_brewer(palette = "Set1") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Berdasarkan hasil di atas diketahui bahwa model 1 memiliki RMSE yang lebih rendah dibandingkan dengan model yang lainnya
ggplot(results_df, aes(x = Model, y = Rsquared, fill = Model)) +
geom_bar(stat = "identity", position = position_dodge()) +
labs(title = "Perbandingan R-squared Model", x = "Model", y = "R-squared") +
theme_minimal() +
scale_fill_brewer(palette = "Set1") +
theme(axis.text.x = element_text(angle = 45, hjust = 1))
Berkaitan dengan Nilai RMSE yang sudah dibandingkan dari seluruh model, dengan menggunakan acuan R-squareed juga diketahui bahwa model1 yang menjadi model dengan R-Squared tertinggi.
Dari lima model yang dikembangkan, model pertama (model1) menunjukkan kinerja terbaik dengan nilai RMSE terendah (199283.5), nilai R-squared tertinggi (0.6991357), dan nilai MAE terendah (125940). Hal ini mengindikasikan bahwa model pertama, yang menggunakan 20 variabel independen, memberikan prediksi yang lebih akurat daripada model-model lainnya. Dengan mempertimbangkan semua variabel independen yang tersedia, model ini mampu memberikan prediksi yang lebih mendekati harga sebenarnya dan memiliki kemampuan penjelasan yang lebih baik.