InSo Insights: Implementation of a Robust Steady State Detector for Industrial Time Series Data
Disclaimer: This is a math-heavy post. Example code is provided to break down the heavier concepts, but it is helpful to have a basic understanding of probability notation for the modeling sections.
Introduction
Data quality management and monitoring have become imperative in acquiring optimal data to drive successful models. In the production optimization arm of the Industry Solutions (InSo) team at Cognite, we use data (and lots of it) to drive informed decisions in the oil and gas sector. Cognite Data Fusion (CDF) gives us the freedom that most data science teams don’t have, in that it provides easy access to the resources we need to solve problems that require complex data wrangling quickly.
Identifying steady-state conditions is a common problem in oil and gas. Solving it can make, or break, the success of a model. For example, when preparing data for input into a model created to optimize the operation of a compressor, we need to verify that inlet pressure conditions are steady before they can be used. If unsteady (i.e., if transient state conditions are used) we may end up significantly over- or underestimating the compressor’s capacity. Additionally, it is necessary to detect transient flow patterns such as slug flow, which is a common flow regime in pipelines that must be controlled, to avoid saturating the processing facility.
Existing steady-state detection methods include the slope detection method SDM, performing a t-test on two recently computed means of two adjacent windows with pooled standard deviation, monitoring the standard deviation of a moving window, and performing an F-test on the ratio of variances of a moving window calculated using two different methods: the mean-squared deviation and the mean of squared differences of successive data.
Although this list of existing methods is extensive, these methods have several downsides. For one, you have to use a data window, and there are no known methods to determine the optimal parameters of this window. Too long of a moving window may delay detection, and too short of a window may increase the false detection rate of the steady-state. Most importantly, these methods are also typically very parameter-heavy, in that they depend on the characteristics of the signal such as the variance of the noise, signal changing rate, scale, etc.
In practice, it is common to determine the steady-state regions of many time series. We then encounter the problem of having to choose the optimal parameters for any of the existing steady-state detection models to fit any arbitrary time series. At Cognite, where we can have over a million different time series per client, these methods become impractical to use. We need one model or one algorithm that can fit all.
Proposed model
Jiangi Wu et. al. have proposed a robust steady-state detection method based on a multiple change-point model. The goal of this method is to sequentially fit a piecewise linear model to a given time series. The following figure, provided by the authors of the paper, is a wonderful illustration of the fitting process:
From the figure, the change-point represents the data point where a new regression line starts. The steady-state is inferred by estimating the parameters of the current line segment at time t. If the slope of the regression line is below a user-defined threshold (a number near 0, e.g. 0.004), then the process is considered to be in steady-state at time t. Given that the steady-state of a time series infers data with an unchanging mean, the slope of the regression line fit to these points should always be near 0.
The authors define the model as a nonlinear state space described by the following equation:
In code, using the Pomegranate library, which offers easy creation of mixture models:
Where t is the model’s regression parameters at time t, i.e. ξt = (a𝑡, b𝑡, σ² 𝑡), and τ𝑡 is the time of the latest change-point. Respectively, they represent the slope of the regression line at time t, the slope, and the variance of the noise of the data present in the regression. Thus, the model state at any time t is given by x𝑡 = (ξ𝑡, τ𝑡). The variable p is simply the state transition probability; in other words, the probability that we transition to a new regression line at time t. We use particle filtering as our inference technique to estimate these parameters whenever we retrieve a new data point. The important takeaway is that every time we obtain a new data point (i.e. an observation y𝑡) we re-calculate the posterior distribution of the regression parameters. As we move through time, we obtain a better and better estimate of the signal parameters (and therefore behavior).
We can solve the parameter estimation problem through particle filtering!
Particle filtering is well-proven to be able to estimate the parameters of a nonlinear system effectively. Commonly applied to object localization and tracking, the power of the particle filter comes in its ability to model parameter distributions that are non-Gaussian in nature. Without going into the finer details of particle filtering, which is outside the scope of this post, I’ll describe the particle filtering inference algorithm which we used to develop this model.
In this application, our particle filter model takes the following form:
f(x) is our mixture distribution, defined by our state-space model for the segmented regression, and g is the likelihood of seeing the observation at time t, given our current parameters. The basic algorithm is as follows:
1. At time step t = 1:
a) Randomly generate a bunch of particles from the mixture distribution f(x)
- Each particle is represented by a vector of our model parameters. So at time t, the ith particle is represented by the vector xᵢ𝑡 = (a𝑡, b𝑡, σ² 𝑡, τ𝑡). Each particle has a weight (a probability) indicating the likelihood that it matches the actual state of the system. In step 1 these particles are all equally weighted.
b) Compute the weights and the normalized weights of the particles
- Thanks to the way the particle filter model is defined, the weight for each particle is simply computed by plugging its state vector into the likelihood function g.
- Example:
c) Resample the particles
- Discard highly improbable particles (ones with very low weight) and replace them with copies of the more probable (highly weighted) particles
2. At time step t >= 2:
a) For these time steps, there is a danger of particle degeneracy over time, meaning that after a few iterations the weight may concentrate only on a few particles, and that most particles will have negligible weights. To counteract this effect, we use a stratified sampling method. We sample a subset of new particles (n0) from our mixture distribution f(x) and a larger subset (n1 = N — n0) from the resampled and weighted particles of the previous iteration. To weigh this composition of particles we use the following schema:
where p is the mixing constant of our mixture distribution. The weights for each group wt are calculated again using the likelihood function g.
b) Sample f(x)
- Given the definition of our state-space model when we sample from f(x), our importance density function (which is a mixture distribution), we assign a weight based on our transition probability p to each component of our mixture.
c) Weigh particles according to the stratified sampling method described in step 2(a)
d) Resample particles the same way as in 1(c)
Although the stratified resampling step can reduce the particle degeneracy effect, it may also reduce particle diversity and thus cause particle impoverishment, meaning there will be fewer unique particles as we iterate. The authors propose a resample-move algorithm to counter these issues, where we resample as per step 2(c) and then move the regression parameters ξ using a one-step Gibbs sampler.
e) Gibbs Move: Select a subset S of the resampled particles and:
- Sample the regression parameters and reset the particle parameters of the subset of particles
- Calculate the means and covariances of the new particle set. Use as the prior for f(x) in the next iteration.
Putting it all together:
Testing the model on Open Industrial Data
Using data from Cognite’s Open Industrial Data project, we were able to test the performance of the model on the output of a liquid level sensor on the Valhall oil field, located in the North Sea. This sensor typically measures the liquid level on a vessel or tank as a percentage of its total height. We typically examine these sensors to determine if slugging is occurring through the separator. If it is, we can see a deviation from a steady-state in the time series. By visually inspecting the time series below, we can see the first period of steady-state occurs from 2020–01–15 20 to ~ 21 followed by a longer period of steady-state starting at 2020–01–16 00.
Using the model, we determine the steady-state detection probability using the following:
Pulling data and running the model is easy:
The probability is calculated as the weighted sum of the indicator function of the particles. If the slope of the given particle is less than the slope detection threshold, its weight is added to the weight of the other particles that meet the criteria. In the context of this model, we set that threshold to 0.0007 (a slope near 0 indicates an unchanging mean, and therefore a steady-state).
The result above proves that the model is not only robust to signal noise, but that it is also able to detect two different periods of steady-state occurring at different means. This shows the model can automatically adapt over time to a signal with changing parameters. The model is also scale-invariant, meaning that we can apply it to virtually any signal in our database.
One of our core values at Cognite is speed. We move fast and try new things rather than exhaust the current solution space. This is especially true for the production optimization team at Cognite, where we take a flexible approach to modeling so that we can meet our clients’ needs. We hope you enjoyed this first showcase of what our team can do. There’s plenty more to come!
Get the code and try it out for yourself! https://github.com/cognitedata/Steady-State-Detector