File size: 141,600 Bytes
651b002
b430afc
651b002
b430afc
 
 
 
6d50123
b430afc
651b002
 
b430afc
 
 
 
 
 
6d50123
b430afc
 
 
 
 
651b002
 
b430afc
 
 
 
651b002
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
651b002
b430afc
 
651b002
 
 
b430afc
 
 
 
 
 
 
651b002
 
b430afc
 
 
 
 
 
 
 
651b002
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
 
 
 
 
 
651b002
b430afc
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
651b002
 
b430afc
 
 
651b002
b430afc
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
651b002
b430afc
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
651b002
b430afc
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
 
 
 
651b002
 
b430afc
 
 
651b002
b430afc
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
b430afc
 
 
 
 
651b002
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
b430afc
651b002
b430afc
 
 
 
 
 
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
 
 
 
 
651b002
 
 
b430afc
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6d50123
b430afc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
651b002
 
b430afc
 
651b002
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
{
  "cells": [
    {
      "attachments": {},
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "# FSRS4Anki v3.13.3 Optimizer"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "metadata": {
        "id": "lurCmW0Jqz3s"
      },
      "source": [
        "[![open in colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-spaced-repetition/fsrs4anki/blob/v3.13.3/fsrs4anki_optimizer.ipynb)\n",
        "\n",
        "↑ Click the above button to open the optimizer on Google Colab.\n",
        "\n",
        "> If you can't see the button and are located in the Chinese Mainland, please use a proxy or VPN."
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "metadata": {
        "id": "wG7bBfGJFbMr"
      },
      "source": [
        "Upload your **Anki Deck Package (.apkg)** file or **Anki Collection Package (.colpkg)** file on the `Left sidebar -> Files`, drag and drop your file in the current directory (not the `sample_data` directory). \n",
        "\n",
        "No need to include media. Need to include scheduling information. \n",
        "\n",
        "> If you use the latest version of Anki, please check the box `Support older Anki versions (slower/larger files)` when you export.\n",
        "\n",
        "You can export it via `File -> Export...` or `Ctrl + E` in the main window of Anki.\n",
        "\n",
        "Then replace the `filename` with yours in the next code cell. And set the `timezone` and `next_day_starts_at` which can be found in your preferences of Anki.\n",
        "\n",
        "After that, just run all (`Runtime -> Run all` or `Ctrl + F9`) and wait for minutes. You can see the optimal parameters in section **2.3 Result**. Copy them, replace the parameters in `fsrs4anki_scheduler.js`, and paste them into the custom scheduling of your deck options (require Anki version >= 2.1.55).\n",
        "\n",
        "**NOTE**: The default output is generated from my review logs. If you find the output is the same as mine, maybe your notebook hasn't run there.\n",
        "\n",
        "**Contribute to SRS Research**: If you want to share your data with me, please fill this form: https://forms.gle/KaojsBbhMCytaA7h8"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 1,
      "metadata": {
        "id": "iqP70_-3EUhi"
      },
      "outputs": [],
      "source": [
        "# Here are some settings that you need to replace before running this optimizer.\n",
        "\n",
        "filename = \"collection-2022-09-18@13-21-58.colpkg\"\n",
        "# If you upload deck file, replace it with your deck filename. E.g., ALL__Learning.apkg\n",
        "# If you upload collection file, replace it with your colpgk filename. E.g., collection-2022-09-18@13-21-58.colpkg\n",
        "\n",
        "# Replace it with your timezone. I'm in China, so I use Asia/Shanghai.\n",
        "# You can find your timezone here: https://gist.github.com/heyalexej/8bf688fd67d7199be4a1682b3eec7568\n",
        "timezone = 'Asia/Shanghai'\n",
        "\n",
        "# Replace it with your Anki's setting in Preferences -> Scheduling.\n",
        "next_day_starts_at = 4\n",
        "\n",
        "# Replace it if you don't want the optimizer to use the review logs before a specific date.\n",
        "revlog_start_date = \"2006-10-05\"\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "bLFVNmG2qd06"
      },
      "source": [
        "## 1 Build dataset"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "EkzFeKawqgbs"
      },
      "source": [
        "### 1.1 Extract Anki collection & deck file"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 2,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "KD2js_wEr_Bs",
        "outputId": "42653d9e-316e-40bc-bd1d-f3a0e2b246c7"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Extract successfully!\n"
          ]
        }
      ],
      "source": [
        "import zipfile\n",
        "import sqlite3\n",
        "import time\n",
        "import tqdm\n",
        "import pandas as pd\n",
        "import numpy as np\n",
        "import os\n",
        "from datetime import timedelta, datetime\n",
        "import matplotlib.pyplot as plt\n",
        "import math\n",
        "import sys\n",
        "import torch\n",
        "from torch import nn\n",
        "from sklearn.utils import shuffle\n",
        "# Extract the collection file or deck file to get the .anki21 database.\n",
        "with zipfile.ZipFile(f'./{filename}', 'r') as zip_ref:\n",
        "    zip_ref.extractall('./')\n",
        "    print(\"Extract successfully!\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "dKpy4VfqGmaL"
      },
      "source": [
        "### 1.2 Create time-series feature & analysis\n",
        "\n",
        "The following code cell will extract the review logs from your Anki collection and preprocess them to a trainset which is saved in `revlog_history.tsv`.\n",
        "\n",
        "The time-series features are important in optimizing the model's parameters. For more detail, please see my paper: https://www.maimemo.com/paper/\n",
        "\n",
        "Then it will generate a concise analysis for your review logs. \n",
        "\n",
        "- The `r_history` is the history of ratings on each review. `3,3,3,1` means that you press `Good, Good, Good, Again`. It only contains the first rating for each card on the review date, i.e., when you press `Again` in review and  `Good` in relearning steps 10min later, only `Again` will be recorded.\n",
        "- The `avg_interval` is the actual average interval after you rate your cards as the `r_history`. It could be longer than the interval given by Anki's built-in scheduler because you reviewed some overdue cards.\n",
        "- The `avg_retention` is the average retention after you press as the `r_history`. `Again` counts as failed recall, and `Hard, Good and Easy` count as successful recall. Retention is the percentage of your successful recall.\n",
        "- The `stability` is the estimated memory state variable, which is an approximate interval that leads to 90% retention.\n",
        "- The `factor` is `stability / previous stability`.\n",
        "- The `group_cnt` is the number of review logs that have the same `r_history`."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 3,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "J2IIaY3PDaaG",
        "outputId": "607916c9-da95-48dd-fdab-6bd83fbbbb40"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "revlog.csv saved.\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "c9bb754c7ac441068199f88788b35a74",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/30711 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Trainset saved.\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "ec878c2155d74cf1adefa0c7a0c8052a",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/96660 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Retention calculated.\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "38f567392f7b4c73b92b3b336b04df4b",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/1312 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Stability calculated.\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "6966fe105e3d4c398100ae20c5fb57fb",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/1312 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "1:again, 2:hard, 3:good, 4:easy\n",
            "\n",
            "  r_history  avg_interval  avg_retention  stability  factor  group_cnt\n",
            "          1           1.7          0.765        1.0     inf       7978\n",
            "        1,3           3.9          0.876        4.3    4.30       4155\n",
            "      1,3,3           8.6          0.883        9.2    2.14       2684\n",
            "    1,3,3,3          17.8          0.857       13.8    1.50       1483\n",
            "  1,3,3,3,3          37.0          0.812       19.4    1.41        606\n",
            "1,3,3,3,3,3          77.1          0.708       23.1    1.19        128\n",
            "          2           1.0          0.901        1.1     inf        234\n",
            "        2,3           3.2          0.943        6.3    5.73        154\n",
            "          3           1.5          0.962        5.4     inf       9070\n",
            "        3,3           3.9          0.966       15.2    2.81       6527\n",
            "      3,3,3           9.0          0.960       23.5    1.55       5036\n",
            "    3,3,3,3          18.6          0.941       35.2    1.50       3052\n",
            "  3,3,3,3,3          39.5          0.914       46.9    1.33       1423\n",
            "3,3,3,3,3,3          74.3          0.853       55.6    1.19        411\n",
            "          4           3.8          0.966       12.1     inf      11436\n",
            "        4,3           8.1          0.975       38.9    3.21       7367\n",
            "      4,3,3          18.0          0.963       57.7    1.48       5147\n",
            "    4,3,3,3          34.0          0.947       77.2    1.34       2525\n",
            "  4,3,3,3,3          46.3          0.906       50.1    0.65        452\n",
            "Analysis saved!\n"
          ]
        }
      ],
      "source": [
        "if os.path.isfile(\"collection.anki21b\"):\n",
        "    os.remove(\"collection.anki21b\")\n",
        "    raise Exception(\n",
        "        \"Please export the file with `support older Anki versions` if you use the latest version of Anki.\")\n",
        "elif os.path.isfile(\"collection.anki21\"):\n",
        "    con = sqlite3.connect(\"collection.anki21\")\n",
        "elif os.path.isfile(\"collection.anki2\"):\n",
        "    con = sqlite3.connect(\"collection.anki2\")\n",
        "else:\n",
        "    raise Exception(\"Collection not exist!\")\n",
        "cur = con.cursor()\n",
        "res = cur.execute(\"SELECT * FROM revlog\")\n",
        "revlog = res.fetchall()\n",
        "\n",
        "df = pd.DataFrame(revlog)\n",
        "df.columns = ['id', 'cid', 'usn', 'r', 'ivl',\n",
        "              'last_lvl', 'factor', 'time', 'type']\n",
        "df = df[(df['cid'] <= time.time() * 1000) &\n",
        "        (df['id'] <= time.time() * 1000) &\n",
        "        (df['r'] > 0)].copy()\n",
        "df['create_date'] = pd.to_datetime(df['cid'] // 1000, unit='s')\n",
        "df['create_date'] = df['create_date'].dt.tz_localize(\n",
        "    'UTC').dt.tz_convert(timezone)\n",
        "df['review_date'] = pd.to_datetime(df['id'] // 1000, unit='s')\n",
        "df['review_date'] = df['review_date'].dt.tz_localize(\n",
        "    'UTC').dt.tz_convert(timezone)\n",
        "df.drop(df[df['review_date'].dt.year < 2006].index, inplace=True)\n",
        "df.sort_values(by=['cid', 'id'], inplace=True, ignore_index=True)\n",
        "type_sequence = np.array(df['type'])\n",
        "time_sequence = np.array(df['time'])\n",
        "df.to_csv(\"revlog.csv\", index=False)\n",
        "print(\"revlog.csv saved.\")\n",
        "df = df[(df['type'] == 0) | (df['type'] == 1)].copy()\n",
        "df['real_days'] = df['review_date'] - timedelta(hours=next_day_starts_at)\n",
        "df['real_days'] = pd.DatetimeIndex(df['real_days'].dt.floor('D')).to_julian_date()\n",
        "df.drop_duplicates(['cid', 'real_days'], keep='first', inplace=True)\n",
        "df['delta_t'] = df.real_days.diff()\n",
        "df.dropna(inplace=True)\n",
        "df['delta_t'] = df['delta_t'].astype(dtype=int)\n",
        "df['i'] = 1\n",
        "df['r_history'] = \"\"\n",
        "df['t_history'] = \"\"\n",
        "col_idx = {key: i for i, key in enumerate(df.columns)}\n",
        "\n",
        "\n",
        "# code from https://github.com/L-M-Sherlock/anki_revlog_analysis/blob/main/revlog_analysis.py\n",
        "def get_feature(x):\n",
        "    for idx, log in enumerate(x.itertuples()):\n",
        "        if idx == 0:\n",
        "            x.iloc[idx, col_idx['delta_t']] = 0\n",
        "        if idx == x.shape[0] - 1:\n",
        "            break\n",
        "        x.iloc[idx + 1, col_idx['i']] = x.iloc[idx, col_idx['i']] + 1\n",
        "        x.iloc[idx + 1, col_idx['t_history']] = f\"{x.iloc[idx, col_idx['t_history']]},{x.iloc[idx, col_idx['delta_t']]}\"\n",
        "        x.iloc[idx + 1, col_idx['r_history']] = f\"{x.iloc[idx, col_idx['r_history']]},{x.iloc[idx, col_idx['r']]}\"\n",
        "    return x\n",
        "\n",
        "tqdm.notebook.tqdm.pandas()\n",
        "df = df.groupby('cid', as_index=False).progress_apply(get_feature)\n",
        "df = df[df['id'] >= time.mktime(datetime.strptime(revlog_start_date, \"%Y-%m-%d\").timetuple()) * 1000]\n",
        "df[\"t_history\"] = df[\"t_history\"].map(lambda x: x[1:] if len(x) > 1 else x)\n",
        "df[\"r_history\"] = df[\"r_history\"].map(lambda x: x[1:] if len(x) > 1 else x)\n",
        "df.to_csv('revlog_history.tsv', sep=\"\\t\", index=False)\n",
        "print(\"Trainset saved.\")\n",
        "\n",
        "def cal_retention(group: pd.DataFrame) -> pd.DataFrame:\n",
        "    group['retention'] = round(group['r'].map(lambda x: {1: 0, 2: 1, 3: 1, 4: 1}[x]).mean(), 4)\n",
        "    group['total_cnt'] = group.shape[0]\n",
        "    return group\n",
        "\n",
        "df = df.groupby(by=['r_history', 'delta_t']).progress_apply(cal_retention)\n",
        "print(\"Retention calculated.\")\n",
        "df = df.drop(columns=['id', 'cid', 'usn', 'ivl', 'last_lvl', 'factor', 'time', 'type', 'create_date', 'review_date', 'real_days', 'r', 't_history'])\n",
        "df.drop_duplicates(inplace=True)\n",
        "df = df[(df['retention'] < 1) & (df['retention'] > 0)]\n",
        "\n",
        "def cal_stability(group: pd.DataFrame) -> pd.DataFrame:\n",
        "    if group['i'].values[0] > 1:\n",
        "        r_ivl_cnt = sum(group['delta_t'] * group['retention'].map(np.log) * pow(group['total_cnt'], 2))\n",
        "        ivl_ivl_cnt = sum(group['delta_t'].map(lambda x: x ** 2) * pow(group['total_cnt'], 2))\n",
        "        group['stability'] = round(np.log(0.9) / (r_ivl_cnt / ivl_ivl_cnt), 1)\n",
        "    else:\n",
        "        group['stability'] = 0.0\n",
        "    group['group_cnt'] = sum(group['total_cnt'])\n",
        "    group['avg_retention'] = round(sum(group['retention'] * pow(group['total_cnt'], 2)) / sum(pow(group['total_cnt'], 2)), 3)\n",
        "    group['avg_interval'] = round(sum(group['delta_t'] * pow(group['total_cnt'], 2)) / sum(pow(group['total_cnt'], 2)), 1)\n",
        "    del group['total_cnt']\n",
        "    del group['retention']\n",
        "    del group['delta_t']\n",
        "    return group\n",
        "\n",
        "df = df.groupby(by=['r_history']).progress_apply(cal_stability)\n",
        "print(\"Stability calculated.\")\n",
        "df.reset_index(drop = True, inplace = True)\n",
        "df.drop_duplicates(inplace=True)\n",
        "df.sort_values(by=['r_history'], inplace=True, ignore_index=True)\n",
        "\n",
        "if df.shape[0] > 0:\n",
        "    for idx in tqdm.notebook.tqdm(df.index):\n",
        "        item = df.loc[idx]\n",
        "        index = df[(df['i'] == item['i'] + 1) & (df['r_history'].str.startswith(item['r_history']))].index\n",
        "        df.loc[index, 'last_stability'] = item['stability']\n",
        "    df['factor'] = round(df['stability'] / df['last_stability'], 2)\n",
        "    df = df[(df['i'] >= 2) & (df['group_cnt'] >= 100)]\n",
        "    df['last_recall'] = df['r_history'].map(lambda x: x[-1])\n",
        "    df = df[df.groupby(['i', 'r_history'])['group_cnt'].transform(max) == df['group_cnt']]\n",
        "    df.to_csv('./stability_for_analysis.tsv', sep='\\t', index=None)\n",
        "    print(\"1:again, 2:hard, 3:good, 4:easy\\n\")\n",
        "    print(df[df['r_history'].str.contains(r'^[1-4][^124]*$', regex=True)][['r_history', 'avg_interval', 'avg_retention', 'stability', 'factor', 'group_cnt']].to_string(index=False))\n",
        "    print(\"Analysis saved!\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "k_SgzC-auWmu"
      },
      "source": [
        "## 2 Optimize parameter"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "WrfBJjqCHEwJ"
      },
      "source": [
        "### 2.1 Define the model\n",
        "\n",
        "FSRS is a time-series model for predicting memory states."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 4,
      "metadata": {
        "id": "tdYp3GMLhTYm"
      },
      "outputs": [],
      "source": [
        "init_w = [1, 1, 5, -0.5, -0.5, 0.2, 1.4, -0.12, 0.8, 2, -0.2, 0.2, 1]\n",
        "'''\n",
        "w[0]: initial_stability_for_again_answer\n",
        "w[1]: initial_stability_step_per_rating\n",
        "w[2]: initial_difficulty_for_good_answer\n",
        "w[3]: initial_difficulty_step_per_rating\n",
        "w[4]: next_difficulty_step_per_rating\n",
        "w[5]: next_difficulty_reversion_to_mean_speed (used to avoid ease hell)\n",
        "w[6]: next_stability_factor_after_success\n",
        "w[7]: next_stability_stabilization_decay_after_success\n",
        "w[8]: next_stability_retrievability_gain_after_success\n",
        "w[9]: next_stability_factor_after_failure\n",
        "w[10]: next_stability_difficulty_decay_after_success\n",
        "w[11]: next_stability_stability_gain_after_failure\n",
        "w[12]: next_stability_retrievability_gain_after_failure\n",
        "For more details about the parameters, please see: \n",
        "https://github.com/open-spaced-repetition/fsrs4anki/wiki/Free-Spaced-Repetition-Scheduler\n",
        "'''\n",
        "\n",
        "\n",
        "class FSRS(nn.Module):\n",
        "    def __init__(self, w):\n",
        "        super(FSRS, self).__init__()\n",
        "        self.w = nn.Parameter(torch.FloatTensor(w))\n",
        "        self.zero = torch.FloatTensor([0.0])\n",
        "\n",
        "    def forward(self, x, s, d):\n",
        "        '''\n",
        "        :param x: [review interval, review response]\n",
        "        :param s: stability\n",
        "        :param d: difficulty\n",
        "        :return:\n",
        "        '''\n",
        "        if torch.equal(s, self.zero):\n",
        "            # first learn, init memory states\n",
        "            new_s = self.w[0] + self.w[1] * (x[1] - 1)\n",
        "            new_d = self.w[2] + self.w[3] * (x[1] - 3)\n",
        "            new_d = new_d.clamp(1, 10)\n",
        "        else:\n",
        "            r = torch.exp(np.log(0.9) * x[0] / s)\n",
        "            new_d = d + self.w[4] * (x[1] - 3)\n",
        "            new_d = self.mean_reversion(self.w[2], new_d)\n",
        "            new_d = new_d.clamp(1, 10)\n",
        "            # recall\n",
        "            if x[1] > 1:\n",
        "                new_s = s * (1 + torch.exp(self.w[6]) *\n",
        "                             (11 - new_d) *\n",
        "                             torch.pow(s, self.w[7]) *\n",
        "                             (torch.exp((1 - r) * self.w[8]) - 1))\n",
        "            # forget\n",
        "            else:\n",
        "                new_s = self.w[9] * torch.pow(new_d, self.w[10]) * torch.pow(\n",
        "                    s, self.w[11]) * torch.exp((1 - r) * self.w[12])\n",
        "        return new_s, new_d\n",
        "\n",
        "    def loss(self, s, t, r):\n",
        "        return - (r * np.log(0.9) * t / s + (1 - r) * torch.log(1 - torch.exp(np.log(0.9) * t / s)))\n",
        "\n",
        "    def mean_reversion(self, init, current):\n",
        "        return self.w[5] * init + (1-self.w[5]) * current\n",
        "\n",
        "\n",
        "class WeightClipper(object):\n",
        "    def __init__(self, frequency=1):\n",
        "        self.frequency = frequency\n",
        "\n",
        "    def __call__(self, module):\n",
        "        if hasattr(module, 'w'):\n",
        "            w = module.w.data\n",
        "            w[0] = w[0].clamp(0.1, 10)\n",
        "            w[1] = w[1].clamp(0.1, 5)\n",
        "            w[2] = w[2].clamp(1, 10)\n",
        "            w[3] = w[3].clamp(-5, -0.1)\n",
        "            w[4] = w[4].clamp(-5, -0.1)\n",
        "            w[5] = w[5].clamp(0, 0.5)\n",
        "            w[6] = w[6].clamp(0, 2)\n",
        "            w[7] = w[7].clamp(-0.2, -0.01)\n",
        "            w[8] = w[8].clamp(0.01, 1.5)\n",
        "            w[9] = w[9].clamp(0.5, 5)\n",
        "            w[10] = w[10].clamp(-2, -0.01)\n",
        "            w[11] = w[11].clamp(0.01, 0.9)\n",
        "            w[12] = w[12].clamp(0.01, 2)\n",
        "            module.w.data = w\n",
        "\n",
        "def lineToTensor(line):\n",
        "    ivl = line[0].split(',')\n",
        "    response = line[1].split(',')\n",
        "    tensor = torch.zeros(len(response), 2)\n",
        "    for li, response in enumerate(response):\n",
        "        tensor[li][0] = int(ivl[li])\n",
        "        tensor[li][1] = int(response)\n",
        "    return tensor\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "8E1dYfgQLZAC"
      },
      "source": [
        "### 2.2 Train the model\n",
        "\n",
        "The `revlog_history.tsv` generated before will be used for training the FSRS model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 5,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "Jht0gneShowU",
        "outputId": "aaa72b79-b454-483b-d746-df1a353b2c8f"
      },
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "749aeda9cb624986ae2872489bcc6762",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/225934 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Tensorized!\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "9ca6df8fb70247afaa07389ebf5bb791",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "pre-train:   0%|          | 0/28972 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "w: [1.0138, 2.293, 5.0, -0.5, -0.5, 0.2, 1.4, -0.12, 0.8, 2.0, -0.2, 0.2, 1.0]\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "278f800ad8a344098c6b4a5de627fec8",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "train:   0%|          | 0/196962 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "iteration: 1\n",
            "w: [1.0138, 2.293, 4.9984, -0.4984, -0.4984, 0.2016, 1.4016, -0.1184, 0.8016, 2.0016, -0.1984, 0.2016, 1.0016]\n",
            "iteration: 19697\n",
            "w: [1.014, 2.2933, 5.1652, -0.8884, -0.7373, 0.026, 1.3259, -0.0494, 0.7189, 1.853, -0.3535, 0.3647, 0.8628]\n",
            "iteration: 39393\n",
            "w: [1.014, 2.2933, 5.1767, -1.0578, -0.7928, 0.0195, 1.3425, -0.0432, 0.7301, 1.822, -0.3883, 0.4718, 0.8202]\n",
            "iteration: 59089\n",
            "w: [1.014, 2.2933, 5.1755, -1.0848, -0.916, 0.0048, 1.3575, -0.0471, 0.7372, 1.783, -0.4253, 0.5637, 0.8399]\n",
            "iteration: 78785\n",
            "w: [1.014, 2.2933, 5.2163, -1.1424, -1.0315, 0.0209, 1.4064, -0.037, 0.7832, 1.729, -0.4696, 0.5912, 0.8048]\n",
            "iteration: 98481\n",
            "w: [1.014, 2.2933, 5.1824, -1.1082, -1.0993, 0.005, 1.4292, -0.0466, 0.8023, 1.752, -0.4439, 0.6245, 0.8375]\n",
            "iteration: 118177\n",
            "w: [1.014, 2.2933, 5.1739, -1.153, -1.0981, 0.0293, 1.4028, -0.0264, 0.771, 1.7137, -0.4739, 0.5661, 0.8806]\n",
            "iteration: 137873\n",
            "w: [1.014, 2.2933, 5.1328, -1.2144, -1.0813, 0.0076, 1.3886, -0.0282, 0.7491, 1.7144, -0.4721, 0.6277, 0.943]\n",
            "iteration: 157569\n",
            "w: [1.014, 2.2933, 5.1073, -1.1666, -1.0882, 0.026, 1.3686, -0.0782, 0.724, 1.7382, -0.4407, 0.6225, 0.9923]\n",
            "iteration: 177265\n",
            "w: [1.014, 2.2933, 5.0097, -1.1477, -1.0749, 0.0118, 1.4076, -0.0469, 0.7584, 1.7131, -0.464, 0.5953, 1.0136]\n",
            "iteration: 196961\n",
            "w: [1.014, 2.2933, 4.9444, -1.1646, -0.9944, 0.0227, 1.3911, -0.0499, 0.7376, 1.7016, -0.4742, 0.6019, 0.9947]\n",
            "\n",
            "Training finished!\n"
          ]
        }
      ],
      "source": [
        "model = FSRS(init_w)\n",
        "clipper = WeightClipper()\n",
        "optimizer = torch.optim.Adam(model.parameters(), lr=5e-4)\n",
        "\n",
        "dataset = pd.read_csv(\"./revlog_history.tsv\", sep='\\t', index_col=None, dtype={'r_history': str ,'t_history': str} )\n",
        "dataset = dataset[(dataset['i'] > 1) & (dataset['delta_t'] > 0) & (dataset['t_history'].str.count(',0') == 0)]\n",
        "dataset['tensor'] = dataset.progress_apply(lambda x: lineToTensor(list(zip([x['t_history']], [x['r_history']]))[0]), axis=1)\n",
        "print(\"Tensorized!\")\n",
        "\n",
        "pre_train_set = dataset[dataset['i'] == 2]\n",
        "# pretrain\n",
        "epoch_len = len(pre_train_set)\n",
        "n_epoch = 1\n",
        "pbar = tqdm.notebook.tqdm(desc=\"pre-train\", colour=\"red\", total=epoch_len*n_epoch)\n",
        "\n",
        "for k in range(n_epoch):\n",
        "    for i, (_, row) in enumerate(shuffle(pre_train_set, random_state=2022 + k).iterrows()):\n",
        "        model.train()\n",
        "        optimizer.zero_grad()\n",
        "        output_t = [(model.zero, model.zero)]\n",
        "        for input_t in row['tensor']:\n",
        "            output_t.append(model(input_t, *output_t[-1]))\n",
        "        loss = model.loss(output_t[-1][0], row['delta_t'],\n",
        "                            {1: 0, 2: 1, 3: 1, 4: 1}[row['r']])\n",
        "        if np.isnan(loss.data.item()):\n",
        "            # Exception Case\n",
        "            print(row, output_t)\n",
        "            raise Exception('error case')\n",
        "        loss.backward()\n",
        "        optimizer.step()\n",
        "        model.apply(clipper)\n",
        "        pbar.update()\n",
        "pbar.close()\n",
        "for name, param in model.named_parameters():\n",
        "    print(f\"{name}: {list(map(lambda x: round(float(x), 4),param))}\")\n",
        "\n",
        "train_set = dataset[dataset['i'] > 2]\n",
        "epoch_len = len(train_set)\n",
        "n_epoch = 1\n",
        "print_len = max(epoch_len*n_epoch // 10, 1)\n",
        "pbar = tqdm.notebook.tqdm(desc=\"train\", colour=\"red\", total=epoch_len*n_epoch)\n",
        "\n",
        "for k in range(n_epoch):\n",
        "    for i, (_, row) in enumerate(shuffle(train_set, random_state=2022 + k).iterrows()):\n",
        "        model.train()\n",
        "        optimizer.zero_grad()\n",
        "        output_t = [(model.zero, model.zero)]\n",
        "        for input_t in row['tensor']:\n",
        "            output_t.append(model(input_t, *output_t[-1]))\n",
        "        loss = model.loss(output_t[-1][0], row['delta_t'],\n",
        "                          {1: 0, 2: 1, 3: 1, 4: 1}[row['r']])\n",
        "        if np.isnan(loss.data.item()):\n",
        "            # Exception Case\n",
        "            print(row, output_t)\n",
        "            raise Exception('error case')\n",
        "        loss.backward()\n",
        "        for param in model.parameters():\n",
        "            param.grad[:2] = torch.zeros(2)\n",
        "        optimizer.step()\n",
        "        model.apply(clipper)\n",
        "        pbar.update()\n",
        "\n",
        "        if (k * epoch_len + i) % print_len == 0:\n",
        "            print(f\"iteration: {k * epoch_len + i + 1}\")\n",
        "            for name, param in model.named_parameters():\n",
        "                print(f\"{name}: {list(map(lambda x: round(float(x), 4),param))}\")\n",
        "pbar.close()\n",
        "\n",
        "w = list(map(lambda x: round(float(x), 4), dict(model.named_parameters())['w'].data))\n",
        "\n",
        "print(\"\\nTraining finished!\")\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "BZ4S2l7BWfzr"
      },
      "source": [
        "### 2.3 Result\n",
        "\n",
        "Copy the optimal parameters for FSRS for you in the output of next code cell after running."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 6,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "NTnPSDA2QpUu",
        "outputId": "49f487b9-69a7-4e96-b35a-7e027f478fbd"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "var w = [1.014, 2.2933, 4.9444, -1.1646, -0.9942, 0.0227, 1.3911, -0.0498, 0.7376, 1.7016, -0.4742, 0.602, 0.9946];\n"
          ]
        }
      ],
      "source": [
        "print(f\"var w = {w};\")"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.4 Preview"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {
        "id": "I_zsoDyTaTrT"
      },
      "source": [
        "You can see the memory states and intervals generated by FSRS as if you press the good in each review at the due date scheduled by FSRS."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 7,
      "metadata": {
        "colab": {
          "base_uri": "https://localhost:8080/"
        },
        "id": "iws4rtP1WKBT",
        "outputId": "890d0287-1a17-4c59-fbbf-ee54d79cd383"
      },
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "1:again, 2:hard, 3:good, 4:easy\n",
            "\n",
            "first rating: 1\n",
            "rating history: 1,3,3,3,3,3,3,3,3,3,3\n",
            "interval history: 0,1,2,4,9,19,39,79,159,315,618\n",
            "difficulty history: 0,7.3,7.2,7.2,7.1,7.1,7.0,7.0,6.9,6.9,6.8\n",
            "\n",
            "first rating: 2\n",
            "rating history: 2,3,3,3,3,3,3,3,3,3,3\n",
            "interval history: 0,3,8,19,44,100,222,485,1041,2193,4543\n",
            "difficulty history: 0,6.1,6.1,6.1,6.0,6.0,6.0,6.0,5.9,5.9,5.9\n",
            "\n",
            "first rating: 3\n",
            "rating history: 3,3,3,3,3,3,3,3,3,3,3\n",
            "interval history: 0,6,16,42,107,265,639,1502,3446,7725,16941\n",
            "difficulty history: 0,4.9,4.9,4.9,4.9,4.9,4.9,4.9,4.9,4.9,4.9\n",
            "\n",
            "first rating: 4\n",
            "rating history: 4,3,3,3,3,3,3,3,3,3,3\n",
            "interval history: 0,8,24,69,192,515,1339,3374,8256,19643,45511\n",
            "difficulty history: 0,3.8,3.8,3.8,3.9,3.9,3.9,3.9,4.0,4.0,4.0\n",
            "\n"
          ]
        }
      ],
      "source": [
        "requestRetention = 0.9  # recommended setting: 0.8 ~ 0.9\n",
        "\n",
        "\n",
        "class Collection:\n",
        "    def __init__(self, w):\n",
        "        self.model = FSRS(w)\n",
        "\n",
        "    def states(self, t_history, r_history):\n",
        "        with torch.no_grad():\n",
        "            line_tensor = lineToTensor(list(zip([t_history], [r_history]))[0])\n",
        "            output_t = [(self.model.zero, self.model.zero)]\n",
        "            for input_t in line_tensor:\n",
        "                output_t.append(self.model(input_t, *output_t[-1]))\n",
        "            return output_t[-1]\n",
        "\n",
        "\n",
        "my_collection = Collection(w)\n",
        "print(\"1:again, 2:hard, 3:good, 4:easy\\n\")\n",
        "for first_rating in (1,2,3,4):\n",
        "    print(f'first rating: {first_rating}')\n",
        "    t_history = \"0\"\n",
        "    d_history = \"0\"\n",
        "    r_history = f\"{first_rating}\"  # the first rating of the new card\n",
        "    # print(\"stability, difficulty, lapses\")\n",
        "    for i in range(10):\n",
        "        states = my_collection.states(t_history, r_history)\n",
        "        # print('{0:9.2f} {1:11.2f} {2:7.0f}'.format(\n",
        "            # *list(map(lambda x: round(float(x), 4), states))))\n",
        "        next_t = max(round(float(np.log(requestRetention)/np.log(0.9) * states[0])), 1)\n",
        "        difficulty = round(float(states[1]), 1)\n",
        "        t_history += f',{int(next_t)}'\n",
        "        d_history += f',{difficulty}'\n",
        "        r_history += f\",3\"\n",
        "    print(f\"rating history: {r_history}\")\n",
        "    print(f\"interval history: {t_history}\")\n",
        "    print(f\"difficulty history: {d_history}\")\n",
        "    print('')\n"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "You can change the `test_rating_sequence` to see the scheduling intervals in different ratings."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 8,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "(tensor(5.6006), tensor(4.9444))\n",
            "(tensor(15.8482), tensor(4.9444))\n",
            "(tensor(41.8218), tensor(4.9444))\n",
            "(tensor(106.7919), tensor(4.9444))\n",
            "(tensor(264.7672), tensor(4.9444))\n",
            "(tensor(21.6391), tensor(6.8877))\n",
            "(tensor(4.2755), tensor(8.7868))\n",
            "(tensor(6.9117), tensor(8.6996))\n",
            "(tensor(11.5771), tensor(8.6143))\n",
            "(tensor(19.6411), tensor(8.5310))\n",
            "(tensor(33.1676), tensor(8.4496))\n",
            "(tensor(55.5986), tensor(8.3701))\n",
            "rating history: 3,3,3,3,3,1,1,3,3,3,3,3\n",
            "interval history: 0,6,16,42,107,265,22,4,7,12,20,33,56\n",
            "difficulty history: 0,4.9,4.9,4.9,4.9,4.9,6.9,8.8,8.7,8.6,8.5,8.4,8.4\n"
          ]
        }
      ],
      "source": [
        "test_rating_sequence = \"3,3,3,3,3,1,1,3,3,3,3,3\"\n",
        "requestRetention = 0.9  # recommended setting: 0.8 ~ 0.9\n",
        "easyBonus = 1.3\n",
        "hardInterval = 1.2\n",
        "\n",
        "t_history = \"0\"\n",
        "d_history = \"0\"\n",
        "for i in range(len(test_rating_sequence.split(','))):\n",
        "    rating = test_rating_sequence[2*i]\n",
        "    last_t = int(t_history.split(',')[-1])\n",
        "    r_history = test_rating_sequence[:2*i+1]\n",
        "    states = my_collection.states(t_history, r_history)\n",
        "    print(states)\n",
        "    next_t = max(1,round(float(np.log(requestRetention)/np.log(0.9) * states[0])))\n",
        "    if rating == '4':\n",
        "        next_t = round(next_t * easyBonus)\n",
        "    elif rating == '2':\n",
        "        next_t = round(last_t * hardInterval)\n",
        "    t_history += f',{int(next_t)}'\n",
        "    difficulty = round(float(states[1]), 1)\n",
        "    d_history += f',{difficulty}'\n",
        "print(f\"rating history: {test_rating_sequence}\")\n",
        "print(f\"interval history: {t_history}\")\n",
        "print(f\"difficulty history: {d_history}\")"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "### 2.5 Predict memory states and distribution of difficulty\n",
        "\n",
        "Predict memory states for each review and save them in `prediction.tsv`.\n",
        "\n",
        "Meanwhile, it will count the distribution of difficulty."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 9,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "7712ed30c62643f4aa834c840458158c",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/119670 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "prediction.tsv saved.\n",
            "difficulty\n",
            "1     0.001872\n",
            "2     0.011003\n",
            "3     0.039538\n",
            "4     0.154465\n",
            "5     0.160835\n",
            "6     0.067524\n",
            "7     0.135336\n",
            "8     0.068502\n",
            "9     0.107031\n",
            "10    0.253893\n",
            "Name: count, dtype: float64\n"
          ]
        }
      ],
      "source": [
        "def predict_memory_states(group):\n",
        "    states = my_collection.states(*group.name)\n",
        "    group['stability'] = float(states[0])\n",
        "    group['difficulty'] = float(states[1])\n",
        "    group['count'] = len(group)\n",
        "    return pd.DataFrame({\n",
        "        'r_history': [group.name[1]], \n",
        "        't_history': [group.name[0]], \n",
        "        'stability': [round(float(states[0]),2)], \n",
        "        'difficulty': [round(float(states[1]),2)], \n",
        "        'count': [len(group)] \n",
        "    })\n",
        "\n",
        "prediction = dataset.groupby(by=['t_history', 'r_history']).progress_apply(predict_memory_states)\n",
        "prediction.reset_index(drop=True, inplace=True)\n",
        "prediction.sort_values(by=['r_history'], inplace=True)\n",
        "prediction.to_csv(\"./prediction.tsv\", sep='\\t', index=None)\n",
        "print(\"prediction.tsv saved.\")\n",
        "prediction['difficulty'] = prediction['difficulty'].map(lambda x: int(round(x)))\n",
        "difficulty_distribution = prediction.groupby(by=['difficulty'])['count'].sum() / prediction['count'].sum()\n",
        "print(difficulty_distribution)\n",
        "difficulty_distribution_padding = np.zeros(10)\n",
        "for i in range(10):\n",
        "    if i+1 in difficulty_distribution.index:\n",
        "        difficulty_distribution_padding[i] = difficulty_distribution.loc[i+1]"
      ]
    },
    {
      "attachments": {},
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 3 Optimize retention to minimize the time of reviews\n",
        "\n",
        "Calculate the optimal retention to minimize the time for long-term memory consolidation. It is an experimental feature. You can use the simulator to get more accurate results:\n",
        "\n",
        "https://github.com/open-spaced-repetition/fsrs4anki/blob/main/fsrs4anki_simulator.ipynb"
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 10,
      "metadata": {},
      "outputs": [
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "average time for failed cards: 25.0s\n",
            "average time for recalled cards: 8.0s\n",
            "terminal stability:  361.62\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "21d643c71d0540949822c71866f7e2b4",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/15 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "expected_time.csv saved.\n",
            "\n",
            "-----suggested retention (experimental): 0.85-----\n"
          ]
        },
        {
          "data": {
            "image/png": "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",
            "text/plain": [
              "<Figure size 640x480 with 1 Axes>"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        }
      ],
      "source": [
        "base = 1.01\n",
        "index_len = 793\n",
        "index_offset = 200\n",
        "d_range = 10\n",
        "d_offset = 1\n",
        "r_time = 8\n",
        "f_time = 25\n",
        "max_time = 200000\n",
        "\n",
        "type_block = dict()\n",
        "type_count = dict()\n",
        "type_time = dict()\n",
        "last_t = type_sequence[0]\n",
        "type_block[last_t] = 1\n",
        "type_count[last_t] = 1\n",
        "type_time[last_t] = time_sequence[0]\n",
        "for i,t in enumerate(type_sequence[1:]):\n",
        "    type_count[t] = type_count.setdefault(t, 0) + 1\n",
        "    type_time[t] = type_time.setdefault(t, 0) + time_sequence[i]\n",
        "    if t != last_t:\n",
        "        type_block[t] = type_block.setdefault(t, 0) + 1\n",
        "    last_t = t\n",
        "\n",
        "r_time = round(type_time[1]/type_count[1]/1000, 1)\n",
        "\n",
        "if 2 in type_count and 2 in type_block:\n",
        "    f_time = round(type_time[2]/type_block[2]/1000 + r_time, 1)\n",
        "\n",
        "print(f\"average time for failed cards: {f_time}s\")\n",
        "print(f\"average time for recalled cards: {r_time}s\")\n",
        "\n",
        "def stability2index(stability):\n",
        "    return int(round(np.log(stability) / np.log(base)) + index_offset)\n",
        "\n",
        "def init_stability(d):\n",
        "    return max(((d - w[2]) / w[3] + 2) * w[1] + w[0], np.power(base, -index_offset))\n",
        "\n",
        "def cal_next_recall_stability(s, r, d, response):\n",
        "    if response == 1:\n",
        "        return s * (1 + np.exp(w[6]) * (11 - d) * np.power(s, w[7]) * (np.exp((1 - r) * w[8]) - 1))\n",
        "    else:\n",
        "        return w[9] * np.power(d, w[10]) * np.power(s, w[11]) * np.exp((1 - r) * w[12])\n",
        "\n",
        "\n",
        "stability_list = np.array([np.power(base, i - index_offset) for i in range(index_len)])\n",
        "print(f\"terminal stability: {stability_list.max(): .2f}\")\n",
        "df = pd.DataFrame(columns=[\"retention\", \"difficulty\", \"time\"])\n",
        "\n",
        "for percentage in tqdm.notebook.tqdm(range(96, 66, -2)):\n",
        "    recall = percentage / 100\n",
        "    time_list = np.zeros((d_range, index_len))\n",
        "    time_list[:,:-1] = max_time\n",
        "    for d in range(d_range, 0, -1):\n",
        "        s0 = init_stability(d)\n",
        "        s0_index = stability2index(s0)\n",
        "        diff = max_time\n",
        "        while diff > 0.1:\n",
        "            s0_time = time_list[d - 1][s0_index]\n",
        "            for s_index in range(index_len - 2, -1, -1):\n",
        "                stability = stability_list[s_index];\n",
        "                interval = max(1, round(stability * np.log(recall) / np.log(0.9)))\n",
        "                p_recall = np.power(0.9, interval / stability)\n",
        "                recall_s = cal_next_recall_stability(stability, p_recall, d, 1)\n",
        "                forget_d = min(d + d_offset, 10)\n",
        "                forget_s = cal_next_recall_stability(stability, p_recall, forget_d, 0)\n",
        "                recall_s_index = min(stability2index(recall_s), index_len - 1)\n",
        "                forget_s_index = min(max(stability2index(forget_s), 0), index_len - 1)\n",
        "                recall_time = time_list[d - 1][recall_s_index] + r_time\n",
        "                forget_time = time_list[forget_d - 1][forget_s_index] + f_time\n",
        "                exp_time = p_recall * recall_time + (1.0 - p_recall) * forget_time\n",
        "                if exp_time < time_list[d - 1][s_index]:\n",
        "                    time_list[d - 1][s_index] = exp_time\n",
        "            diff = s0_time - time_list[d - 1][s0_index]\n",
        "        df.loc[0 if pd.isnull(df.index.max()) else df.index.max() + 1] = [recall, d, s0_time]\n",
        "\n",
        "df.sort_values(by=[\"difficulty\", \"retention\"], inplace=True)\n",
        "df.to_csv(\"./expected_time.csv\", index=False)\n",
        "print(\"expected_time.csv saved.\")\n",
        "\n",
        "optimal_retention_list = np.zeros(10)\n",
        "for d in range(1, d_range+1):\n",
        "    retention = df[df[\"difficulty\"] == d][\"retention\"]\n",
        "    time = df[df[\"difficulty\"] == d][\"time\"]\n",
        "    optimal_retention = retention.iat[time.argmin()]\n",
        "    optimal_retention_list[d-1] = optimal_retention\n",
        "    plt.plot(retention, time, label=f\"d={d}, r={optimal_retention}\")\n",
        "print(f\"\\n-----suggested retention (experimental): {np.inner(difficulty_distribution_padding, optimal_retention_list):.2f}-----\")\n",
        "plt.ylabel(\"expected time (second)\")\n",
        "plt.xlabel(\"retention\")\n",
        "plt.legend()\n",
        "plt.grid()\n",
        "plt.semilogy()\n",
        "plt.show()"
      ]
    },
    {
      "cell_type": "markdown",
      "metadata": {},
      "source": [
        "## 4 Evaluate the model\n",
        "\n",
        "Evaluate the model with the log loss. It will compare the log loss between initial model and trained model."
      ]
    },
    {
      "cell_type": "code",
      "execution_count": 11,
      "metadata": {},
      "outputs": [
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "63e8453d80124699b1f40395051577d7",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/225934 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loss before training: 0.3402\n"
          ]
        },
        {
          "data": {
            "application/vnd.jupyter.widget-view+json": {
              "model_id": "e94ce239601948379611720ca3c73228",
              "version_major": 2,
              "version_minor": 0
            },
            "text/plain": [
              "  0%|          | 0/225934 [00:00<?, ?it/s]"
            ]
          },
          "metadata": {},
          "output_type": "display_data"
        },
        {
          "name": "stdout",
          "output_type": "stream",
          "text": [
            "Loss after training: 0.3172\n"
          ]
        }
      ],
      "source": [
        "def log_loss(row):\n",
        "    states = my_collection.states(row['t_history'], row['r_history'])\n",
        "    row['log_loss'] = float(my_collection.model.loss(states[0], row['delta_t'], {1: 0, 2: 1, 3: 1, 4: 1}[row['r']]))\n",
        "    return row\n",
        "\n",
        "my_collection = Collection(init_w)\n",
        "dataset = dataset.progress_apply(log_loss, axis=1)\n",
        "print(f\"Loss before training: {dataset['log_loss'].mean():.4f}\")\n",
        "my_collection = Collection(w)\n",
        "dataset = dataset.progress_apply(log_loss, axis=1)\n",
        "print(f\"Loss after training: {dataset['log_loss'].mean():.4f}\")"
      ]
    }
  ],
  "metadata": {
    "colab": {
      "authorship_tag": "ABX9TyMnk8/Ih2JAJZJ1PBkXQUBC",
      "collapsed_sections": [],
      "provenance": [],
      "toc_visible": true
    },
    "kernelspec": {
      "display_name": "Python 3.8.13 ('fsrs4anki')",
      "language": "python",
      "name": "python3"
    },
    "language_info": {
      "codemirror_mode": {
        "name": "ipython",
        "version": 3
      },
      "file_extension": ".py",
      "mimetype": "text/x-python",
      "name": "python",
      "nbconvert_exporter": "python",
      "pygments_lexer": "ipython3",
      "version": "3.8.13"
    },
    "vscode": {
      "interpreter": {
        "hash": "8dd9a290ffd10997e0b0d411ff1325a47862ea932e0fd309ade800e0e51d2b4b"
      }
    }
  },
  "nbformat": 4,
  "nbformat_minor": 0
}