library('readxl')
d <- read_excel('data.xlsx')
head(d)
## # A tibble: 6 × 19
## Address Neighborhood Bedrooms Bathrooms `Square Meters` `Building Age` Garden
## <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 78 Rege… Notting Hill 2 3 179 72 0
## 2 198 Oxf… Westminster 2 1 123 34 1
## 3 18 Rege… Soho 5 3 168 38 0
## 4 39 Picc… Islington 5 1 237 53 1
## 5 116 Fle… Marylebone 4 1 127 23 0
## 6 32 Bond… Notting Hill 5 2 69 69 1
## # ℹ 12 more variables: Garage <dbl>, Floors <dbl>, `Property Type` <chr>,
## # `Heating Type` <chr>, Balcony <chr>, `Interior Style` <chr>, View <chr>,
## # Materials <chr>, `Building Status` <chr>, Price <dbl>,
## # price_for_square_meter <dbl>, Total_Rooms <dbl>
variable.names(d)
## [1] "Address" "Neighborhood" "Bedrooms"
## [4] "Bathrooms" "Square Meters" "Building Age"
## [7] "Garden" "Garage" "Floors"
## [10] "Property Type" "Heating Type" "Balcony"
## [13] "Interior Style" "View" "Materials"
## [16] "Building Status" "Price" "price_for_square_meter"
## [19] "Total_Rooms"
summary(d)
## Address Neighborhood Bedrooms Bathrooms
## Length :1000 Length :1000 Min. :1.000 Min. :1.000
## N.unique : 770 N.unique : 10 1st Qu.:2.000 1st Qu.:1.000
## N.blank : 0 N.blank : 0 Median :3.000 Median :2.000
## Min.nchar: 8 Min.nchar: 4 Mean :3.013 Mean :2.003
## Max.nchar: 22 Max.nchar: 12 3rd Qu.:4.000 3rd Qu.:3.000
## Max. :5.000 Max. :3.000
## Square Meters Building Age Garden Garage
## Min. : 50.0 Min. : 1.00 Min. :0.000 Min. :0.000
## 1st Qu.: 99.0 1st Qu.:24.00 1st Qu.:0.000 1st Qu.:0.000
## Median :148.0 Median :50.00 Median :1.000 Median :1.000
## Mean :149.6 Mean :49.97 Mean :0.512 Mean :0.501
## 3rd Qu.:201.0 3rd Qu.:76.00 3rd Qu.:1.000 3rd Qu.:1.000
## Max. :249.0 Max. :99.00 Max. :1.000 Max. :1.000
## Floors Property Type Heating Type Balcony
## Min. :1.000 Length :1000 Length :1000 Length :1000
## 1st Qu.:1.000 N.unique : 3 N.unique : 4 N.unique : 3
## Median :2.000 N.blank : 0 N.blank : 0 N.blank : 0
## Mean :1.991 Min.nchar: 9 Min.nchar: 11 Min.nchar: 10
## 3rd Qu.:3.000 Max.nchar: 14 Max.nchar: 18 Max.nchar: 18
## Max. :3.000
## Interior Style View Materials Building Status
## Length :1000 Length :1000 Length :1000 Length :1000
## N.unique : 4 N.unique : 5 N.unique : 4 N.unique : 3
## N.blank : 0 N.blank : 0 N.blank : 0 N.blank : 0
## Min.nchar: 6 Min.nchar: 3 Min.nchar: 4 Min.nchar: 3
## Max.nchar: 10 Max.nchar: 6 Max.nchar: 17 Max.nchar: 9
##
## Price price_for_square_meter Total_Rooms
## Min. : 386666 Min. : 6667 Min. :2.000
## 1st Qu.:1161400 1st Qu.:10000 1st Qu.:4.000
## Median :1721999 Median :12000 Median :5.000
## Mean :1840807 Mean :12331 Mean :5.016
## 3rd Qu.:2390500 3rd Qu.:15000 3rd Qu.:6.000
## Max. :4980000 Max. :20000 Max. :8.000
sum(duplicated(d))
## [1] 0
No duplicated to remove
colSums(is.na(d))
## Address Neighborhood Bedrooms
## 0 0 0
## Bathrooms Square Meters Building Age
## 0 0 0
## Garden Garage Floors
## 0 0 0
## Property Type Heating Type Balcony
## 0 0 0
## Interior Style View Materials
## 0 0 0
## Building Status Price price_for_square_meter
## 0 0 0
## Total_Rooms
## 0
No missing values
d$Neighborhood <- as.factor(d$Neighborhood)
d$`Property Type` <- as.factor(d$`Property Type`)
d$`Heating Type` <- as.factor(d$`Heating Type`)
d$`Interior Style`<- as.factor(d$`Interior Style`)
d$View <- as.factor(d$View)
d$Materials <- as.factor(d$Materials)
d$`Building Status` <-as.factor(d$`Building Status`)
d$Garden <- as.factor(d$Garden)
d$Garage<- as.factor(d$Garage )
d$Balcony <- as.factor(d$Balcony)
set.seed(2026)
total <- nrow(d)
train <- floor(total * 0.8)
test <- floor(total * 0.2)
train_ids <- sample(1:train, train)
train_data <- d[train_ids,]
test_data <- d[-train_ids,]
print(paste('Total: ', total, ' Train: ', train, ' Test: ', test, ' Train IDs: ', length(train_ids), ' Train Data: ', nrow(train_data), ' Test Data: ', nrow(test_data)))
## [1] "Total: 1000 Train: 800 Test: 200 Train IDs: 800 Train Data: 800 Test Data: 200"
head(train_data)
## # A tibble: 6 × 19
## Address Neighborhood Bedrooms Bathrooms `Square Meters` `Building Age` Garden
## <chr> <fct> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 154 Str… Kensington 4 2 99 22 1
## 2 22 Park… Greenwich 1 2 152 2 0
## 3 96 Flee… Soho 5 1 247 60 0
## 4 52 Rege… Soho 4 2 166 98 1
## 5 191 Reg… Camden 1 1 228 9 1
## 6 188 Str… Shoreditch 5 2 167 67 0
## # ℹ 12 more variables: Garage <fct>, Floors <dbl>, `Property Type` <fct>,
## # `Heating Type` <fct>, Balcony <fct>, `Interior Style` <fct>, View <fct>,
## # Materials <fct>, `Building Status` <fct>, Price <dbl>,
## # price_for_square_meter <dbl>, Total_Rooms <dbl>
head(test_data)
## # A tibble: 6 × 19
## Address Neighborhood Bedrooms Bathrooms `Square Meters` `Building Age` Garden
## <chr> <fct> <dbl> <dbl> <dbl> <dbl> <fct>
## 1 178 Pic… Shoreditch 5 3 249 13 1
## 2 55 Stra… Camden 3 3 171 34 1
## 3 176 Fle… Camden 5 1 67 83 0
## 4 72 Camd… Islington 5 1 121 77 0
## 5 95 Park… Greenwich 1 2 177 80 1
## 6 183 Str… Westminster 5 1 109 25 1
## # ℹ 12 more variables: Garage <fct>, Floors <dbl>, `Property Type` <fct>,
## # `Heating Type` <fct>, Balcony <fct>, `Interior Style` <fct>, View <fct>,
## # Materials <fct>, `Building Status` <fct>, Price <dbl>,
## # price_for_square_meter <dbl>, Total_Rooms <dbl>
model <- lm(Price ~ Neighborhood + Bedrooms + Bathrooms + `Square Meters` + `Building Age` + Garden + Garage + Floors + `Property Type` + `Heating Type` + Balcony + `Interior Style` + View + Materials + `Building Status` + Total_Rooms, data=train_data)
predicted <- predict(model, test_data)
mae <- mean(abs(test_data$Price - predicted))
mae
## [1] 164050.4
re <- mae / mean(d$Price)
re
## [1] 0.08911875
I have choosed a housing dataset from kaggle (https://www.kaggle.com/code/atamoaty/houses/notebook) then I used it to predict house price using different variables. I have splitted the data 80% train, then 20% testing, trained the model then made prediction then calculated MAE then calculated the relative error
The Mean Average Error was 164050.4 while the average price was 1840807 which give use relative error of like 8% which is not bad. That mean the model can be able to perform the house predict with 8% possible error which is a reasonable good accuracy
Variable selection is a process by which we choose which independent variables should be included in a regression model The goal is to keep the variables that help predict the target variable and remove those that add little value
Starts with no variables and adds them one by one.
model0 <- lm(Price ~ 1, data=d)
model1 <- lm(Price ~ ., data=d)
step(model0, scope=list(lower=model0, upper=model1), direction="forward")
Starts with all variables and removes the least useful ones.
full_model <- lm(Price ~ ., data=d)
step(full_model, direction="backward")
Combination of forward and backward
full_model <- lm(Price ~ ., data=d)
step(full_model, direction="both")
Remove variables whose p-value is greater than 0.05
Remove variables that are highly correlated with each other (multicollinearity). If two variables contain almost the same information, you may keep only one.