# Confusing Offset in my Support Vector Regression and other Models

I am experiencing a weird offset in my Support Vector Regression prediction (code below).

A brief overview: I have a set of 10 .xls sheets as input data (each with 30 rows and 27 columns), and a 11th .xls sheet that I am using as my testing dataset.

I am working with an electricity dataset, and I am trying to predict the 11th month of electricity usage using the SVR. I am using the code written and released by Luke Benning on Github: https://github.com/lbenning/Load-Forecasting

All of my datasets are structured the same, but when I run the prediction model, I am receiving an offset (as shown in the photo below). The actual data versus the predicted data seem to follow a similar pattern, but the two plots are offset.

Does anyone know of what I may want to explore in order to try and understand the source of this offset? #! /usr/bin/python

import math
import statistics
import visualizer
import numpy as np
from datagen import constructData
from sklearn import svm

# Applies Support Vector Regression to the electricity dataset,
# prints out the accuracy rate to the terminal and plots
# predictions against actual values
def suppVectorRegress():

kernelList = ["linear","rbf",polyKernel]
names = ["linear","radial basis","poly"]
preds = []

# Retrieve time series data & apply preprocessing
data = constructData()

cutoff = len(data)-30
xTrain = data[0:cutoff]
yTrain = data[0:cutoff]
xTest = data[cutoff:]
yTest = data[cutoff:]

# Fill in missing values denoted by zeroes as an average of
# both neighbors
statistics.estimateMissing(xTrain,0.0)
statistics.estimateMissing(xTest,0.0)

# Logarithmically scale the data
xTrain = [[math.log(y) for y in x] for x in xTrain]
xTest = [[math.log(y) for y in x] for x in xTest]
yTrain = [math.log(x) for x in yTrain]

# Detrend the time series
indices = np.arange(len(data))
trainIndices = indices[0:cutoff]
testIndices = indices[cutoff:]
detrended,slope,intercept = statistics.detrend(trainIndices,yTrain)
yTrain = detrended

for gen in range(len(kernelList)):

# Use SVR to predict test observations based upon training observations
pred = svrPredictions(xTrain,yTrain,xTest,kernelList[gen])
# Add the trend back into the predictions
trendedPred = statistics.reapplyTrend(testIndices,pred,slope,intercept)
# Reverse the normalization
trendedPred = [math.exp(x) for x in trendedPred]
# Compute the NRMSE
err = statistics.normRmse(yTest,trendedPred)

print ("The Normalized Root-Mean Square Error is " + str(err) + " using kernel " + names[gen] + "...")

preds.append(trendedPred)

names.append("actual")
preds.append(yTest)

# Change the parameters 2017,2,1 based on the month you want to predict.
visualizer.comparisonPlot(2017,2,1,preds,names,plotName="Support Vector Regression Load Predictions vs. Actual",
yAxisName="Predicted Kilowatts")

# Construct a support vector machine and get predictions
# for the test set
# Returns a 1-d vector of predictions
def svrPredictions(xTrain,yTrain,xTest,k):
clf = svm.SVR(C=2.0,kernel=k)
clf.fit(xTrain,yTrain)
return clf.predict(xTest)

# A scale invariant kernel (note only conditionally semi-definite)
def polyKernel(x,y):
return (np.dot(x,y.T)+1.0)**0.95

if __name__=="__main__":
suppVectorRegress()


I am generating the data as follows:

'''
Functions for retrieving Elia dataset
& forming training/testing datasets
'''

# constructs dataset for simulations
# the last dataset in this file list, is the one used as the training set.
def constructData():
files = ["data/jan_16_elec_scaled.xls", "data/feb_16_elec_scaled.xls",
"data/mar_16_elec_scaled.xls", "data/apr_16_elec_scaled.xls",
"data/may_16_elec_scaled.xls","data/jun_16_elec_scaled.xls",
"data/jul_16_elec_scaled.xls", "data/aug_16_elec_scaled.xls",
"data/sep_16_elec_scaled.xls", "data/oct_16_elec_scaled.xls",
"data/nov_16_elec_scaled.xls"]

#  files = ["data/jan_16_elec_NOscaled.xls", "data/feb_16_elec_NOscaled.xls",
#           "data/mar_16_elec_NOscaled.xls", "data/apr_16_elec_NOscaled.xls",
#           "data/may_16_elec_NOscaled.xls","data/jun_16_elec_NOscaled.xls",
#           "data/jul_16_elec_NOscaled.xls", "data/aug_16_elec_NOscaled.xls",
#           "data/sep_16_elec_NOscaled.xls", "data/oct_16_elec_NOscaled.xls",
#           "data/nov_16_elec_NOscaled.xls"]
return labelSeries(loadSeries(files))

# constructs labelled data from a
# univariate time series
sdef labelSeries(series):
xData = []
yData = []
for x in range(len(series)-1):
xData.append(series[x]) # xData contains all of the items up until the last item
yData.append(np.mean(series[x+1])) # yData is the last item in the list
return (xData,yData)

# arg1 : list of excel spreadsheets filenames
# returns : load univariate time series
def loadSeries(fileList):
# Retrieve time series examples
xData = []
for fileName in fileList:
book = xlrd.open_workbook(fileName)
sheet = book.sheet_by_index(0)
for rx in range(2,sheet.nrows):
row = sheet.row(rx)[3:]
row = [row[x].value for x in range(0,len(row)-4)]
xData.append(row)
return xData


## 1 Answer

See this answer by Xu Cui. The reason, as he stated is simple: the model itself is very simple SVM. He suggests lagging 2 points behind to "improve" and get a more powerful model. Let me know what you think of it. We might be overthinking and he might be on point.

• Based on my code given, do you know how to add this lag? – Gary Mar 22 '17 at 22:32
• Hi @Gary I am not sure whether your data is an matrix or a list. Assuming it is a matrix with the topmost row as the oldest observation then xTrain should be xTrain = xTrain[ 0:-2 , :] , and yTrain[2:,]. the svm can be kept as is. just adjust the training data such that you are calculating Yt in terms of Xt-2. hope this helps. – python novice Mar 23 '17 at 4:57