R语言与数据分析练习:使用ARIMA模型预测网站访问量


使用ARIMA模型预测网站访问量

一、实验背景:

随着流量的增大,某网站的数据信息量也在以一定的幅度增长
基于该网站2016年9月~2017年2月每天的访问量,使用ARIMA模型预测网站未来7天的访问量

二、实验目的:

预测网站未来7天的访问量

三、实验设计方案和流程图:

实验设计方案:

  1. 由于我们获取的原数据文件为sql类型的,因此我们需要将原数据文件导入mysql,再通过R语言中的方法连接mysql进行数据的读取。
  2. 读取数据之后,对数据进行观察。
  3. 观察完毕,对数据进行预处理及清洗。
  4. 对整理好的数据进行序列平稳性的检查:若数据平稳,则进行下一步。若数据不平稳,将进行差分运算。
  5. 对数据进行纯随机性检测:若数据为白噪声,则进行下一步。若数据为非白噪声,数据没有研究意义,结束实验。
  6. 对数据绘制BIC图进行定阶,观察平均误差的大小,获取最优的模型数值。
  7. 使用最优的模型,预测未来7天的网站访问量。

实验设计流程图:

r语言建立ar模型实例 r语言arima模型拟合及预测_r语言

四、实验过程:

1、Mysql数据导入及数据清洗

通过 Navicat Premium 将 jc_content_viewlog.sql 文件导入mysql数据库



r语言建立ar模型实例 r语言arima模型拟合及预测_r语言建立ar模型实例_02

数据清洗源代码:

# 设置工作目录并导入需要的包
setwd("D:/bigdata/R语言与数据分析/project/test1")
library("RMySQL")
library(tidyr)
library(dplyr)
library(TSA)
library(tseries)
library(forecast)

# 连接数据库 读取数据
mysqlconnection = dbConnect(MySQL(), user = 'root', password = '123456', dbname = 'rdata',
                            host = 'localhost')
dbSendQuery(mysqlconnection,'SET NAMES gbk') 
data <- dbReadTable(mysqlconnection,'data')
# 将日期切分成年月日和时分秒
data <- separate(data = data, col = date_time, into = c("date_ymd", "date_hms"), sep = " ")
# 根据日期进行分组计数
data_Day <- aggregate(data$id, by=list(type=data$date_ymd),length)
# 保存一份训练数据 一份预测数据
dataView <- ts(data_Day[1:166, 2])
dataView1 <- ts(data_Day[1:173, 2])

2、绘制原数据的时序图与自相关图,检验序列的平稳性

# 绘制原数据的时序图和自相关图
# 结果得出原数据为不平稳数据 因此需要进行差分
plot(dataView, xlab = "时间/天", ylab = "访问量")  # 绘制时序图
acf(dataView, lag.max = 200)  # 绘制ACF图
# 检验序列的平稳性 
adf.test(dataView) # p值大于0.05,原数据为不平稳数据
ndiffs(dataView) # 值为1,原数据为不平稳数据

# 一次差分
dataView.diff <- diff(dataView)  # 进行差分
acf(dataView.diff, lag.max = 200)  # 绘制差分后序列的ACF图
# 检验序列的平稳性 
adf.test(dataView.diff) # p值大于0.05,原数据为不平稳数据
ndiffs(dataView.diff) # 值为1,原数据为不平稳数据
# 纯随机性检验
Box.test(dataView.diff, type = "Ljung-Box") # p值小于0.05,差分后的数据为白噪声

r语言建立ar模型实例 r语言arima模型拟合及预测_r语言建立ar模型实例_03

3、通过纯随机性检验,判断序列的价值

# 一次差分
dataView.diff <- diff(dataView)  # 进行差分
acf(dataView.diff, lag.max = 200)  # 绘制差分后序列的ACF图
# 检验序列的平稳性 
adf.test(dataView.diff) # p值大于0.05,原数据为不平稳数据
ndiffs(dataView.diff) # 值为1,原数据为不平稳数据
# 纯随机性检验
Box.test(dataView.diff, type = "Ljung-Box") # p值小于0.05,差分后的数据为白噪声

r语言建立ar模型实例 r语言arima模型拟合及预测_r语言建立ar模型实例_04

4、绘制BIC图进行定价

