\chapter{Regularising linear regression for prediction}


\chapter{Operational Semantics of SLCO}
\label{ap:sos-slco}

\input{sos-slco/start}

\input{sos-slco/syntax}

\input{sos-slco/semantics}

\input{sos-slco/initialization}


% JuliaCon proceedings template
\documentclass{juliacon}
\setcounter{page}{1}

\hyphenation{TSMLextra}
\hyphenation{TSML}

\begin{document}

\input{header}

\maketitle

\begin{abstract}

  Over the past years, the industrial sector has seen many innovations brought about by automation.
  Inherent in this automation is the installation of sensor networks for status monitoring and data collection.
  One of the major challenges in these data-rich environments is how to extract and exploit information from
  these large volume of data to detect anomalies, discover patterns to reduce downtimes and manufacturing
  errors, reduce energy usage, predict faults/failures, effective maintenance schedules, etc.
  To address these issues, we developed \textbf{TSML}. Its technology is based
  on using the pipeline of lightweight filters as building blocks to process huge amount of industrial time series data in parallel.

\end{abstract}

\section{Introduction}

\textbf{TSML}\cite{tsml2019} is a \emph{Julia}\cite{bezanson2017julia} package for time series data processing, classification, and prediction.
It provides common API for ML (Machine Learning) libraries from Python's \emph{Scikit-Learn},
R's \emph{Caret}, and native \emph{Julia} MLs for seamless integration of heterogeneous
libraries to create complex ensembles for robust time series prediction, clustering, and classification.
\textbf{TSML} has the following features:
\begin{enumerate}
\item data type clustering/classification for automatic data discovery
\item aggregation based on date/time interval
\item imputation based on symmetric Nearest Neighbors
\item statistical metrics for data quality assessment and classification input features
\item ML wrapper with more than 100+ libraries from caret, scikit-learn, and julia
\item date/value matrix conversion of 1-D time series using sliding windows to generate features for ML prediction
\item pipeline API for high-level description of the processing workflow
\item specific cleaning/normalization workflow based on data type
\item automatic selection of optimised ML model
\item automatic segmentation of time-series data into matrix form for ML training and prediction
\item extensible architecture using just two main interfaces: fit and transform
\item meta-ensembles for automatic feature and model selection
\item support for distributed/threaded computation for scalability and speed
\end{enumerate}

The \textbf{TSML} package assumes a two-column input for any time series data composed of \emph{dates} and \emph{values}. The first part of the workflow aggregates values based on the specified date/time interval which minimizes occurrence of missing values and noise. The aggregated data is then left-joined to the complete sequence of dates in a specified date/time interval. Remaining missing values are replaced by the median/mean or user-defined aggregation function of the \textit{k}-nearest neighbors (\emph{k-NN}) where \textit{k} is the symmetric distance from the location of missing value. This approach can be called several times until there are no more missing values.

\vskip 6pt

For prediction tasks, TSML extracts the date features and
convert the value column into matrix form parameterized by
the size and stride of the sliding window. The final part joins
 the date features and the value matrix to serve as input to the
 ML with the output representing the values of the time periods
 to be predicted ahead of time.

 \vskip 6pt

\textbf{TSML} uses a pipeline which iteratively calls the \texttt{fit!} and \texttt{transform!}
families of functions relying on \emph{multiple dispatch} to dynamically select the correct algorithm from the steps outlined above. Machine learning functions in
\textbf{TSML} are wrappers to the corresponding Scikit-Learn, Caret, and native Julia ML libraries.
There are more than hundreds of classifiers and regression functions available using \textbf{TSML}'s common API.

\section{TSML Workflow}
\label{sec:tsmlworkflow}
%

All major data processing types in \textbf{TSML} are subtypes of the \texttt{Transformer}. There are two major types of transformers, namely: \emph{filters} for data processing and \emph{learners} for machine learning. Both transformers implement the \texttt{fit!} and \texttt{transform!} multi-dispatch functions. All filters are direct subtypes of the \texttt{Transformer} while all learners are subtypes of the \texttt{TSLearner}. The \texttt{TSLearner} is a direct subtype of the \texttt{Transformer}.

\vskip 6pt

Filters are normally used for pre-processing tasks such as imputation, normalization, feature extraction, feature transformation, scaling, etc.
Consequently, filters' \texttt{fit!} and \texttt{transform!} functions expect one argument which represents an input data for feature extraction or transformation. Each data type must implement \texttt{fit!} and \texttt{transform!} although in some cases, only \texttt{transform!} operation is needed. For instance, \emph{square root} or \emph{log} filters do not require any initial computation of parameters to transform their inputs. On the other hand, feature transformations such as scaling, normalization, PCA, ICA, etc. require initial computation of certain parameters in their input before applying the transformation to new datasets. In these cases, initial computations of these parameters are performed by the \texttt{fit!} function while their applications to new datasets are done by the \texttt{transform!} function.

\vskip 6pt

Learners, on the other hand, expect two arguments (input vs output) and require training cycle to optimize their parameters for optimal \emph{input--output} mapping. The training part is handled by the \texttt{fit!} function while the prediction part is handled by the \texttt{transform!} function.

\vskip 6pt

The \textbf{TSML} workflow borrows the idea of the  \emph{Unix} pipeline\cite{orchestra2014, combineml2016}.
The \texttt{Pipeline} data type is also a subtype of the \texttt{Transformer} and expects two arguments: input and output. The main elements in a \textbf{TSML} pipeline are series of transformers with each performing one specific task and does it well. The series of filters are used to perform pre-processing of the input while a machine learner at the end of the pipeline is used to learn the \emph{input--output} mapping. From the perspective of using the \texttt{Pipeline} where the last component is a machine learner, the \texttt{fit!} function is the training phase while the \texttt{transform!} function is the prediction or classification phase.
\vskip 6pt

The \texttt{fit!} function in the \texttt{Pipeline} iteratively calls the \texttt{fit!} and \texttt{transform!} functions in a series of transformers. If the last transformer in the pipeline is a learner, the last transformed output from a series of filters will be used as input features for the \texttt{fit!} or training phase of the said learner.

\vskip 6pt

During the prediction task, the \texttt{transform!} function in the \texttt{Pipeline} iteratively calls the \texttt{transform!} operations in each filter and learner. The transform operation is direct application of the parameters computed during normalization, scaling, training, etc. to the new data. If the last element in the pipeline during transform is a learner, it performs prediction or classification. Otherwise, the transform operation acts as a feature extractor if they are composed of filters only.

\vskip 6pt
To illustrate, below describes the main steps in using the \textbf{TSML}.
First, we create filters for csv reading, aggregation, imputation, and data quality
assessment.

\begin{lstlisting}[language = Julia]
fname = joinpath(dirname(pathof(TSML)),
  "../data/testdata.csv")
csvfilter = CSVDateValReader(Dict(
  :filename=>fname,
  :dateformat=>"dd/mm/yyyy HH:MM"))
valgator = DateValgator(Dict(
  :dateinterval=>Dates.Hour(1)))
valnner = DateValNNer(Dict(
  :dateinterval=>Dates.Hour(1)))
stfier = Statifier(Dict(:processmissing=>true))
\end{lstlisting}

We can then setup a pipeline containing these filters to process the csv data
by aggregating the time series hourly and check the data quality using the
\texttt{Statifier} filter (Fig.~\ref{fig:dataquality}).

\begin{lstlisting}[language = Julia]
apipeline = Pipeline(Dict(
  :transformers => [csvfilter, valgator, stfier]))
fit!(apipeline)
mystats = transform!(apipeline)
@show mystats
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{stat1.png} % requires the graphicx package
   \vskip 2pt
      \includegraphics[width=\columnwidth]{stat2.png} % requires the graphicx package
   \caption{Data Quality Statistics. Column names starting with `b` refer to statistics of contiguous blocks of missing data.}
   \label{fig:dataquality}
\end{figure}

