Skip to contents

Start with detect_drift()

detect_drift() is the high-level entry point: it wraps the detectors so you can run them with a single call.


Error-rate detectors (binary stream)

These methods work with an error stream like as.integer(y_pred != y_true).

set.seed(123)
error_stream <- c(
  rbinom(500, 1, 0.05),
  rbinom(500, 1, 0.30)
)

DDM

detect_drift(error_stream, method = "ddm", include_warnings = TRUE)
#>     index value    type
#> 1     401     1 warning
#> 2     402     0 warning
#> 3     403     0 warning
#> 4     404     0 warning
#> 5     405     0 warning
#> 6     406     0 warning
#> 7     407     0 warning
#> 8     408     0 warning
#> 9     409     0 warning
#> 10    410     0 warning
#> 11    411     0 warning
#> 12    412     0 warning
#> 13    413     0 warning
#> 14    417     1 warning
#> 15    418     0 warning
#> 16    419     0 warning
#> 17    420     0 warning
#> 18    421     0 warning
#> 19    422     0 warning
#> 20    423     0 warning
#> 21    424     0 warning
#> 22    425     0 warning
#> 23    426     0 warning
#> 24    427     0 warning
#> 25    431     1 warning
#> 26    432     0 warning
#> 27    433     0 warning
#> 28    434     1 warning
#> 29    435     0 warning
#> 30    436     0 warning
#> 31    437     0 warning
#> 32    438     0 warning
#> 33    439     0 warning
#> 34    440     0 warning
#> 35    441     0 warning
#> 36    442     0 warning
#> 37    443     0 warning
#> 38    444     0 warning
#> 39    445     0 warning
#> 40    446     0 warning
#> 41    447     0 warning
#> 42    448     0 warning
#> 43    449     0 warning
#> 44    450     0 warning
#> 45    451     0 warning
#> 46    452     0 warning
#> 47    453     0 warning
#> 48    454     0 warning
#> 49    455     0 warning
#> 50    456     0 warning
#> 51    461     1 warning
#> 52    462     0 warning
#> 53    463     0 warning
#> 54    464     0 warning
#> 55    465     0 warning
#> 56    466     0 warning
#> 57    467     0 warning
#> 58    468     0 warning
#> 59    469     0 warning
#> 60    470     0 warning
#> 61    496     1 warning
#> 62    497     0 warning
#> 63    498     0 warning
#> 64    509     1 warning
#> 65    510     0 warning
#> 66    511     0 warning
#> 67    512     0 warning
#> 68    513     1 warning
#> 69    514     0 warning
#> 70    515     1 warning
#> 71    516     0 warning
#> 72    517     0 warning
#> 73    518     1 warning
#> 74    519     0 warning
#> 75    520     1 warning
#> 76    521     0 warning
#> 77    522     0 warning
#> 78    523     0 warning
#> 79    524     0 warning
#> 80    525     0 warning
#> 81    526     0 warning
#> 82    527     1 warning
#> 83    528     0 warning
#> 84    529     1 warning
#> 85    530     0 warning
#> 86    531     1 warning
#> 87    532     0 warning
#> 88    533     0 warning
#> 89    534     1 warning
#> 90    535     0 warning
#> 91    536     1 warning
#> 92    537     0 warning
#> 93    538     1   drift
#> 94    623     1 warning
#> 95    638     1 warning
#> 96    639     1 warning
#> 97    640     0 warning
#> 98    642     1 warning
#> 99    643     1 warning
#> 100   644     0 warning
#> 101   645     0 warning
#> 102   647     1 warning
#> 103   648     0 warning
#> 104   652     1 warning
#> 105   653     0 warning
#> 106   655     1 warning
#> 107   656     1 warning
#> 108   657     1 warning
#> 109   658     0 warning
#> 110   659     0 warning
#> 111   660     0 warning
#> 112   661     1 warning
#> 113   662     1 warning
#> 114   663     0 warning
#> 115   664     1 warning
#> 116   665     0 warning
#> 117   666     0 warning
#> 118   667     1 warning
#> 119   668     0 warning
#> 120   669     0 warning
#> 121   670     0 warning
#> 122   685     1 warning

EDDM

detect_drift(error_stream, method = "eddm", include_warnings = TRUE)
#>   index value  type
#> 1   461     1 drift
#> 2   585     1 drift
#> 3   662     1 drift
#> 4   782     1 drift
#> 5   896     1 drift

HDDM-A

