Browse Source

Edit models, working shiny app

Petra Lamborn 5 years ago
parent
commit
e1020e7d3f
3 changed files with 139 additions and 1 deletions
  1. 1
    1
      R/combmodels.R
  2. 3
    0
      R/weathmod.R
  3. 135
    0
      shiny/app.R

+ 1
- 1
R/combmodels.R View File

@@ -138,7 +138,7 @@ for (clus in clusters) {
138 138
     clusdf <- filter(aggdf, cluster == clus) %>% 
139 139
         dplyr::select(read_time, kwh = kwh_tot_mean) %>% 
140 140
         left_join(mtempdf, by = "read_time") %>% cbind(harm.y, harm.w, harm.d)
141
-    largm <- lm(nform.comp, data = clusdf, model = FALSE, qr = FALSE)
141
+    largm <- lm(nform.comp, data = clusdf, model = FALSE, qr = TRUE)
142 142
     allmods[[clus]] <- largm
143 143
 }
144 144
 

+ 3
- 0
R/weathmod.R View File

@@ -80,3 +80,6 @@ ctmplot
80 80
 ctmplot + coord_cartesian(xlim = c(as.POSIXct("2017-05-01", tz = "UTC"), as.POSIXct("2017-06-01", tz = "UTC")))
81 81
 
82 82
 write.csv(hmdf.comb, "../data/weatherharm.csv", row.names = FALSE)
83
+
84
+saveRDS(hmod, "../models/weatherMinharmonic.rds")
85
+saveRDS(maxhmod, "../models/weatherMaxharmonic.rds")

+ 135
- 0
shiny/app.R View File

