|
9 | 9 | "\n",
|
10 | 10 | "In this tutorial, we show how to conduct drift detection using CapyMOA\n",
|
11 | 11 | "\n",
|
12 |
| - "* Usage example of several detectors\n", |
| 12 | + "* Then test different drift detectors\n", |
13 | 13 | "* Example using ADWIN\n",
|
14 |
| - "* Evaluating detectors based on known drift locations\n", |
15 |
| - "* Multivariate drift detection using ABCD\n", |
| 14 | + "* Evaluating detectors based on known drift location\n", |
16 | 15 | "\n",
|
17 | 16 | "---\n",
|
18 | 17 | "\n",
|
19 | 18 | "*More information about CapyMOA can be found in* https://www.capymoa.org\n",
|
20 | 19 | "\n",
|
21 |
| - "**last update on 02/04/2025**" |
| 20 | + "**last update on 25/07/2024**" |
22 | 21 | ]
|
23 | 22 | },
|
24 | 23 | {
|
|
80 | 79 | "name": "stdout",
|
81 | 80 | "output_type": "stream",
|
82 | 81 | "text": [
|
83 |
| - "ADWIN 1\n", |
84 |
| - "CUSUM 2\n", |
| 82 | + "ADWIN 2\n", |
| 83 | + "CUSUM 1\n", |
85 | 84 | "DDM 1\n",
|
86 | 85 | "EWMAChart 1\n",
|
87 | 86 | "GeometricMovingAverage 1\n",
|
88 |
| - "HDDMAverage 130\n", |
89 |
| - "HDDMWeighted 100\n", |
90 |
| - "PageHinkley 2\n", |
| 87 | + "HDDMAverage 126\n", |
| 88 | + "HDDMWeighted 89\n", |
| 89 | + "PageHinkley 1\n", |
91 | 90 | "RDDM 2\n",
|
92 | 91 | "SEED 2\n",
|
93 | 92 | "STEPD 1\n",
|
94 | 93 | "ABCD 1\n",
|
95 |
| - "STUDD 0\n", |
96 | 94 | "dtype: int64\n"
|
97 | 95 | ]
|
98 | 96 | }
|
|
102 | 100 | "\n",
|
103 | 101 | "n_detections = {k: 0 for k in all_detectors}\n",
|
104 | 102 | "for detector_name in all_detectors:\n",
|
105 |
| - " if detector_name == 'STUDD':\n", |
106 |
| - " continue\n", |
107 |
| - " \n", |
108 | 103 | " detector = getattr(detectors, detector_name)()\n",
|
109 | 104 | "\n",
|
110 | 105 | " for i in range(2000):\n",
|
|
133 | 128 | "name": "stdout",
|
134 | 129 | "output_type": "stream",
|
135 | 130 | "text": [
|
136 |
| - "Change detected in data: 1 - at index: 25\n", |
137 |
| - "Change detected in data: 11 - at index: 1009\n" |
| 131 | + "Change detected in data: 1 - at index: 24\n", |
| 132 | + "Change detected in data: 6 - at index: 1010\n" |
138 | 133 | ]
|
139 | 134 | }
|
140 | 135 | ],
|
|
158 | 153 | {
|
159 | 154 | "data": {
|
160 | 155 | "text/plain": [
|
161 |
| - "[1010, 2026, 3010]" |
| 156 | + "[1011, 2025, 3011]" |
162 | 157 | ]
|
163 | 158 | },
|
164 | 159 | "execution_count": 5,
|
|
180 | 175 | {
|
181 | 176 | "data": {
|
182 | 177 | "text/plain": [
|
183 |
| - "[1009, 2024, 2025, 3009]" |
| 178 | + "[1009, 1010, 2022, 2023, 2024, 3009, 3010]" |
184 | 179 | ]
|
185 | 180 | },
|
186 | 181 | "execution_count": 6,
|
|
224 | 219 | "\n",
|
225 | 220 | "Assuming the drift locations are known, you can evaluate detectors using **EvaluateDetector** class\n",
|
226 | 221 | "\n",
|
227 |
| - "This class takes a parameter called **max_delay**, which is the maximum number of instances for which we consider a detector to have detected a change. After **max_delay** instances, we assume that the change is obvious and has been missed by the detector." |
| 222 | + "This class takes a parameter called **max_delay**, which is the maximum number of instances for which we consider a detector to have detected a change. After **max_delay** instances, we assume that the change is obvious and have been missed by the detector." |
228 | 223 | ]
|
229 | 224 | },
|
230 | 225 | {
|
231 | 226 | "cell_type": "code",
|
232 |
| - "execution_count": 5, |
| 227 | + "execution_count": 8, |
233 | 228 | "id": "598a89e7-8460-415f-8a92-6854509e4697",
|
234 | 229 | "metadata": {},
|
235 | 230 | "outputs": [],
|
236 | 231 | "source": [
|
237 |
| - "from capymoa.drift.eval_detector import EvaluateDriftDetector" |
| 232 | + "from capymoa.drift.eval_detector import EvaluateDetector" |
238 | 233 | ]
|
239 | 234 | },
|
240 | 235 | {
|
241 | 236 | "cell_type": "code",
|
242 |
| - "execution_count": 7, |
| 237 | + "execution_count": 9, |
243 | 238 | "id": "4a2df820-9314-42e8-bf37-575c837ffabe",
|
244 | 239 | "metadata": {},
|
245 | 240 | "outputs": [],
|
246 | 241 | "source": [
|
247 |
| - "drift_eval = EvaluateDriftDetector(max_delay=200)" |
| 242 | + "eval = EvaluateDetector(max_delay=200)" |
248 | 243 | ]
|
249 | 244 | },
|
250 | 245 | {
|
|
259 | 254 | },
|
260 | 255 | {
|
261 | 256 | "cell_type": "code",
|
262 |
| - "execution_count": 9, |
| 257 | + "execution_count": 10, |
263 | 258 | "id": "352a52da-71e0-4f7b-bf74-09230086b91a",
|
264 | 259 | "metadata": {},
|
265 | 260 | "outputs": [
|
266 | 261 | {
|
267 | 262 | "data": {
|
268 | 263 | "text/plain": [
|
269 |
| - "{'fp': 0,\n", |
270 |
| - " 'tp': 1,\n", |
271 |
| - " 'fn': 0,\n", |
272 |
| - " 'precision': 1.0,\n", |
273 |
| - " 'recall': 1.0,\n", |
274 |
| - " 'episode_recall': 1.0,\n", |
275 |
| - " 'f1': 1.0,\n", |
276 |
| - " 'mdt': np.float64(11.0),\n", |
277 |
| - " 'far': 0.0,\n", |
278 |
| - " 'ar': 0.25,\n", |
279 |
| - " 'n_episodes': 1,\n", |
280 |
| - " 'n_alarms': 1}" |
| 264 | + "mean_time_to_detect 11.0\n", |
| 265 | + "missed_detection_ratio 0.0\n", |
| 266 | + "mean_time_btw_false_alarms NaN\n", |
| 267 | + "no_alarms_per_episode 0.0\n", |
| 268 | + "dtype: float64" |
281 | 269 | ]
|
282 | 270 | },
|
283 |
| - "execution_count": 9, |
| 271 | + "execution_count": 10, |
284 | 272 | "metadata": {},
|
285 | 273 | "output_type": "execute_result"
|
286 | 274 | }
|
|
289 | 277 | "trues = np.array([1000])\n",
|
290 | 278 | "preds = detector.detection_index\n",
|
291 | 279 | "\n",
|
292 |
| - "drift_eval.calc_performance(trues, preds, tot_n_instances=detector.idx)" |
| 280 | + "eval.calc_performance(preds, trues)" |
293 | 281 | ]
|
294 | 282 | },
|
295 | 283 | {
|
|
488 | 476 | "name": "python",
|
489 | 477 | "nbconvert_exporter": "python",
|
490 | 478 | "pygments_lexer": "ipython3",
|
491 |
| - "version": "3.10.16" |
| 479 | + "version": "3.9.19" |
492 | 480 | }
|
493 | 481 | },
|
494 | 482 | "nbformat": 4,
|
|
0 commit comments