A mentioned previously, the \texttt{fit!} and \texttt{transform!} in the pipeline
iteratively calls the corresponding \texttt{fit!} and \texttt{transform!} within each filter.
This common API relying on \emph{Julia's} multi-dispatch mechanism greatly simplifies the implementations, operations,
and understanding of the entire workflow. In addition, extending \textbf{TSML} functionality is just a
matter of creating a new data type filter and define its own  \texttt{fit!} and \texttt{transform!}
functions.

\vskip 6pt

In the \texttt{Statifier} filter result, blocks of missing data is indicated by column names starting
with \emph{b}. Running the code indicates that there are plenty of missing data blocks.
We can add the \texttt{ValNNer} filter to perform \emph{k}-nearest neighbour (\emph{k-NN}) imputation and check
the statistics (Fig.~\ref{fig:imputation}):

\begin{lstlisting}[language = Julia]
bpipeline = Pipeline(Dict(
  :transformers => [csvfilter, valgator,
                    valnner,stfier]))
fit!(bpipeline)
imputed = transform!(bpipeline)
@show imputed
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{imputed1.png} % requires the graphicx package
   \vskip 2pt
      \includegraphics[width=\columnwidth]{imputed2.png} % requires the graphicx package
   \caption{Statistics after Imputation. All statistics for blocks of missing data indicate NaN to indicate the stats of empty set. This implies that all missing blocks are imputed.}
   \label{fig:imputation}
\end{figure}

The result in Fig.~\ref{fig:imputation} indicates \emph{NaN} for all missing data statistics column because the set
of missing blocks count is now empty.

\vskip 6pt

We can also visualise our time series data using the \texttt{Plotter} filter instead of the \texttt{Statifier} as shown in Fig~\ref{fig:mplot}. Looking closely, you will see discontinuities in the plot due to blocks of missing data.

\begin{lstlisting}[language = Julia]
pltr=Plotter(Dict(:interactive => true))
plpipeline = Pipeline(Dict(
  :transformers => [csvfilter, valgator, pltr]))
fit!(plpipeline)
transform!(plpipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{mplot.png} % requires the graphicx package
   \caption{Plot with Missing Data}
   \label{fig:mplot}
\end{figure}

Using the imputation pipeline described before, we can visualise the result by replacing the \texttt{Statifier} with the \texttt{Plotter} filter. Figure~\ref{fig:amplot} shows the plot after imputation which gets rid of missing data.

\begin{lstlisting}[language = Julia]
bplpipeline = Pipeline(Dict(
  :transformers => [csvfilter, valgator,
                    valnner,pltr]))
fit!(bplpipeline)
transform!(bplpipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{amplot.png} % requires the graphicx package
   \caption{Plot after Data Imputation}
   \label{fig:amplot}
\end{figure}

\subsection{Processing Monotonic Time Series}
This subsection dicusses additional filters to handle monotonic data which are commonly employed in energy/water meter and footfall sensors. In the former case, the time series type is strictly monotonically increasing while in the latter case, the monotonicity happens daily. We use the filter called \texttt{Monotonicer} which automatically detects these two types of monotonic sensors and apply the normalisation accordingly.

\begin{lstlisting}[language = Julia]
mono = joinpath(dirname(pathof(TSML)),
  "../data/typedetection/monotonic.csv")
monocsv = CSVDateValReader(Dict(:filename=>mono,
  :dateformat=>"dd/mm/yyyy HH:MM"))
\end{lstlisting}

Let us plot in Fig.~\ref{fig:mono} the monotonic data with the usual workflow of aggregating and imputing the data first.

\begin{lstlisting}[language = Julia]
monopipeline = Pipeline(Dict(
  :transformers => [monofilecsv,valgator,
                    valnner,pltr]))
fit!(monopipeline)
transform!(monopipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=0.9\columnwidth]{mono.png} % requires the graphicx package
   \caption{Monotonic Time Series}
   \label{fig:mono}
\end{figure}

Let us now normalise using \texttt{Monotonicer} and show the plot in Fig.~\ref{fig:nmono}.

\begin{lstlisting}[language = Julia]
mononicer = Monotonicer(Dict())
monopipeline = Pipeline(Dict(
  :transformers => [monofilecsv,valgator,valnner,
                    mononicer, pltr]))
fit!(monopipeline)
transform!(monopipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{mononicer.png} % requires the graphicx package
   \caption{Normalized Monotonic Time Series}
   \label{fig:nmono}
\end{figure}

The presence of outlier due to some random errors during meter reading  becomes obvious after the normalisation. To remedy this issue, we add the \texttt{Outliernicer} filter which detects outliers and replace them  using the \emph{k-NN} imputation technique used by the \texttt{DateValNNer} filter (Fig.~\ref{fig:outnicer}).

\begin{lstlisting}[language = Julia]
outliernicer = Outliernicer(
       Dict(:dateinterval=>Dates.Hour(1)))
monopipeline = Pipeline(Dict(
  :transformers => [monofilecsv,valgator,valnner,
                    mononicer,outliernicer,pltr]))
fit!(monopipeline)
transform!(monopipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{outnicer.png} % requires the graphicx package
   \caption{Normalized Monotonic Time Series With Outlier Removal Filter}
   \label{fig:outnicer}
\end{figure}

\subsection{Processing Daily Monotonic Time Series}
We follow similar workflow in the previous subsection to normalize daily monotonic time series. First, let us visualize the original data after aggregation and imputation (Fig.~\ref{fig:dailymono}).

\begin{lstlisting}[language = Julia]
dailymono = joinpath(dirname(pathof(TSML)),
     "../data/type-detection/dailymonotonic.csv")
dailymonocsv = CSVDateValReader(Dict(
     :filename=>dailymono,
     :dateformat=>"dd/mm/yyyy HH:MM"))
dailymonopipeline = Pipeline(Dict(
  :transformers => [dailymonocsv,valgator,
                    valnner,pltr]))
fit!(dailymonopipeline)
transform!(dailymonopipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{dailymono.png} % requires the graphicx package
   \caption{Daily Monotonic Time Series}
   \label{fig:dailymono}
\end{figure}

\vskip 6pt

Then, we reuse the \texttt{Monotonicer} filter in the previous subsection to normalise the data and plot (Fig.~\ref{fig:ndailymono}).

\begin{lstlisting}[language = Julia]
dailymonopipeline = Pipeline(Dict(
  :transformers => [dailymonocsv,valgator,
                    valnner,mononicer,pltr]))
fit!(dailymonopipeline)
transform!(dailymonopipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{normdailymono.png}  % requires the graphicx package
   \caption{Normalized Daily Monotonic Time Series}
   \label{fig:ndailymono}
\end{figure}

To remove outliers, we can reuse the \texttt{Outliernicer} filter in the previous subsection and plot the cleaned data (Fig.~\ref{fig:outndailymono}).

\begin{lstlisting}[language = Julia]
dailymonopipeline = Pipeline(Dict(
  :transformers=>[dailymonocsv,valgator,valnner,
                  mononicer,outliernicer,pltr]))
fit!(dailymonopipeline)
transform!(dailymonopipeline)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=\columnwidth]{outnormdailymono.png}  % requires the graphicx package
   \caption{Normalized Daily Monotonic Time Series with Outlier Detector}
   \label{fig:outndailymono}
\end{figure}

\section{Time Series Classification}

We can use the knowledge we learned in setting up the \textbf{TSML}
\emph{pipeline} containing \emph{filters} and \emph{machine learners} to build higher level
operations to solve a specific industrial problem. One major problem
which we consider relevant because it is a common issue in IOT (Internet of Things)
 is the time series classification. This problem is prevalent nowadays
due to the increasing need to use many sensors to monitor status in different aspects of industrial
operations and maintenance of cars, buildings, hospitals, supermarkets, homes, and cities.

\vskip 6pt

Rapid deployment of these sensors result to many of them not properly labeled or classified.
Time series classification is a significant first step for optimal prediction and anomaly detection.
Identifying the correct sensor data types can help in the choice of what the most optimal prediction
model to use for actuation or pre-emption to minimise wastage in resource utilisation.
To successfully perform the latter operations, it is necessary to identify first the time series
type so that appropriate model and cleaning routines can be selected for optimal model performance. The  \texttt{TSClassifier} filter aims to address this problem and its usage is described below.

\vskip 6pt

First, we setup the locations of files for training, testing, and saving the model.
Next, we start the training phase by calling \texttt{fit!} which loads
file in the training directory and learn the mapping between their
statistic features extracted by \texttt{Statifier} with their types indicated
by a substring in their filenames. Once the training is done, the final model
is saved in the \emph{model} directory which will be used for
testing accuracy and classifying new time series datasets.

\vskip 6pt

The code below initialises the \texttt{TSClassifier} with the locations of the \emph{training}, \emph{testing}, and \emph{model} repository. Training is carried out by the \texttt{fit!} function which extracts the stat features of the training data and save them as a \emph{dataframe}  to be processed by the \emph{RandomForest} classifier. The trained model is saved in the \emph{model} directory and used during testing.

\begin{lstlisting}[language = Julia]
trdirname = joinpath(dirname(pathof(TSML)),
     "../data/realdatatsclassification/training")
tstdirname = joinpath(dirname(pathof(TSML)),
     "../data/realdatatsclassification/testing")
modeldirname = joinpath(dirname(pathof(TSML)),
     "../data/realdatatsclassification/model")
tscl = TSClassifier(Dict(
  :trdirectory=>trdirname,
  :tstdirectory=>tstdirname,
  :modeldirectory=>modeldirname,
  :num_trees=>75)
)
fit!(tscl)
predictions = transform!(tscl)
@show testingAccuracy(predictions)
\end{lstlisting}

Figure~\ref{fig:tcl} shows: a) a snapshot of the output during training and testing which extracts the statistical features of the time series; and b) the testing performance of the classifier. The training and testing data are labeled based on their sensor type for easier validation. The labels are not used as input during training. The classification workflow is purely driven by the statistical features. The prediction indicates 80\% accuracy.

\begin{figure}[htbp]
   \centering
   \includegraphics[width=0.5\columnwidth]{tscl1.png} % requires the graphicx package

   ..........

   ..........
   \vskip 2pt
   \includegraphics[width=0.4\columnwidth]{tscl2.png} % requires the graphicx package
   \caption{Extraction of Statistical Features for Training and Prediction. By convention, the \texttt{TSClassifier} validates the ground truth based on the filename which contains the label of the sensor type disregarding the numerical component.}
   \label{fig:tcl}
\end{figure}

\section{Extending TSML with Scikit-Learn and Caret}
In the latest \textbf{TSML} version (2.3.4 and above),
we refactored the base \textbf{TSML}
to only include pure \emph{Julia} code implementations and moved the external libs and binary dependencies into the \textbf{TSMLextra} package.
One major reason is to have a smaller code base so that it can be easily
maintained and rapidly deployed in a dockerized solution for \emph{Kubernetes} or IBM's \emph{OpenShift} cluster. Moreover, smaller codes make
static compilation fast for smaller docker image
in cloud deployment.

\vskip 6pt

There are cases where the main task of time series classification
requires more complex ensemble model using hierarchy or tree structure where
members are composed of heterogeneous ML learners derived from binaries in
different languages. For illustration purposes, we will show how to
ensemble ML libraries from \emph{Scikit-Learn} and \emph{Caret} using \textbf{TSML} meta-ensembles that support the  \texttt{fit!} and \texttt{transform!} APIs.

\subsection{Parallel TSML Using Distributed Workflow}

We will use \emph{Julia's} built-in support for parallelism by using the \emph{Distributed} standard library. We also let \emph{Julia} detect the number of processors available and activate them using the following statements:

\begin{lstlisting}[language = Julia]
using Distributed
nprocs() == 1 && addprocs()
\end{lstlisting}

With several workers active, we use the \emph{@everywhere} macro to load the necessary filters and transformers to all workers.

\begin{lstlisting}[language = Julia]
@everywhere using TSML
@everywhere using TSMLextra
@everywhere using DataFrames
@everywhere using Random
@everywhere using Statistics
@everywhere using StatsBase: iqr
@everywhere using RDatasets
\end{lstlisting}

With all the necessary \textbf{TSML} functions loaded, we can now setup the different MLs starting with some learners from \emph{Caret} and \emph{Scikit-Learn}. The list is not exhaustive for demonstration purposes.

\begin{lstlisting}[language = Julia]
# Caret ML
@everywhere caret_svmlinear =
   CaretLearner(Dict(:learner=>"svmLinear"))
@everywhere caret_treebag =
   CaretLearner(Dict(:learner=>"treebag"))

# Scikit-Learn ML
@everywhere sk_knn =
  SKLearner(Dict(:learner=>"KNeighborsClassifier"))
@everywhere sk_gb =
  SKLearner(Dict(:learner=>
    "GradientBoostingClassifier",
    :impl_args=>Dict(:n_estimators=>10)))
@everywhere sk_extratree =
  SKLearner(Dict(:learner=>"ExtraTreesClassifier",
    :impl_args=>Dict(:n_estimators=>10)))
@everywhere sk_rf =
  SKLearner(Dict(:learner=>
    "RandomForestClassifier",
    :impl_args=>Dict(:n_estimators=>10)))
\end{lstlisting}

Let us setup ML instances from a pure \emph{Julia} implementation of learners and ensembles wrapped from the \emph{DecisionTree.jl} package \cite{decisiontree2008,orchestra2014,combineml2016,tsmlextra2019}.

\begin{lstlisting}[language = Julia]
# Julia ML
@everywhere jrf = RandomForest()
@everywhere jpt = PrunedTree()
@everywhere jada = Adaboost()

# Julia Ensembles
@everywhere jvote_ens=VoteEnsemble(Dict(
   :learners=>[jrf,jpt,sk_gb,sk_extratree,sk_rf]))
@everywhere jstack_ens=StackEnsemble(Dict(
   :learners=>[jrf,jpt,sk_gb,sk_extratree,sk_rf]))
@everywhere jbest_ens=BestLearner(Dict(
   :learners=>[jrf,sk_gb,sk_rf]))
@everywhere jsuper_ens=VoteEnsemble(Dict(
   :learners=>[jvote_ens,jstack_ens,
               jbest_ens,sk_rf,sk_gb]))
\end{lstlisting}

Next, we setup the pipeline for training and prediction.

\begin{lstlisting}[language = Julia]
@everywhere function predict(learner,
            data,train_ind,test_ind)
  features = convert(Matrix,data[:, 1:(end-1)])
  labels = convert(Array,data[:, end])
  # Create pipeline
  pipeline = Pipeline(
    Dict(
      :transformers => [
        OneHotEncoder(), # nominal to bits
        Imputer(), # Imputes NA values
        StandardScaler(), # normalize
        learner # Predicts labels on instances
      ]
    )
  )
  # Train
  fit!(pipeline, features[train_ind, :],
       labels[train_ind])
  # Predict
  predictions = transform!(pipeline,
      features[test_ind, :])
  # Assess predictions
  result = score(:accuracy,
      labels[test_ind], predictions)
  return result
end
\end{lstlisting}

Finally, we setup the \texttt{parallelmodel} function to run different learners distributed to different workers running in parallel relying on \emph{Julia's} native support of parallelism. Take note that there are two parallelisms in the code. The first one is the distribution of task in different trials and the second one is the distribution of tasks among different models for each trial. It is interesting to note that with this relative compact function definition, the \emph{Julia} language makes it easy to define a parallel task within another parallel task
in a straightforward manner without any problem.

\begin{lstlisting}[language = Julia]
function parallelmodel(learners::Dict,
         data::DataFrame;trials=5)
  models=collect(keys(learners))
  ctable=@distributed (vcat) for i=1:trials
    # Split into training and test sets
    Random.seed!(3i)
    (trndx, tstndx) = holdout(size(data, 1), 0.20)
    acc=@distributed (vcat) for model in models
      res=predict(learners[model],
             data,trndx,tstndx)
      println("trial ",i,", ",model," => ",
              round(res))
      [model res i]
    end
    acc
  end
  df = ctable |> DataFrame
  rename!(df,:x1=>:model,:x2=>:acc,:x3=>:trial)
  gp=by(df,:model) do x
    DataFrame(mean=mean(x.acc),std=std(x.acc),
              n=length(x.acc))
  end
  sort!(gp,:mean,rev=true)
  return gp
end
\end{lstlisting}

We benchmark the performance of the different machine learners by creating a dictionary of workers containing instances of learners from \emph{Caret}, \emph{Scikit-Learn}, and \emph{Julia} libraries. We pass the dictionary of learners to the \texttt{parallelmodel} function for evaluation.

\begin{lstlisting}[language = Julia]
learners=Dict(
  :jvote_ens=>jvote_ens,:jstack_ens=>jstack_ens,
  :jbest_ens=>jbest_ens,:jrf=>jrf,:jada=>jada,
  :jsuper_ens=>jsuper_ens,
  :crt_svmlinear=>caret_svmlinear,
  :crt_treebag=>caret_treebag,
  :skl_knn=>sk_knn,:skl_gb=>sk_gb,
  :skl_extratree=>sk_extratree, :sk_rf=>sk_rf
)

datadir = joinpath("tsdata/")
tsdata = extract_features_from_timeseries(datadir)
first(tsdata,5)

respar = parallelmodel(learners,tsdata;trials=3)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=0.8\columnwidth]{sim.png} % requires the graphicx package
   \caption{Output During Training with Several Workers}
   \label{fig:sim}
\end{figure}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=0.6\columnwidth]{results.png} % requires the graphicx package
   \caption{@distributed: Classification Performance in 3 Trials}
   \label{fig:performance}
\end{figure}

The data used in the experiment are sample snapshots of the data in our building operations. For reproducibility, the data can be found in the  \emph{juliacon2019-paper} branch of \textbf{TSML} in \emph{Github}:  /data/benchmark/tsclassifier. There are four time series types, namely: AirOffTemp, Energy, Pressure, and RetTemp.  We  took a minimal number of samples and classes for the sake of discussion and demonstration purposes in this paper.

\vskip 6pt

Figures~\ref{fig:sim}~and~\ref{fig:performance}  show a snapshot of running workers exploiting the distributed library of \emph{Julia} and the classification performance of each model, respectively. There are 8 workers running in parallel over 12 different machine learning classifiers.

\vskip 6pt

From the results, \emph{ExtraTree} from \emph{Scikit-Learn} has the best performance with 91.67\% accuracy followed by \emph{TreeBag} and \emph{SVMLinear} from \emph{Caret} library with 83.33 \% accuracy for both. With this workflow, it becomes trivial to search for optimal model by running them in parallel relying on \emph{Julia} to do the low-level tasks of scheduling and queueing as well as making sure that  the dynamically available compute resources such as cpu cores and memory resources are fairly optimised.

\subsection{Parallel TSML Using Threads Workflow}
With \emph{Julia} 1.3, lightweight multi-threading support in \emph{Julia} becomes possible. We will be using the pure \emph{Julia}-written ML models because installing external dependencies such as \emph{Caret} MLs through \emph{RCall} package has some issues with the alpha version of \emph{Julia} 1.3 at this point in time. We will update this documentation and add more MLs once the issues are resolved.

\vskip 6pt

The main difference in the workflow between \emph{Julia's} distributed computation model compared to the threaded model is the presence of \texttt{@everywhere} macro in the former for each function defined to indicate that these function definitions shall be exported to all running workers. Since threaded processes share the same memory model with the \emph{Julia} main process, there is no need for this macro. Instead, threading workflow requires the use of \emph{ReentrantLock} in the update of the global dataframe that accumulates the prediction performance of models running in their respective threads. In similar observation with the distributed framework, the \texttt{threadedmodel} function contains two parallelism: threads in different trials and threads among models in each trial. The function is surprisingly compact to implement threads within threads without issues and the main bottleneck happens only during the update operation of the global \emph{ctable} dataframe.

\begin{lstlisting}[language = Julia]
function threadedmodel(learners::Dict,
         data::DataFrame;trials=5)
  Random.seed!(3)
  models=collect(keys(learners))
  global ctable = DataFrame()
  @threads for i=1:trials
     # Split into training and test sets
     (train_ind, test_ind) =
          holdout(size(data, 1), 0.20)
     mtx = SpinLock()
     @threads for themodel in models
       res=predict(learners[themodel],
          data,train_ind,test_ind)
       println(themodel," => ",round(res),",
          thread=",threadid())
       lock(mtx)
       global ctable=vcat(ctable,
          DataFrame(model=themodel, acc=res))
       unlock(mtx)
     end
  end
    df = ctable |> DataFrame
    gp=by(df,:model) do x
       DataFrame(mean=mean(x.acc),
          std=std(x.acc),n=nrow(x))
    end
    sort!(gp,:mean,rev=true)
    return gp
end
\end{lstlisting}

Let us define a set of learners that are written in pure \emph{Julia} for this thread experiment.

\begin{lstlisting}[language = Julia]
# Julia ML
jrf = RandomForest(Dict(:impl_args=>
   Dict(:num_trees=>500)))
jpt = PrunedTree()
jada = Adaboost(Dict(:impl_args=>
   Dict(:num_iterations=>20)))

## Julia Ensembles
jvote_ens=VoteEnsemble(Dict(:learners=>
   [jrf,jpt,jada]))
jstack_ens=StackEnsemble(Dict(:learners=>
   [jrf,jpt,jada]))
jbest_ens=BestLearner(Dict(:learners=>
   [jrf,jpt,jada]))
jsuper_ens=VoteEnsemble(Dict(:learners=>
   [jvote_ens,jstack_ens,jbest_ens]));
\end{lstlisting}

Let us run in parallel the different models using the same dataset with that of the distributed workflow.

\begin{lstlisting}[language = Julia]
using Base.Threads

learners=Dict(
      :jvote_ens=>jvote_ens,
      :jstack_ens=>jstack_ens,
      :jbest_ens=>jbest_ens,
      :jrf => jrf,:jada=>jada,
      :jsuper_ens=>jsuper_ens);

datadir = joinpath("tsdata/")
tsdata = extract_features_from_timeseries(datadir)

resthr = threadedmodel(learners,tsdata;trials=10)
\end{lstlisting}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=0.5\columnwidth]{threadrunning.png} % requires the graphicx package
   \caption{Output During Training Using Several Threads}
   \label{fig:threadrunning}
\end{figure}

\begin{figure}[htbp]
   \centering
   \includegraphics[width=0.5\columnwidth]{threadresult.png} % requires the graphicx package
   \caption{@threads: Classification Performance in 10 Trials}
   \label{fig:threadresult}
\end{figure}

Figures~\ref{fig:threadrunning}~and~\ref{fig:threadresult} show example snapshot of the running threads and the final result of classification, respectively. In this experiment, Adaboost has 85.0\% accuracy followed by Random Forest with 82.5\% accuracy.

\section{Applications Using Public IoT Datasets}

This section summarizes the results of applying the TSML workflow for classification tasks using data in this site:
\emph{http://www.timeseriesclassification.com/}. Among the hundreds of datasets available, we handpicked
only 4 datasets, namely: ElectricDevices, RefrigerationDevices, FordB, and Earthquakes.

\vskip 6pt

ElectricDevices dataset covers 251 households, sampled in 2-minute intervals over a month. The target is to collect
how consumers use electricity within the home based on the devices they use at a particular time of the day.  The dataset
is highly imbalanced with the following total count in each class, repectively: 1394, 4187, 1606, 2639, 4275, 1252, 1284. This dataset is a good test on the robustness of the classifier to handle bias during training. The class distribution in training is consist of: 727, 2231, 851, 1471, 2406, 509, 728. For testing, the class distribution is: 667, 1956,  755, 1165, 1869,  743,  556. Using this highly imbalanced dataset is a good way to determine which among the classifiers has the best method to deal with this sampling bias. There are 96 input features and 6 output classes in a total of 16637  samples.

\vskip 6pt

RefrigerationDevices dataset is based on similar study with that of ElectricalDevices dataset. The dataset uses the same set of households and sampling protocol for gathering electric consumption data from three types of refrigeration devices: Fridge/Freezer, Refrigerator, Upright Freezer. Unlike in ElectricDevices, the class distribution in RefrigerationDevices are balanced, i.e., 250 for each class in training and 125 for each class during testing. There are 720 input features and 3 output classes in a total of
750 samples.

\vskip 6pt

The Earthquakes classification problem requires predicting whether a major event is about to occur based on the most recent readings in the surrounding area. The data is aggregated hourly with the Rictor scale reading over 5 indicating a  major event. There are 368 negative cases versus 93 positive cases of major events. This dataset is highly imbalanced in class distribution which makes predicting whether a major event occurs very problematic. The training set is composed of 264 negative examples and only 58 positive examples. The testing data is composed of 104 negative cases and only 35 positive cases.
There are 512 input features and 2 output classes in a total of 461 samples. The highly imbalanced distribution of this dataset will provide a good way to determine which among the classifiers are robust to deal with this bias.

\vskip 6pt

FordB dataset is a classification problem to diagnose whether a certain symptom exists in an automative system. There are 500 measurements of engine noise. The training data were collected in typical operating conditions while the test data were collected under noisy conditions. The dataset is slightly imbalanced consisting of 1860 class1 vs 1776 class2 in training while 401 class1 and 409 class2 in testing. There are 500 input features and 2 output classes in a total of 4446 samples.

\vskip 6pt

\begin{table}
\tbl{Classification Problems}{
\begin{tabular}{|r|c|c|c|}\hline
\textbf{Problem} & \textbf{Classes} & \textbf{Imbalance} & \textbf{Dimension}\\\hline
Electric Devices & 6 & Y & 16637 x 96\\\hline
Refrigeration Devices & 3 & N & 750 x 720\\\hline
Earthquakes & 2 & Y & 461 x 512\\\hline
FordB & 2 & N & 4446 x 500 \\\hline
\end{tabular}}
\label{tab:balance}
\end{table}

Table~\ref{tab:balance} summarizes the differences and similarities among the different classification problems under consideration. Two of the problems have highly imbalanced dataset, namely: Electric Devices and Earthquakes. Both FordB and Refrigeration Devices have no or slightly less imbalanced data.

\vskip 6pt

One thing to note is that the Refrigeration dataset has almost the same number of features with its total number of samples. We expect that this will result into a much harder classification problem eventhough it does not suffer from imbalanced class distribution. Ideally, there must be more samples than features in order for the classifier to properly extract the correct subset of features for robust classification.

\subsection{Results}

\begin{table}
\tbl{Electric Devices}{
\begin{tabular}{|r|c|c|c|}\hline
\textbf{Model} & \textbf{MeanFscore} & \textbf{Std} & \textbf{Trials}\\\hline
c-rf & 0.56 & 0.00 & 10\\\hline
c-treebag & 0.54 & 0.01 & 10\\\hline
s-extratree & 0.52 & 0.01 & 10\\\hline
j-vote & 0.51 & 0.01 & 10 \\\hline
j-rf & 0.51 & 0.01 & 10 \\\hline
... & ... & ... & ...\\\hline
\end{tabular}}
\label{tab:elec}
\end{table}

\begin{table}
\tbl{Refrigeration Devices}{
\begin{tabular}{|r|c|c|c|}\hline
\textbf{Model} & \textbf{MeanFscore} & \textbf{Std} & \textbf{Trials}\\\hline
s-gb & 0.51 & 0.00 & 10\\\hline
c-rf & 0.51 & 0.01 & 10\\\hline
c-treebag & 0.50 & 0.01 & 10\\\hline
j-super & 0.50 & 0.02 & 10 \\\hline
s-rf & 0.48 & 0.03 & 10 \\\hline
... & ... & ... & ...\\\hline
\end{tabular}}
\label{tab:ref}
\end{table}

\begin{table}
\tbl{Earthquakes}{
\begin{tabular}{|r|c|c|c|}\hline
\textbf{Model} & \textbf{MeanFscore} & \textbf{Std} & \textbf{Trials}\\\hline
c-treebag & 0.86 & 0.01 & 10\\\hline
c-rf & 0.86 & 0.00 & 10\\\hline
c-rpart & 0.86 & 0.00 & 10\\\hline
s-extratree & 0.85 & 0.01 & 10 \\\hline
s-gb & 0.85 & 0.00 & 10 \\\hline
... & ... & ... & ...\\\hline
\end{tabular}}
\label{tab:earth}
\end{table}

\begin{table}
\tbl{FordB}{
\begin{tabular}{|r|c|c|c|}\hline
\textbf{Model} & \textbf{MeanFscore} & \textbf{Std} & \textbf{Trials}\\\hline
c-rf & 0.66 & 0.01 & 10\\\hline
s-knn & 0.62 & 0.00 & 10\\\hline
j-vote & 0.61 & 0.01 & 10\\\hline
j-rf & 0.61 & 0.01 & 10 \\\hline
j-super & 0.60 & 0.03 & 10 \\\hline
... & ... & ... & ...\\\hline
\end{tabular}}
\label{tab:fordb}
\end{table}

Due to the data imbalance, the typical accuracy measurement will not be able to capture the performance of the algorithms because its value may be overshadowed by the dominant class. In this regard, we use F-score to measure the performance of a given classifier to each of its classes and get the mean of these F-scores.

\vskip 6pt

Table~\ref{tab:elec} shows the top 5 performing classifiers together with the 2 worst performing classifiers. The first letter of each classifier's name indicates whether the classifier comes from (c)aret, (s)cikitLearn, or (j)ulia. The table indicates that \emph{Random Forest} and \emph{TreeBag} from \emph{Caret} performed the best followed by \emph{ExtraTree} of \emph{ScikitLearn}. Julia's \emph{Vote} ensemble and \emph{Random Forest} complete the top 5. On the other hand, Julia's \emph{Adaboost} and Caret's \emph{RPart} are the worst classifiers for this problem.

\vskip 6pt

Using similar naming convention, Table~\ref{tab:ref} indicates that \emph{GradientBoost} from \emph{ScikitLearn} and \emph{Random Forest} from \emph{Caret} are the best classifiers for the Refrigeration Devices problem. The two worst algorithms are the same as in Table~\ref{tab:elec}.

\vskip 6pt

For Earthquakes classification problem (Table~\ref{tab:earth}), the top 3 best classifiers are dominated by those from \emph{Caret} library, namely: \emph{TreeBag}, \emph{Random Forest}, and \emph{RPart}. The worst performers are from \emph{Caret's} \emph{SVMLinear} and \emph{Julia's} \emph{PartitionTree}.

\vskip 6pt

For the FordB dataset (Table~\ref{tab:fordb}), the best performers are: \emph{Random Forest} from \emph{Caret}, \emph{k-NN} from \emph{ScikitLearn}, and \emph{Vote Ensemble} from \emph{Julia}. The worst performers are similar to Tables~\ref{tab:elec}~and~\ref{tab:ref}.

\subsection{Discussion}
Comparing the performances of different classifiers among the four problems indicate that the most difficult problem to classify is the Refrigeration Devices while the easiest one is the Earthquakes problem. As we expected, there is no enough sample for the classifiers to learn the mapping in Refrigeration dataset relative to its feature dimension. One way to alleviate this problem is to remove features that are highly correlated or perform PCA to reduce the feature dimension. This is beyond the scope of the current paper which focuses mainly on the applicability of TSML MLs to different set of problems.

\vskip 6pt

Among the classifiers, the \emph{Random Forest} from \emph{Caret} is the top performer in all problems. On the other hand, \emph{TreeBag} from \emph{Caret} and \emph{Gradient Boosting} from \emph{ScikitLearn} are the top performers in Refrigeration Devices and Earthquakes, respectively. It is interesting to note that among the \emph{Random Forest} implementations, the top performer is the \emph{Caret's} version written by Breiman\cite{Breiman2001} who was the original author of the said algorithm in \emph{Fortran}. The superior performance of Breiman's \emph{Random Forest} can be highlighted in the FordB classification performance.  \emph{k}NN, the next best classifier is 4\% lower than Breiman's \emph{Random Forest}. In all other cases, the next best performer has almost same performance with  Breiman's \emph{Random Forest}.

\vskip 6pt

As we expected based on past studies, the different ensemble models dominated the top 5 performers. While not shown in the table, the most consistent worst performer is the \emph{Caret's} \emph{RPart}. This is consistent to Breiman's observation that \emph{Random Forest} performs well by using unstable or inferior ML models in its leaves. In \emph{Caret's} \emph{Random Forest}, the leaves are composed of \emph{RPart} models which has the poorest performance in all problems. The combination of boosting and bagging weak learners such as \emph{RPart} make the \emph{Random Forest} robust from datasets imbalances.

\section{Summary and Conclusion}
Packages for time series analysis are becoming important tools with the rapid proliferation of sensor data brought about by \textbf{IoT}.  We created \textbf{TSML} as a time series machine learning framework which can easily be extended to handle large volume of time series data.
\textbf{TSML}  exploits the following \emph{Julia} features: multiple dispatch, type inference, custom data types and abstraction, and parallel computations.

\vskip 6pt

\textbf{TSML} main strength is the adoption of \emph{UNIX} pipeline architecture containing filters and machine learners to perform both preprocessing and modelling tasks.  In addition, \textbf{TSML} uses a common machine learning API for both internal and external ML libraries, distributed and threaded support for modeling, and a growing collection of filters for preprocessing, classification, clustering, and prediction.

\vskip 6pt

Extending \textbf{TSML} can easily be done by creating a custom data type filter and defining its corresponding \texttt{fit!} and \texttt{transform!} operations which the \textbf{TSML} pipeline iteratively calls for each transformer in the workflow.

%TODO:
%\begin{itemize}
%\item add threading examples for scalability (buggy, need fixes)
%\item add simulations of different datasets to show general applicability (still doing simulations): %Earthquakes sensor; Electric Devices; car sensors; refrigeration devices; household consumption
%\end{itemize}

\input{bib.tex}

\end{document}

% Inspired by the International Journal of Computer Applications template


\subsection{LOESS}


\documentclass[11pt,letterpaper]{amsart}
\setlength{\oddsidemargin}{.0in}
\setlength{\evensidemargin}{.0in}
\setlength{\textwidth}{6.5in}
\setlength{\topmargin}{-.3in}
\setlength{\headsep}{.20in}
\setlength{\textheight}{9.in}
\usepackage[leqno]{amsmath}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{amsthm}
\usepackage{bbm}
\usepackage{amssymb}
\usepackage[all]{xy}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[foot]{amsaddr}
%Here are some user-defined notations
\newcommand{\RR}{\mathbf R}
\newcommand{\CC}{\mathbf C}
\newcommand{\ZZ}{\mathbf Z}
\newcommand{\ZZn}[1]{\ZZ/{#1}\ZZ}
\newcommand{\QQ}{\mathbf Q}
\newcommand{\rr}{\mathbb R}
\newcommand{\cc}{\mathbb C}
\newcommand{\zz}{\mathbb Z}
\newcommand{\zzn}[1]{\zz/{#1}\zz}
\newcommand{\qq}{\mathbb Q}
\newcommand{\calM}{\mathcal M}
\newcommand{\latex}{\LaTeX}
\newcommand{\tex}{\TeX}
\newcommand{\dd}{{\rm d}}
\newcommand{\sm}{\setminus}

%Here are commands with variable inputs
\newcommand{\intf}[1]{\int_a^b{#1}\,\dd{x}}
\newcommand{\intfb}[3]{\int_{#1}^{#2}{#3}\,\dd{x}}
\newcommand{\pln}[1]{$\sm${\tt #1}}
\newcommand{\bgn}[1]{$\tt {\sm}begin\{#1\}$}
\newcommand{\nd}[1]{$\tt {\sm}end\{#1\}$}
\newcommand{\marginalfootnote}[1]{%
        \footnote{#1}
        \marginpar[\hfill{\sf\thefootnote}]{{\sf\thefootnote}}}
\newcommand{\edit}[1]{\marginalfootnote{#1}}

%Here are some user-defined operators
\newcommand{\Tr}{\operatorname {Tr}}
\newcommand{\GL}{\operatorname {GL}}
\newcommand{\SL}{\operatorname {SL}}
\newcommand{\Prob}{\operatorname {Prob}}
\newcommand{\re}{\operatorname {Re}}
\newcommand{\im}{\operatorname {Im}}

%These commands deal with theorem-like environments (i.e., italic)
\theoremstyle{plain}
\newtheorem{theorem}{Theorem}[section]
\newtheorem{corollary}[theorem]{Corollary}
\newtheorem{lemma}[theorem]{Lemma}
\newtheorem{conjecture}[theorem]{Conjecture}

%These deal with definition-like environments (i.e., non-italic)
\theoremstyle{definition}
\newtheorem{definition}[theorem]{Definition}
\newtheorem{example}[theorem]{Example}
\newtheorem{remark}[theorem]{Remark}

%This numbers equations by section
\numberwithin{equation}{section}

\title{An implementation of optimized weighted ensemble}
\author{Felix Jones$^1$}
\address{$^1$Department of Mathematics, Drexel University}
\email{fgj23@drexel.edu}
\author{Gideon Simpson$^1$}
\email{grs53@drexel.edu}
\author{David Aristoff$^2$}
\address{$^2$Department of Mathematics, Colorado State University}
\email{aristoff@rams.colostate.edu}
\author{Jeremy Copperman$^3$}
\address{$^3$Department of Biomedical Engineering, Oregon
Health \& Science University}
\email{copperma@ohsu.edu}
\author{Robert J. Webber$^4$}
\address{$^4$Courant Institute, New York University}
\email{rw2515@nyu.edu}
\author{Daniel M. Zuckerman$^3$}
\email{zuckermd@ohsu.edu}

\begin{document}
\maketitle

\section{Desciption of the method}

\subsection{Introduction} Weighted ensemble is an
importance sampling interacting
particle method that simulates
the evolution of a generic
Markov chain.
The method consists of a fixed number of
weighted particles,
evolving via repeated
{\em selection} and {\em mutation} steps.

The mutation step
is simply evolution by the underlying
Markov chain kernel.
The selection step corresponds to
resampling from the weighted particles.
The resampling is based on {\em binning}
the particles,
and it may be designed
to keep more particles in important
regions of space to reduce the
variance of computations of the
quantity of interest (QOI).
Using a genealogical
analogy, we refer to particles
before selection as {\em parents},
and just after selection as {\em children}.

This implementation of weighted ensemble
focuses on optimizing the parameter
choices, namely the bins and the
number of children to put in each bin.

\subsection{Outline of the algorithm}

In the selection step, each
parent is either killed, or copied
to produce one or more children. The
children are initially identical to
their parents, but they evolve forward
in time independently. The
childrens' weights are
adjusted so that
the weighted ensemble is not
biased. This is implemented as follows.
\begin{itemize}
\item The parents are grouped
into {\em bins},
and a target number of
children is defined for each bin. We refer
to these targets as the {\em particle allocation}.
Both the bins and the particle allocation
are user-chosen parameters.
\item In each bin, the
children are resampled
from parents according to their weights.
For instance, the
children could be obtained by
sampling, with replacement,
the target number of parents,
according to the weight distribution
of the parents in the bin.
\item
In each bin, the children
are all given the same weight, which is
chosen so that the total weight
in the bin remains the same before
and after the selection step.
\end{itemize}

In the mutation step, the
children evolve independently
according to the law of the
underlying Markov chain, becoming
the next parents.
Their weights remain
the same during this step.

\subsection{Algorithm details}

Let $K$ be the underlying Markov kernel,
$N$ the total number of particles,
and $t \ge 0$ the time,
which counts the number of combined selection
and mutation steps. Before selection, the particles
and their weights are written, respectively,
$$\xi_t^1,\ldots,\xi_t^N \text{ and }
\omega_t^1,\ldots,\omega_t^N,$$
After resampling, the particles
and weights are denoted
$$\hat\xi_t^1,\ldots,\hat\xi_t^N\text{ and }
\hat\omega_t^1,\ldots,\hat\omega_t^N.$$
Weighted ensemble evolves from
time $t$ to $t+1$ as follows:
\begin{align*}
&\{\xi_t^i\}^{i=1,\ldots,N}
\xrightarrow{\textup{selection}}
\{{\hat \xi}_t^i\}^{i=1,\ldots,N}
\xrightarrow{\textup{mutation}}
\{{\xi}_{t+1}^i\}^{i=1,\ldots,N},\\
&\{\omega_t^i\}^{i=1,\ldots,N}
\xrightarrow{\textup{selection}}
\{{\hat \omega}_t^i\}^{i=1,\ldots,{N}}
\xrightarrow{\textup{mutation}}
\{{\omega}_{t+1}^i\}^{i=1,\ldots,N}.
\end{align*}
The initial weights must be strictly positive and sum to one,
$\omega_0^1+\ldots+\omega_0^N = 1$.

The mutation step consists
of the particles evolving independently
according to
$K$.
This means that $\xi_{t+1}^j$ is
distributed as $K({\hat \xi}_t^j,\cdot)$,
and the $\xi_{t+1}^j$ are independent over
$j$, conditional on $\hat{\xi}_t^1,\ldots,\hat{\xi}_t^N$.
The
weights do not change during the
mutation step,
$${\omega}_{t+1}^{j} = \hat{\omega}_{t}^j.$$

The selection step requires user-chosen
{\em bins} and {\em particle
allocation}.
The bins are labeled by ${\mathcal B}$,
and the particle allocation is defined
by $N_t(u)$, the number of children in each bin $u \in {\mathcal B}$ at time $t$.
The children in bin $u \in {\mathcal B}$
are obtained by sampling $N_t(u)$
times, with replacement, from the
weight distribution of the parents in bin $u$:
$$Pr(\textup{sample }\xi_t^j\text{ in bin }u) = \frac{\omega_t^j}{\omega_t(u)}, \qquad \omega_t(u) := \sum_{i:\textup{bin}(\xi_t^i) = u}\omega_t^i.$$
Here $\textup{bin}(\xi_t^i) = u$ means $\xi_t^i$ is assigned to bin $u$.
All of the children in any bin have the same weight,
$$\hat{\omega}_t^j = \frac{\omega_t(u)}{N_t(u)},\qquad \text{if bin}(\hat{\xi}_t^j) =u.$$

Each bin with a parent
must have at least
one child after selection, and if a bin
contains no parents,
it can have no children. Thus, $N_t(u) \ge 1$
if and only if $\omega_t(u)>0$. The total number of particles is always $N$,
so $\sum_{u \in {\mathcal B}}N_t(u) = N$.
Total particle weight is also preserved in time.

\section{Optimizing the parameters}

\subsection{Quantities of interest}

Let
$(\xi_t)$ be a Markov chain with kernel $K$, and let
$f$ be a function on its state space. The bin optimization and optimal particle allocation
are targeted for the computation of a particular
QOI. We
consider two types:
\begin{itemize}
\item[] {\em Finite time}: The QOI is ${\mathbb E}[f(\xi_T)]$, where $T$ is a deterministic time, which is estimated by
$${\mathbb E}[f(\xi_T)] \approx \sum_{i=1}^N \omega_T^i f(\xi_T^i).$$
\item[]{\em Steady state}: The QOI is $\int f\,d\mu$, where
$\mu$ is the stationary distribution of $(\xi_t)$, which we assume is ergodic. Given a user-chosen final time $T$, weighted ensemble estimates this by
$$\int f \,d\mu \approx \frac{1}{T}\sum_{t=0}^{T-1}\sum_{i=1}^N \omega_t^i f(\xi_t^i).$$
\end{itemize}

\subsection{Bin optimization}

The bins can be optimized by using a
{\em selection
discrepancy function} $H_t = H_t(\xi)$ defined on
the particles $\xi$.
The bins are defined so that the values
of $H_t$ on the particles in each
bin does not vary too much. More precisely:
\begin{itemize}
\item The bins are chosen to minimize, over choices of bins, the cost function
$$\sum_{u \in {\mathcal B}} \textup{Var}(H_t(\xi_t^i)^{i:\textup{bin}(\xi_t^i) = u}),$$
where $H_t(\xi_t^i)^{i:\textup{bin}(\xi_t^i) = u}$ is the vector of values of $H_t$ on the particles in bin $u$.
\end{itemize}

We implement this by applying $k$-means to the vector
$H_t(\xi_t^i)^{i=1,\ldots,N}$ of the values of $H_t$
on all the particles. The $k$-means clusters are the bins,
and $k$ is the user-chosen number of bins.

\subsection{Optimal allocation}

The particle allocation can be optimized
via a {\em
selection value function} $V_t = V_t(u)$ defined
on the bins $u$. The particle
allocation is defined so that
\begin{itemize}
\item The number of children in bin $u$ satisfies
\begin{equation*}
N_t(u) \approx \frac{N\omega_t(u)V_t(u)}{\sum_{u \in {\mathcal B}}\omega_t(u)V_t(u)} \qquad \text{and}\qquad N_t(u) \ge 1\text{ whenever } \omega_t(u)>0.
\end{equation*}
\end{itemize}

We achieve this by assigning one child to
each bin with a parent, and then allocating
the remainder of the children according to the
distribution $\omega_t(u)V_t(u)/\sum_{u \in {\mathcal B}}\omega_t(u)V_t(u)$. If the denominator here is zero, we skip the selection step and proceed directly to mutation.

\section{Formulas for optimization}

\subsection{Feedback formulas}

The selection discrepancy and selection value
functions that minimize the variance can
be written in terms of the QOI in a
feedback form. The feedback expressions we need are as follows.
\begin{align*}
&\textup{\em Finite time}: h_t(\xi) = {\mathbb E}[f(\xi_T)|\xi_t = \xi] \equiv K^{T-t}f(\xi),\\
&\textup{\em Steady state}: h(\xi) = \sum_{s=0}^\infty {\mathbb E}\left.\left[f(\xi_s)-\int f\,d\mu\right|\xi_0 = \xi\right] \equiv \sum_{s=0}^\infty \left(K^sf(\xi) - \int f\,d\mu\right).
\end{align*}

Note
that $h$ is the solution to the Poisson equation $(\textup{Id} -K)h = f - \int f\,d\mu$. Since we
will also require variances of the quantities above, we
introduce the notation
$$\textup{Var}_{K(\xi,\cdot)}g = \textup{Var}[g(\xi_{t+1})|\xi_t = \xi] \equiv Kg^2(\xi) - (Kg(\xi))^2,$$
where we will have either $g = h_{t+1}$ or $g = h$.

Because of their feedback form, these functions
are not exactly computable in practice.
In the code, the expressions above are estimated
by using a {\em coarse model} for $K$ and $f$.

\subsection{The selection discrepancy and selection value functions}

Exact formulas for the selection
discrepancy function $H_t = H_t(\xi)$ that minimizes variance are:
\begin{align*}
&\textup{\em Finite time}: H_t(\xi) = Kh_{t+1}(\xi) = h_t(\xi),\\
&\textup{\em Steady state}: H_t(\xi) = Kh(\xi).
\end{align*}

Exact formulas for the selection
value function $V_t = V_t(u)>0$ that minimizes variance are:
\begin{align*}
&\textup{\em Finite time}: V_t(u)^2 = \sum_{i:\textup{bin}(\xi_t^i) = u} \frac{\omega_t^i}{\omega_t(u)} \textup{Var}_{K(\xi_t^i,\cdot)}h_{t+1},\\
&\textup{\em Steady state}: V_t(u)^2 = \sum_{i:\textup{bin}(\xi_t^i) = u} \frac{\omega_t^i}{\omega_t(u)} \textup{Var}_{K(\xi_t^i,\cdot)}h.
\end{align*}

\section{Traditional implementation}

This code also includes the traditional
weighted ensemble implementation, in
which bins
are usually defined as Voronoi regions,
and the allocation is {\em uniform},
meaning roughly the same number of children
are in each bin, that is, $N_t(u)$ is nearly
constant in $u \in {\mathcal B}$.

\section{Reference guide}

See~\cite{aristoff2016analysis,aristoff2018steady} for details on some of the
optimizations described above. See~\cite{huber1996weighted} for the original
weighted ensemble paper, and~\cite{aristoff2016analysis,aristoff2019ergodic,aristoff2018steady,
bhatt2010steady,costaouec2013analysis,darve2013computing,
zhang2010weighted,zuckerman}
for analyses of weighted ensemble. See~\url{https://westpa.github.io/westpa/}
for a complete list of weighted ensemble papers. See~\cite{westpa,zwier2015westpa} for the main weighted ensemble
code and Github page.
See~\cite{del2004feynman,del2005genealogical,webber1}
and references therein for a
related sequential Monte Carlo method and~\cite{chraibi2018optimal,webber1} for
optimization in that context. See~\cite{jeremy}
for details more details on
combining weighted ensemble with a coarse
model to improve efficiency and accuracy. For
a comparison of different resampling techniques,
see~\cite{douc2005comparison,webber2}.

\begin{thebibliography}{}

\bibitem{aristoff2016analysis}
D.~Aristoff.
\newblock Analysis and optimization of weighted ensemble sampling.
\newblock {\em ESAIM: Mathematical Modelling and Numerical Analysis}, 52(2018), 1219--1238,
2018.

\bibitem{aristoff2019ergodic}
D.~Aristoff.
\newblock An ergodic theorem for weighted ensemble.
\newblock {\em arXiv preprint arXiv:1906.00856v4}.

 \bibitem{aristoff2018steady} D. Aristoff and D.M. Zuckerman, Optimizing weighted ensemble sampling of steady states,
       {\em arXiv preprint arXiv:1806.00860v4}, 2019.

\bibitem{bhatt2010steady}
D.~Bhatt, B.~W. Zhang, and D.~M. Zuckerman.
\newblock Steady-state simulations using weighted ensemble path sampling.
\newblock {\em The Journal of chemical physics}, 133(1):014110, 2010.

\bibitem{jeremy}
J. Copperman and D.M. Zuckerman.
\newblock Accelerated estimation of long-timescale kinetics by
combining weighted ensemble simulation with
Markov model “microstates” using non-Markovian
theory.
\newblock {\em arXiv preprint arXiv:1903.04673}.

\bibitem{chraibi2018optimal}
H.~Chraibi, A.~Dutfoy, T.~Galtier, and J.~Garnier.
\newblock Optimal input potential functions in the interacting particle system
  method.
\newblock {\em arXiv preprint arXiv:1811.10450}, 2018.

\bibitem{costaouec2013analysis}
R.~Costaouec, H.~Feng, J.~Izaguirre, and E.~Darve.
\newblock Analysis of the accelerated weighted ensemble methodology.
\newblock {\em Discrete and Continuous Dynamical Systems}, pages 171--181,
  2013.

\bibitem{darve2013computing}
E.~Darve and E.~Ryu.
\newblock Computing reaction rates in bio-molecular systems using discrete
  macro-states.
\newblock {\em arXiv preprint arXiv:1307.0763}, 2013.

 \bibitem{douc2005comparison}
R.~Douc and O.~Capp{\'e}.
\newblock Comparison of resampling schemes for particle filtering.
\newblock In {\em Image and Signal Processing and Analysis, 2005. ISPA 2005.
  Proceedings of the 4th International Symposium on}, pages 64--69. IEEE, 2005.

\bibitem{huber1996weighted}
G.~A. Huber and S.~Kim.
\newblock Weighted-ensemble brownian dynamics simulations for protein
  association reactions.
\newblock {\em Biophysical journal}, 70(1):97--110, 1996.

\bibitem{del2004feynman}
P.~Del~Moral.
\newblock Feynman-kac formulae: genealogical and interacting particle
  approximations.
\newblock {\em Probability and Its Applications, Springer}, 2004.

\bibitem{del2005genealogical}
P.~Del~Moral, J.~Garnier, et~al.
\newblock Genealogical particle analysis of rare events.
\newblock {\em The Annals of Applied Probability}, 15(4):2496--2534, 2005.

\bibitem{webber2}
R.J. Webber.
\newblock  Unifying Sequential Monte Carlo with Resampling Matrices.
\newblock {\em arXiv preprint arXiv:1903.12583}, 2019.

\bibitem{webber1}
R.J. Webber, D.A. Plotkin, M.E. O'Neill, D.S. Abbot, and J. Weare.
\newblock Practical rare event sampling for extreme mesoscale weather.
\newblock {\em arXiv preprint arXiv:1904.03464}, 2019.

\bibitem{zhang2010weighted}
B.~W. Zhang, D.~Jasnow, and D.~M. Zuckerman.
\newblock The “weighted ensemble” path sampling method is statistically
  exact for a broad class of stochastic processes and binning procedures.
\newblock {\em The Journal of chemical physics}, 132(5):054107, 2010.

\bibitem{zuckerman}
D.M. Zuckerman and L.T. Chong.
\newblock
Weighted Ensemble Simulation: Review of Methodology, Applications, and Software.
\newblock {Annu. Rev. Biophys.} 46: 43--57, 2017.

\bibitem{westpa}
M.C. Zwier, J.~L. Adelman, J.~W. Kaus, A.~J. Pratt, K.~F. Wong, N.~S. Rego,
  E.~Su{\'a}rez, S.~Lettieri, D.~W. Wang, M.~Grabe, D.~M. Zuckerman, and L.~T.
  Chong.
\newblock Westpa github pack.
\newblock {\em https://westpa.github.io/westpa/}, 2015--.

\bibitem{zwier2015westpa}
M.~C. Zwier, J.~L. Adelman, J.~W. Kaus, A.~J. Pratt, K.~F. Wong, N.~B. Rego,
  E.~Su{\'a}rez, S.~Lettieri, D.~W. Wang, M.~Grabe, D.M. Zuckerman, andL.T. Chong.
\newblock Westpa: An interoperable, highly scalable software package for
  weighted ensemble simulation and analysis.
\newblock {\em Journal of chemical theory and computation}, 11(2):800--809,
  2015.

       \end{thebibliography}

\end{document}


\section{User Guide}
When using this model, the user should follow the setup procedure corresponding to his or her desired conversion described below. The procedures outline the required inputs and for each conversion and some recommended parameter values.
\subsection{Element to Cartesian}
	\begin{itemize}
		\item \textit{Elements2Cart} = \textit{True}
		\item \textit{useEphemFormat}
		\begin{itemize}
			\item \textit{True} for planet state data
			\item \textit{False} for spacecraft state data
		\end{itemize}
		\item \textit{inputsGood} = True
		\item $\mu$ is recommended to be $3.86\text{e+}14$ $\frac{\text{m}^3}{\text{s}^2}$.
		\item Keplerian orbital elements should abide by the cases layed out in the Model Functions section.
	\end{itemize}
\subsection{Cartesian to Element}
	\begin{itemize}
		\item \textit{Elements2Cart} = \textit{False}
		\item \textit{useEphemFormat}
		\begin{itemize}
			\item \textit{True} for planet state data
			\item \textit{False} for spacecraft state data
		\end{itemize}
		\item \textit{inputsGood} = \textit{True}
		\item $\mu$ is recommended to be $3.86\text{e+}14$ $\frac{\text{m}^3}{\text{s}^2}$.
		\item Recommended Cartesian vectors can be obtained from Figures \ref{fig:2} through \ref{fig:13}, which correspond to the allowed orbit types.
	\end{itemize}

\subsection{Variable Definition and Code Description}
The variables in Table \ref{tabular:vars} are available for user input. Variables used by the module but not available to the user are not mentioned here. Variables with default settings do not necessarily need to be changed by the user, but may be.
\begin{table}[H]
	\caption{Definition and Explanation of Variables Used.}
	\label{tab:errortol}
	\centering \fontsize{10}{10}\selectfont
	\begin{tabular}{  m{3cm}| m{3cm} | m{3cm} | m{6cm} } % Column formatting,
		\hline
		\textbf{Variable}   							& \textbf{LaTeX Equivalent} 	&		\textbf{Variable Type} & \textbf{Notes}			  \\ \hline
		r$_N$	&$\bm{r}$ & double & [km]Default setting: 0.0. Position vector either used as an input to or obtained as an output from the conversions.\\ \hline
		v$_N$	& $\bm{\dot{r}}$ & double & [km/s]Default setting: 0.0. Velocity vector either used as an input to or obtained as an output from the conversions.\\
		\hline
		$\mu$	& $\mu$ & double & [m3/s2] Required Input. This is the gravitational parameter of the body. Replaces the product of Earth's gravitational force and mass for this test..\\
		\hline
		a & $a$ & double & [km] Required Input. The semimajor axis of the body's orbit.\\
		\hline
		e & $e$ & double & Required Input. The eccentricity of the body's orbit.\\
		\hline
		i & $i$ & double & [rad] Required Input. The inclination of the body's orbit\\
		\hline
		Omega & $\Omega$ & double & [rad] Required Input. The ascending node of the body's orbit. \\
		\hline
		omega & $\omega$ & double & [rad] Required Input. The argument of periapses of the body's orbit. \\
		\hline
		f & $f$ & double & [rad] Required Input. The true anomaly of the body's orbit \\
		\hline
		Elements2Cart & N/A & bool & Default Setting: False. Identifies the desired conversion. \\
		\hline
		useEphemFormat & N/A & bool & Default Setting: False. Identifies whether the body is a spacecraft or a planet.\\
		\hline
		inputsGood & N/A & bool & Default Setting: False. Indicates whether the code reads valid state data for conversion.\\
		\hline
	\end{tabular}
	\label{tabular:vars}
\end{table}
\begin{thebibliography}{1}
	\bibitem{bib:1}
	Vallado, D. A., and McClain, W. D., \textit{Fundamentals of Astrodynamics and Applications, 4th ed}. Hawthorne, CA: Published by Microcosm Press, 2013.
	\bibitem{bib:2}
	Schaub, H., and Junkins, J. L., \textit{Analytical Mechanics of Space Systems, 3rd ed.}. Reston, VA: American Institute of Aeronautics and Astronautics.
\end{thebibliography}


\documentclass[]{report}
\usepackage{graphicx}
\usepackage{hyperref}
\usepackage[a4paper, lmargin=2.5cm, right=2.5cm, top=2.5cm, bottom=2.5cm]{geometry} %, headsep=1.2cm

\def\thesection{\arabic{section}}

\title{Benchmarking oneSolver with droplet instances}
\author{Bart\l{}omiej Gardas}

\begin{document}
\maketitle

\begin{abstract}
It is well established that annealing-based spin-glass solvers can ``stuck'' in local minimum, ultimately preventing
the heuristic from reaching the ground state (\emph{i.e.}, true optimal solution). This, in fact, remains true for all heuristic
approaches designed for optimization. Therefore, it is essential to perform testing, and benchmarking against problem
instances that are considered to be ``hard" (\emph{e.g.}, have a nontrivial structure). Herein, we investigate how well
the oneSolver performs trying to solve droplets instances encoded in two-dimensional Ising spin-glass problems.
Similar idea has recently been incorporated to test sophisticated solvers, which are based on tensor networks, and
and projected entangled pair states.
\end{abstract}

\begin{figure}[h!]
	\includegraphics[width=1.0\textwidth]{HYP-24_chimera_128.pdf}
	\caption{
	Difference between the true ground state, and the solution found by oneSolver for the Chimera graph with $L=128$ vertices, and
	various repetitions. ``linear'', and ``geometric'' reefer to the possible schedules of the inverse Boltzmann temperature, $\beta$,
	that is used in the Metropolis-Hastings update.}
	\label{fig1}
\end{figure}
%
\begin{figure}[h!]
	\includegraphics[width=1.0\textwidth]{HYP-24_chimera_512.pdf}
	\caption{As above, for the Chimera graph with $L=512$ vertices.}
	\label{fig2}
\end{figure}
%
\begin{figure}[h!]
	\includegraphics[width=1.0\textwidth]{HYP-24_chimera_2048.pdf}
	\caption{As above, for the Chimera graph with $L=2014$ vertices.}
	\label{fig3}
\end{figure}

\newpage

\section{Conclusions}

For details concerning droplet instances cf.
M. M. Rams, M. Mohseni, B. Gardas,  ``\emph{Heuristic optimization and sampling with tensor networks for quasi-2D spin glass problems}'',
\href{https://arxiv.org/abs/1811.06518}{arxiv.org/abs/1811.06518 (2018)}. Further details, including additional testing problems with known solutions,
can also be found at \href{https://github.com/marekrams/tnac4o}{https://github.com/marekrams/tnac4o}.

As can been seen in Figs.~\ref{fig1} -~\ref{fig3}, the difference between the true ground state (obtained by the tensor network solver), and the solution found by oneSolver
increases with the increasing system size (number of vertices). This behaviour was to be expected as the problem is NP-hard.
Moreover, the geometric inverse temperature schedule, performed better than the linear one.  Nevertheless, oneSolver was unable
to find the correct ground state in \emph{any} of the considered cases.

That being said, the issue is not with the implementation (which is efficient) but rather with the algorithm itself, which in a way is too simplistic to capture sophisticated interactions
between spins encoded in the droplet instances.

\section{Recommendation}

Based on the performed benchmarks, it is therefore recommended to implement solvers that incorporate more clever spin updates.
A good starting point in this context would be the population annealing, and parallel tempering. More sophisticated approaches that
could also be incorporated are based on tensor networks, tropical algebras, and Lagrange multipliers.

\end{document}


\subsubsection{CPI Leg Data}
\label{ss:cpilegdata}

A CPI leg contains a series of CPI-linked coupon payments $(I(t)/I_0)\,N\,c\,\delta$ and, if \lstinline!NotionalFinalExchange! is set to \emph{true}, a final
inflation-linked redemption $(I(t)/I_0)\,N$. Each coupon and the final redemption can be
subtracting the (un-inflated) notional $N$, i.e. $(I(t)/I_0-1)\,N$,
see below.

Note that CPI legs with just a final redemption and no coupons, can be set up with a dates-based Schedule containing just a single date - representing the date of the final redemption flow. In this case \lstinline!NotionalFinalExchange! must be set to \emph{true}, otherwise the whole leg is empty, and the Rate is not used and can be set to any value.

Listing \ref{lst:cpilegdata} shows an example for a leg of type CPI with annual coupons, and \ref{lst:cpilegdatafinal} shows an example for a leg of type CPI with just the final redemption.

The  \lstinline!CPILegData! block contains the following elements:

\begin{itemize}
\item Index: The underlying zero inflation index.

Allowable values:  See \lstinline!Inflation CPI Index! in Table \ref{tab:cpiindex_data}.
\item Rates: The fixed real rate(s) of the leg. As usual, this can be a single value, a vector of values or a dated vector of
  values.

 Allowable values: Each rate element can take any  real number. The rate is
  expressed in decimal form, e.g. 0.05 is a rate of 5\%.
\item BaseCPI: The base CPI value $I_0$ used to determine the lifting factor for the fixed coupons.

Allowable values:  Any positive real number.

\item StartDate [Optional]: The start date needs to be provided in case the schedule comprises only a single date. If
  the schedule has at least two dates and a start date is given at the same time, the first schedule date is taken as
  the start date and the supplied \lstinline!StartDate! is ignored.

Allowable values:  See \lstinline!Date! in Table \ref{tab:allow_stand_data}.

\item ObservationLag: The observation lag to be applied. It's the amount of time from the fixing at the start or end of the period, moving backward in time, to the inflation index observation date (the inflation fixing).

Allowable values: An integer followed by \emph{D}, \emph{W}, \emph{M} or \emph{Y}. Interpolation lags are typically expressed in a positive number of  \emph{M}, months. Note that negative values are allowed, but mean that the inflation is observed forward in time from the period start/end date, which is unusual.

\item Interpolation: The type of interpolation that is applied to inflation fixings. \emph{Linear} interpolation means that the inflation fixing for a given date is interpolated linearly between the surrounding - usually monthly - actual fixings, whereas with  \emph{Flat} interpolation the inflation fixings are constant for each day at the value of the previous/latest actual fixing (flat forward interpolation).
%\emph{AsIndex} means that the underlying inflation index interpolation is applied. Note that if an inflation index have fixing interpolation switched off,  \emph{AsIndex}  is equivalent to \emph{Flat} interpolation.

Allowable values:  \emph{Linear, Flat}

\item SubtractInflationNotional [Optional]: A flag indicating whether
  the non-inflation adjusted notional amount should be subtracted from
  the the final inflation-adjusted notional exchange at maturity.
  Note that the final coupon payment is not affected by this flag. \\
Final notional payment if \emph{true}: $N \,(I(T)/I_0-1)$. \\
Final notional payment if  \emph{false}: $N \,I(T)/I_0$

\item SubtractInflationNotionalAllCoupons [Optional]: A flag indicating whether
  the non-inflation adjusted notional amount should be subtracted from
  all coupons.
  Note that the final redemption payment is not affected by this flag. \\
Coupon payment if \emph{true}: $N \,(I(T)/I_0-1)$. \\
Coupon payment if  \emph{false}: $N \,I(T)/I_0$

Allowable values: Boolean node, allowing \emph{Y, N, 1, 0, true, false} etc. The full set of allowable values is given in Table \ref{tab:boolean_allowable}.
\\Defaults to \emph{false}  if left blank or omitted.

\item Caps [Optional]: This node contains child elements of type
  \lstinline!Cap! indicating that the inflation indexed payment is
  capped; the cap is applied to the inflation index and expressed as
  an inflation rate, see CPI Cap/Floor in the Product Description. \\
  If the cap is constant over the life of the
cpi leg, only one cap value should
be entered. If two or more coupons have different caps, multiple cap values
are required, each represented by a \lstinline!Cap! child element. The first cap value
corresponds to the first coupon, the second cap value corresponds to the
second coupon, etc. If the number of coupons exceeds the number of cap
values, the cap will be kept at at the value of last entered spread for the
remaining coupons. The number of entered cap values cannot exceed the
number of coupons. Notice that the caps defined under this node only apply to the cpi coupons,
but not a final notional flow (if present). A cap for the final notional flow can be defined
under the FinalFlowCap node.

Allowable values: Each child element can take any real number. The cap is
expressed in decimal form, e.g. 0.03 is a cap of 3\%.

\item Floors [Optional]: This node contains child elements of type
  \lstinline!Floor! indicating that the inflation indexed payment is
  floored; the floor is applied to the inflation index and expressed as
  an inflation rate. The mode of specification is analogous to caps, see
  above. Notice that the floors defined under this node only apply to the cpi coupons,
  but not a final notional flow (if present). A floor for the final notional flow can be defined
  under the FinalFlowFloor node.

Allowable values: Each child element can take any real number. The floor is
expressed in decimal form, e.g. 0.01 is a cap of 1\%.

\item FinalFlowCap [Optional]: The cap to be applied to the final notional flow of the cpi leg. If not given, no cap
  is applied.

Allowable values: A real number.

\item FinalFlowFloor [Optional]: The floor to be applied to the final notional flow of the cpi leg. If not given, no floor
  is applied.

Allowable values: A real number.

\item NakedOption [Optional]: Optional node, if \emph{true} the leg represents only the embedded floor, cap or collar.
By convention these embedded options are considered long if the leg is a receiver leg, otherwise short.

 Allowable values:  \emph{true}, \emph{false}. Defaults to \emph{false} if left blank or omitted.

\end{itemize}

Whether the leg cotains a final redemption flow at all or not depends on the
 notional exchange setting, see section \ref{ss:leg_data} and listing \ref{lst:notional_exchange}.

\begin{listing}[H]
%\hrule\medskip
\begin{minted}[fontsize=\footnotesize]{xml}
      <LegData>
        <LegType>CPI</LegType>
        <Payer>false</Payer>
        <Currency>GBP</Currency>
        <Notionals>
          <Notional>10000000</Notional>
          <Exchanges>
            <NotionalInitialExchange>false</NotionalInitialExchange>
            <NotionalFinalExchange>true</NotionalFinalExchange>
          </Exchanges>
        </Notionals>
        <DayCounter>ACT/ACT</DayCounter>
        <PaymentConvention>Following</PaymentConvention>
        <ScheduleData>
          <Rules>
            <StartDate>2016-07-18</StartDate>
            <EndDate>2021-07-18</EndDate>
            <Tenor>1Y</Tenor>
            <Calendar>UK</Calendar>
            <Convention>ModifiedFollowing</Convention>
            <TermConvention>ModifiedFollowing</TermConvention>
            <Rule>Forward</Rule>
            <EndOfMonth/>
            <FirstDate/>
            <LastDate/>
          </Rules>
        </ScheduleData>
        <CPILegData>
          <Index>UKRPI</Index>
          <Rates>
            <Rate>0.02</Rate>
          </Rates>
          <BaseCPI>210</BaseCPI>
          <StartDate>2016-07-18</StartDate>
          <ObservationLag>2M</ObservationLag>
          <Interpolation>Linear</Interpolation>
          <Caps>
             <Cap>0.03</Cap>
          </Caps>
          <Floors>
            <Floor>0.0</Floor>
          <Floors>
          <FinalFlowCap>0.03</FinalFlowCap>
          <FinalFlowFloor>0.0</FinalFlowFloor>
          <NakedOption>false</NakedOption>
          <SubtractInflationNotionalAllCoupons>false</SubtractInflationNotionalAllCoupons>
        </CPILegData>
      </LegData>
\end{minted}
\caption{CPI leg data with capped annual coupons}
\label{lst:cpilegdata}
\end{listing}

\begin{listing}[H]
%\hrule\medskip
\begin{minted}[fontsize=\footnotesize]{xml}
      <LegData>
        <Payer>false</Payer>
        <LegType>CPI</LegType>
        <Currency>GBP</Currency>
        <PaymentConvention>ModifiedFollowing</PaymentConvention>
        <DayCounter>ActActISDA</DayCounter>
        <Notionals>
          <Notional>25000000.0</Notional>
          <Exchanges>
            <NotionalInitialExchange>false</NotionalInitialExchange>
            <NotionalFinalExchange>true</NotionalFinalExchange>
          </Exchanges>
        </Notionals>
        <ScheduleData>
          <Dates>
            <Calendar>GBP</Calendar>
            <Dates>
              <Date>2020-08-17</Date>
            </Dates>
          </Dates>
        </ScheduleData>
        <CPILegData>
          <Index>UKRPI</Index>
          <Rates>
            <Rate>1.0</Rate>
          </Rates>
          <BaseCPI>280.64</BaseCPI>
          <StartDate>2018-08-19</StartDate>
          <ObservationLag>2M</ObservationLag>
          <Interpolated>false</Interpolated>
          <SubtractInflationNotional>true</SubtractInflationNotional>
          <SubtractInflationNotionalAllCoupons>false</SubtractInflationNotionalAllCoupons>
        </CPILegData>
      </LegData>
\end{minted}
\caption{CPI leg data with just the final redemption}
\label{lst:cpilegdatafinal}
\end{listing}


\documentclass[8 pt]{article}

\usepackage[utf8x]{inputenc}
\usepackage{dsfont}
\usepackage{amsthm}
\usepackage{amsfonts}
\usepackage{amssymb}
\usepackage{tensor}
\usepackage{mathtools}
\usepackage[T1]{fontenc}
%\usepackage[spanish]{babel}
\usepackage[cm]{fullpage}
\usepackage{graphicx}
%\usepackage{float}
\usepackage{bm}
\usepackage{setspace}
\usepackage{enumitem}
\usepackage{mdwlist}
\usepackage{parskip}
\usepackage{listings}
\usepackage{color}
%\usepackage{epstopdf}
\usepackage{tikz,datatool}
\usepackage{hyperref}
\usepackage{mathabx}
\usepackage{multicol}
\usepackage{eurosym}
\usepackage{caption}

\newcommand{\HRule}{\rule{\linewidth}{0.5mm}}

\AtBeginDocument{
  \let\myThePage\thepage
  \renewcommand{\thepage}{\oldstylenums{\myThePage}}
}

\newcommand{\gra}{$^\text{o}$}
\newcommand{\dif}{\text{d}}
\newcommand{\avg}[1]{\left\langle #1 \right\rangle}
\newcommand{\ket}[1]{\left| #1 \right\rangle}
\newcommand{\bra}[1]{\left\langle #1 \right|}
\newcommand{\bket}[2]{\left\langle #1 \middle| #2 \right\rangle}
\newcommand{\der}[2]{\frac{\text{d} #1}{\text{d} #2}}
\newcommand{\prt}[2]{\frac{\partial #1}{\partial #2}}
\newcommand{\dert}[3]{\frac{\text{d}^#3 #1}{\text{d} #2^#3}}
\newcommand{\prtt}[3]{\frac{\partial^#3 #1}{\partial #2^#3}}
\newcommand{\dl}{\mathcal{L}}
\newcommand{\dha}{\mathcal{H}}
\newcommand{\vol}{\text{vol}}
\renewcommand{\vec}[1]{\pmb{#1}}

\DeclarePairedDelimiter\ceil{\lceil}{\rceil}
\DeclarePairedDelimiter\floor{\lfloor}{\rfloor}

\newenvironment{Figure}
  {\par\medskip\noindent\minipage{\linewidth}}
  {\endminipage\par\medskip}

\begin{document}

\begin{minipage}{\textwidth}
    \centering
    \Large \textbf{\textsc{Homework 3: Dual Listing Arbitrage}}
    \vspace{0.5cm}

    \small \textsc{Francisco García Flórez, Joris van Lammeren, Wouter Varenkamp}
    \vspace{0.5cm}

    \begin{minipage}{0.8\textwidth}
      \textbf{Abstract.} In this homework we study pure arbitrage as a way of making risk-free profits by trading some volume between two markets. Even though profits per trade are low compared to the amount of cash involved, it is still possible to make a significant profit over time.
    \end{minipage}
\end{minipage}

\vspace{0.5cm}

\begin{multicols*}{2}

  \section{Trading robot}

  In this homework we focus on pure arbitrage, meaning buying low in one market and selling high in another, however we can only use immediate transactions (fill or kill), and remain with a null position.

  The trading algorithm is implemented in three separate steps, executed every time there is a book update. These three steps are \emph{offers and bids checking}, \emph{trading} and \emph{book updating}, each of them explained in the following sections.

  We consider each book to be a set of price and volume pairs, that we denote as $(P^{a,b}_i, V^{a,b}_i)$, where the superscript $a, b$ refer to \emph{ask} and \emph{bid} respectively, and $i\in [1, N_{a,b}]$ is the index of the entry. In a more general setting we would also want to specify the market, however in this case there are only two options: buying \texttt{CHI\_AKZA} and selling \texttt{EUR\_AKZA} or the opposite, so references to bids or asks are implicitly connected to the right market.

  \paragraph{Offers and bids checking}

  In the first place, right after the robot receives a book update, it computes a matrix of logical values (\texttt{True} or \texttt{False}) representing which trades are profitable. This matrix $T$ is computed as follows:

  \begin{equation*}
    T_{ij} = P^a_i < P^b_j ~,~~ \forall i,j \in [1, N_a]\times[1, N_b] ~~.
  \end{equation*}

  Since not every time we receive a book update there are going to be any profitable trades, we need to check that at least one of the elements of $T$ is \texttt{True}, which we could check by computing the product of its components:

  \begin{equation*}
    \text{\texttt{check}} = \bigoplus_{i, j}^{N_a, N_b} T_{ij} ~~,
  \end{equation*}

  thus if \texttt{check} is \texttt{True}, we proceed with the next step, in which we compute the data we need for the \emph{trading} part. This data is contained in two matrices, each element composed of a pair of prices and volumes:

  \begin{align*}
    \begin{split}
      V_{ij} &= ( V^a_i, V^b_j ) ~,~~ \forall i,j \in [1, N_a]\times[1, N_b] \\
      P_{ij} &= ( P^a_i, P^b_j ) ~,~~ \forall i,j \in [1, N_a]\times[1, N_b]
    \end{split}
    ~~.
  \end{align*}

  However we still need to do one extra computation with $V$, since the volume that can be traded is limited by either $V^a_i$ or $V^b_i$ the final volume we can trade is given by $\tilde V_{ij} = \min(V_{ij,1}, V_{ij, 2})$, where the subscript $1$ and $2$ reference each element of the pair.

  Finally, selecting components $\tilde V_{ij}$ and $P_{ij}$ for which $T_{ij} = $ \texttt{True}, we can proceed to the next step.

  \paragraph{Trading}

  Now, taking the volumes and prices selected in the last step and iterating over them, buying at price $P^a_i$ and selling at $P^b_j$, we perform the profitable trades. Algorithmically this can be implemented as

  \begin{verbatim}
    for i, j such that T[i, j] is True {
      buy(ask_price[i], limit_volume[i, j])
      sell(bid_price[j], limit_volume[i, j])
    }
  \end{verbatim}

  This step can be slightly improved by optimizing the traded volume when more there are more than one trades possible, maximizing the volume we buy selling to more than one bidder and vice versa. However there is one detail that we need to take care of, discussed in the next step.

  \paragraph{Book updating}

  Finally we can proceed to perform the last step of the implementation: update the books. After every successful transaction the market changes, but in the next book update only one of the books will be saved. This means that we need to manually modify the stored book after selling and buying, so that the algorithm doesn't get tricked into sending the same transaction into the market several times.

  We achieve this by looking up the entry by price and either removing it completely if the volume moved is maximum, or adjusting it if it isn't.

  \section{Results}

  As we can see in Table \ref{table:assets} (see Appendix) as we expected the cash moved is several orders of magnitude higher than profits, but these are completely risk-free earned in about 21 minutes of trading. Since this is only pure arbitrage there are many opportunities to improve on it, basically introducing all the possible strategies that characterize algorithmic trading.

\section{Appendix}

\begin{minipage}{\textwidth}
\begin{center}
  \Large
  \label{table:cash}
  \begin{tabular}{|c|c|c|c|c|c|}
    \hline
    \# & CHI (Buy) & CHI (Sell) & EUR (Buy) & EUR (Sell) & Profit \\ \hline
    \input{tables/profits.tex}
  \end{tabular}
  \captionof{table}{Cash moved for each feed.}
\end{center}

\vspace{1.0cm}

\begin{center}
  \Large
  \label{table:assets}
  \begin{tabular}{|c|c|c|c|c|c|}
    \hline
    \# & CHI (Buy) & CHI (Sell) & EUR (Buy) & EUR (Sell) & Position \\ \hline
    \input{tables/assets.tex}
  \end{tabular}
  \captionof{table}{Assets moved for each feed.}
\end{center}
\end{minipage}

\begin{thebibliography}{28}
\raggedright
\addcontentsline{toc}{section}{Bibliography}

\bibitem{Wilmott} P. Wilmott et al, \emph{The Mathematics of Financial Derivatives}, 1995.

\end{thebibliography}

\end{multicols*}

\end{document}


\section{Background}

\subsection{GPS Positioning}
\input{figures/fig-gps-how}

GPS Positioning technology makes use of satelites in known orbits around the earth, broadcasting the current time. By consulting the orbits and the time taken for a signal to arrive from a number of satelites, GPS recievers can determine their own location on Earth, as shown in \figref{fig:gps:how}.

\input{figures/fig-reflect}

However, GPS cannot produce perfectly precise locations. Error is introduced by a variety of factors: Orbital information can be out-of-date or subtly incorrect, or too few satelites may be within reach. \figref{fig:gps:reflect} shows a more dramatic problem, in which the signal recieved is bounced off a nearby object before being received.

\subsection{Path Refinement}

GPS positions inherently include measurement error, as mentioned above, but naive attempts to interpolate between positions can cause dramatically more error if done poorly. Lonergan \textit{et al.} demonstrated that point-connecting strategies such as linear or quadratic interpolation have error that scales linearly with the time between GPS positions when tracking wild animals~\cite{lonergan09}.

Different strategies can be applied to refine positions within a \textit{path}, depending on the goal. If attempting to determine the length of the path, map-matching techniques allow a path to be overlaid on a known (and presumably accurate) network. Conversely, if the goal is to extract a more accurate path, sensor readings can be combined with additional information and rules.

Path refinement is extremely difficult to evaluate, as the underlying premise is that the sensor data provided is inaccurate. As a result, evaluation of such techniques tends to focus around path \textit{recoverability}, in which the sensor data is randomly permuted across trials, and the similarity of the refined paths is compared.


\section{Order statistics}


\section{Performances}
\label{sec:performances}

\subsection{Baseline}
We use the first model with a unigram underlying language model without smoothing as the baseline to evaluate the performances of the different n-gram orders and smoothing methods.
The baseline model simply assigns to each word the concept with the highest frequency in the training set for the specific word.
The model reached a F1 score of $57.13\%$, as showed in the first line of \cref{tab:v1-ngrams}.

\begin{table}[t!]
	\centering
    \begin{tabular}{ l l l l l }
    	\toprule
    		n & smoothing & prec. & recall & F1 \\
    	\midrule
            \input{table/v1-ngrams}
    	\bottomrule
	\end{tabular}
    \caption{Comparison of the performances of different n-gram orders for model 1.}
	\label{tab:v1-ngrams}
\end{table}

\subsection{n-gram Order}
The model without smoothing has the best performances for bigrams and 5-grams, reaching respectively a F1 of $76.21\%$  and $76.05\%$.
The smoothing helps to get slightly better performances, but does not change the ranking of the n-gram orders.
All models with n-gram order greater then $1$ perform significantly better than the baseline, with an increase in the F1 score of about $20\%$.

\begin{table}[t!]
	\centering
    \begin{tabular}{ l l l l l }
    	\toprule
    		n & smoothing & prec. & recall & F1 \\
    	\midrule
            \input{table/v1-smoothing}
    	\bottomrule
	\end{tabular}
    \caption{Comparison of the performances of different smoothing methods for model 1.}
	\label{tab:v1-smoothing}
\end{table}

\subsection{Smoothing Methods}
For both bigrams and 5-grams, the best smoothing method is Witten-Bell, followed by Absolute and Kneser-Ney.
\cref{tab:v1-smoothing} shows a detailed comparison of all smoothing methods for the best n-gram order choices.

\subsection{Features}
The model can be trained with a different feature rather than the word.
\cref{tab:v1-features} compares performances of the 5-grams model with Witten-Bell smoothing for the different input features: \ac{POS} and word stems.
The best option is to use just the original words.
Word stems have slightly worse performances than words.
\ac{POS} have terrible performances, with a F1 score of only about $20\%$.

\begin{table}
	\centering
    \begin{tabular}{ l l l l l }
    	\toprule
    		feature & n & prec. & recall & F1 \\
    	\midrule
            \input{table/v1-features}
    	\bottomrule
	\end{tabular}
    \caption{Comparison of the performances of different input features for model 1, using Witten-Bell smoothing.}
	\label{tab:v1-features}
\end{table}

\subsection{Improved model}
The improved model described in \cref{sec:improvements} achieves significantly better performances than the original model, with a F1 score around $82\%$.
The best performances are obtained with a 4-gram underlying language model with Kneser-Ney smoothing, with a F1 value of $82.74\%$.
Similarly to the original model, the additional features obtain worse performances.
Opposite to the previous case, the best smoothing methods seems to be Kneser-Ney.
More detailed results are showed in \cref{tab:v2}.

\begin{table}
	\centering
    \begin{tabular}{ l l l l l }
    	\toprule
    		n & smoothing & prec. & recall & F1 \\
    	\midrule
            \input{table/v2}
    	\bottomrule
	\end{tabular}
    \caption{Comparison of the performances of different parameters for model 2, using words as input.}
	\label{tab:v2}
\end{table}