@@ -0,0 +1,135 @@
1
+library(reticulate)
2
+library(shiny)
3
+library(dplyr)
4
+library(ggplot2)
5
+library(shinycssloaders)
6
+library(TSA)
7
+theme_set(theme_bw())
8
+
9
+p <- import("pandas")
10
+aggdf <- p$read_pickle("../data/9-clusters.agg.pkl")
11
+aggdf$cluster <- factor(aggdf$cluster)
12
+sns <- import("seaborn")
13
+
14
+models <- readRDS('../models/1kmods.rds')
15
+clusters = names(models)
16
+cbp <- as.character(p$Series(sns$color_palette("colorblind", as.integer(length(clusters)))$as_hex()))
17
+names(cbp) <- clusters
18
+minhwm <- readRDS("../models/weatherMinharmonic.rds")
19
+maxhwm <- readRDS("../models/weatherMaxharmonic.rds")
20
+monthchoices <- 1:12
21
+names(monthchoices) <- month.name
22
+weekdaychoices = 1:7
23
+names(weekdaychoices) = c("Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday")
24
+
25
+
26
+ui <- navbarPage("Counties Power demand modelling", collapsible = TRUE, selected = "Prediction",
27
+      tabPanel("Data and model",
28
+               plotOutput("dataPlot") %>% withSpinner(type = 5),
29
+               fluidRow(
30
+                       column(4,
31
+               selectInput("selDR", "Cluster", choices = clusters, selected = clusters[1])
32
+               ),
33
+                       column(4,
34
+               dateRangeInput("dpDR", "Date range", start = min(as.Date(aggdf$read_time)),
35
+                              end = max(as.Date(aggdf$read_time)),
36
+                              min = min(as.Date(aggdf$read_time)),
37
+                              max = max(as.Date(aggdf$read_time)),
38
+                              format = "dd/mm/yyyy")
39
+               ),
40
+                       column(4, p(paste("Point represents mean value of cluster, coloured line represents model prediction of",
41
+                                          "mean value of cluster."))
42
+               )
43
+               )),
44
+      tabPanel("Prediction",
45
+               plotOutput("predPlot") %>% withSpinner(type = 5),
46
+               fluidRow(
47
+                        column(8,
48
+               sliderInput("temprange", "Temperature range", min = 0, max = 30, value = c(10, 18), width = "100%", post = " °C",
49
+                           step = 0.5, dragRange = TRUE)),
50
+               column(2,
51
+                      selectInput("predmon", "Month (approximate)", monthchoices, selected = 1, width = "100%")
52
+                      ),
53
+               column(2,
54
+                      selectInput("predday", "Day of week", weekdaychoices, selected = 2, width = "100%")
55
+                      )
56
+               ),
57
+
58
+               h5("Number of ICPs of each cluster serviced by node:"),
59
+               fluidRow(
60
+                    column(1, numericInput("c1v", "1:", value = 1, min = 0, step = 1, width = "100%"), offset = 0),
61
+                    column(1, numericInput("c2v", "2:", value = 1, min = 0, step = 1, width = "100%")),
62
+                    column(1, numericInput("c3v", "3:", value = 1, min = 0, step = 1, width = "100%")),
63
+                    column(1, numericInput("c4v", "4:", value = 1, min = 0, step = 1, width = "100%")),
64
+                    column(1, numericInput("c5v", "5:", value = 1, min = 0, step = 1, width = "100%")),
65
+                    column(1, numericInput("c6v", "6:", value = 1, min = 0, step = 1, width = "100%")),
66
+                    column(1, numericInput("c7v", "7:", value = 1, min = 0, step = 1, width = "100%")),
67
+                    column(1, numericInput("c8v", "8:", value = 1, min = 0, step = 1, width = "100%")),
68
+                    column(1, numericInput("c9v", "9:", value = 1, min = 0, step = 1, width = "100%"))
69
+                )
70
+               
71
+               )
72
+      )
73
+
74
+
75
+server <- function(input, output) {
76
+    output$dataPlot <- renderPlot({
77
+        clus <- input$selDR
78
+        fildf <- filter(aggdf, cluster %in% clus) %>% 
79
+            mutate(r = resid(models[[clus]]), f = fitted(models[[clus]])) %>%
80
+            filter(read_time >= as.POSIXct(input$dpDR[1], tz = "UTC"), read_time <= as.POSIXct(input$dpDR[2], tz = "UTC"))
81
+
82
+        yrange = range(c(range(fildf$f), range(fildf$kwh_tot_mean)))
83
+        dplot <- ggplot(fildf, aes(x = read_time, y = f, color = cluster))
84
+
85
+        dplot <- dplot + geom_line(size = 2)
86
+
87
+        dplot <- dplot + geom_point(aes(y = kwh_tot_mean), color = "black")
88
+
89
+        dplot <- dplot + coord_cartesian(xlim = as.POSIXct(input$dpDR, tz = "UTC"), 
90
+                                         ylim = c(yrange[1] - (yrange[2] - yrange[1]) * 0.05,
91
+                                                  yrange[2] + (yrange[2] - yrange[1]) * 0.05),
92
+                                         expand = FALSE)
93
+
94
+        dplot <- dplot + scale_color_manual(values = cbp)
95
+        dplot <- dplot + theme(legend.position = "none")
96
+
97
+        dplot <- dplot + labs(y = "kwh", x = "Date/Time", caption = sprintf("Cluster: %s", clus))
98
+
99
+        return(dplot)
100
+    })
101
+
102
+    prediction <- reactive({
103
+        numeclus <- c(input$c1v,input$c2v,input$c3v,input$c4v,input$c5v,input$c6v,input$c7v,input$c8v,input$c9v)
104
+        numeclus[is.na(numeclus)] <- 0
105
+        ystart <- floor((as.numeric(input$predmon) - 0.5) / 12 * 365.25 * 48)
106
+        harm.y <- ts(1:48, frequency = 365.25 * 48, start = c(1, ystart)) %>% harmonic(2)
107
+        harm.w <- ts(1:48, frequency = 7 * 48, start = c(1, 48 * as.numeric(input$predday))) %>% harmonic(3)
108
+        harm.d <- ts(1:48, frequency = 48, start = c(1, 1)) %>% harmonic(3)
109
+        colnames(harm.y) <- sprintf("%s.%s.%s", "year", rep(c("cos", "sin"), each = ncol(harm.y)/2), rep(1:(ncol(harm.y)/2), times = 2))
110
+        colnames(harm.w) <- sprintf("%s.%s.%s", "week", rep(c("cos", "sin"), each = ncol(harm.w)/2), rep(1:(ncol(harm.w)/2), times = 2))
111
+        colnames(harm.d) <- sprintf("%s.%s.%s", "day",  rep(c("cos", "sin"), each = ncol(harm.d)/2), rep(1:(ncol(harm.d)/2), times = 2))
112
+        yharm <- harmonic(ts(1:48, frequency = floor(365.25 * 48), start = c(1, ystart)), 2)
113
+        harnames <- paste0("yharm", colnames(yharm))
114
+        # yharm <- as.data.frame(yharm)
115
+        colnames(yharm) <- harnames
116
+        wmmin <- input$temprange[1] - predict(minhwm, as.data.frame(yharm))
117
+        wmmax <- input$temprange[2] - predict(maxhwm, as.data.frame(yharm))
118
+        predinp <- data.frame(resmin = wmmin, resmax = wmmax)
119
+        predinp <- cbind(predinp, harm.y, harm.w, harm.d)
120
+        predvec = rep(0, 48)
121
+        for (c in 1:length(clusters)) {
122
+            predvec <- predvec + numeclus[c] * predict(models[[c]], predinp)
123
+        }
124
+        return(data.frame(x = 1:48, y = predvec))
125
+    })
126
+
127
+    output$predPlot <- renderPlot({
128
+        predf <- prediction()
129
+        ggplot(predf, aes(x, y)) + geom_line()
130
+    })
131
+
132
+}
133
+
134
+
135
+shinyApp(ui = ui, server = server)