blog bg left
Back to Blog

Understanding Kolmogorov-Smirnov (KS) Tests for Data Drift on Profiled Data

TLDR: We experimented with statistical tests, Kolmogorov-Smirnov (KS) specifically, applied to full datasets as well as dataset profiles and compared results. The results allow us to discuss the limitations of data profiling for KS drift detection and the pros and cons of the KS algorithm for different scenarios. We also provide the code for you to reproduce the experiments yourself.

Data drift is a well-known issue in ML applications. If unaddressed, it can degrade your model significantly and make your model downright unusable. The first step to address those issues is to be able to detect and monitor for data drift.

There are multiple approaches to monitoring data drift in production. It is very common to use statistical tests to get a drift detection value and monitor it over time. Traditional drift detection algorithms usually need the full original data to calculate these values, but for large-scale systems, having complete access to historical data might be infeasible due to storage or privacy concerns. A possible alternative is to sample your data beforehand, which also comes with disadvantages: you might lose important information, such as rare events and outliers, through aggregation, damaging the result’s reliability.

A third approach is to profile your data before applying your drift detection algorithm. Profiles capture key statistical properties of data, such as distribution metrics, frequent items, missing values, and much more. We can then use those statistical properties to apply adapted versions of drift detection techniques. Of course, since there is no such thing as a free lunch, this strategy has its downsides. A profile is an estimate of the original data and, as such, using it for drift detection will generate approximations of the actual drift detection value that you would get if you had used the complete data.

But how exactly does the profiling process work with the drift detection algorithms, and how much do we lose by doing it?

In this blog post, we’ll limit ourselves to numerical univariate distributions, and choose one specific algorithm to run the experiment: the Kolmogorov-Smirnov (KS) test. We’ll also get to have some nice insights into the suitability of the KS test itself for different scenarios.

Here’s what we’ll cover in this blog post:

  • What is the KS test?
  • What is data profiling?
  • Experiment Design
  • The Experiments
    - Experiment #1 — Data volume
    - Experiment #2 — No. of buckets
    - Experiment #3 — Profile size

You can check the code used in this blog post or even run the experiment yourself by accessing the experiment’s Google Colab notebook.

The Kolmogorov-Smirnov Test

The KS test is a test of the equality between two one-dimensional probability distributions. It can be used to compare a sample with a reference probability distribution or compare two samples. Right now, we are interested in the latter. When comparing two samples, we are trying to answer the following question:

“What is the probability that these two sets of samples were drawn from the same probability distribution?”

The KS test is nonparametric, which means we don’t need to rely on assumptions that the data are drawn from a given family of distributions. This is good, since we often won’t know the underlying distribution beforehand in the real world.

The statistic

The KS statistic can be expressed as:

D = supₓ|F₁(x) — F₂(x)|

where F1 and F2 are the two cumulative distribution functions of the first and second samples, respectively.

Another way to put it is that the KS statistic is the maximum absolute difference between the two cumulative distributions.

The image below shows an example of the statistic, depicted as a black arrow.

The two-sample KS statistic. Source: Wikipedia[1]

The Null Hypothesis

The null hypothesis for this test is that both samples are drawn from the same distribution. For example, a p-value of 0.05 would mean a 5% probability of both samples being from the same distribution. To calculate this probability, the KS statistic is taken into account along with the sample size of both distributions. Common p-values for rejecting the null hypothesis are 1% and 5%, for example.

Data Profiling

Profiling a dataset means collecting statistical measurements of the data. This enables us to generate statistical fingerprints, or summaries, of our data in a scalable, lightweight, and flexible manner. Rare events and outlier-dependent metrics can be accurately captured.

To profile our data, we’ll use the open-source data logging library whylogs. Profiling with whylogs is done in a streaming fashion, requiring a single pass over the data, and allows for parallelization. Profiles are also mergeable, allowing you to inspect your data across multiple computing instances, time periods, or geographic locations. This is made possible with a technique called sketching, pioneered by Apache DataSketches.

Precisely for this example, we’ll leverage the profile’s distribution metrics. To calculate the KS statistic, we need to generate an approximation for the sample’s cumulative distribution function. This is made possible with a technique called data sketching, pioneered by Apache DataSketches.

Experiment Design

First, we need the data. For this experiment, we will take two samples of equal size from the following distributions:

  • Normal: Broad class of data. Unskewed and peaked around the center
  • Pareto: Skewed data with long tail/outliers
  • Uniform: Evenly sampled across its domain
In this blog post, we’ll show the results for normal distribution only, but you can find the same experiments for Pareto and Uniform distributions directly in the example notebook here. The overall conclusions drawn from the normal distribution case can also be applied to the remaining distributions.