# 绘制BIC图,根据BIC图定阶
# 原序列定阶
dataView.BIC <- armasubsets(y = dataView, nar = 5, nma = 5)
plot(dataView.BIC)
# 差分后的序列定阶
dataView.diff.BIC <- armasubsets(y = dataView.diff, nar = 5, nma = 5)
plot(dataView.diff.BIC)
# 初始化
checkout <- data.frame(p = 0, d = 0, q = 0, P = 0, D = 0, 
                       Q = 0, "残差P值" = 0, "平均误差" = 0)
test_checkout <- data.frame(p = 0, d = 0, q = 0, P = 0, D = 0, 
                            Q = 0, "残差P值" = 0, "平均误差" = 0)
# 设置行数变量 方便后期根据行号写入数据
j <- 1
# 构造一个方法
# 实现功能:根据训练数据预测结果,根据预测结果计算平均误差,
#          根据平均误差的高低,选出最优模型预测。
test_model <- function(p, q, P, Q){
  model <- Arima(dataView, order = c(p, 0, q),
                 seasonal = list(order = c(P, 1, Q), period = 7))
  result <- Box.test(model$residuals, type = "Ljung-Box")
  # 预测
  data_Day.forecast <- forecast(model, h = 7, level = c(99.5))
  # 计算平均绝对百分误差
  error <- abs(as.numeric(data_Day.forecast[[4]]) - data_Day[167:173,2]) / data_Day[167:173,2]
  # 计算残差P值
  p.value <- round(result$p.value, 4)
  # 输出相关数据
  print(paste('p=', p, ';q=', q, ';P=', P,',Q=', Q, ';残差P值:',
              p.value, ';平均误差:', mean(error), collapse = ""))
  test_checkout[1,1] <- p
  test_checkout[1,2] <- 0
  test_checkout[1,3] <- q
  test_checkout[1,4] <- P
  test_checkout[1,5] <- 1
  test_checkout[1,6] <- Q
  test_checkout[1,7] <- round(result$p.value, 4)
  test_checkout[1,8] <- mean(error) 
  return(test_checkout)
}
# 根据BIC图,自行设定需要计算误差的p,q,P,Q
# 将参数循环传入test_model方法中
for(p in c(0,1,5)){
  for(q in c(1,5)){
    for(P in c(0,4,5)){
      for(Q in c(1)){
        test_checkout <- test_model(p, q, P, Q)
        checkout[j, ] <- test_checkout[1, ]
        j <- j + 1
      }
    }
  }
}
# 将checkout数据保存到本地
write.csv(checkout, "./checkout.csv", row.names = F)  # 导出每个模型的结果

选择平均误差最小的模型进行预测!

r语言建立ar模型实例 r语言arima模型拟合及预测_r语言建立ar模型实例_05

5、预测未来7天的网站访问

# 观察保存的数据,取最优模型预测
model <- Arima(dataView, order = c(1,0,1), 
               seasonal = list(order = c(0,1,1), period = 7))
summary(model)
# 纯随机性检验
Box.test(model$residuals, type = "Ljung-Box") # p值小于0.05,差分后的数据为白噪声
# 用训练数据,预测原数据后7天的访问量
data_Day.forecast <- forecast(model, h = 7, level = c(99.5))
# 计算平均误差
error <- abs(as.numeric(data_Day.forecast[[4]]) - data_Day[167:173,2]) / data_Day[167:173,2]
mean(error)


# 根据最优模型预测,预测未来7天的访问量
model <- Arima(dataView1, order = c(1,0,1), 
               seasonal = list(order = c(0,1,1), period = 7))
summary(model)
# 纯随机性检验
Box.test(model$residuals, type = "Ljung-Box") # p值小于0.05,差分后的数据为白噪声
# 预测未来7天的访问量
data_Day.forecast <- forecast(model, h = 7, level = c(99.5))
# 预测结果展示
plot(data_Day.forecast,shadecols = "oldstyle")

r语言建立ar模型实例 r语言arima模型拟合及预测_r语言建立ar模型实例_06

五、实验结论:

模型选择:
选择平均误差最小的模型进行预测,p,q,P,Q分别为1,1,0,1

预测分析:
从图预测的结果可以看出,在未来7天内,访问量总体的趋势的向上的,但是具体到每日的网站访问量先下降,然后再上升。因此最终得出网站访问量上升趋势且波动较大!