detect_drift(error_stream, method = "hddm_a", include_warnings = TRUE)
#>    index value    type
#> 1    548     1 warning
#> 2    549     1 warning
#> 3    550     0 warning
#> 4    551     0 warning
#> 5    552     0 warning
#> 6    553     0 warning
#> 7    554     1 warning
#> 8    555     0 warning
#> 9    556     0 warning
#> 10   557     0 warning
#> 11   558     0 warning
#> 12   559     0 warning
#> 13   560     0 warning
#> 14   562     1 warning
#> 15   563     1 warning
#> 16   564     0 warning
#> 17   565     0 warning
#> 18   566     0 warning
#> 19   567     0 warning
#> 20   568     1 warning
#> 21   569     0 warning
#> 22   570     1   drift

HDDM-W

detect_drift(error_stream, method = "hddm_w", include_warnings = TRUE)
#>   index value    type
#> 1   546     1 warning
#> 2   548     1 warning
#> 3   549     1   drift

Continuous-stream detectors (numeric stream)

These methods work with any numeric stream: a feature, a sensor, or a model score.

set.seed(1)
x <- c(rnorm(300, 0, 1), rnorm(200, 3, 1))

Page-Hinkley

detect_drift(x, method = "page_hinkley", delta = 0.05, threshold = 50)
#>   index    value  type
#> 1   315 2.964078 drift

ADWIN

detect_drift(x, method = "adwin", delta = 0.002)
#>   index    value  type
#> 1   320 3.494313 drift

KSWIN

head(detect_drift(x, method = "kswin", alpha = 0.001, window_size = 120, stat_size = 40), 1)
#>   index      value  type
#> 1   154 -0.9293621 drift

KL divergence (batch vs. batch)

KLDivergence compares two distributions (approximated via histograms) and can flag drift when the KL divergence crosses a threshold.

set.seed(42)
ref <- rnorm(400, mean = 0, sd = 1)
cur <- rnorm(400, mean = 1.5, sd = 1)

kld <- KLDivergence$new(bins = 30, drift_level = 0.15)
kld$set_initial_distribution(ref)
kld$add_distribution(cur)

data.frame(
  kl = kld$get_kl_result(),
  drift = kld$is_drift_detected()
)
#>         kl drift
#> 1 2.326739  TRUE

ProfileDifference (behavior drift)

ProfileDifference compares two profiles with shared x and y (e.g., PDPs, calibration curves, or any feature effect curve).

set.seed(123)
profile1 <- list(x = 1:100, y = sin(1:100))
profile2 <- list(x = 1:100, y = sin(1:100) + rnorm(100, 0, 0.2))