Drift Injection

Next, we’ll inject drift into one sample (which we’ll call the target distribution) to compare it to the reference, unaltered, distribution.

We will inject drift artificially by simply shifting the data’s mean according to a parameter. We chose to use the ratio of the distribution’s interquartile range. Here’s what it looks like for the normal distribution case:

Image by author

The idea is to have four different scenarios: no drift, small drift, medium drift, and large drift. The magnitude classification and the ideal process of detecting/alerting for drifts can be very subjective, depending on the desired sensitivity for your particular application. In this case, we are assuming that the small-drift scenario is small enough for it to be safely ignored. We are also expecting that the medium and large drift scenarios should result in a drift alert since both would be cases for further inspection.

Applying the KS test

As the ground truth, we will use scipy’s implementation of the two-sample KS test with the complete data from both samples. We will then compare those results with the profiled version of the test. To do so, we’ll use whylogs’ approximate implementation of the same test, which uses only the statistical profile of each sample.

The distribution metrics contained in the profiles are obtained from a process called sketching, which gives them many useful properties but adds some amount of error to the result. For this reason, the KS test result can be different each time a profile is generated. We’ll profile the data 10 times for every scenario, and compare the ground truth to statistics such as the mean, maximum, and minimum of those runs.

Experiment Variables

Our main goal is to answer:

“How does whylogs’ KS implementation compare to scipy’s implementation?”

However, this answer depends on several different variables. We will run three separate experiments to better understand the effect of each variable: data volume, number of buckets, and profile size. The first one relates to the number of data points in each sample, whereas the last two relate to whylogs internal, tunable parameters.

Experiment #1 — Data Volume

The number of data points in a sample affects not only the KS test in general but also the profiling process itself. It is reasonable, then, to investigate how it affects the results.

We compared the p-values for both implementations with varying sample sizes (for both target and reference distributions): 500, 1k, 5k, 10k, and 50k.

Image by author

You’ll notice that we don’t have error bars for the ground truth. For a given sample size and drift magnitude, scipy’s result is deterministic, since we’re always using the complete data, whereas, for whylogs, the error bars represent the maximum and minimum values found in the 10 runs.

Note that, for medium and large drift cases, both y-axis are really close to 0, so even for a sample size of 500, both implementations result in a p-value of effectively 0, rightfully detecting the presence of drift. For the no drift and small drift scenarios, we can see that both implementations yield very similar results when comparing the mean p-value of the sketch-based implementation, but with some difference for specific runs, especially for large sized samples. However, for almost all cases, the ground truth lies somewhere in between the error bounds of the profiled case. It is also worth noting that, at a 95% confidence interval, both implementations would yield the same decision (drift vs. no drift) for all points in all scenarios.

KS test is really sensitive, and its sensitivity increases according to the sample size: in the small-drift scenario, for sample sizes greater than or equal to 5k, we reject the null hypothesis. Even though this is not technically wrong, we initially considered this case to be so small that it could be safely ignored.

At this point, we should ask ourselves whether this test is actually telling us what we care about. A p-value smaller than 0.05 tells us that these samples aren’t from identical populations, but it doesn’t tell us anything about the effect size. In other words, it tells us that there is a difference, but not how much of a difference there is. There might be statistical significance, but not an actual practical significance to it.

Experiment #2 — No. of Buckets

To get a discrete cumulative distribution, we first need to define the number of buckets. The sketch-based KS test will then use those buckets to calculate the statistics. We will run experiments with equally spaced bins of sizes: 5, 10, 50, and 100. For each of the 10 runs, we will calculate the absolute error between the exact and the sketch-based whylogs’ implementation and plot the mean, along with the error bars representing the minimum and maximum errors found. We will show those errors according to the sample size and drift magnitude, just like in the previous experiment.

whylogs’ current version has 100 as the default number of buckets, and that is also the value used in the previously shown results.

Image by author

Since some of the values in the graphs are much higher than the remaining ones, we’re breaking the y axis in some cases, to better visualize all the bars in the plot. Even so, some of the bars are still too small to be seen. The errors for the medium and large drift scenarios are very close to 0, meaning that both implementations get similar results.

Overall, the error’s mean seems to decrease when increasing the number of buckets. However, the variance of the errors increases for higher sample sizes, which is due to the increasing estimation errors in the profiling process.

The experiments so far show some degree of randomness for the no-drift scenario, for both implementations. Since the KS test relies solely on the maximum absolute difference between distributions, any slight changes resulting from the data generation process will greatly affect the no-drift scenario. For the remaining scenarios, the drift injected will outweigh these slight differences.

Experiment #3 — Profile Size

