We have a data set related to weather and we want to predict the apparent temperature based of some independent variables and build a simple linear regression model.
Let’s import our data set
library(tidyverse)
library(ggplot2)
library(ggcorrplot)
library(dplyr)
library(mlbench)
library(caret)
#importing data set
data <- read.csv('Weather_History.csv')
and have a look at our data
summary(data)
## Precip.Type Temperature Apparent.Temperature Humidity
## Length:96453 Min. :-21.822 Min. :-27.717 Min. :0.0000
## Class :character 1st Qu.: 4.689 1st Qu.: 2.311 1st Qu.:0.6000
## Mode :character Median : 12.000 Median : 12.000 Median :0.7800
## Mean : 11.933 Mean : 10.855 Mean :0.7349
## 3rd Qu.: 18.839 3rd Qu.: 18.839 3rd Qu.:0.8900
## Max. : 39.906 Max. : 39.344 Max. :1.0000
## Wind.Speed Wind.Bearing Visibility Loud.Cover Pressure
## Min. : 0.000 Min. : 0.0 Min. : 0.00 Min. :0 Min. : 0
## 1st Qu.: 5.828 1st Qu.:116.0 1st Qu.: 8.34 1st Qu.:0 1st Qu.:1012
## Median : 9.966 Median :180.0 Median :10.05 Median :0 Median :1016
## Mean :10.811 Mean :187.5 Mean :10.35 Mean :0 Mean :1003
## 3rd Qu.:14.136 3rd Qu.:290.0 3rd Qu.:14.81 3rd Qu.:0 3rd Qu.:1021
## Max. :63.853 Max. :359.0 Max. :16.10 Max. :0 Max. :1046
colnames(data)
## [1] "Precip.Type" "Temperature" "Apparent.Temperature"
## [4] "Humidity" "Wind.Speed" "Wind.Bearing"
## [7] "Visibility" "Loud.Cover" "Pressure"
#checking for missing values
sum(is.na(data))
## [1] 0
#one of the columns has only 0 values so we'll remove it
data<-data[,-8]
# Removing zero pressure, Looks like an error #
data<-data %>% filter(!data$Pressure==0)
data$Precip.Type[data$Precip.Type=="null"]<- "none"
Let’s measure the strength and direction of the relationship between two variables by looking at the correlation coefficient:
num_cols <- data %>% select(where(is.numeric)) %>% colnames()
options(repr.plot.width = 10.0, repr.plot.height = 10.0)
ggcorrplot(cor(data[,num_cols], method = 'pearson'), type="upper", lab=T, title = 'Correlations')
Now we’ll look at the model (and let’s say principal assumptions are true):
model <- lm(Apparent.Temperature~Humidity+Wind.Speed+Visibility+Pressure+Wind.Bearing,data = data)
summary(model)
##
## Call:
## lm(formula = Apparent.Temperature ~ Humidity + Wind.Speed + Visibility +
## Pressure + Wind.Bearing, data = data)
##
## Residuals:
## Min 1Q Median 3Q Max
## -57.501 -4.797 0.677 5.354 27.419
##
## Coefficients:
## Estimate Std. Error t value Pr(>|t|)
## (Intercept) 4.735e+02 3.313e+00 142.91 <2e-16 ***
## Humidity -3.314e+01 1.349e-01 -245.69 <2e-16 ***
## Wind.Speed -4.454e-01 3.694e-03 -120.58 <2e-16 ***
## Visibility 3.374e-01 6.241e-03 54.06 <2e-16 ***
## Pressure -4.303e-01 3.226e-03 -133.38 <2e-16 ***
## Wind.Bearing 2.912e-03 2.244e-04 12.97 <2e-16 ***
## ---
## Signif. codes: 0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
##
## Residual standard error: 7.377 on 95159 degrees of freedom
## Multiple R-squared: 0.5235, Adjusted R-squared: 0.5234
## F-statistic: 2.091e+04 on 5 and 95159 DF, p-value: < 2.2e-16
We removed Temperature form the model to avoid multicollinearity.
If you’re only interested in how well your model works on the data you already have, you don’t need to split your data.
But if you want your model to work well on new, unseen data, then you need to check how it performs on data it hasn’t seen before. That’s why we split the data into two parts:
Training set: Used to build the model.
Test set: Used to check how good the model really is.
Because our data is big, let’s use a sample:
weather<-sample_n(data,1000)
We want to split our data set into two parts, one (bigger) on which the model is trained, and the other (smaller) that is used for model evaluation. Before we do anything, let’s set a random seed. Train/test split is a random process, and seed ensures the randomization works the same:
set.seed(10)
80% of the data is used for training, and the remaining 20% is used for testing.
Index<-createDataPartition(weather$Apparent.Temperature,p=0.8,list=FALSE)
TrainingSet<-weather[Index,]
TestingSet<-weather[-Index,]
NewModel<-train(Apparent.Temperature~.,
data = TrainingSet,
method = "lm",
na.action = na.omit, #omitting missing values
preProcess = c("scale","center"), #scaling variables
trControl=trainControl(method="none"))
We’re trying to predict the Apparent Temp as a linear combination of every other attribute. R also handles the categorical variables automatically, which is nice.
ModelTraining<-predict(NewModel,TrainingSet)
ModelTesting<-predict(NewModel,TestingSet)
Let’s see the how good do actual value and predicted value fit by looking at the scatter plots:
plot(TrainingSet$Apparent.Temperature,ModelTraining)
plot(TestingSet$Apparent.Temperature,ModelTesting)