blob: 9292ad5d6255334e6d0ef43110ac1a8f5f0f9441 [file]
#-------------------------------------------------------------
#
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.
#
#-------------------------------------------------------------
# Built-in function for detecting and repairing outliers in time series, by training an ARIMA model
# and classifying values that are more than k standard-deviations away from the predicated values as outliers.
#
# INPUT:
# -------------------------------------------------------------------------------------------
# X Matrix X
# k threshold values 1, 2, 3 for 68%, 95%, 99.7% respectively (3-sigma rule)
# repairMethod values: 0 = delete rows having outliers, 1 = replace outliers as zeros
# 2 = replace outliers as missing values
# p non-seasonal AR order
# d non-seasonal differencing order
# q non-seasonal MA order
# P seasonal AR order
# D seasonal differencing order
# Q seasonal MA order
# s period in terms of number of time-steps
# include_mean If the mean should be included
# solver solver, is either "cg" or "jacobi"
# -------------------------------------------------------------------------------------------
#
# OUTPUT:
# -------------------------------------------------------------------------------------------------
# X_corrected Matrix X with no outliers
# -------------------------------------------------------------------------------------------------
m_outlierByArima = function(Matrix[Double] X, Double k = 3, Integer repairMethod = 1, Integer p=0, Integer d=0,
Integer q=0, Integer P=0, Integer D=0, Integer Q=0, Integer s=1, Boolean include_mean=FALSE, String solver="jacobi")
return(Matrix[Double] X_corrected)
{
outlierFilter = as.matrix(0)
if( k < 1 | k > 7)
stop("outlierBySd: invalid argument - k should be in range 1-7 found "+k)
features = transform_matrix(X,p)
X_adapted = X[p+1:nrow(X),]
# TODO replace by ARIMA once fully supported, LM only emulated the AR part
model = lm(X=features, y=X_adapted)
y_hat = lmPredict(X=features, B=model, ytest=matrix(0,1,1))
upperBound = sd(X) + k * y_hat
lowerBound = sd(X) - k * y_hat
outlierFilter = (X_adapted < lowerBound) | (X_adapted > upperBound)
outlierFilter = rbind(matrix(0.0, rows=p,cols=1), outlierFilter)
X_corrected = fix_outliers(X, outlierFilter, repairMethod)
}
transform_matrix = function(Matrix[Double] X, Integer p) return (Matrix[Double] features){
nrows = nrow(X)
features = matrix(0, rows=nrows-p, cols=1)
for (i in 1:p){
features = cbind(features, X[p+1-i:nrows-i,])
}
features = features[,2:p+1]
}
fix_outliers = function(Matrix[Double] X, Matrix[Double] outlierFilter, Integer repairMethod)
return (Matrix[Double] X_filtered)
{
rows = nrow(X)
cols = ncol(X)
if(repairMethod == 0) {
sel = (outlierFilter == 0)
X = removeEmpty(target = X, margin = "rows", select = sel)
}
else if(repairMethod == 1)
X = (outlierFilter == 0) * X
else if (repairMethod == 2) {
outlierFilter = replace(target = (outlierFilter == 0), pattern = 0, replacement = NaN)
X = outlierFilter * X
}
else{
stop("outlierBySd: invalid argument - repair required 0-1 found: "+repairMethod)
}
X_filtered = X
}