As previously stated, in a profile we have an approximate distribution in the format of a data sketch. A data sketch is configured with a parameter K, which dictates the profile’s size and its estimation error[2]. The higher this parameter, the lower the estimation error will be. All of the previous experiments were run with a K=1024, but now we want to see how the errors get affected with varying numbers of K.

This time, we will fix the sample size to 100k and the number of buckets to 100 and vary the K parameter to the following values: 256, 512, 1024, 2048, and 4096.

Image by author

We have omitted charts for drift sizes 0.4 and 0.75 due to the consistently small amounts of errors making visualization unnecessary.

The X-axis is shown according to the profile’s size when serialized: K values of 256, 512, 1024, 2048, and 4096 yield approximate profile sizes of 6KB, 11KB, 22KB, 43KB, and 83KB, respectively.

As seen before, any drifted scenario just shows how sensitive the KS test is. The bars can’t be seen for the medium and large drift scenarios because their values are effectively 0, but in the no-drift scenario we can see that the error is inversely proportional to the profile size, and by extension to the K parameter. By increasing K, the errors due to profiling decrease, approximating both implementation’s results.

We can also verify that, for this scenario, the errors are quite small. But if we are interested in minimizing those errors, we can sacrifice profile space for better results.

Conclusion

Let’s summarize some key takeaways from these experiments:

  • Performing the KS test on data profiles is possible, and the results are very close to the standard implementation. However, the results are non-deterministic.
  • KS test is very sensitive, and it tends to get even more sensitive with higher sample sizes. It might tell us whether there is a difference between distributions, but is insensitive to how much of a difference there is.
  • We can tune internal parameters for better results for the whylogs’ implementation. In particular, we can increase the profile size to get results closer to the ground truth.

We hope this helps in building intuition on how the KS test works along with data profiling. We also got to have a better understanding of KS test limitations. Motivated by that, we at whylogs are already implementing additional similarity measures! For instance, Hellinger distance is already implemented in whylogs, so stay tuned for more experiments and benchmarks!

Thank you for reading, and feel free to reach out if you have any questions/suggestions! If you’re interested in exploring whylogs in your projects, consider joining our Slack community to get support and also share feedback!

Understanding Kolmogorov-Smirnov (KS) Tests for Data Drift on Profiled Data was originally published by Towards Data Science.

References

[1] — Kolmogorov–Smirnov test. (2022, October 29). In Wikipedia. https://en.wikipedia.org/wiki/Kolmogorov%E2%80%93Smirnov_test

[2] — Karnin, Z., Lang, K., & Liberty, E. (2016). Optimal Quantile Approximation in Streams. arXiv. https://doi.org/10.48550/arXiv.1603.05346

Other posts

Achieving Ethical AI with Model Performance Tracing and ML Explainability

With Model Performance Tracing and ML Explainability, we’ve accelerated our customers’ journey toward achieving the three goals of ethical AI - fairness, accountability and transparency.

BigQuery Data Monitoring with WhyLabs

We’re excited to announce the release of a no-code solution for data monitoring in Google BigQuery, making it simple to monitor your data quality without writing a single line of code.

Robust & Responsible AI Newsletter - Issue #4

Every quarter we send out a roundup of the hottest MLOps and Data-Centric AI news including industry highlights, what’s brewing at WhyLabs, and more.

WhyLabs Private Beta: Real-time Data Monitoring on Prem

We’re excited to announce our Private Beta release of an extension service for the Profile Store, enabling production use cases of whylogs on customers' premises.

Re-imagine Data Monitoring with whylogs and Apache Spark

An overview of how the whylogs integration with Apache Spark achieves large scale data profiling, and how users can apply this integration into existing data and ML pipelines.

ML Monitoring in Under 5 Minutes

A quick guide to using whylogs and WhyLabs to monitor common issues with your ML models to surface data drift, concept drift, data quality, and performance issues.

AIShield and WhyLabs: Threat Detection and Monitoring for AI

The seamless integration of AIShield’s security insights on WhyLabs AI observability platform delivers comprehensive insights into ML workloads and brings security hardening to AI-powered enterprises.

Large Scale Data Profiling with whylogs and Fugue on Spark, Ray or Dask

Profiling large-scale data for use cases such as anomaly detection, drift detection, and data validation with Fugue on Spark, Ray or Dask.

Monitoring Image Data with whylogs v1

When operating computer vision systems, data quality and data drift issues always pose the risk of model performance degradation. Whylabs provides a simple yet highly customizable solution for maintaining observability into data to detect issues and take action sooner.
pre footer decoration
pre footer decoration
pre footer decoration

Run AI With Certainty

Book a demo
loading...