pd <- ProfileDifference$new(method = "pdi", deriv = "gold")
pd$set_profiles(profile1, profile2)
pd$calculate_difference()
#> $method
#> [1] "pdi"
#> 
#> $method_detail
#> [1] "gold_spline"
#> 
#> $distance
#> [1] 0.03780069
#> 
#> $der1
#>   [1] -0.556299786 -0.680888836 -0.707237688 -0.652151952 -0.532053347
#>   [6] -0.361728978 -0.155530956  0.070389101  0.291722081  0.481848509
#>  [11]  0.616852303  0.685867273  0.681959581  0.601284460  0.455874705
#>  [16]  0.262851448  0.040398589 -0.187490790 -0.394844588 -0.557383239
#>  [21] -0.660720740 -0.694052130 -0.649180777 -0.534125644 -0.363138432
#>  [26] -0.151637366  0.077290441  0.297429407  0.483641208  0.618502694
#>  [31]  0.687929291  0.679924567  0.598243129  0.453865805  0.258953193
#>  [36]  0.034943320 -0.192215608 -0.397172896 -0.560039600 -0.663738995
#>  [41] -0.692807344 -0.646623008 -0.532654653 -0.359498576 -0.146242397
#>  [46]  0.081974734  0.300239471  0.486862411  0.622121207  0.687488233
#>  [51]  0.677998213  0.597435772  0.450629791  0.253684301  0.030392689
#>  [56] -0.195384900 -0.400893505 -0.564174647 -0.664102408 -0.691546314
#>  [61] -0.646509291 -0.529949937 -0.354448417 -0.141931701  0.085362311
#>  [66]  0.304390737  0.491426946  0.623259682  0.686912521  0.678589207
#>  [71]  0.595371508  0.445889482  0.249710537  0.026938292 -0.199888138
#>  [76] -0.405794142 -0.566028836 -0.664218957 -0.692836840 -0.645171386
#>  [81] -0.525606869 -0.350897612 -0.138565826  0.090129502  0.309530064
#>  [86]  0.493909848  0.624061449  0.688882515  0.678036356  0.591507471
#>  [91]  0.442835799  0.246585611  0.022003496 -0.205166905 -0.408794804
#>  [96] -0.567493909 -0.666834933 -0.693097900 -0.641860543 -0.523112054
#> [101] -0.348156493 -0.133566796  0.095448575  0.312918462  0.496000745
#> [106]  0.627278004  0.689955371  0.675343075  0.589620584  0.440605603
#> [111]  0.241631089  0.016741437 -0.208799784 -0.411458008 -0.571255224
#> [116] -0.668686913 -0.691074492 -0.640617902 -0.521498786 -0.343358568
#> [121] -0.128455790  0.099175923  0.316084284  0.500242041  0.629847816
#> [126]  0.688639800  0.674768363  0.588704844  0.436077311  0.236760632
#> [131]  0.013069597 -0.212382614 -0.416106926 -0.574456341 -0.668100549
#> [136] -0.691178973 -0.640451916 -0.517351336 -0.338812524 -0.124982648
#> [141]  0.103074964  0.321062191  0.503967355  0.629993335  0.689422594
#> [146]  0.675374476  0.585044510  0.431932951  0.233616239  0.008969068
#> [151] -0.217605832 -0.420234639 -0.575315864 -0.669548946 -0.692550751
#> [156] -0.637376629 -0.513678469 -0.336109226 -0.120807429  0.108455937
#> [161]  0.325463888  0.505500951  0.632083116  0.691530595  0.672970216
#> [166]  0.581904659  0.429763960  0.229502722  0.000000000 -0.222152250
#> [171] -0.422379110 -0.578011634 -0.672344464 -0.690886793 -0.634822233
#> [176] -0.512117170 -0.332199239 -0.115383416  0.113020461  0.328130716
#> [181]  0.508756485  0.635501170  0.690651685  0.671043819  0.581004486
#> [186]  0.426197894  0.224195431  0.000000000 -0.225228971 -0.426137740
#> [191] -0.581974029 -0.672266692 -0.689620222 -0.634617083 -0.509027113
#> [196] -0.327100122 -0.111137518  0.116375166  0.332325780  0.513174836
#> [201]  0.636210286  0.690065204  0.671548908  0.578507805  0.421396191
#> [206]  0.220268079  0.000000000 -0.229784379 -0.430916375 -0.583425326
#> [211] -0.672368160 -0.690833287 -0.632810730 -0.504608351 -0.323582553
#> [216] -0.107671784  0.121206118  0.337364449  0.515294586  0.636994341
#> [221]  0.691967962  0.670504744  0.574552156  0.418367052  0.216977724
#> [226] -0.009441825 -0.234980717 -0.433604729 -0.584872644 -0.674927922
#> [231] -0.690594644 -0.629391216 -0.502133065 -0.320615865 -0.102574119
#> [236]  0.126457842  0.340499662  0.517371262  0.640165712  0.692547627
#> [241]  0.667685310  0.572682624  0.415859900  0.211900656 -0.014648640
#> [246] -0.238424462 -0.436261853 -0.588599233 -0.676307645 -0.688428136
#> [251] -0.628165798 -0.500203023 -0.315667110 -0.097508884  0.130061344
#> [256]  0.343673162  0.521587364  0.642297251  0.691073686  0.667128970
#> [261]  0.571424044  0.411148542  0.207068825 -0.018259388 -0.242035755
#> [266] -0.440894625 -0.591406691 -0.675548884 -0.688550608 -0.627646716
#> [271] -0.495843500 -0.311162696 -0.094038197  0.134041592  0.348674908
#> [276]  0.524964595  0.642170415  0.691754254  0.667407755  0.567851867
#> [281]  0.407500916  0.203822078 -0.023717565 -0.249014054 -0.444588759
#> [286] -0.587447540 -0.670430216 -0.689869516 -0.641253826 -0.516898689
#> [291] -0.308374510
#> 
#> $der2
#>   [1] -0.48266303 -0.64811565 -0.70077322 -0.66015318 -0.54478374 -0.36898085
#>   [7] -0.14593950  0.10650814  0.34950870  0.53825519  0.63597017  0.64463623
#>  [13]  0.57791563  0.45012621  0.27894407  0.08312154 -0.11805913 -0.30241564
#>  [19] -0.44677770 -0.53179724 -0.56045151 -0.54379857 -0.49101041 -0.39944204
#>  [25] -0.26190641 -0.07534719  0.13576812  0.33574386  0.49164321  0.59035496
#>  [31]  0.62734705  0.59957129  0.51498411  0.38659066  0.22740771  0.05033215
#>  [37] -0.13179743 -0.30620505 -0.46065645 -0.58319631 -0.66167370 -0.68209014
#>  [43] -0.62944007 -0.49152886 -0.28445246 -0.04062520  0.20767958  0.43183419
#>  [49]  0.60543533  0.70327405  0.71365712  0.63361109  0.46245048  0.22638010
#>  [55] -0.03005686 -0.26354310 -0.45220174 -0.58960764 -0.66977879 -0.68823401
#>  [61] -0.64163495 -0.52754994 -0.35759291 -0.15467419  0.05827960  0.26363608
#>  [67]  0.44825984  0.59902395  0.70024093  0.73392657  0.68292938  0.54920064
#>  [73]  0.35278380  0.11469038 -0.13817410 -0.37301010 -0.55719686 -0.66917095
#>  [79] -0.69904396 -0.63809054 -0.49463761 -0.29602334 -0.07051867  0.15564772
#>  [85]  0.35865150  0.51513423  0.61331537  0.65581010  0.64608258  0.58557039
#>  [91]  0.47304937  0.30735506  0.09821778 -0.12951487 -0.34988605 -0.53716228
#>  [97] -0.66593755 -0.71111534 -0.66460106 -0.54465309 -0.37180095 -0.16686860
#> [103]  0.04883747  0.25398398  0.42872751  0.55580747  0.61829635  0.60676635
#> [109]  0.52554829  0.38050863  0.18500995 -0.03302656 -0.24405480 -0.42570686
#> [115] -0.57038040 -0.67226178 -0.72004118 -0.69042864 -0.55864601 -0.32239289
#> [121] -0.03131299  0.25766941  0.49930783  0.67698180  0.77838351  0.79440839
#> [127]  0.72428573  0.56859670  0.33797748  0.07084389 -0.18963705 -0.40723209
#> [133] -0.56606138 -0.65396358 -0.66553379 -0.61644985 -0.52648921 -0.41011655
#> [139] -0.26416559 -0.08181802  0.13482337  0.35215698  0.52963276  0.63504319
#> [145]  0.66753005  0.63359752  0.54091401  0.40180502  0.22976032  0.03811626
#> [151] -0.16044397 -0.35341100 -0.52497818 -0.64439189 -0.67666516 -0.59886426
#> [157] -0.44623700 -0.27156320 -0.11736939  0.02655083  0.18730337  0.38115776
#> [163]  0.56497906  0.67539496  0.66182911  0.54852877  0.38682415  0.22129389
#> [169]  0.05423099 -0.12832479 -0.33443056 -0.53267498 -0.67554580 -0.72152514
#> [175] -0.67199838 -0.54691638 -0.36667889 -0.15452958  0.06498313  0.26802684
#> [181]  0.43664183  0.55572331  0.61145686  0.60109335  0.52758116  0.39522038
#> [187]  0.22049144  0.02651415 -0.16406941 -0.33407860 -0.46948302 -0.55674633
#> [193] -0.58725246 -0.55538735 -0.45645088 -0.29586959 -0.08560335  0.16080757
#> [199]  0.41135562  0.62143906  0.74800827  0.77238013  0.69343198  0.51242466
#> [205]  0.25999470 -0.01085457 -0.24844531 -0.43128300 -0.56214847 -0.64423899
#> [211] -0.67602463 -0.65196014 -0.56699546 -0.42794755 -0.25227749 -0.05761464
#> [217]  0.14278030  0.33978408  0.52387103  0.67251500  0.75018936  0.72214873
#> [223]  0.58787078  0.38296790  0.14456256 -0.09640316 -0.31587765 -0.49045416
#> [229] -0.60564103 -0.65744238 -0.64263580 -0.56405098 -0.43204261 -0.25753800
#> [235] -0.05553910  0.15360079  0.34922270  0.51329268  0.63141917  0.68956655
#> [241]  0.67824868  0.59465050  0.43674293  0.21776240 -0.02539311 -0.25394763
#> [247] -0.44015996 -0.57437445 -0.64863083 -0.65653838 -0.59442737 -0.45903769
#> [253] -0.26084051 -0.03549780  0.17872859  0.35547065  0.49146008  0.58606468
#> [259]  0.63596172  0.63229400  0.56556583  0.43444253  0.25537807  0.04717328
#> [265] -0.17045901 -0.37569839 -0.54643733 -0.66385148 -0.71716460 -0.69682056
#> [271] -0.59782957 -0.42708204 -0.19339109  0.08328202  0.35217638  0.55727305
#> [277]  0.66180090  0.68548836  0.65837299  0.60019253  0.49854530  0.33478120
#> [283]  0.10427543 -0.15105246 -0.37964111 -0.54167173 -0.63878664 -0.68177430
#> [289] -0.67921227 -0.63137004 -0.53656596
#> 
#> $x
#>   [1]   1   2   3   4   5   6   7   8   9  10  11  12  13  14  15  16  17  18
#>  [19]  19  20  21  22  23  24  25  26  27  28  29  30  31  32  33  34  35  36
#>  [37]  37  38  39  40  41  42  43  44  45  46  47  48  49  50  51  52  53  54
#>  [55]  55  56  57  58  59  60  61  62  63  64  65  66  67  68  69  70  71  72
#>  [73]  73  74  75  76  77  78  79  80  81  82  83  84  85  86  87  88  89  90
#>  [91]  91  92  93  94  95  96  97  98  99 100

References

The drift detection methods implemented in datadriftR are based on established algorithms from the streaming data mining literature.