├── .gitignore ├── Comparisons.ipynb ├── KDE.ipynb ├── Point processes.ipynb ├── Temporal points processes.ipynb ├── Temporal spatial processes.ipynb ├── readme.md └── utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | __pycache__ 2 | .ipy* 3 | -------------------------------------------------------------------------------- /Comparisons.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "code", 5 | "execution_count": 1, 6 | "metadata": { 7 | "collapsed": false 8 | }, 9 | "outputs": [], 10 | "source": [ 11 | "%matplotlib inline\n", 12 | "import matplotlib.pyplot as plt\n", 13 | "import numpy as np\n", 14 | "import pandas as pd\n", 15 | "import scipy.stats\n", 16 | "import scipy.integrate" 17 | ] 18 | }, 19 | { 20 | "cell_type": "markdown", 21 | "metadata": {}, 22 | "source": [ 23 | "# Comparisons\n", 24 | "\n", 25 | "To make things really easy, let's ignore time, and work in one dimension. Events will take place in $[0,1]$.\n", 26 | "\n", 27 | "## Example 1\n", 28 | "\n", 29 | "Actual pattern is [CSR](https://en.wikipedia.org/wiki/Complete_spatial_randomness) with some overall rate (say 10 events, on average). One \"prediction\" is the same, other other is a inhomogeneous Poisson process with intensity $2t$ for $0\\leq t\\leq 1$.\n", 30 | "\n", 31 | "## Hit rate\n", 32 | "\n", 33 | "We put a grid down (chunk $[0,1]$ into intervals), select 5% (or whatever) of the intervals by risk, and see how many events we capture. If grid cells have the same risk, we'll break at random.\n", 34 | "\n", 35 | "We cannot tell the difference (as should be)." 36 | ] 37 | }, 38 | { 39 | "cell_type": "code", 40 | "execution_count": 2, 41 | "metadata": { 42 | "collapsed": false 43 | }, 44 | "outputs": [], 45 | "source": [ 46 | "def coverage1(total_cells, cells_to_pick):\n", 47 | " # Homogeneous, so pick at random\n", 48 | " return np.random.choice(total_cells, size=cells_to_pick, replace=False)\n", 49 | " \n", 50 | "def coverage2(total_cells, cells_to_pick):\n", 51 | " # Intensity increases, so top slice will always pick the last cells\n", 52 | " return np.arange(total_cells)[-cells_to_pick:]\n", 53 | "\n", 54 | "assert np.all(coverage2(10, 3) == [7,8,9])\n", 55 | "\n", 56 | "def score(events, total_cells, cells):\n", 57 | " count = 0\n", 58 | " for t in events:\n", 59 | " t = int(np.floor(t * total_cells))\n", 60 | " if t in cells:\n", 61 | " count += 1\n", 62 | " return count / len(events)" 63 | ] 64 | }, 65 | { 66 | "cell_type": "code", 67 | "execution_count": 3, 68 | "metadata": { 69 | "collapsed": false 70 | }, 71 | "outputs": [], 72 | "source": [ 73 | "trials = 10000\n", 74 | "cells = 10\n", 75 | "coverage = 3\n", 76 | "\n", 77 | "hit_rate_1 = []\n", 78 | "hit_rate_2 = []\n", 79 | "for _ in range(trials):\n", 80 | " num_events = np.random.poisson(lam=10)\n", 81 | " events = np.random.random(size=num_events)\n", 82 | " if len(events) == 0:\n", 83 | " continue\n", 84 | " pred1 = coverage1(cells, coverage)\n", 85 | " pred2 = coverage2(cells, coverage)\n", 86 | " hit_rate_1.append( score(events, cells, pred1) )\n", 87 | " hit_rate_2.append( score(events, cells, pred2) )" 88 | ] 89 | }, 90 | { 91 | "cell_type": "code", 92 | "execution_count": 4, 93 | "metadata": { 94 | "collapsed": false 95 | }, 96 | "outputs": [ 97 | { 98 | "data": { 99 | "text/html": [ 100 | "
\n", 101 | "\n", 102 | " \n", 103 | " \n", 104 | " \n", 105 | " \n", 106 | " \n", 107 | " \n", 108 | " \n", 109 | " \n", 110 | " \n", 111 | " \n", 112 | " \n", 113 | " \n", 114 | " \n", 115 | " \n", 116 | " \n", 117 | " \n", 118 | " \n", 119 | " \n", 120 | " \n", 121 | " \n", 122 | " \n", 123 | " \n", 124 | " \n", 125 | " \n", 126 | " \n", 127 | " \n", 128 | " \n", 129 | " \n", 130 | " \n", 131 | " \n", 132 | " \n", 133 | " \n", 134 | " \n", 135 | " \n", 136 | " \n", 137 | " \n", 138 | " \n", 139 | " \n", 140 | " \n", 141 | " \n", 142 | " \n", 143 | " \n", 144 | " \n", 145 | " \n", 146 | " \n", 147 | " \n", 148 | " \n", 149 | " \n", 150 | " \n", 151 | "
OneTwo
count10000.00000010000.000000
mean0.3026640.299560
std0.1550890.156065
min0.0000000.000000
25%0.2000000.200000
50%0.3000000.285714
75%0.4000000.400000
max1.0000001.000000
\n", 152 | "
" 153 | ], 154 | "text/plain": [ 155 | " One Two\n", 156 | "count 10000.000000 10000.000000\n", 157 | "mean 0.302664 0.299560\n", 158 | "std 0.155089 0.156065\n", 159 | "min 0.000000 0.000000\n", 160 | "25% 0.200000 0.200000\n", 161 | "50% 0.300000 0.285714\n", 162 | "75% 0.400000 0.400000\n", 163 | "max 1.000000 1.000000" 164 | ] 165 | }, 166 | "execution_count": 4, 167 | "metadata": {}, 168 | "output_type": "execute_result" 169 | } 170 | ], 171 | "source": [ 172 | "pd.DataFrame({\"One\":hit_rate_1, \"Two\":hit_rate_2}).describe()" 173 | ] 174 | }, 175 | { 176 | "cell_type": "markdown", 177 | "metadata": {}, 178 | "source": [ 179 | "## Likelihood\n", 180 | "\n", 181 | "For each prediction, compute the likelihood of the events, the product of density function evaluated at each point. As ever, we really work with log likelihood, to avoid numerical errors. We can then:\n", 182 | "\n", 183 | "- Compute the likelihood ratio, to see which prediction is closer. This strongly favours model 1.\n", 184 | "- Normalise to give some absolute likelihood. Model 1 again is favoured." 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 5, 190 | "metadata": { 191 | "collapsed": true 192 | }, 193 | "outputs": [], 194 | "source": [ 195 | "def likelihood1(events):\n", 196 | " return 0\n", 197 | "\n", 198 | "def likelihood2(events):\n", 199 | " return np.sum(np.log(np.asarray(events) * 2))" 200 | ] 201 | }, 202 | { 203 | "cell_type": "code", 204 | "execution_count": 6, 205 | "metadata": { 206 | "collapsed": false 207 | }, 208 | "outputs": [], 209 | "source": [ 210 | "ratios = []\n", 211 | "\n", 212 | "for _ in range(10000):\n", 213 | " num_events = np.random.poisson(lam=10)\n", 214 | " events = np.random.random(size=num_events)\n", 215 | " log_ratio = likelihood1(events) - likelihood2(events)\n", 216 | " ratios.append(log_ratio)" 217 | ] 218 | }, 219 | { 220 | "cell_type": "code", 221 | "execution_count": 7, 222 | "metadata": { 223 | "collapsed": false 224 | }, 225 | "outputs": [ 226 | { 227 | "data": { 228 | "text/html": [ 229 | "
\n", 230 | "\n", 231 | " \n", 232 | " \n", 233 | " \n", 234 | " \n", 235 | " \n", 236 | " \n", 237 | " \n", 238 | " \n", 239 | " \n", 240 | " \n", 241 | " \n", 242 | " \n", 243 | " \n", 244 | " \n", 245 | " \n", 246 | " \n", 247 | " \n", 248 | " \n", 249 | " \n", 250 | " \n", 251 | " \n", 252 | " \n", 253 | " \n", 254 | " \n", 255 | " \n", 256 | " \n", 257 | " \n", 258 | " \n", 259 | " \n", 260 | " \n", 261 | " \n", 262 | " \n", 263 | " \n", 264 | " \n", 265 | " \n", 266 | " \n", 267 | " \n", 268 | " \n", 269 | " \n", 270 | " \n", 271 | "
0
count10000.000000
mean3.063269
std3.319015
min-4.781459
25%0.640241
50%2.633811
75%4.994303
max20.325528
\n", 272 | "
" 273 | ], 274 | "text/plain": [ 275 | " 0\n", 276 | "count 10000.000000\n", 277 | "mean 3.063269\n", 278 | "std 3.319015\n", 279 | "min -4.781459\n", 280 | "25% 0.640241\n", 281 | "50% 2.633811\n", 282 | "75% 4.994303\n", 283 | "max 20.325528" 284 | ] 285 | }, 286 | "execution_count": 7, 287 | "metadata": {}, 288 | "output_type": "execute_result" 289 | } 290 | ], 291 | "source": [ 292 | "pd.DataFrame(ratios).describe()" 293 | ] 294 | }, 295 | { 296 | "cell_type": "code", 297 | "execution_count": 8, 298 | "metadata": { 299 | "collapsed": true 300 | }, 301 | "outputs": [], 302 | "source": [ 303 | "one, two = [], []\n", 304 | "for _ in range(10000):\n", 305 | " num_events = np.random.poisson(lam=10)\n", 306 | " events = np.random.random(size=num_events)\n", 307 | " if len(events) == 0:\n", 308 | " continue\n", 309 | " one.append( likelihood1(events) / len(events) )\n", 310 | " two.append( likelihood2(events) / len(events) )" 311 | ] 312 | }, 313 | { 314 | "cell_type": "code", 315 | "execution_count": 9, 316 | "metadata": { 317 | "collapsed": false 318 | }, 319 | "outputs": [ 320 | { 321 | "data": { 322 | "text/html": [ 323 | "
\n", 324 | "\n", 325 | " \n", 326 | " \n", 327 | " \n", 328 | " \n", 329 | " \n", 330 | " \n", 331 | " \n", 332 | " \n", 333 | " \n", 334 | " \n", 335 | " \n", 336 | " \n", 337 | " \n", 338 | " \n", 339 | " \n", 340 | " \n", 341 | " \n", 342 | " \n", 343 | " \n", 344 | " \n", 345 | " \n", 346 | " \n", 347 | " \n", 348 | " \n", 349 | " \n", 350 | " \n", 351 | " \n", 352 | " \n", 353 | " \n", 354 | " \n", 355 | " \n", 356 | " \n", 357 | " \n", 358 | " \n", 359 | " \n", 360 | " \n", 361 | " \n", 362 | " \n", 363 | " \n", 364 | " \n", 365 | " \n", 366 | " \n", 367 | " \n", 368 | " \n", 369 | " \n", 370 | " \n", 371 | " \n", 372 | " \n", 373 | " \n", 374 | "
onetwo
count10000.010000.000000
mean0.0-0.302210
std0.00.334594
min0.0-2.553526
25%0.0-0.492402
50%0.0-0.268450
75%0.0-0.069880
max0.00.670229
\n", 375 | "
" 376 | ], 377 | "text/plain": [ 378 | " one two\n", 379 | "count 10000.0 10000.000000\n", 380 | "mean 0.0 -0.302210\n", 381 | "std 0.0 0.334594\n", 382 | "min 0.0 -2.553526\n", 383 | "25% 0.0 -0.492402\n", 384 | "50% 0.0 -0.268450\n", 385 | "75% 0.0 -0.069880\n", 386 | "max 0.0 0.670229" 387 | ] 388 | }, 389 | "execution_count": 9, 390 | "metadata": {}, 391 | "output_type": "execute_result" 392 | } 393 | ], 394 | "source": [ 395 | "pd.DataFrame({\"one\":one, \"two\":two}).describe()" 396 | ] 397 | }, 398 | { 399 | "cell_type": "markdown", 400 | "metadata": {}, 401 | "source": [ 402 | "## KDE and mean squared error\n", 403 | "\n", 404 | "Use the events and KDE to estimate a \"real\" density, and compare this with the model by integrating the error.\n", 405 | "\n", 406 | "This again favours model 1 (smaller average error)." 407 | ] 408 | }, 409 | { 410 | "cell_type": "code", 411 | "execution_count": 10, 412 | "metadata": { 413 | "collapsed": false 414 | }, 415 | "outputs": [ 416 | { 417 | "data": { 418 | "text/plain": [ 419 | "[]" 420 | ] 421 | }, 422 | "execution_count": 10, 423 | "metadata": {}, 424 | "output_type": "execute_result" 425 | }, 426 | { 427 | "data": { 428 | "image/png": "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\n", 429 | "text/plain": [ 430 | "" 431 | ] 432 | }, 433 | "metadata": {}, 434 | "output_type": "display_data" 435 | } 436 | ], 437 | "source": [ 438 | "events = np.random.random(size=10)\n", 439 | "kernel = scipy.stats.kde.gaussian_kde(events)\n", 440 | "\n", 441 | "fig, ax = plt.subplots(figsize=(8,6))\n", 442 | "ax.scatter(events, [0.1 for e in events])\n", 443 | "x = np.linspace(0, 1, 100)\n", 444 | "ax.plot(x, kernel(x))" 445 | ] 446 | }, 447 | { 448 | "cell_type": "code", 449 | "execution_count": 11, 450 | "metadata": { 451 | "collapsed": true 452 | }, 453 | "outputs": [], 454 | "source": [ 455 | "def func1(x):\n", 456 | " return 1\n", 457 | "\n", 458 | "def func2(x):\n", 459 | " return 2 * x" 460 | ] 461 | }, 462 | { 463 | "cell_type": "code", 464 | "execution_count": 12, 465 | "metadata": { 466 | "collapsed": false 467 | }, 468 | "outputs": [], 469 | "source": [ 470 | "errors = []\n", 471 | "for _ in range(10000):\n", 472 | " num_events = np.random.poisson(lam=10)\n", 473 | " events = np.random.random(size=num_events)\n", 474 | " if len(events) < 2:\n", 475 | " continue\n", 476 | " kernel = scipy.stats.kde.gaussian_kde(events)\n", 477 | " e1, _ = scipy.integrate.quad(lambda x : (kernel(x) - func1(x))**2, 0, 1)\n", 478 | " e2, _ = scipy.integrate.quad(lambda x : (kernel(x) - func2(x))**2, 0, 1)\n", 479 | " errors.append((e1, e2))" 480 | ] 481 | }, 482 | { 483 | "cell_type": "code", 484 | "execution_count": 13, 485 | "metadata": { 486 | "collapsed": false 487 | }, 488 | "outputs": [ 489 | { 490 | "data": { 491 | "text/html": [ 492 | "
\n", 493 | "\n", 494 | " \n", 495 | " \n", 496 | " \n", 497 | " \n", 498 | " \n", 499 | " \n", 500 | " \n", 501 | " \n", 502 | " \n", 503 | " \n", 504 | " \n", 505 | " \n", 506 | " \n", 507 | " \n", 508 | " \n", 509 | " \n", 510 | " \n", 511 | " \n", 512 | " \n", 513 | " \n", 514 | " \n", 515 | " \n", 516 | " \n", 517 | " \n", 518 | " \n", 519 | " \n", 520 | " \n", 521 | " \n", 522 | " \n", 523 | " \n", 524 | " \n", 525 | " \n", 526 | " \n", 527 | " \n", 528 | " \n", 529 | " \n", 530 | " \n", 531 | " \n", 532 | " \n", 533 | " \n", 534 | " \n", 535 | " \n", 536 | " \n", 537 | " \n", 538 | " \n", 539 | " \n", 540 | " \n", 541 | " \n", 542 | " \n", 543 | "
onetwo
count9996.0000009996.000000
mean0.1461970.477317
std0.2766290.383686
min0.0310760.039300
25%0.0643860.275886
50%0.0925970.410025
75%0.1533320.588994
max12.79090614.769045
\n", 544 | "
" 545 | ], 546 | "text/plain": [ 547 | " one two\n", 548 | "count 9996.000000 9996.000000\n", 549 | "mean 0.146197 0.477317\n", 550 | "std 0.276629 0.383686\n", 551 | "min 0.031076 0.039300\n", 552 | "25% 0.064386 0.275886\n", 553 | "50% 0.092597 0.410025\n", 554 | "75% 0.153332 0.588994\n", 555 | "max 12.790906 14.769045" 556 | ] 557 | }, 558 | "execution_count": 13, 559 | "metadata": {}, 560 | "output_type": "execute_result" 561 | } 562 | ], 563 | "source": [ 564 | "pd.DataFrame({\"one\":[p[0] for p in errors], \"two\":[p[1] for p in errors]}).describe()" 565 | ] 566 | }, 567 | { 568 | "cell_type": "markdown", 569 | "metadata": {}, 570 | "source": [ 571 | "# Nothing special about CSR\n", 572 | "\n", 573 | "Let's do the same, with the same models, but now \"ground truth\" will be that events are twice as likely in $[0,1/2]$ as opposed to $[1/2,1]$.\n", 574 | "\n", 575 | "The results are the same, except that now \"hit rate\" also favours model 1." 576 | ] 577 | }, 578 | { 579 | "cell_type": "code", 580 | "execution_count": 14, 581 | "metadata": { 582 | "collapsed": false 583 | }, 584 | "outputs": [ 585 | { 586 | "data": { 587 | "image/png": "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\n", 588 | "text/plain": [ 589 | "" 590 | ] 591 | }, 592 | "metadata": {}, 593 | "output_type": "display_data" 594 | } 595 | ], 596 | "source": [ 597 | "def make_events(average_number):\n", 598 | " num_events = np.random.poisson(lam=average_number)\n", 599 | " events = np.random.random(size=num_events) * 1.5\n", 600 | " mask = events < 1\n", 601 | " events[mask] = events[mask] * 0.5\n", 602 | " events[~mask] = events[~mask] - 0.5\n", 603 | " return events\n", 604 | "\n", 605 | "plt.hist(make_events(100000), bins=np.linspace(0, 1, 20))\n", 606 | "None" 607 | ] 608 | }, 609 | { 610 | "cell_type": "code", 611 | "execution_count": 15, 612 | "metadata": { 613 | "collapsed": false 614 | }, 615 | "outputs": [ 616 | { 617 | "data": { 618 | "text/html": [ 619 | "
\n", 620 | "\n", 621 | " \n", 622 | " \n", 623 | " \n", 624 | " \n", 625 | " \n", 626 | " \n", 627 | " \n", 628 | " \n", 629 | " \n", 630 | " \n", 631 | " \n", 632 | " \n", 633 | " \n", 634 | " \n", 635 | " \n", 636 | " \n", 637 | " \n", 638 | " \n", 639 | " \n", 640 | " \n", 641 | " \n", 642 | " \n", 643 | " \n", 644 | " \n", 645 | " \n", 646 | " \n", 647 | " \n", 648 | " \n", 649 | " \n", 650 | " \n", 651 | " \n", 652 | " \n", 653 | " \n", 654 | " \n", 655 | " \n", 656 | " \n", 657 | " \n", 658 | " \n", 659 | " \n", 660 | " \n", 661 | " \n", 662 | " \n", 663 | " \n", 664 | " \n", 665 | " \n", 666 | " \n", 667 | " \n", 668 | " \n", 669 | " \n", 670 | "
OneTwo
count10000.00000010000.000000
mean0.3025550.199724
std0.1604720.136016
min0.0000000.000000
25%0.2000000.100000
50%0.2941180.187500
75%0.4000000.285714
max1.0000001.000000
\n", 671 | "
" 672 | ], 673 | "text/plain": [ 674 | " One Two\n", 675 | "count 10000.000000 10000.000000\n", 676 | "mean 0.302555 0.199724\n", 677 | "std 0.160472 0.136016\n", 678 | "min 0.000000 0.000000\n", 679 | "25% 0.200000 0.100000\n", 680 | "50% 0.294118 0.187500\n", 681 | "75% 0.400000 0.285714\n", 682 | "max 1.000000 1.000000" 683 | ] 684 | }, 685 | "execution_count": 15, 686 | "metadata": {}, 687 | "output_type": "execute_result" 688 | } 689 | ], 690 | "source": [ 691 | "trials = 10000\n", 692 | "cells = 10\n", 693 | "coverage = 3\n", 694 | "\n", 695 | "hit_rate_1 = []\n", 696 | "hit_rate_2 = []\n", 697 | "for _ in range(trials):\n", 698 | " events = make_events(10)\n", 699 | " if len(events) == 0:\n", 700 | " continue\n", 701 | " pred1 = coverage1(cells, coverage)\n", 702 | " pred2 = coverage2(cells, coverage)\n", 703 | " hit_rate_1.append( score(events, cells, pred1) )\n", 704 | " hit_rate_2.append( score(events, cells, pred2) )\n", 705 | "\n", 706 | "pd.DataFrame({\"One\":hit_rate_1, \"Two\":hit_rate_2}).describe()" 707 | ] 708 | }, 709 | { 710 | "cell_type": "code", 711 | "execution_count": 16, 712 | "metadata": { 713 | "collapsed": false 714 | }, 715 | "outputs": [ 716 | { 717 | "data": { 718 | "text/html": [ 719 | "
\n", 720 | "\n", 721 | " \n", 722 | " \n", 723 | " \n", 724 | " \n", 725 | " \n", 726 | " \n", 727 | " \n", 728 | " \n", 729 | " \n", 730 | " \n", 731 | " \n", 732 | " \n", 733 | " \n", 734 | " \n", 735 | " \n", 736 | " \n", 737 | " \n", 738 | " \n", 739 | " \n", 740 | " \n", 741 | " \n", 742 | " \n", 743 | " \n", 744 | " \n", 745 | " \n", 746 | " \n", 747 | " \n", 748 | " \n", 749 | " \n", 750 | " \n", 751 | " \n", 752 | " \n", 753 | " \n", 754 | " \n", 755 | " \n", 756 | " \n", 757 | " \n", 758 | " \n", 759 | " \n", 760 | " \n", 761 | "
0
count10000.000000
mean5.419622
std3.777092
min-3.657635
25%2.688512
50%4.904619
75%7.595387
max24.506569
\n", 762 | "
" 763 | ], 764 | "text/plain": [ 765 | " 0\n", 766 | "count 10000.000000\n", 767 | "mean 5.419622\n", 768 | "std 3.777092\n", 769 | "min -3.657635\n", 770 | "25% 2.688512\n", 771 | "50% 4.904619\n", 772 | "75% 7.595387\n", 773 | "max 24.506569" 774 | ] 775 | }, 776 | "execution_count": 16, 777 | "metadata": {}, 778 | "output_type": "execute_result" 779 | } 780 | ], 781 | "source": [ 782 | "ratios = []\n", 783 | "\n", 784 | "for _ in range(10000):\n", 785 | " events = make_events(10)\n", 786 | " log_ratio = likelihood1(events) - likelihood2(events)\n", 787 | " ratios.append(log_ratio)\n", 788 | " \n", 789 | "pd.DataFrame(ratios).describe()" 790 | ] 791 | }, 792 | { 793 | "cell_type": "code", 794 | "execution_count": 17, 795 | "metadata": { 796 | "collapsed": false 797 | }, 798 | "outputs": [ 799 | { 800 | "data": { 801 | "text/html": [ 802 | "
\n", 803 | "\n", 804 | " \n", 805 | " \n", 806 | " \n", 807 | " \n", 808 | " \n", 809 | " \n", 810 | " \n", 811 | " \n", 812 | " \n", 813 | " \n", 814 | " \n", 815 | " \n", 816 | " \n", 817 | " \n", 818 | " \n", 819 | " \n", 820 | " \n", 821 | " \n", 822 | " \n", 823 | " \n", 824 | " \n", 825 | " \n", 826 | " \n", 827 | " \n", 828 | " \n", 829 | " \n", 830 | " \n", 831 | " \n", 832 | " \n", 833 | " \n", 834 | " \n", 835 | " \n", 836 | " \n", 837 | " \n", 838 | " \n", 839 | " \n", 840 | " \n", 841 | " \n", 842 | " \n", 843 | " \n", 844 | " \n", 845 | " \n", 846 | " \n", 847 | " \n", 848 | " \n", 849 | " \n", 850 | " \n", 851 | " \n", 852 | " \n", 853 | "
onetwo
count9998.09998.000000
mean0.0-0.537126
std0.00.354822
min0.0-2.881477
25%0.0-0.742671
50%0.0-0.500278
75%0.0-0.295465
max0.00.440049
\n", 854 | "
" 855 | ], 856 | "text/plain": [ 857 | " one two\n", 858 | "count 9998.0 9998.000000\n", 859 | "mean 0.0 -0.537126\n", 860 | "std 0.0 0.354822\n", 861 | "min 0.0 -2.881477\n", 862 | "25% 0.0 -0.742671\n", 863 | "50% 0.0 -0.500278\n", 864 | "75% 0.0 -0.295465\n", 865 | "max 0.0 0.440049" 866 | ] 867 | }, 868 | "execution_count": 17, 869 | "metadata": {}, 870 | "output_type": "execute_result" 871 | } 872 | ], 873 | "source": [ 874 | "one, two = [], []\n", 875 | "for _ in range(10000):\n", 876 | " events = make_events(10)\n", 877 | " if len(events) == 0:\n", 878 | " continue\n", 879 | " one.append( likelihood1(events) / len(events) )\n", 880 | " two.append( likelihood2(events) / len(events) )\n", 881 | "pd.DataFrame({\"one\":one, \"two\":two}).describe()" 882 | ] 883 | }, 884 | { 885 | "cell_type": "code", 886 | "execution_count": 18, 887 | "metadata": { 888 | "collapsed": true 889 | }, 890 | "outputs": [], 891 | "source": [ 892 | "errors = []\n", 893 | "for _ in range(10000):\n", 894 | " events = make_events(10)\n", 895 | " if len(events) < 2:\n", 896 | " continue\n", 897 | " kernel = scipy.stats.kde.gaussian_kde(events)\n", 898 | " e1, _ = scipy.integrate.quad(lambda x : (kernel(x) - func1(x))**2, 0, 1)\n", 899 | " e2, _ = scipy.integrate.quad(lambda x : (kernel(x) - func2(x))**2, 0, 1)\n", 900 | " errors.append((e1, e2))" 901 | ] 902 | }, 903 | { 904 | "cell_type": "code", 905 | "execution_count": 19, 906 | "metadata": { 907 | "collapsed": false 908 | }, 909 | "outputs": [ 910 | { 911 | "data": { 912 | "text/html": [ 913 | "
\n", 914 | "\n", 915 | " \n", 916 | " \n", 917 | " \n", 918 | " \n", 919 | " \n", 920 | " \n", 921 | " \n", 922 | " \n", 923 | " \n", 924 | " \n", 925 | " \n", 926 | " \n", 927 | " \n", 928 | " \n", 929 | " \n", 930 | " \n", 931 | " \n", 932 | " \n", 933 | " \n", 934 | " \n", 935 | " \n", 936 | " \n", 937 | " \n", 938 | " \n", 939 | " \n", 940 | " \n", 941 | " \n", 942 | " \n", 943 | " \n", 944 | " \n", 945 | " \n", 946 | " \n", 947 | " \n", 948 | " \n", 949 | " \n", 950 | " \n", 951 | " \n", 952 | " \n", 953 | " \n", 954 | " \n", 955 | " \n", 956 | " \n", 957 | " \n", 958 | " \n", 959 | " \n", 960 | " \n", 961 | " \n", 962 | " \n", 963 | " \n", 964 | "
onetwo
count9992.0000009992.000000
mean0.2007300.762903
std0.2795270.461152
min0.0322370.054530
25%0.0768750.481650
50%0.1252530.669875
75%0.2294430.936467
max10.07852210.682809
\n", 965 | "
" 966 | ], 967 | "text/plain": [ 968 | " one two\n", 969 | "count 9992.000000 9992.000000\n", 970 | "mean 0.200730 0.762903\n", 971 | "std 0.279527 0.461152\n", 972 | "min 0.032237 0.054530\n", 973 | "25% 0.076875 0.481650\n", 974 | "50% 0.125253 0.669875\n", 975 | "75% 0.229443 0.936467\n", 976 | "max 10.078522 10.682809" 977 | ] 978 | }, 979 | "execution_count": 19, 980 | "metadata": {}, 981 | "output_type": "execute_result" 982 | } 983 | ], 984 | "source": [ 985 | "pd.DataFrame({\"one\":[p[0] for p in errors], \"two\":[p[1] for p in errors]}).describe()" 986 | ] 987 | }, 988 | { 989 | "cell_type": "markdown", 990 | "metadata": {}, 991 | "source": [ 992 | "# Finally...\n", 993 | "\n", 994 | "Flip it about, now \"ground truth\" will be that events are twice as likely in $[1/2,1]$ as opposed to $[0,1/2]$.\n", 995 | "\n", 996 | "Now hit rate favours model 2. Likelihood favours (weakly) model 1. KDE favours model 1." 997 | ] 998 | }, 999 | { 1000 | "cell_type": "code", 1001 | "execution_count": 20, 1002 | "metadata": { 1003 | "collapsed": false 1004 | }, 1005 | "outputs": [ 1006 | { 1007 | "data": { 1008 | "image/png": "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\n", 1009 | "text/plain": [ 1010 | "" 1011 | ] 1012 | }, 1013 | "metadata": {}, 1014 | "output_type": "display_data" 1015 | } 1016 | ], 1017 | "source": [ 1018 | "def make_events1(average_number):\n", 1019 | " return 1 - make_events(average_number)\n", 1020 | "\n", 1021 | "plt.hist(make_events1(100000), bins=np.linspace(0, 1, 20))\n", 1022 | "None" 1023 | ] 1024 | }, 1025 | { 1026 | "cell_type": "code", 1027 | "execution_count": 21, 1028 | "metadata": { 1029 | "collapsed": false 1030 | }, 1031 | "outputs": [ 1032 | { 1033 | "data": { 1034 | "text/html": [ 1035 | "
\n", 1036 | "\n", 1037 | " \n", 1038 | " \n", 1039 | " \n", 1040 | " \n", 1041 | " \n", 1042 | " \n", 1043 | " \n", 1044 | " \n", 1045 | " \n", 1046 | " \n", 1047 | " \n", 1048 | " \n", 1049 | " \n", 1050 | " \n", 1051 | " \n", 1052 | " \n", 1053 | " \n", 1054 | " \n", 1055 | " \n", 1056 | " \n", 1057 | " \n", 1058 | " \n", 1059 | " \n", 1060 | " \n", 1061 | " \n", 1062 | " \n", 1063 | " \n", 1064 | " \n", 1065 | " \n", 1066 | " \n", 1067 | " \n", 1068 | " \n", 1069 | " \n", 1070 | " \n", 1071 | " \n", 1072 | " \n", 1073 | " \n", 1074 | " \n", 1075 | " \n", 1076 | " \n", 1077 | " \n", 1078 | " \n", 1079 | " \n", 1080 | " \n", 1081 | " \n", 1082 | " \n", 1083 | " \n", 1084 | " \n", 1085 | " \n", 1086 | "
OneTwo
count9999.0000009999.000000
mean0.2990050.401429
std0.1617170.163036
min0.0000000.000000
25%0.1818180.285714
50%0.2857140.400000
75%0.4000000.500000
max1.0000001.000000
\n", 1087 | "
" 1088 | ], 1089 | "text/plain": [ 1090 | " One Two\n", 1091 | "count 9999.000000 9999.000000\n", 1092 | "mean 0.299005 0.401429\n", 1093 | "std 0.161717 0.163036\n", 1094 | "min 0.000000 0.000000\n", 1095 | "25% 0.181818 0.285714\n", 1096 | "50% 0.285714 0.400000\n", 1097 | "75% 0.400000 0.500000\n", 1098 | "max 1.000000 1.000000" 1099 | ] 1100 | }, 1101 | "execution_count": 21, 1102 | "metadata": {}, 1103 | "output_type": "execute_result" 1104 | } 1105 | ], 1106 | "source": [ 1107 | "trials = 10000\n", 1108 | "cells = 10\n", 1109 | "coverage = 3\n", 1110 | "\n", 1111 | "hit_rate_1 = []\n", 1112 | "hit_rate_2 = []\n", 1113 | "for _ in range(trials):\n", 1114 | " events = make_events1(10)\n", 1115 | " if len(events) == 0:\n", 1116 | " continue\n", 1117 | " pred1 = coverage1(cells, coverage)\n", 1118 | " pred2 = coverage2(cells, coverage)\n", 1119 | " hit_rate_1.append( score(events, cells, pred1) )\n", 1120 | " hit_rate_2.append( score(events, cells, pred2) )\n", 1121 | "\n", 1122 | "pd.DataFrame({\"One\":hit_rate_1, \"Two\":hit_rate_2}).describe()" 1123 | ] 1124 | }, 1125 | { 1126 | "cell_type": "code", 1127 | "execution_count": 22, 1128 | "metadata": { 1129 | "collapsed": false 1130 | }, 1131 | "outputs": [ 1132 | { 1133 | "data": { 1134 | "text/html": [ 1135 | "
\n", 1136 | "\n", 1137 | " \n", 1138 | " \n", 1139 | " \n", 1140 | " \n", 1141 | " \n", 1142 | " \n", 1143 | " \n", 1144 | " \n", 1145 | " \n", 1146 | " \n", 1147 | " \n", 1148 | " \n", 1149 | " \n", 1150 | " \n", 1151 | " \n", 1152 | " \n", 1153 | " \n", 1154 | " \n", 1155 | " \n", 1156 | " \n", 1157 | " \n", 1158 | " \n", 1159 | " \n", 1160 | " \n", 1161 | " \n", 1162 | " \n", 1163 | " \n", 1164 | " \n", 1165 | " \n", 1166 | " \n", 1167 | " \n", 1168 | " \n", 1169 | " \n", 1170 | " \n", 1171 | " \n", 1172 | " \n", 1173 | " \n", 1174 | " \n", 1175 | " \n", 1176 | " \n", 1177 | "
0
count10000.000000
mean0.744658
std2.803817
min-7.572446
25%-1.216704
50%0.316195
75%2.285786
max18.178649
\n", 1178 | "
" 1179 | ], 1180 | "text/plain": [ 1181 | " 0\n", 1182 | "count 10000.000000\n", 1183 | "mean 0.744658\n", 1184 | "std 2.803817\n", 1185 | "min -7.572446\n", 1186 | "25% -1.216704\n", 1187 | "50% 0.316195\n", 1188 | "75% 2.285786\n", 1189 | "max 18.178649" 1190 | ] 1191 | }, 1192 | "execution_count": 22, 1193 | "metadata": {}, 1194 | "output_type": "execute_result" 1195 | } 1196 | ], 1197 | "source": [ 1198 | "ratios = []\n", 1199 | "\n", 1200 | "for _ in range(10000):\n", 1201 | " events = make_events1(10)\n", 1202 | " log_ratio = likelihood1(events) - likelihood2(events)\n", 1203 | " ratios.append(log_ratio)\n", 1204 | " \n", 1205 | "pd.DataFrame(ratios).describe()" 1206 | ] 1207 | }, 1208 | { 1209 | "cell_type": "code", 1210 | "execution_count": 23, 1211 | "metadata": { 1212 | "collapsed": false 1213 | }, 1214 | "outputs": [ 1215 | { 1216 | "data": { 1217 | "text/html": [ 1218 | "
\n", 1219 | "\n", 1220 | " \n", 1221 | " \n", 1222 | " \n", 1223 | " \n", 1224 | " \n", 1225 | " \n", 1226 | " \n", 1227 | " \n", 1228 | " \n", 1229 | " \n", 1230 | " \n", 1231 | " \n", 1232 | " \n", 1233 | " \n", 1234 | " \n", 1235 | " \n", 1236 | " \n", 1237 | " \n", 1238 | " \n", 1239 | " \n", 1240 | " \n", 1241 | " \n", 1242 | " \n", 1243 | " \n", 1244 | " \n", 1245 | " \n", 1246 | " \n", 1247 | " \n", 1248 | " \n", 1249 | " \n", 1250 | " \n", 1251 | " \n", 1252 | " \n", 1253 | " \n", 1254 | " \n", 1255 | " \n", 1256 | " \n", 1257 | " \n", 1258 | " \n", 1259 | " \n", 1260 | " \n", 1261 | " \n", 1262 | " \n", 1263 | " \n", 1264 | " \n", 1265 | " \n", 1266 | " \n", 1267 | " \n", 1268 | " \n", 1269 | "
onetwo
count10000.010000.000000
mean0.0-0.080728
std0.00.301639
min0.0-2.402754
25%0.0-0.247010
50%0.0-0.038585
75%0.00.133735
max0.00.602009
\n", 1270 | "
" 1271 | ], 1272 | "text/plain": [ 1273 | " one two\n", 1274 | "count 10000.0 10000.000000\n", 1275 | "mean 0.0 -0.080728\n", 1276 | "std 0.0 0.301639\n", 1277 | "min 0.0 -2.402754\n", 1278 | "25% 0.0 -0.247010\n", 1279 | "50% 0.0 -0.038585\n", 1280 | "75% 0.0 0.133735\n", 1281 | "max 0.0 0.602009" 1282 | ] 1283 | }, 1284 | "execution_count": 23, 1285 | "metadata": {}, 1286 | "output_type": "execute_result" 1287 | } 1288 | ], 1289 | "source": [ 1290 | "one, two = [], []\n", 1291 | "for _ in range(10000):\n", 1292 | " events = make_events1(10)\n", 1293 | " if len(events) == 0:\n", 1294 | " continue\n", 1295 | " one.append( likelihood1(events) / len(events) )\n", 1296 | " two.append( likelihood2(events) / len(events) )\n", 1297 | "pd.DataFrame({\"one\":one, \"two\":two}).describe()" 1298 | ] 1299 | }, 1300 | { 1301 | "cell_type": "code", 1302 | "execution_count": 24, 1303 | "metadata": { 1304 | "collapsed": true 1305 | }, 1306 | "outputs": [], 1307 | "source": [ 1308 | "errors = []\n", 1309 | "for _ in range(10000):\n", 1310 | " events = make_events1(10)\n", 1311 | " if len(events) < 2:\n", 1312 | " continue\n", 1313 | " kernel = scipy.stats.kde.gaussian_kde(events)\n", 1314 | " e1, _ = scipy.integrate.quad(lambda x : (kernel(x) - func1(x))**2, 0, 1)\n", 1315 | " e2, _ = scipy.integrate.quad(lambda x : (kernel(x) - func2(x))**2, 0, 1)\n", 1316 | " errors.append((e1, e2))" 1317 | ] 1318 | }, 1319 | { 1320 | "cell_type": "code", 1321 | "execution_count": 26, 1322 | "metadata": { 1323 | "collapsed": false 1324 | }, 1325 | "outputs": [ 1326 | { 1327 | "data": { 1328 | "text/html": [ 1329 | "
\n", 1330 | "\n", 1331 | " \n", 1332 | " \n", 1333 | " \n", 1334 | " \n", 1335 | " \n", 1336 | " \n", 1337 | " \n", 1338 | " \n", 1339 | " \n", 1340 | " \n", 1341 | " \n", 1342 | " \n", 1343 | " \n", 1344 | " \n", 1345 | " \n", 1346 | " \n", 1347 | " \n", 1348 | " \n", 1349 | " \n", 1350 | " \n", 1351 | " \n", 1352 | " \n", 1353 | " \n", 1354 | " \n", 1355 | " \n", 1356 | " \n", 1357 | " \n", 1358 | " \n", 1359 | " \n", 1360 | " \n", 1361 | " \n", 1362 | " \n", 1363 | " \n", 1364 | " \n", 1365 | " \n", 1366 | " \n", 1367 | " \n", 1368 | " \n", 1369 | " \n", 1370 | " \n", 1371 | " \n", 1372 | " \n", 1373 | " \n", 1374 | " \n", 1375 | " \n", 1376 | " \n", 1377 | " \n", 1378 | " \n", 1379 | " \n", 1380 | "
onetwo
count9994.0000009994.000000
mean0.2014970.303939
std0.2813990.268947
min0.0310060.037054
25%0.0768100.160567
50%0.1241210.251117
75%0.2261640.379557
max13.15197713.420936
\n", 1381 | "
" 1382 | ], 1383 | "text/plain": [ 1384 | " one two\n", 1385 | "count 9994.000000 9994.000000\n", 1386 | "mean 0.201497 0.303939\n", 1387 | "std 0.281399 0.268947\n", 1388 | "min 0.031006 0.037054\n", 1389 | "25% 0.076810 0.160567\n", 1390 | "50% 0.124121 0.251117\n", 1391 | "75% 0.226164 0.379557\n", 1392 | "max 13.151977 13.420936" 1393 | ] 1394 | }, 1395 | "execution_count": 26, 1396 | "metadata": {}, 1397 | "output_type": "execute_result" 1398 | } 1399 | ], 1400 | "source": [ 1401 | "pd.DataFrame({\"one\":[p[0] for p in errors], \"two\":[p[1] for p in errors]}).describe()" 1402 | ] 1403 | }, 1404 | { 1405 | "cell_type": "code", 1406 | "execution_count": null, 1407 | "metadata": { 1408 | "collapsed": true 1409 | }, 1410 | "outputs": [], 1411 | "source": [] 1412 | } 1413 | ], 1414 | "metadata": { 1415 | "kernelspec": { 1416 | "display_name": "Python 3", 1417 | "language": "python", 1418 | "name": "python3" 1419 | }, 1420 | "language_info": { 1421 | "codemirror_mode": { 1422 | "name": "ipython", 1423 | "version": 3 1424 | }, 1425 | "file_extension": ".py", 1426 | "mimetype": "text/x-python", 1427 | "name": "python", 1428 | "nbconvert_exporter": "python", 1429 | "pygments_lexer": "ipython3", 1430 | "version": "3.6.0" 1431 | } 1432 | }, 1433 | "nbformat": 4, 1434 | "nbformat_minor": 2 1435 | } 1436 | -------------------------------------------------------------------------------- /Temporal spatial processes.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": { 6 | "collapsed": true 7 | }, 8 | "source": [ 9 | "# Marked processes #\n", 10 | "\n", 11 | "We shall be interested in spatial processes which occur in time.\n", 12 | "\n", 13 | "- For example, we might wish to model a self-exciting process where events occur at a location in (2 or 3 dimensional) space, and the \"offspring\" events show a clustering behaviour close to the parent event.\n", 14 | "\n", 15 | "The standard way of treating such a process is via \"marks\". We start with a temporal process as already discussed, and to each event we also associate a \"mark\" from a \"mark space\".\n", 16 | "\n", 17 | "- Our mark space will be $\\mathbb R^2$, or a subset thereof, i.e. a 2 dimensional point in space.\n", 18 | "- Marks can also be discrete, for example to classify events into a number of different types." 19 | ] 20 | }, 21 | { 22 | "cell_type": "markdown", 23 | "metadata": {}, 24 | "source": [ 25 | "We shall consider a restricted setup. Marks may occur in a \"mark space\" $M$ (probably $M\\subseteq \\mathbb R^2$).\n", 26 | "\n", 27 | "- Immigrants will have independently chosen marks, say with density $\\gamma(\\kappa,t)$.\n", 28 | "- The immigrant intensity may vary with time, $\\mu(t)$.\n", 29 | "- Offspring intensity is $\\alpha(\\kappa) \\beta(t,\\kappa)$ where $\\alpha$ is the \"total intensity\" depending on the mark, and $\\beta$ is taken to be a normalised intensity, depending on time and the mark.\n", 30 | "- The offspring marks are independent and only depend upon the time and mark of the parent.\n", 31 | "\n", 32 | "Thus the total intensity function is\n", 33 | "$$ \\lambda^*(t) = \\mu(t) + \\sum_{t_i < t} \\alpha(\\kappa_i) \\beta(t-t_i,\\kappa_i). $$" 34 | ] 35 | }, 36 | { 37 | "cell_type": "markdown", 38 | "metadata": {}, 39 | "source": [ 40 | "An example of an ETAS (epidemic type aftershock) model has mark space consisting of triples $\\kappa=(m,x,y)$ where $m>0$ is the \"magnitude\" of the event, and $(x,y)$ are coordinates in a window $W$.\n", 41 | "\n", 42 | "- $\\mu(t) = \\mu_1$ for $t\\geq 0$. So background intensity is constant.\n", 43 | "- $\\alpha(\\kappa) = \\alpha_1 e^{m \\alpha_2}$. So the total intensity is exponential in the magnitude.\n", 44 | "- $\\beta(t,\\kappa) = \\beta(t)$ is some decaying function in $t$. For example, a power law\n", 45 | "$$ \\beta(t) = \\frac{\\beta_2}{\\beta_1} \\Big( 1+\\frac{t}{\\beta_1} \\Big)^{-\\beta_2-1} $$\n", 46 | "where we scale by $\\beta_1$, and decay at rate $\\beta_2$, and normalise. Notice that this example is independant of the mark.\n", 47 | "- For immigrants we have mark density $\\gamma_1 e^{-\\gamma_1 m} |W|^{-1}$ for $(x,y)\\in W$. So the coordinates of events are uniform in $W$, and the magnitude follows an exponential distribution.\n", 48 | "- For offspring, we have a more complicated mark density:\n", 49 | "$$ \\gamma(\\kappa | t, (t_p,\\kappa_p)) = \\gamma_1 e^{-\\gamma_1 m} \\frac{1}{2\\pi\\gamma_2^2}\n", 50 | "\\exp\\Big( - \\frac{\\| (x,y) - (x_p,y_p) \\|^2}{2\\gamma_2^2} \\Big) $$\n", 51 | "where the parent event occurred at time $t_p$ with mark $\\kappa_p$. Thus the magnitude continues to follow an exponential distribution, but the location of the \"aftershock\" follows a Gaussian distribution centred on the location of the parent event.\n", 52 | "\n", 53 | "Here we have followed [Rasmussen, \"Bayesian Inference for Hawkes Processes\"](https://doi.org/10.1007/s11009-011-9272-5)." 54 | ] 55 | }, 56 | { 57 | "cell_type": "markdown", 58 | "metadata": {}, 59 | "source": [ 60 | "This approach via \"marks\" may seem complicated, but it allows us to easily adapt the simulation procedure from the unmarked case, by simply adding in the marks.\n", 61 | "\n", 62 | "Let us consider a one dimensional mark space, which is easier to visualise.\n", 63 | "\n", 64 | "- $\\mu(t) = \\mu$\n", 65 | "- $\\alpha(\\kappa)=\\alpha$\n", 66 | "- $\\beta(t,\\kappa) = (1+t)^{-2}$\n", 67 | "- Immigrants will have mark uniformly chosen in $[0,1]$\n", 68 | "- Offspring have mark density following a Gaussian centred on the parent location, say with variance $\\sigma^2$." 69 | ] 70 | }, 71 | { 72 | "cell_type": "code", 73 | "execution_count": 235, 74 | "metadata": { 75 | "collapsed": true 76 | }, 77 | "outputs": [], 78 | "source": [ 79 | "%matplotlib inline\n", 80 | "import numpy as np\n", 81 | "import matplotlib.pyplot as plt\n", 82 | "import scipy.stats\n", 83 | "import utils" 84 | ] 85 | }, 86 | { 87 | "cell_type": "code", 88 | "execution_count": 304, 89 | "metadata": { 90 | "collapsed": false 91 | }, 92 | "outputs": [ 93 | { 94 | "data": { 95 | "image/png": "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\nefNQs+OYqVJVF5L86SQ/miSttU+11p6JY5npdC7JC6rqXJK5JB+NY5kp0Fr7pSS/s6N5t2P34SRv\na61ttdY+nOTx9LPhriYRVu9L8pGh5Se322BqVNViki9L8stJXtxa+9j2Q7+R5MUT6hYc1A8k+RtJ\nnhtqcxwzbR5I8nSSf7w9pP3NVfXZcSwzZVprTyX5B0k2k3wsyY3W2s/Hscz02u3YPXQONMESHFJV\n3ZPkp5J8Z2vt94Yfa/1rQbkeFJ1VVX8uycdba4/tto7jmClxLsmXJ/nh1tqXJflkdgyTdCwzDbbP\n53s4/X/AfF6Sz66qbx1ex7HMtLrbY3cSYfWpJC8ZWr5/uw06r6o+K/2g2mutvX27+Ter6nO3H//c\nJB+fVP/gAP5kkj9fVU+kfxrGn6mqH4/jmOnzZJInW2u/vL38T9MPr45lps3XJvlwa+3p1tqnk7w9\nyX8YxzLTa7dj99A5cBJh9d1JHqyqB6rqeemfZPvoBPoBh1JVlf65Ue9vrf2PQw89muS121+/Nsk/\nO+m+wUG11v5ma+3+1tpi+u+/v9ha+9Y4jpkyrbXfSPKRqvqC7aavSfK+OJaZPptJvqqq5rY/a3xN\n+vNiOJaZVrsdu48meXVVPb+qHkjyYJJ/s9eGql+ZPVlV9ar0z5k6m+QtrbW1E+8EHFJVvTzJO5P8\nWm6d6/e30j9v9SeTzCfZSPKXWms7TzSHzqmq5SR/vbX256rqj8VxzJSpqkvpTxT2vCQfSvLt6f8j\n3rHMVKmqv5Pkm9K/8sCvJvnLSe6JY5mOq6qfSLKc5EVJfjPJ9yb56exy7FbV5ST/efrH+ne21n5m\nz+1PIqwCAADAXkywBAAAQOcIqwAAAHSOsAoAAEDnCKsAAAB0jrAKAABA5wirAAAAdI6wCgAAQOf8\n/9JZKnUu0t+EAAAAAElFTkSuQmCC\n", 96 | "text/plain": [ 97 | "" 98 | ] 99 | }, 100 | "metadata": {}, 101 | "output_type": "display_data" 102 | } 103 | ], 104 | "source": [ 105 | "from collections import namedtuple\n", 106 | "Event = namedtuple(\"Event\", [\"t\", \"loc\"])\n", 107 | "\n", 108 | "mu = 0.1\n", 109 | "alpha = 1\n", 110 | "sigma = 0.01\n", 111 | "\n", 112 | "def sort_with_causes(points, caused_by):\n", 113 | " \"\"\"Sorts `points` in time order, and maintains caused by information\"\"\"\n", 114 | " # caused_by[i] = j= alpha:\n", 131 | " return points\n", 132 | " loc = np.random.normal(loc=parent.loc, scale=sigma)\n", 133 | " points.append(Event(parent.t + t / (alpha - t), loc))\n", 134 | " \n", 135 | "def simulate(window_size=100):\n", 136 | " backgrounds = utils.sample_poisson_process(window_size, 1/mu)\n", 137 | " backgrounds = [Event(t, np.random.uniform()) for t in backgrounds]\n", 138 | " points = list(backgrounds)\n", 139 | " caused_by = [ i for i in range(len(points)) ]\n", 140 | " to_process = [(i,p) for i, p in enumerate(points)]\n", 141 | " while len(to_process) > 0:\n", 142 | " (index, next_point) = to_process.pop()\n", 143 | " for event in simulate_sub_process(next_point):\n", 144 | " if event.t < window_size:\n", 145 | " points.append(event)\n", 146 | " caused_by.append(index)\n", 147 | " to_process.append((len(points) - 1,event))\n", 148 | " points, caused_by = sort_with_causes(points, caused_by)\n", 149 | " return points, backgrounds, caused_by\n", 150 | "\n", 151 | "points, backgrounds, caused_by = simulate()\n", 152 | "width, _ = utils.slim_aspect()\n", 153 | "fig, ax = plt.subplots(nrows=1, ncols=1, figsize=(width,7))\n", 154 | "ax.set(xlim=[0,100], ylim=[-0.1,1.1], title=\"1D ETAS simulation\")\n", 155 | "_ = ax.scatter(x=[e.t for e in points], y=[e.loc for e in points], color=\"blue\", marker=\"+\")\n", 156 | "_ = ax.scatter(x=[e.t for e in backgrounds], y=[e.loc for e in backgrounds], color=\"black\")" 157 | ] 158 | }, 159 | { 160 | "cell_type": "markdown", 161 | "metadata": {}, 162 | "source": [ 163 | "In this example, we have set the background rate to be low, and the mark distribution of offspring to be tightly bound to the location of the parent. This allows us to visualise how an immigrant sets off a chain of \"aftershocks\" which spread out slowly in space." 164 | ] 165 | }, 166 | { 167 | "cell_type": "markdown", 168 | "metadata": {}, 169 | "source": [ 170 | "# Model extraction #\n", 171 | "\n", 172 | "Let us start by assuming we know the form, and parameters, of the distributions. We aim then to classify points as \"background\" or \"triggered by another point\". Let us consider a more \"bundled\" way to write the conditional intensity:\n", 173 | "\n", 174 | "$$ \\lambda^*(t,x) = \\mu(t,x) + \\sum_{t_ij$. Given our simplified form, we have that\n", 183 | "$$ p_{i,i} \\lambda^*(t_i,x_i) = \\mu(t_i,x_i), \\quad\n", 184 | "p_{i,j} \\lambda^*(t_i,x_i) = g(t_j-t_i, x_j-x_i). $$" 185 | ] 186 | }, 187 | { 188 | "cell_type": "code", 189 | "execution_count": 305, 190 | "metadata": { 191 | "collapsed": false 192 | }, 193 | "outputs": [], 194 | "source": [ 195 | "def mu_func(t, x, mu):\n", 196 | " return mu * (x>=0) * (x<=1)\n", 197 | "\n", 198 | "def g_func(dt, dx, alpha, sigma):\n", 199 | " beta = (1 + dt)**(-2)\n", 200 | " beta_x = np.exp(-0.5 * (dx/sigma)**2) / np.sqrt(2*np.pi*sigma*sigma)\n", 201 | " return alpha * beta * beta_x" 202 | ] 203 | }, 204 | { 205 | "cell_type": "code", 206 | "execution_count": 306, 207 | "metadata": { 208 | "collapsed": false 209 | }, 210 | "outputs": [], 211 | "source": [ 212 | "def make_probability_matrix(points, mu, alpha, sigma):\n", 213 | " p_matrix = np.zeros((len(points), len(points)))\n", 214 | " for i, point in enumerate(points):\n", 215 | " p_matrix[i][i] = mu_func(point.t, point.loc, mu)\n", 216 | " for j in range(i):\n", 217 | " j_point = points[j]\n", 218 | " p_matrix[j][i] = g_func(point.t - j_point.t, point.loc - j_point.loc, alpha, sigma)\n", 219 | "\n", 220 | " column_sums = np.sum(p_matrix, axis=0)\n", 221 | " p_matrix /= column_sums\n", 222 | " return p_matrix" 223 | ] 224 | }, 225 | { 226 | "cell_type": "markdown", 227 | "metadata": {}, 228 | "source": [ 229 | "Using the matrix of probabilities, we can estimate which events were background events. Here we simply use a maximum likelihood estimate." 230 | ] 231 | }, 232 | { 233 | "cell_type": "code", 234 | "execution_count": 307, 235 | "metadata": { 236 | "collapsed": false 237 | }, 238 | "outputs": [], 239 | "source": [ 240 | "p_matrix = make_probability_matrix(points, mu, alpha, sigma)\n", 241 | "percentage_array = (p_matrix*100+0.5).astype(int)\n", 242 | "max_index = [ np.argmax(percentage_array[:,i]) for i in range(len(points)) ]\n", 243 | "\n", 244 | "background_points, triggered_points = [], []\n", 245 | "for i, p in enumerate(points):\n", 246 | " if max_index[i] == i:\n", 247 | " background_points.append(p)\n", 248 | " else:\n", 249 | " triggered_points.append(p)" 250 | ] 251 | }, 252 | { 253 | "cell_type": "code", 254 | "execution_count": 308, 255 | "metadata": { 256 | "collapsed": false, 257 | "scrolled": true 258 | }, 259 | "outputs": [ 260 | { 261 | "data": { 262 | "image/png": "iVBORw0KGgoAAAANSUhEUgAAA6sAAAE/CAYAAACgilX5AAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3X2UJHdd7/HPd2aTTIaNu0LWSB66e68nhMSHjDgkiKs7\nCkjCg4tehZDWQIynbxQUvSAGRwUutqIHvcI1mDNAEglNIk9KkAhEcSZGRDOBIZBH1mR7dkNCQpZd\nEgYnZvd7/6iqTE1P90xNd3VXdff7dc6cma6q7vpNTc985vurX/3K3F0AAAAAAOTJSNYNAAAAAACg\nEcUqAAAAACB3KFYBAAAAALlDsQoAAAAAyB2KVQAAAABA7lCsAgAAAAByh2IVyDkzmzKzA5vYftbM\nfqWbbQIADDYzO8nMbjKzR83szzJqw1vM7AMt1m0qGzexz6vN7A/Tft1u69bxALJGsQpsICz+vmlm\nxyXcvmRmbmZbut22TpnZPjN7ftbtAAB03yb/5lckfUPSd7n767vYLAyo9TobgKQoVoF1mFlJ0o9L\nckk/k2ljAADonaKkO9zdN/vEZp21/dCBm6Zh+36BbqFYBdZ3kaTPS7pa0qviK8zseDP7MzOrm9lh\nM7vZzI6XdFO4ySEze8zMfrSxd7Hx7KuZXWxmd4bDre41s/+VtIFm9gIzuytsw19Ksti67zOzz5rZ\nI2b2DTOrmdn2cN01kgqSPhG2843h8g+b2YPh691kZt/fxnEDAOSYmb06zK13hKOH7jOz88N1VyvI\nvDeG+fB8Mxsxs8vM7D/DTPmQmT013D7KtEvMbFHSZ5stC7d9jpl9zswOmdmXzGwq1qadZjYXZuGN\nkk5M8H38bphv+8ysHFv+YjP7opl9y8z2m9lbGp63K9aO/Wb26iavfYKZ/bOZvcsCTzOzT4SveYuZ\n/aGZ3Rzb3s3sNWb2VUlfDZc9N9z2cPj5ubHtV53pjv+vEDt+rzKzxfB7nI5te7wFQ5a/aWZ3SHr2\nBsfpmWZ2o5kdNLO7zezl4fJzw8wfjW37s2Z2W/h1kp/7mjaa2XmSflfSK8L30JfC5a+24P+cR8P3\nXLmxrUAcxSqwvosk1cKPF5rZSbF175D0I5KeK+mpkt4o6aiknwjXb3f3re7+bwn285Ckl0j6LkkX\nS/q/ZvasjZ5kZidK+pik31MQ6v8p6cfim0j6Y0knSzpT0mmS3iJJ7v5LkhYlvTRs55+Gz/kHSadL\n+h5JXwi/dwDA4DlX0t0K8uNPJb3PzMzdX63gb/+fhvnwj5J+XdLLJO1WkCnflHR5w+vtVpA1L2y2\nzMxOkfRJSX+oIDffIOmjZrYj3PaDkm4N2/M2NXQSN/G94banhNvOmNkZ4bpvK8jw7ZJeLOlXzexl\nkmRmRQVZ9/8k7ZA0IWkh/sJm9jRJ/yTpX939N8IzzJeHr/u94f6ate9lCo7rWWFR90lJ75L0NEl/\nLumT4WsntUvSGZKeJ+kPzOzMcPmbJX1f+PHCFm2JvpenSLpRwfH9HkkXSHq3mZ3l7v8efk8/FXvK\nheG2UrKf+5o2uvunJP2RpL8J30Nnh+14l6Tz3f0EBf8/LQhYB8Uq0IKZ7VIwDOpD7n6rgkLwwnDd\niKRflvQ6d7/f3Y+4++fcfbmdfbn7J939Pz0wJ+kzCoYfb+RFkm5394+4+39L+gtJD8Zed6+73+ju\ny+7+sIKg3L1BW65090fD7+Utks42s23tfF8AgFyru/t73P2IpL+W9HRJJ7XY9lJJ0+5+IJYPP2+r\nh7u+xd2/7e7fabHsFyXd4O43uPtRd79R0rykF5lZQcHZwd8PM+smSZ9I8D1E288pKAxfLknuPuvu\nXw73c5uka7WSfxdK+kd3v9bd/9vdH3H3eNF0sqQ5SR9299+TpPDM4/+U9GZ3X3L3O8Jj1uiP3f1g\n+P2+WNJX3f0ad3/C3a+VdJeklyb4viJvdffvuPuXJH1J0tnh8pdLqob72q+gCGzlJZL2uftVYTu+\nKOmjkn4hXH+tpFeG3+cJCv63uDZcl+Tn3qqNzRyV9ANmdry7P+Dutyc6ChhaFKtAa6+S9Bl3/0b4\n+INa6bk8UdKYggK2Y2Z2vpl9Phyec0hBUGw4/ElBoO6PHoQ9v08+tmA2x+vM7H4z+5akD6z3umY2\namZvD4f7fEvSvnBVkrYAAPpLvHNzKfxya4tti5L+Nhw2e0jSnZKOaHVxu7/J8+LLipJ+IXqN8HV2\nKSiST5b0TXf/dmz7+gbtb7b9ydKTw1v/2cweNrPDCoquKMtO0/r5/WJJx0u6IrZsh6QtDd/PRt/v\nyU2+h7qCM8FJPRj7ekkrP59V+d9kP3FFSec2HPeygjPEUvD/zc9ZMJHkz0n6grvXY8/d6Ofeqo2r\nhD+rVyj4WTxgZp80s2eu026AYhVoxoJrT18uaXd4LceDkn5LwVnGsxXMkPhfCobfNGo2GcW3JY3H\nHkcBoTAcPqpgWPFJ7r5d0g2KXXu6jgcUhG70WhZ/rGAIjkv6QXf/LgW92vHXbWzrhZL2SHq+pG2S\nStFLJ2gLAGBw7VcwfHN77GPM3e+PbdMs/+LL9ku6puE1nuLub1eQZ98dDhWNFDZoU7PtvxZ+/UFJ\n10s6zd23KSg8oyzbr+b5HXmPpE9JuiH2+g9LekLSqbHtTmt8olZ/v19TUOzFFSRFx6zl/wYJrMp/\nrX+s9kuaazjuW939VyUpPEtcl3S+Vg8Bjp670c+9lTXvB3f/tLu/QEEHxV0KjjXQEsUq0NzLFPQc\nnqXgWpYJBdfc/Iuki9z9qKQrJf25mZ0cnpH80bDwfFjBMJf/EXu9BUk/YWaFcEjtm2LrjpUUPe8J\nCya4+OmE7fykpO83s58Lh+T8hlaH3QmSHpN0OLxW6Lcbnv/1hnaeIGlZ0iMKAvSPErYDADDYrpBU\nDa/3lJntMLM9m3yND0h6qZm9MMzNMQvuD3pqeCZvXtJbzezY8FKcJMNlo+1/XMFw1w+Hy0+QdNDd\n/8vMzlF4GU+oJun5ZvZyM9tiwcRJEw2v+1oF1/N+IhyyekTBHBFvMbPx8IzgRRu07QZJzzCzC8P9\nvELB/xV/H65fkHSBmR1jZpOSfj7B9xv5kKQ3mdl3m9mpCq4tbeXvw3b8UrivY8zs2bHrX6WgQH2d\ngnk3Phxb3snP/euSSuGlU9Forz1hB8Cygv9PjiZ8LQwpilWguVdJusrdF939wehD0l9KKoeF4Rsk\nfVnSLZIOSvoTSSPhUKqqpH8Nh808J7wu528k3aZg8ogoqOTujyooMj+kYOKCCxX0Bm8oHKL8C5Le\nrqDAPF3Sv8Y2eaukZ0k6rKCw/VjDS/yxpN8L2/kGSe9X0Lt6v6Q7FMyEDADAOxVk02fM7FEF+XDu\nZl4gvLZyj4JZYh9WcNbut7Xy/+iF4WseVDCB0Ps3eMkHFeTm1xQUoJe6+13hul+T9H/Ctv6BgoyN\n2rGo4HKb14f7WlDDdZbhZTUVSQckfdzMxhQUsNvC/V6j4LrOlnNVuPsjCgro1yvI6DdKekns8qLf\nV3CG95sK8vqDzV6nhbcqyOv7FMxzcc067XhUQSf4BQqO1YMK/meJ3z8+uqb3s7H2SZ393KOi9xEz\n+4KCn/P/DttwMNzfryZ8LQwp883fPgsAAAAYamb2J5K+1903mrUYQJs4swoAAABswIJ7lf6QBc6R\ndImkv826XcAg27LxJgAAAMDQO0HBcNmTFVyP+WeSPp5pi4ABxzBgAAAAAEDuMAwYAAAAAJA7FKsA\nAAAAgNzJ7JrVE0880UulUla7BwAMmFtvvfUb7r4j63b0M7IZAJCmTrM5s2K1VCppfn4+q90DAAaM\nmdWzbkO/I5sBAGnqNJsZBgwAAAAAyB2KVQAAAABA7lCsAgAAAAByh2IVAAAAAJA7FKsAAAAAgNyh\nWAUAAAAA5A7FKgAAAAAgdyhWAQAAAAC5Q7EKAAAAAMgdilUAAAAAQO5QrAIAAAAAcodiFQAAAACQ\nOxSrAAAAAIDcoVgFAAAAAOQOxSoAAAAAIHcoVgEAAAAAuUOxCgAAAADInQ2LVTO70sweMrOvtFhv\nZvYuM9trZreZ2bPSbyYAAIiQzQCAYZDkzOrVks5bZ/35kk4PPyqS/qrzZgEAgHVcLbIZADDgNixW\n3f0mSQfX2WSPpPd74POStpvZ09NqIAAAWI1sBgAMgzSuWT1F0v7Y4wPhMgAAkA2yGQDQ93o6wZKZ\nVcxs3szmH3744V7uGgAANEE2AwDyKo1i9X5Jp8UenxouW8PdZ9x90t0nd+zYkcKuAQBAE2QzAKDv\npVGsXi/ponDmwedIOuzuD6TwugAAoD1kMwCg723ZaAMzu1bSlKQTzeyApDdLOkaS3P0KSTdIepGk\nvZKWJF3crcYCAACyGQAwHDYsVt39lRusd0mvSa1FAABgXWQzAGAY9HSCJQAAAAAAkqBYBQAAAADk\nDsUqAAAAACB3KFYBAAAAALlDsQoAAAAAyB2KVQAAAABA7lCsAgAAAAByh2IVAAAAAJA7FKsAAAAA\ngNyhWAUAAAAA5A7FKgAAAAAgdyhWAQAAAAC5Q7EKAAAAAMgdilUAAAAAQO5QrAIAJEm1Wk1jYyWZ\njahUKqlWq6W+j6mp4KPZ48Z1AAAMu1qtplKppJGR4czmLdntGgCQF7VaTZVKRcvLS5Kker2uSqUi\nSSqXy6nvL0nwRdvMzqa+ewAAci/K5qWl4c1mc/fe7KnB5OSkz8/PZ7JvAMBqY2MlLS/X1ywvFova\nt29fx68fhdvcXPB5dDT4fOTIyuPo6927Vz83aSCa2a3uPtlJO4cd2QwA+VEqlVSvD3c2c2YVAKDl\n5cWmyxcXmy/vVBR+zSwsBJ8PHw4+c4YVADCMWmXwMGUzxSoAQMVioWnvbaFQSOX1ozDbvj34HIVd\n1Gt75Ii0bVuwbGIi+Bz19AIAMIwKBbKZYhUAoGq1uuq6GEkaHx9XtVpNdT9R2Elre2kjUXhyRhUA\nMMzIZmYDBgAomKhhZmZGxWJRZqZisaiZmZnUJ3CYnV0JuIkJ6dChoNd227bg60OHUt0dAAB9i2xm\ngiUAQEYaJ3aIJm9ot7eWCZY6RzYDwHDLWzZzZhUAAAAAkDtcswoAyATXpgIAkC95y2bOrAIAAAAA\ncoczqwCATGXdawsAAFbLSzZzZhVALk1NrQxBAQAA2SOb0WuZFasHDx7U2FhJZiMqlUqq1Wpd3ye/\nYGjEewKNeE9gmB08eFClUkkjI2QzssN7Ao14TwyvzIYB1+t1HT169MmvK5WKJKV+36DI1FRwk9v4\nTW/zcuEwOrd9e/A5ug/Uej9bfu7t6dVxa5wynZ8X0DtkM9JENncf2YxBl1mxGoVhZGlpSdPT010J\nxCgMDx8OfsnomRkc7f4sFxaC50Z/dBsDFcOHIAbIZnSuVqtpenpai4uLkgoaG6tKSvb+IZvRiGxG\nriZYqtcXNTUVvAHTejPGwzBy883S1q0ry3jj96+bb5aOHFl5vCV8R0fL4j/bxj94Cwvt7XOj90ur\nf7jafX+l+bvQzuv0OijyNmU6MOzIZiRVq9VUqVS0tLQULqnrO9+paGREGhkpk80pvg7ZjGGRq2LV\nrNCV152YWPll3rZt7TL0n+iPZbxQjcSX3Xzz6nXxEJyY6M0/R+0GL3qLIAaaI5uR1PT0dKxQjSzJ\nfVpHjqycXY2yN0I2oxWyGRkWqyOS4sONxuVe1dxcMOwjrT9Q8Td5dF0Mb/zB0Cxodu1aWTcx0Xyb\nbdtW3gfREKMkNurFbFzfaPv21ddlbfS+S6vXtNPXafz+eoXfSyALZDPaFwz9bbpGu3evLUrjyObN\nvQ7ZjGGRWbG6c2dRR48eVb2+KLOCzjijqrvu6s4EDpF4GKK/RUOHGoeRxR/Hg2nLltVnXKPrYpJM\n+pCWxx5bO5FIZDP7z3roUd72kbZ+aiuQNrIZnSgUCqrX62uWmxXWFItzc2sv3SGbyeZW+qmtSFdm\nxepTn/pUzc/PN71uIc3rYiLNXoc3fn+LF6zxkIkCcXR0JQCbDReOSzIcaKNe/+hx1CMcL6KjNjz2\nWPKJI1rtb71e1FbbxnuqO+2N7db1Mf0YnsCgIZvRiWq12nDNqjQyMq5nPKOqu+5auz3ZTDYDG8n8\nmlXe/OhEs3+eGkPgsceC4cGN10bFRUOGW00ispk/1o89lqztjz0WhGR85sNm+42K8XaGDC0sBPuJ\nh1/jGeloCFSav4vM3gf0N35X0Y5o1ujp6WnV64s67riC3ve+qsrl8qociorQZtctx5HNZDOQqFg1\ns/MkvVPSqKT3uvvbG9Zvk/QBSYXwNd/h7ldttjHxXxZ+cZDURu+VrVtbn4VtNgthtCwekJvdn7QS\nONEZ3t27g8eNE0c09hw37jcKqyS9to09w9E+4rMmRyG5WZ1cT7befRQJT6A9ZDPyqFwuJ7rVUTzb\nyGayGWhlw2LVzEYlXS7pBZIOSLrFzK539ztim71G0h3u/lIz2yHpbjOrufvjXWk1sI74H9JWw3ji\nPbnxcDh8eHV4RNfURI+TTMQQrY/2sWtX8JrxHtPGYUhRW+LB3apXN0lgRD3DkcahVvHH8QlT0h7a\n12zyFACdI5vRb5JkANm88jXZDASSnFk9R9Jed79XkszsOkl7JMUD0SWdYGYmaaukg5KeSLmtQEea\n9YDGZwxuFlLSxtfUJLF169rhTtH+omn6oyFB0TaNt91ZT7NrXRonnxodXdlfJ7eGSBps8SFNc3Or\nw7HdoAfwJLIZA4FsXtkf2QyslaRYPUXS/tjjA5LObdjmLyVdL+lrkk6Q9Ap3PyogZ9abGCE+HCbe\ngxt3+PDqoNnodSKNw4Xi19NKq4cBRVoFcZLAiE8oEV2zG1/X+I9Bt0KonfAlGIFEyGYMDLKZbAZa\nSWuCpRdKWpD0U5K+T9KNZvYv7v6t+EZmVpFUkYLpzYG8aBVW7fTcNgu/Vts1m+kwPovxZjXuK76P\nXgfMetfRNFvW6UyIANYgm9HXyOb0kc3oN0mK1fslnRZ7fGq4LO5iSW93d5e018zuk/RMSf8R38jd\nZyTNSNLk5KS322igUxvdLuHQobWhGA3VOXSo9YyE8SE0zXpxW01UEm3fOLlCtM92w6zV8/LYM8pk\nDsCmkM0YOGRze6/XTWQzsjaSYJtbJJ1uZjvN7FhJFygYVhS3KOl5kmRmJ0k6Q9K9aTYU6LWJiZXZ\nA9t9/mb/mG/dunpY0CCYnW0+ayNBB3SEbMZQIpvTQTajX2x4ZtXdnzCz10r6tILp8a9099vN7NJw\n/RWS3ibpajP7siST9Dvu/o0uthvouvi1JVLra2HiX7fT4xg9p3HChWjih2HRyTEEhg3ZjGFFNvcW\n2YysJbpm1d1vkHRDw7IrYl9/TdJPp9s0APF7szHFPIA4shnIBtkM9E5aEywBAyu6V2uSXsV2AqtZ\nr2XjNSL9Io2eV0IfALARsjk5shn9LMk1qwB6LAqFbduCz43DnIbN1NTqDwAAeo1sXo1sRi9wZhVI\nqNu9iv3ca8lsgQCALJDNrZHNGAQUq0BONU4iMYzh0mrIFYELAMgC2Uw2o7coVgF0rB9mC8xz2wAA\nSBvZjEFAsQrkVOO0+cM462Bj0DYub2Wj8NtMOBKkAIAI2Uw2o7coVgGkJuvQaDbBQ7NrdhYWVu6T\nF3+cdfsBAEhb1tlGNqMTFKtATkXT5G/bFvTgxmcdHNQ/3K16SpN+vwsLwef4sYqHX7TN4cNBQEbr\n12tLNyamoEcYAPoT2byCbEYvcOsaAJmo1WoaGyvJbESlUkm1Wk1SEFCbnQI/mjY//o9DJOqV3b07\n+OciHo4337zynLm5YDgX0+8DAIZZs1vRkM3ICmdWgRzrh8kR2lGr1VSpVLS8vCRJqtfruuiiio4e\nlaTyk6HY7vcb3QOv8flROMZ7beMB+thjQUjG992NXltuIwAA/WtQs7lRY2aRzcgCxSqAnrvkkukn\nC9XI0aNLkqYllXX48OZCsdVkD822iTSGY9Sr22roEQAAg6yxaNu2LSgUI2QzskCxCvSBQevdW15e\nbLFmZXl8SNBmbXS8GtdHvbZHjgSPo2FHaU/sMCy98QAwDAb9b/jExNoznWQzeo1iFUDPFYsF1ev1\nNcuPO66gsbH2g6jd50Q9uI3X1LSDsAMA9KNWRVunM/OSzegEEywB6Llqtarx8fFVy8bHx/W+91U7\n6rVt1+ysdOjQykQPu3d31nucZH8EJgCgH8zOdjcT19sv2QzOrALouXK5LEmanp7W4uKiCoWCqtWq\nyuWywlV9hwkaAACDoFlu9WuWkc39j2IVQCaCwjRflWk07Egi2AAAyAOyebhRrAJACpigAQCAfCGb\n+x/FKgDEEGwAAOQL2Ty8KFYBYBM2CkoCFACA3klSwJLN/YtiFQCaINgAAMgXsnn4UKwCQALrTe7A\nsCQAAHpro0mXyObBwH1WAQAAAAC5w5lVAEigWU/t1FTwwVT6AAD0VqszqNzmZrBwZhUAAAAAkDuc\nWQWATYj3zHJdDAAA2WrMXrJ5sHBmFQAAAACQO5xZBYAO0WsLAEC+kM2DgTOrAAAAAIDcoVgFAAAA\nAOQOxSoAAAAAIHcoVgEAAAAAuUOxCgAAAADIHYpVJFar1TQyUpLZiEqlkmq1WtZNAgBgqNVqNY2N\nkc0ABhO3rkEitVpNlUpF7kuSpHq9rkqlIkkql8tZNg0AgKEUZfPyMtkMYDCZu2ey48nJSZ+fn89k\n39i8kZGS3OtrlheLRe3bt6/3DQKABmZ2q7tPZt2OfkY295exsZKWl8lmAPnVaTYzDBiJuC82Xb64\n2Hx5lqamgg8AAAbZ8jLZDGCwJSpWzew8M7vbzPaa2WUttpkyswUzu93M5tJtJrJWLBaaLi8Umi8H\nAHQX2QyyGcCg2/CaVTMblXS5pBdIOiDpFjO73t3viG2zXdK7JZ3n7otm9j3dajCyUa1WValUtLS0\n9OSy8fFxVavVDFu1WtRjOze3+vHCQvD50KFetwgAuoNshkQ2Axh8Sc6sniNpr7vf6+6PS7pO0p6G\nbS6U9DEPx4q6+0PpNhNZK5fLmpmZUbFYlJmpWCxqZmaGCRwAIBtkM8hmAAMvyWzAp0jaH3t8QNK5\nDds8Q9IxZjYr6QRJ73T396fSQuRGuVzOdQDOzgafG3ttDx8OPm/fHnymFxfAACCbIYlsBjDY0rp1\nzRZJPyLpeZKOl/RvZvZ5d78nvpGZVSRVJK6nAACgy8hmAEBfS1Ks3i/ptNjjU8NlcQckPeLu35b0\nbTO7SdLZklYForvPSJqRgunx2200sJ6oFzdCry2AAUQ2o6+QzQDakeSa1VsknW5mO83sWEkXSLq+\nYZuPS9plZlvMbFzBUKQ7020qkG9Myw+gh8hmIAGyGehvG55ZdfcnzOy1kj4taVTSle5+u5ldGq6/\nwt3vNLNPSbpN0lFJ73X3r3Sz4UBS9NoCGDRkM/od2QwgCXPPZsTP5OSkz8/PZ7JvIE2N0/Lv3h18\nbhzyBKC7zOxWd5/Muh39jGzGoCCbgXzoNJuTDAMGAAAAAKCn0poNGBhajdPy02sLAEC2yGZgMHBm\nFQAAAACQO5xZBVJCry0AAPlCNgP9jTOrAAAAAIDcoVgFAAAAAOQOxSoAAAAAIHcoVgEAAAAAuUOx\nCgAAAADIHYpVAAAAAEDuUKwCAAAAAHKHYhUAAAAAkDsUqwAAAACA3KFYBQAAAADkDsUqAAAAACB3\nKFYBAAAAALlDsQoAAAAAyB2KVQAAAABA7lCsAgAAAAByh2IVAAAAAJA7FKsAAAAAgNyhWAUAAAAA\n5A7FKgAAAAAgdyhWAQAAAAC5Q7GKgTM1FXwAAIB8IJsBtGNL1g0A0hAPwIUFaWIis6YAAACRzQA6\nx5lV9J1araaxsZLMRlQqlVSr1SQFQbiwIB0+LM3NBSG5fTs9uQAAdFutVlOpVNLICNkMID2cWUVf\nqdVqqlQqWl5ekiTV63VddFFFR49KUnnVtgsLvW8fAADDJsrmpSWyGUC6zN0z2fHk5KTPz89nsm/0\nr7GxkpaX603WFCXtW7VkdFQ6ciT4evfu4PPsbBcbByBTZnaru09m3Y5+RjajHaVSSfU62QxgrU6z\nmWHA6CvLy4st1qxdvnVrd9sCAACkxUWyGUB3MAwYfaVYLDTtvTUrKBokMDoahOGhQyvXxNBrCwBA\ndxQKZDOA7uDMKvpKtVrV+Pj4qmXj4+O65pqqdu8OhhTt2sWMgwAA9ArZDKBbKFbRV8rlsmZmZlQs\nFmVmKhaLmpmZUbm8MoHD7OxKb238awAAkD6yGUC3MMESAGAgMMFS58hmAECamGAJAAAAADBwKFYB\nAAAAALlDsQoAAAAAyJ1ExaqZnWdmd5vZXjO7bJ3tnm1mT5jZz6fXRAAA0IhsBgAMug2LVTMblXS5\npPMlnSXplWZ2Vovt/kTSZ9Ju5GZNTa3cwwsAgEFDNgMAhkGSM6vnSNrr7ve6++OSrpO0p8l2vy7p\no5IeSrF9TRF4AIAhRzYDAAbelgTbnCJpf+zxAUnnxjcws1Mk/aykn5T07NRa12CjEIzWz82tPF5Y\nCG5Czf28AAADhGwGAAy8JMVqEn8h6Xfc/aiZtdzIzCqSKpJUKBQ2tYNaraa5uWlJi5IKkqqamgpu\nNk3YAQCwRk+y+aabpuVONgMA0pekWL1f0mmxx6eGy+ImJV0XhuGJkl5kZk+4+9/FN3L3GUkzUnDj\n8aSNPPPMmu65pyJpKVxSl1TR178unXRS+cle29nZoMd227aV5x4+HPTmxrcBAKDP5Sab3clmAEB3\nJLlm9RZJp5vZTjM7VtIFkq6Pb+DuO9295O4lSR+R9GuNYdiJu++e1tGjSw1Ll3TffdNp7QIAgH6S\neTbfdx/ZDADorg3PrLr7E2b2WkmfljQq6Up3v93MLg3XX9HlNobDi9ZaXl7UwkLQQytJ27evfL17\n9+rP9NoCAAZFHrL58cfJZgBAdyW6ZtXdb5B0Q8OypkHo7q/uvFmrFYsF1ev1NcuPO66giYmVSRuS\n6uWwI4Y4AQC6IetsLhTIZgBAdyUZBpy5arWq8fHxVctGRsa1c2d1w+fOziYPI6bdHzzr/Uz5eQNA\n+8hmtKMHq1HkAAAP5ElEQVRWq6lUKmlkZESlUkm1Wm3Ven7eAOLSmg24q8rlYGbB6elpLS4uqlAo\nqFqt6j3vKW/qdRqnz9++Pfh86FDweWGh+fbt9Lw2m6q/3dcCACBvyGZsVq1WU6VS0dJScK1zvV5X\npVKRtPJ+AoC4vihWpeCPWOMfsve8Z/U2ExPt3bstuudbdE1NWj16jQGL3lnvHxL+WQGAdJDN2Izp\n6eknC9XI0tKSpqenn+zkIJsBxPVNsZqG6A9e1GsbBeDNN0tHjqxs13idTTt/MKOiiBufAwDQGtk8\nPBYXm0/Ktbi4qFKpt20B0B/6uliNQqYbvW+jo6tDcjMaz9wtLATLCMXeWe+90c33DQAMO7IZrbSa\nlKtQKJDNAJrqiwmW0nboUPCxe3dwk/Jdu9Zuc+RIsG7bts1NBNHMxET7z0VvMKEDAGSLbB58zSbl\nGh8fV7XafFIushlAX59ZjeSl1zZC72B+rHfs+bkAQPeQzWjUalKu+HXP/FwAxA1Esdqu+GQ7kV27\nuJZlmDDZEgDkC9k82JpNytWIbAYQGepiVWre05rWkBP+qAIAsHlkMwBAolhtKosgo9cwGwwLA4D+\nQDYPD7IZQIRiNbTZP4T8AQUAoLvIZgAYbhSrGeO6jHzgeAMAImRzPnC8AVCsblJ0M/HopuUEGAAA\n2SKbAWAwUaxmjOsyAADIF7IZAPJhJOsG5FGrm1BHy6Ke223bgs+EGAAA3UU2A8Dw4cxqlyXtlSVU\nAQDoDbIZAPrDwBSraQzV2WhCBYYFAQCQHNkMAOhE7ocB12o1jY2VZDaiUqmkWq3WctuFhc5uGr6w\nEHykIRquNDcXfLQavgQAQL+p1WoqlUoaGSGbAQDdk+szq7VaTZVKRcvLS5Kker2uSqUiSSqXy5LW\n9rhGodhOz+rExOrHrV6DXlsAwLCKsnlpiWwGAHSXuXsmO56cnPT5+fl1txkbK2l5ub5mebFY1L59\n+yStna5eCiZXmJhIHlyNoRpNznDoULLnJ3ltQhQAusvMbnX3yazb0c+SZHOpVFK9TjYDADbWaTbn\nehjw8vJi0+WLiyvLZ2eD8ItCTFrbCxtJOtxnYqL1awAAMMziGdxqOdkMAEhDrocBF4uFpr23hUJh\n1ePZ2ZVe3M302safL3Wnp5VeWwDAICkUyGYAQG/k+sxqtVrV+Pj4qmXj4+OqVqtrto16cZthQgUA\nANJBNgMAeiXXZ1ajiRqmp6e1uLioQqGgarX65PJGnfaU0tMKAMD6yGYAQK/keoKltDGhAoBhVavV\ndMkl01peXlSxWHjyLFjjslYFRz9ggqXOkc0A0Du1Wq1px98g/V3sNJtzfWYVANC5ZrcBu/jii2Vm\nevzxx59c1nj7EQAA0B3r3QZMIocjQ3VmFQCGUavbgDUTv/1Iv+HMaufIZgDojVa3ATvuuKKWl/dJ\nknbvDpb18xnWgb51DQCgc61uA9ZMq9uSAACA9LTK281k9jBgGDAADLhWtwFrpvH2IwAAIH2tbgNW\nLBZUKgVf9/MZ1bRwZhUABlyzW40cc8wxOvbYY1cta3X7EQAAkK7N3AZsmFGsAsCAK5fLmpmZUbFY\nlJmpWCzqqquu0pVXXrlq2czMDJMrAQDQA82yOcrh2VnOqkaYYAkAMBCYYKlzZDMAIE1MsAQAAAAA\nGDgUqwAAAACA3KFYBQAAAADkDsUqAAAAACB3EhWrZnaemd1tZnvN7LIm68tmdpuZfdnMPmdmZ6ff\nVAAAECGbAQCDbsNi1cxGJV0u6XxJZ0l6pZmd1bDZfZJ2u/sPSnqbpJm0GwoAAAJkMwBgGCQ5s3qO\npL3ufq+7Py7pOkl74hu4++fc/Zvhw89LOjXdZgIAgBiyGQAw8JIUq6dI2h97fCBc1solkv6hk0YB\nAIB1kc0AgIG3Jc0XM7OfVBCIu1qsr0iqSFKhUEhz1wAAoAmyGQDQr5KcWb1f0mmxx6eGy1Yxsx+S\n9F5Je9z9kWYv5O4z7j7p7pM7duxop70AAIBsBgAMgSTF6i2STjeznWZ2rKQLJF0f38DMCpI+JumX\n3P2e9JsJAABiyGYAwMDbcBiwuz9hZq+V9GlJo5KudPfbzezScP0Vkv5A0tMkvdvMJOkJd5/sXrMB\nABheZDMAYBiYu2ey48nJSZ+fn89k3wCAwWNmt1KMdYZsBgCkqdNsTjIMGAAAAACAnqJYBQAAAADk\nDsUqAAAAACB3KFYBAAAAALlDsQoAAAAAyB2KVQAAAABA7lCsAgAAAAByh2IVAAAAAJA7FKsAAAAA\ngNyhWAUAAAAA5A7FKgAAAAAgdyhWAQAAAAC5Q7EKYNOmpoIPAACQD2QzBhHFKgAAAAAgdyhWASR2\n5pk1jYyUNDc3orm5ks48s0YvLgAAGTrzzJrGxshmDKYtWTcAQH+o1Wq6556K3JfCJXXdc08l/Lqc\nVbMAABhaUTYfPUo2YzBxZhVAIpdcMh0Lw8DRo0v6znemM2oRAADDbXqabMZgo1gFkMjy8mLT5YuL\nzZcDAIDuapXBZDMGBcUqgESKxULT5YVC8+UAAKC7WmUw2YxBQbEKIJFqtarx8fFVy8bHx1WtVjNq\nEQAAw41sxqCjWAWQSLlc1szMjIrFosxMxWJRMzMzKpeZwAEAgCyQzRh05u6Z7HhyctLn5+cz2TcA\nYPCY2a3uPpl1O/oZ2QwASFOn2cyZVQAAAABA7lCsAgAAAAByh2IViKnVahobK8lsRKVSSbVaLesm\nAQAw1Gq1mkqlkkZGyGZg2GzJugFAXtRqNVUqFS0vBzfXrtfrqlQqksREBQAAZCDK5qUlshkYRkyw\nBITGxkpaXq6vWV4sFrVv377eNwjApjDBUufIZuRNqVRSvU42A/2KCZaAlCwvLzZdvrjYfDkAAOiu\nVhlMNgPDgWIVCBWLhabLC4XmywEAQHe1ymCyGRgOFKtAqFqtanx8fNWy8fFxVavVjFoEAMBwI5uB\n4UaxCoTK5bJmZmZULBZlZioWi5qZmWECBwAAMkI2A8ONCZYAAAOBCZY6RzYDANLEBEsAAAAAgIFD\nsQoAAAAAyB2KVQAAAABA7lCsAgAAAAByJ1GxambnmdndZrbXzC5rst7M7F3h+tvM7FnpNxUAAETI\nZgDAoNuwWDWzUUmXSzpf0lmSXmlmZzVsdr6k08OPiqS/SrmdAAAgRDYDAIZBkjOr50ja6+73uvvj\nkq6TtKdhmz2S3u+Bz0vabmZPT7mtAAAgQDYDAAZekmL1FEn7Y48PhMs2uw0AAEgH2QwAGHg9nWDJ\nzCpmNm9m8w8//HAvdw0AAJogmwEAeZWkWL1f0mmxx6eGyza7jdx9xt0n3X1yx44dm20rAAAIkM0A\ngIGXpFi9RdLpZrbTzI6VdIGk6xu2uV7SReHMg8+RdNjdH0i5rQAAIEA2AwAG3paNNnD3J8zstZI+\nLWlU0pXufruZXRquv0LSDZJeJGmvpCVJF3evyQAADDeyGQAwDDYsViXJ3W9QEHrxZVfEvnZJr0m3\naQAAoBWyGQAw6Ho6wRIAAAAAAElQrAIAAAAAcodiFQAAAACQOxSrAAAAAIDcoVgFAAAAAOQOxSoA\nAAAAIHcoVgEAAAAAuUOxCgAAAADIHYpVAAAAAEDuUKwCAAAAAHKHYhUAAAAAkDsUqwAAAACA3KFY\nBQAAAADkDsUqAAAAACB3KFYBAAAAALlDsQoAAAAAyB2KVQAAAABA7lCsAgAAAAByx9w9mx2bPSrp\n7kx2PjhOlPSNrBsxADiOneMYdo5j2Lkz3P2ErBvRz8jmVPC7nA6OY+c4hp3jGHauo2zekmZLNulu\nd5/McP99z8zmOYad4zh2jmPYOY5h58xsPus2DACyuUP8LqeD49g5jmHnOIad6zSbGQYMAAAAAMgd\nilUAAAAAQO5kWazOZLjvQcExTAfHsXMcw85xDDvHMewcx7BzHMN0cBw7xzHsHMewcx0dw8wmWAIA\nAAAAoBWGAQMAAAAAcieTYtXMzjOzu81sr5ldlkUb+o2ZnWZm/2xmd5jZ7Wb2unD5U83sRjP7avj5\nu7Nua96Z2aiZfdHM/j58zDHcBDPbbmYfMbO7zOxOM/tRjuHmmNlvhb/HXzGza81sjGO4MTO70swe\nMrOvxJa1PG5m9qYwZ+42sxdm0+r+QTZvHtmcHrK5M2Rz58jm9nQ7m3terJrZqKTLJZ0v6SxJrzSz\ns3rdjj70hKTXu/tZkp4j6TXhcbtM0j+5++mS/il8jPW9TtKdscccw815p6RPufszJZ2t4FhyDBMy\ns1Mk/YakSXf/AUmjki4QxzCJqyWd17Cs6XEL/z5eIOn7w+e8O8wfNEE2t41sTg/Z3BmyuQNkc0eu\nVhezOYszq+dI2uvu97r745Kuk7Qng3b0FXd/wN2/EH79qII/QqcoOHZ/HW7215Jelk0L+4OZnSrp\nxZLeG1vMMUzIzLZJ+glJ75Mkd3/c3Q+JY7hZWyQdb2ZbJI1L+po4hhty95skHWxY3Oq47ZF0nbsv\nu/t9kvYqyB80Rza3gWxOB9ncGbI5NWRzG7qdzVkUq6dI2h97fCBchoTMrCTphyX9u6ST3P2BcNWD\nkk7KqFn94i8kvVHS0dgyjmFyOyU9LOmqcLjWe83sKeIYJubu90t6h6RFSQ9IOuzunxHHsF2tjhtZ\nszkcrw6RzR0hmztDNneIbE5datnMBEt9xsy2SvqopN9092/F13kwtTPTO7dgZi+R9JC739pqG47h\nhrZIepakv3L3H5b0bTUMieEYri+8bmOPgn8uTpb0FDP7xfg2HMP2cNyQFbK5fWRzKsjmDpHN3dPp\nccuiWL1f0mmxx6eGy7ABMztGQRjW3P1j4eKvm9nTw/VPl/RQVu3rAz8m6WfMbJ+CIW4/ZWYfEMdw\nMw5IOuDu/x4+/oiCgOQYJvd8Sfe5+8Pu/t+SPibpueIYtqvVcSNrNofj1SayuWNkc+fI5s6RzelK\nLZuzKFZvkXS6me00s2MVXGR7fQbt6CtmZgquRbjT3f88tup6Sa8Kv36VpI/3um39wt3f5O6nuntJ\nwfvus+7+i+IYJubuD0rab2ZnhIueJ+kOcQw3Y1HSc8xsPPy9fp6C69w4hu1pddyul3SBmR1nZjsl\nnS7pPzJoX78gm9tANneObO4c2ZwKsjldqWWzBWdme8vMXqTg+oRRSVe6e7XnjegzZrZL0r9I+rJW\nrun4XQXXxnxIUkFSXdLL3b3xImc0MLMpSW9w95eY2dPEMUzMzCYUTIJxrKR7JV2soOOLY5iQmb1V\n0isUzCT6RUm/ImmrOIbrMrNrJU1JOlHS1yW9WdLfqcVxM7NpSb+s4Dj/prv/QwbN7htk8+aRzeki\nm9tHNneObG5Pt7M5k2IVAAAAAID1MMESAAAAACB3KFYBAAAAALlDsQoAAAAAyB2KVQAAAABA7lCs\nAgAAAAByh2IVAAAAAJA7FKsAAAAAgNyhWAUAAAAA5M7/B+SPb+gbrRvKAAAAAElFTkSuQmCC\n", 263 | "text/plain": [ 264 | "" 265 | ] 266 | }, 267 | "metadata": {}, 268 | "output_type": "display_data" 269 | } 270 | ], 271 | "source": [ 272 | "fig, ax = plt.subplots(nrows=1, ncols=2, figsize=(width,5))\n", 273 | "\n", 274 | "ax[0].set(xlim=[0,100], ylim=[-0.1,1.1], title=\"Actual data\")\n", 275 | "_ = ax[0].scatter(x=[e.t for e in points], y=[e.loc for e in points], color=\"blue\", marker=\"+\")\n", 276 | "_ = ax[0].scatter(x=[e.t for e in backgrounds], y=[e.loc for e in backgrounds], color=\"black\", marker=\"o\")\n", 277 | "\n", 278 | "ax[1].set(xlim=[0,100], ylim=[-0.1,1.1], title=\"Inferred background events\")\n", 279 | "_ = ax[1].scatter(x=[e.t for e in triggered_points], y=[e.loc for e in triggered_points], color=\"blue\", marker=\"+\")\n", 280 | "_ = ax[1].scatter(x=[e.t for e in background_points], y=[e.loc for e in background_points], color=\"black\", marker=\"o\")" 281 | ] 282 | }, 283 | { 284 | "cell_type": "markdown", 285 | "metadata": {}, 286 | "source": [ 287 | "*TODO:* These keep changing, of course...\n", 288 | "\n", 289 | "I think these plots are intuitively explainable:\n", 290 | "\n", 291 | "- We miss a background event at time 40, but it fell in the middle of a clump of triggered events.\n", 292 | "- Three triggered event at time circa 70 are classified as background-- but they look like unlikely events, so this seems plausible." 293 | ] 294 | }, 295 | { 296 | "cell_type": "markdown", 297 | "metadata": {}, 298 | "source": [ 299 | "# Iterative approximation for parametric distributions #\n", 300 | "\n", 301 | "Suppose now we do not know the parameters $\\mu, \\alpha$ and $\\sigma$. We take an iterative, monte carlo approach.\n", 302 | "\n", 303 | "1. Take an initial \"guess\" of the parameters\n", 304 | "2. Use these to form $\\mu$ and $g$ and hence form the matrix $p$.\n", 305 | "3. For each event, using the probabilities from the matrix, randomly decide if the event is background, or assign it to a \"triggering\" event.\n", 306 | "4. Use the background events to estimate the parameter $\\mu$ (e.g. via MLE) and similarly use the triggered events to estimate $\\alpha, \\sigma$.\n", 307 | "\n", 308 | "See below for calculations of what the MLEs are." 309 | ] 310 | }, 311 | { 312 | "cell_type": "code", 313 | "execution_count": 309, 314 | "metadata": { 315 | "collapsed": false 316 | }, 317 | "outputs": [], 318 | "source": [ 319 | "def compute_backgrounds_deltas(causes, points):\n", 320 | " backgrounds, trigger_deltas = [], []\n", 321 | " causes = sample_causality(p_matrix)\n", 322 | " for i, p in enumerate(points):\n", 323 | " c = causes[i]\n", 324 | " if c == i:\n", 325 | " backgrounds.append(p)\n", 326 | " else:\n", 327 | " tp = points[c]\n", 328 | " delta = Event(p.t - tp.t, p.loc - tp.loc)\n", 329 | " trigger_deltas.append(delta)\n", 330 | " return backgrounds, trigger_deltas\n", 331 | "\n", 332 | "def make_estimates(causes, points):\n", 333 | " \"\"\"Returns MLEs for mu, alpha and sigma.\"\"\"\n", 334 | " backgrounds, trigger_deltas = compute_backgrounds_deltas(causes, points)\n", 335 | " #background_event_times = np.array([e.t for e in backgrounds])\n", 336 | " #background_event_time_deltas = background_event_times[1:] - background_event_times[:-1]\n", 337 | " #mu = 1 / np.mean(background_event_time_deltas)\n", 338 | " window_size = 100\n", 339 | " mu = len(backgrounds) / window_size\n", 340 | " \n", 341 | " space_points = [e.loc for e in trigger_deltas]\n", 342 | " sigma = np.std(space_points, ddof=1)\n", 343 | " \n", 344 | " # Biased...\n", 345 | " counts = np.empty(len(causes) - 1, dtype=np.int32)\n", 346 | " for i in range(len(causes) - 1):\n", 347 | " counts[i] = sum(c==i for c in causes[i+1:])\n", 348 | " alpha = np.mean(counts)\n", 349 | " \n", 350 | " return mu, alpha, sigma" 351 | ] 352 | }, 353 | { 354 | "cell_type": "code", 355 | "execution_count": 314, 356 | "metadata": { 357 | "collapsed": true 358 | }, 359 | "outputs": [], 360 | "source": [ 361 | "def sample_causality(p_matrix):\n", 362 | " \"\"\"Returns a list where entry i is the j