library(dplyr)
library(GGally)
library(MLmetrics)
library(tidyverse)
library(car)
library(lmtest)
library(inspectdf)
library(performance)
options(scipen = 100, max.print = 1e+08)
Read and save the data it into house data frame
house <- read.csv("data_input/USA_Housing.csv")
Checking data structure
glimpse(house)
## Rows: 5,000
## Columns: 7
## $ Avg..Area.Income <dbl> 79545.46, 79248.64, 61287.07, 63345.24, 5…
## $ Avg..Area.House.Age <dbl> 5.682861, 6.002900, 5.865890, 7.188236, 5…
## $ Avg..Area.Number.of.Rooms <dbl> 7.009188, 6.730821, 8.512727, 5.586729, 7…
## $ Avg..Area.Number.of.Bedrooms <dbl> 4.09, 3.09, 5.13, 3.26, 4.23, 4.04, 3.41,…
## $ Area.Population <dbl> 23086.80, 40173.07, 36882.16, 34310.24, 2…
## $ Price <dbl> 1059033.6, 1505890.9, 1058988.0, 1260616.…
## $ Address <chr> "208 Michael Ferry Apt. 674\nLaurabury, N…
Deleting unused columns
house_clean <- house %>% select(-c(Address))
Checking is any missing values on the data
colSums(is.na(house_clean))
## Avg..Area.Income Avg..Area.House.Age
## 0 0
## Avg..Area.Number.of.Rooms Avg..Area.Number.of.Bedrooms
## 0 0
## Area.Population Price
## 0 0
No missing value on the data
Checking the correlation between Price as the target
with all the other variables
ggcorr(house_clean, label = T, label_size = 2.9, hjust = 1, layout.exp = 2)
From the graph above we could see that Avg..Area.Income
has the strongest correlation with Price
Because Price has the strongest correlation with
Avg..Area.Income, so we will create the model with
Price as the target and Avg..Area.Income as
the predictor variable.
house_lm <- lm(Price ~ Avg..Area.Income,
data = house_clean)
summary(house_lm)
##
## Call:
## lm(formula = Price ~ Avg..Area.Income, data = house_clean)
##
## Residuals:
## Min 1Q Median 3Q Max
## -965112 -187163 -2365 183084 983680
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) -221579.4782 25000.1306 -8.863 <0.0000000000000002 ***
## Avg..Area.Income 21.1955 0.3602 58.844 <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 271400 on 4998 degrees of freedom
## Multiple R-squared: 0.4093, Adjusted R-squared: 0.4091
## F-statistic: 3463 on 1 and 4998 DF, p-value: < 0.00000000000000022
From the summary above, we can see the Adjusted R-squared is 0.4091
which means 40.91% of the price was explained by
Avg..Area.Income and the rest from other variables.
Next we will create a model using Price as the target
with all the variables in the data frame as the predictor
house_lm1 <- lm(Price ~ .,
data = house_clean)
summary(house_lm1)
##
## Call:
## lm(formula = Price ~ ., data = house_clean)
##
## Residuals:
## Min 1Q Median 3Q Max
## -337020 -70236 320 69175 361870
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -2637299.0333 17157.8092 -153.708
## Avg..Area.Income 21.5780 0.1343 160.656
## Avg..Area.House.Age 165637.0269 1443.4130 114.754
## Avg..Area.Number.of.Rooms 120659.9488 1605.1604 75.170
## Avg..Area.Number.of.Bedrooms 1651.1391 1308.6712 1.262
## Area.Population 15.2007 0.1442 105.393
## Pr(>|t|)
## (Intercept) <0.0000000000000002 ***
## Avg..Area.Income <0.0000000000000002 ***
## Avg..Area.House.Age <0.0000000000000002 ***
## Avg..Area.Number.of.Rooms <0.0000000000000002 ***
## Avg..Area.Number.of.Bedrooms 0.207
## Area.Population <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 101200 on 4994 degrees of freedom
## Multiple R-squared: 0.918, Adjusted R-squared: 0.9179
## F-statistic: 1.119e+04 on 5 and 4994 DF, p-value: < 0.00000000000000022
From the summary, we can see there is 1 variables that doesn’t
significantly impact the house price. So next we will use Step-Wise
Regression with direction backward to create a new model
with the best variables.
house_back <- step(house_lm1, direction = "backward")
## Start: AIC=115249.9
## Price ~ Avg..Area.Income + Avg..Area.House.Age + Avg..Area.Number.of.Rooms +
## Avg..Area.Number.of.Bedrooms + Area.Population
##
## Df Sum of Sq RSS AIC
## - Avg..Area.Number.of.Bedrooms 1 16287981430 51114959547695 115250
## <none> 51098671566265 115250
## - Avg..Area.Number.of.Rooms 1 57816321293270 108914992859535 119032
## - Area.Population 1 113653120691812 164751792258077 121101
## - Avg..Area.House.Age 1 134739428405496 185838099971761 121704
## - Avg..Area.Income 1 264092032671228 315190704237493 124345
##
## Step: AIC=115249.5
## Price ~ Avg..Area.Income + Avg..Area.House.Age + Avg..Area.Number.of.Rooms +
## Area.Population
##
## Df Sum of Sq RSS AIC
## <none> 51114959547695 115250
## - Avg..Area.Number.of.Rooms 1 74764641482450 125879601030145 119754
## - Area.Population 1 113657374142563 164772333690258 121100
## - Avg..Area.House.Age 1 134791004859689 185905964407384 121703
## - Avg..Area.Income 1 264409832482435 315524792030129 124348
summary(house_back)
##
## Call:
## lm(formula = Price ~ Avg..Area.Income + Avg..Area.House.Age +
## Avg..Area.Number.of.Rooms + Area.Population, data = house_clean)
##
## Residuals:
## Min 1Q Median 3Q Max
## -338419 -70058 132 69074 362025
##
## Coefficients:
## Estimate Std. Error t value
## (Intercept) -2637560.6725 17157.5724 -153.73
## Avg..Area.Income 21.5827 0.1343 160.74
## Avg..Area.House.Age 165657.8724 1443.4039 114.77
## Avg..Area.Number.of.Rooms 121598.1646 1422.6077 85.48
## Area.Population 15.1961 0.1442 105.39
## Pr(>|t|)
## (Intercept) <0.0000000000000002 ***
## Avg..Area.Income <0.0000000000000002 ***
## Avg..Area.House.Age <0.0000000000000002 ***
## Avg..Area.Number.of.Rooms <0.0000000000000002 ***
## Area.Population <0.0000000000000002 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 101200 on 4995 degrees of freedom
## Multiple R-squared: 0.918, Adjusted R-squared: 0.9179
## F-statistic: 1.398e+04 on 4 and 4995 DF, p-value: < 0.00000000000000022
From the summary above, we can see that the Adjusted R-squared both
have the same numbers between before and
afterStep-Wise Regression. Both have 0.9179 which means
that both model was 91.79% explained by the variables.
Based on 3 models that we created, the best model that we could use is the model with all variables and the step-wise model.
MAPE for model with Price target with all variables
MAPE(y_pred = house_clean$Price,
y_true = predict(house_lm1, house_clean)) *100
## [1] 7.390759
MAPE for step-wise model
MAPE(y_pred = house_clean$Price,
y_true = predict(house_back, house_clean)) *100
## [1] 7.387608
From calculation above, step-wise model is a better model by 0.003 points. This means both models are good enough to be used because both models value number is close to 0.
Normality test with all Variables
hist(house_lm1$residuals)
shapiro.test(house_lm1$residuals)
##
## Shapiro-Wilk normality test
##
## data: house_lm1$residuals
## W = 0.99955, p-value = 0.3056
Normality test with Step-Wise model
hist(house_back$residuals)
shapiro.test(house_back$residuals)
##
## Shapiro-Wilk normality test
##
## data: house_back$residuals
## W = 0.99957, p-value = 0.341
Based on the Shapiro test above, both models has p-value > alpha . Which means H0 is accepted, residual distributed normally for both models.
Homoscedasticity test with all Variable
plot(house_clean$Price, house_lm1$residuals)
abline(h = 0, col = "red")
bptest(house_lm1)
##
## studentized Breusch-Pagan test
##
## data: house_lm1
## BP = 10.314, df = 5, p-value = 0.0668
Homoscedasticity test with Step-Wise model
plot(house_clean$Price, house_back$residuals)
abline(h = 0, col = "red")
bptest(house_back)
##
## studentized Breusch-Pagan test
##
## data: house_back
## BP = 10.385, df = 4, p-value = 0.03441
Based on Homoscedasticity test above, p-value for model with all variables > alpha (0.05), which means H0 is accepted. Data error spread constantly (Homoscedasticity). But p-value for Step-Wise model < alpha (0.05), which means H1 is accepted. Data error spread creating a pattern (Heteroscedasticity)
Multicolinearity test model with all variables
vif(house_lm1)
## Avg..Area.Income Avg..Area.House.Age
## 1.001159 1.000577
## Avg..Area.Number.of.Rooms Avg..Area.Number.of.Bedrooms
## 1.273535 1.274413
## Area.Population
## 1.001266
Multicolinearity test with Step-Wise model
vif(house_back)
## Avg..Area.Income Avg..Area.House.Age Avg..Area.Number.of.Rooms
## 1.000390 1.000445 1.000214
## Area.Population
## 1.000619
Based on Multicolinearity test, both models variable values is less than 10. Which means all the variables are independent and there is no correlation between each of the variables from both model.
Based on the test above, model with all variable is better and
useable than Step-Wise model. Although
Avg..Area.Number.of.Bedrooms variable doesn’t have any
significant impact to the intercept, but from this case it could make a
huge different based on the Homoscedasticity test.