1.1 Import data
data <- read_csv("Sales Analyst CL Ltd.csv") %>%
clean_names()
update <- read_csv("clean_update.csv") %>%
clean_names()
# Check dataset
glimpse(data)
## Rows: 1,593
## Columns: 5
## $ date <dbl> 20240423, 20240423, 20240424, 20240424, 20240425, 20240427, 2024…
## $ sku <chr> "B0B1X3N2LX", "UF24917", "B0B1X3N2LX", "B0B1X3N2LX", "B0B1X3N2LX…
## $ qty <dbl> 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1…
## $ price <dbl> 10, 35, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, …
## $ sale <dbl> 10, 70, 10, 10, 20, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, …
1.2 Data Cleaning
data <- data %>%
mutate(date = ymd(date),
year = year(date),
month = as.factor(month.abb[month(date)]),
day = day(date),
wday = wday(date, label = TRUE)) %>%
select(sku, qty, month, day, wday, year, date)
update <- update %>%
mutate(date = ymd(date)) %>%
select(sku, qty, date)
1.3 Data Manipulation
1.3.1 Historical Data
data_ts <- data %>%
group_by(date) %>%
summarise(total_sale_qty = sum(qty))
1.3.2 Updated Data
# Set up date range
start_date <- as.Date("2024-06-15")
end_date <- as.Date("2024-06-17")
num_dates <- 143 # Number of dates to generate
# Generate random dates
random_dates <- sample(seq(start_date, end_date, by = "day"), num_dates, replace = TRUE)
table(random_dates)
## random_dates
## 2024-06-15 2024-06-16 2024-06-17
## 45 36 62
# Change part of 0615
update_df <- update %>%
mutate(date_atc = random_dates) %>%
arrange(date_atc)
update_df[1:19, 4] <- as.Date("2024-06-16")
table(update_df$date_atc)
##
## 2024-06-15 2024-06-16 2024-06-17
## 26 55 62
# Change part of 0617
update_df <- update_df %>%
arrange(date_atc)
update_df[136:143, 4] <- as.Date("2024-06-16")
# Data aggregation
update_df <- update_df %>%
group_by(date_atc) %>%
summarise(total_sale_qty = sum(qty))
colnames(update_df)[1] <- c("date")
1.3.3 Merging Data
df_ts <- rbind(data_ts, update_df)
2. Data Visualization
df_ts %>%
plot_time_series(date, total_sale_qty, .interactive = TRUE)
3. Sale Forecasting
3.1 Split dataset
set.seed(231)
#Split data into test and training set
split <- df_ts %>%
time_series_split(date_var = date,
assess = "1 months", # use the last month as test set
cumulative = TRUE)
#Visualize test train split
split %>%
tk_time_series_cv_plan() %>%
plot_time_series_cv_plan(date, total_sale_qty, .interactive = TRUE)
3.2 Model Fit
model_fit_prophet <- prophet_reg() %>%
set_engine('prophet') %>%
fit(total_sale_qty ~ ., data = training(split))
# Put model into a modeltime table
models_tbl <- modeltime_table(model_fit_prophet)
models_tbl
## # Modeltime Table
## # A tibble: 1 × 3
## .model_id .model .model_desc
## <int> <list> <chr>
## 1 1 <fit[+]> PROPHET
# Calibrate model
calibration_tbl <- models_tbl %>%
modeltime_calibrate(new_data = testing(split))
# Check model accuracy
(accuracy_table <- calibration_tbl %>%
modeltime_accuracy())
## # A tibble: 1 × 9
## .model_id .model_desc .type mae mape mase smape rmse rsq
## <int> <chr> <chr> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
## 1 1 PROPHET Test 41.7 138. 0.725 59.6 58.2 0.0647
3.3 Forecast test data
#Step 6: Create future forecast on test data
(forecast_tbl <- calibration_tbl %>%
modeltime_forecast(
new_data = testing(split),
actual_data = data_ts,
keep_data = TRUE
))
## # A tibble: 68 × 9
## .model_id .model_desc .key .index .value .conf_lo .conf_hi date
## <int> <chr> <fct> <date> <dbl> <dbl> <dbl> <date>
## 1 NA ACTUAL actual 2024-04-23 3 NA NA 2024-04-23
## 2 NA ACTUAL actual 2024-04-24 2 NA NA 2024-04-24
## 3 NA ACTUAL actual 2024-04-25 2 NA NA 2024-04-25
## 4 NA ACTUAL actual 2024-04-27 1 NA NA 2024-04-27
## 5 NA ACTUAL actual 2024-04-28 8 NA NA 2024-04-28
## 6 NA ACTUAL actual 2024-04-30 12 NA NA 2024-04-30
## 7 NA ACTUAL actual 2024-05-01 6 NA NA 2024-05-01
## 8 NA ACTUAL actual 2024-05-02 2 NA NA 2024-05-02
## 9 NA ACTUAL actual 2024-05-03 19 NA NA 2024-05-03
## 10 NA ACTUAL actual 2024-05-04 5 NA NA 2024-05-04
## # ℹ 58 more rows
## # ℹ 1 more variable: total_sale_qty <dbl>
plot_modeltime_forecast(forecast_tbl)
#Create a tibble of observations with length out being the number of observations we want in reference to our date variable (new_data)
#Create tibble of dates
dates <- df_ts %>%
future_frame(date, .length_out = "3 months")
#Put data into dataframe
explanatory_data <- dates
# Refit to the full dataset
refit_tbl <- calibration_tbl %>%
modeltime_refit(df_ts)
#Forecast on the new tibble dataframe
forecast_tbl_future_data <- refit_tbl %>%
modeltime_forecast(
new_data = dates
)
#Check results of forecast
head(forecast_tbl_future_data)
## # A tibble: 6 × 7
## .model_id .model_desc .key .index .value .conf_lo .conf_hi
## <int> <chr> <fct> <date> <dbl> <dbl> <dbl>
## 1 1 PROPHET prediction 2024-06-18 113. -1.96 229.
## 2 1 PROPHET prediction 2024-06-19 87.8 -27.6 203.
## 3 1 PROPHET prediction 2024-06-20 86.3 -29.1 202.
## 4 1 PROPHET prediction 2024-06-21 76.2 -39.1 192.
## 5 1 PROPHET prediction 2024-06-22 66.3 -49.1 182.
## 6 1 PROPHET prediction 2024-06-23 100. -15.1 216.
plot_modeltime_forecast(forecast_tbl_future_data, .interactive = TRUE)