library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.4
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.4.4     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.0
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(ggthemes)
library(ggrepel)
library(patchwork)
library(broom)
library(lindia)
library(nnet)
sensor_data <- read.csv("/Users/manojdannana/Desktop/Manoj/IUPUI/class work/intro to statistics/datasets/Occupancy_Estimation.csv")

Binary column chosen for the analysis is S6_PIR

Logistic Regression Model for the above chosen Response Variable

Explanatory Variables chosen for this model are S1_Temp, S1_Light, S1_Sound, S5_CO2

model <- glm(S6_PIR ~ S1_Temp + S1_Light + S1_Sound + S5_CO2, data = sensor_data,
             family = binomial(link = 'logit'))

model$coefficients
##   (Intercept)       S1_Temp      S1_Light      S1_Sound        S5_CO2 
## -2.599266e+01  8.523600e-01  2.339065e-02  1.249646e+00 -2.932467e-04

Inferences:

  1. Intercept: The intercept is the log odds of the outcome when all the other coefficients are zero.
  2. S1_Temp coeff: This is the rate at which log odds of the outcome increases when all the other variables are constant. i.e; for every one-unit increase in S1_Temp, the log-odds of the outcome increase by approximately 0.852.
  3. S1_Light coeff: This is the rate at which log odds of the outcome increases when all the other variables are constant. i.e; for every one-unit increase in S1_Light, the log-odds of the outcome increase by approximately 0.0233.
  4. S1_Sound coeff: This is the rate at which log odds of the outcome increases when all the other variables are constant. i.e; for every one-unit increase in S1_Sound, the log-odds of the outcome increase by approximately 1.249.
  5. S5_CO2 coeff: This is the rate at which log odds of the outcome increases when all the other variables are constant. i.e; for every one-unit increase in S5_CO2, the log-odds of the outcome increase by approximately -0.0002.
summary_model <- summary(model)

coefficients <- summary_model$coefficients[, 1]
standard_errors <- summary_model$coefficients[, 2]

coefs_and_errors <- data.frame(Coefficient = coefficients, `Standard Error` = standard_errors)
print(coefs_and_errors)
##               Coefficient Standard.Error
## (Intercept) -2.599266e+01   5.7892821167
## S1_Temp      8.523600e-01   0.2313641709
## S1_Light     2.339065e-02   0.0010448537
## S1_Sound     1.249646e+00   0.1060243694
## S5_CO2      -2.932467e-04   0.0003032332

Let’s get the CI for coefficient of S1_Temp

conf_int = list(model$coefficients[[2]] + 1.96 * coefs_and_errors$Standard.Error[2], model$coefficients[[2]] - 1.96 * coefs_and_errors$Standard.Error[2])

print(conf_int)
## [[1]]
## [1] 1.305834
## 
## [[2]]
## [1] 0.3988862

Translation:

This means that we are 95% confident that the true value of the coefficient for S1_Temp lies within this interval of (0.3988862, 1.305834).

Transformations:

For this I am going to consider S1_Temp as the explanatory variable and Room_Occupancy_Count as the response variable.

Plot of S1_Temp vs Room_Occupancy_Count

p1 <- ggplot(data=sensor_data, mapping = aes(x = S1_Temp, y = Room_Occupancy_Count)) + 
  geom_point() +
  geom_smooth(method = 'lm', color = 'gray', linetype = 'dashed', 
              se = FALSE) 
  labs(title = 'Before Transformation')
## $title
## [1] "Before Transformation"
## 
## attr(,"class")
## [1] "labels"
p1
## `geom_smooth()` using formula = 'y ~ x'

unique_values <- unique(sensor_data$Room_Occupancy_Count)
print(unique_values)
## [1] 1 2 3 0

The data can’t be represented either by using a Linear Regression Model or a Logistic Regression Model.

Reasons:

  1. Although Room_Occupancy_Count may seem like a numerical column, upon further analysis I found that the column is much like a categorical column rather than a numerical column. All the data has been distributed among the only 4 values.
  2. Logistic Regression fails at multi class classification, so instead of using a sigmoid function we can use a softmax transformation which will give a better fitting model.
softmax <- function(x) {
  exp_x <- exp(x)
  return(exp_x / sum(exp_x))
}

# Apply the softmax function to x_values
softmax_values <- softmax(sensor_data$S1_Temp)

# Plot the softmax function
plot(sensor_data$S1_Temp, softmax_values, type = "l", 
     main = "Softmax Activation Function", 
     xlab = "Input Value (x)", 
     ylab = "Output Probability",
     col = "blue")

softmax_model <- multinom(Room_Occupancy_Count ~ S1_Temp, data = sensor_data)
## # weights:  12 (6 variable)
## initial  value 14041.775584 
## iter  10 value 4366.087189
## final  value 4334.785270 
## converged
summary(softmax_model)
## Call:
## multinom(formula = Room_Occupancy_Count ~ S1_Temp, data = sensor_data)
## 
## Coefficients:
##   (Intercept)  S1_Temp
## 1   -107.4298 4.098568
## 2   -187.4300 7.207411
## 3   -203.5574 7.823912
## 
## Std. Errors:
##   (Intercept)   S1_Temp
## 1    3.937190 0.1534105
## 2    4.867704 0.1880931
## 3    5.488867 0.2117259
## 
## Residual Deviance: 8669.571 
## AIC: 8681.571