a b/examples/irhythm/notebooks/agreement_rates.ipynb
1
{
2
 "cells": [
3
  {
4
   "cell_type": "code",
5
   "execution_count": 42,
6
   "metadata": {},
7
   "outputs": [],
8
   "source": [
9
    "import json\n",
10
    "import numpy as np\n",
11
    "import os\n",
12
    "import sys\n",
13
    "sys.path.append(\"../../../ecg\")\n",
14
    "\n",
15
    "import load\n",
16
    "import util\n",
17
    "\n",
18
    "def fleiss_kappa(ratings):\n",
19
    "    \"\"\"\n",
20
    "    Args:\n",
21
    "        ratings: An N x R numpy array. N is the number of\n",
22
    "            samples and R is the number of reviewers. Each\n",
23
    "            entry (n, r) is the category assigned to example\n",
24
    "            n by reviewer r.\n",
25
    "    Returns:\n",
26
    "        Fleiss' kappa score.\n",
27
    "    https://en.wikipedia.org/wiki/Fleiss%27_kappa\n",
28
    "    \"\"\"\n",
29
    "    N, R = ratings.shape\n",
30
    "    NR =  N * R\n",
31
    "    categories = set(ratings.ravel().tolist())\n",
32
    "    P_example = -np.full(N, R)\n",
33
    "    p_class = 0.0\n",
34
    "    for c in categories:\n",
35
    "        c_sum = np.sum(ratings == c, axis=1)\n",
36
    "        P_example += c_sum**2\n",
37
    "        p_class += (np.sum(c_sum) / float(NR)) ** 2\n",
38
    "    P_example = np.sum(P_example) / float(NR * (R-1))\n",
39
    "    k = (P_example - p_class) / (1 - p_class)\n",
40
    "    return k\n",
41
    "\n",
42
    "def average_pairwise_agreement(revs):\n",
43
    "    \"\"\"\n",
44
    "    Here, we use the same method as the diabetic\n",
45
    "    retinopathy paper. The number of pair-wise\n",
46
    "    agreements over the total number of pairwise\n",
47
    "    comparisons.\n",
48
    "    \"\"\"\n",
49
    "    corr = 0\n",
50
    "    tot = 0\n",
51
    "    n_revs = len(revs)\n",
52
    "    for i in range(n_revs):\n",
53
    "        for j in range(i+1, n_revs):\n",
54
    "            c = np.sum(revs[i] == revs[j])\n",
55
    "            t = revs[i].size\n",
56
    "            corr += c\n",
57
    "            tot += t\n",
58
    "    return corr / float(tot)\n"
59
   ]
60
  },
61
  {
62
   "cell_type": "code",
63
   "execution_count": 10,
64
   "metadata": {},
65
   "outputs": [],
66
   "source": [
67
    "model_path = \"/deep/group/awni/ecg_models/default/1527627404-9/0.337-0.880-012-0.255-0.906.hdf5\"\n",
68
    "preproc = util.load(os.path.dirname(model_path))\n",
69
    "\n",
70
    "revs = []\n",
71
    "for i in range(6):\n",
72
    "    with open(\"../test_rev{}.json\".format(i), 'r') as fid:\n",
73
    "        revs.append([json.loads(l)['labels'] for l in fid])\n",
74
    "revs = [np.argmax(preproc.process_y(r), axis=2) for r in revs]\n"
75
   ]
76
  },
77
  {
78
   "cell_type": "markdown",
79
   "metadata": {},
80
   "source": [
81
    "### Sequence Level Agreements"
82
   ]
83
  },
84
  {
85
   "cell_type": "code",
86
   "execution_count": 66,
87
   "metadata": {},
88
   "outputs": [
89
    {
90
     "name": "stdout",
91
     "output_type": "stream",
92
     "text": [
93
      "\t     Fleiss' kappa  \t Avg Pairwise\n",
94
      "AF           0.613 \t\t 0.904\n",
95
      "AVB          0.707 \t\t 0.950\n",
96
      "BIGEMINY     0.796 \t\t 0.989\n",
97
      "EAR          0.407 \t\t 0.977\n",
98
      "IVR          0.535 \t\t 0.978\n",
99
      "JUNCTIONAL   0.610 \t\t 0.956\n",
100
      "NOISE        0.729 \t\t 0.962\n",
101
      "SINUS        0.678 \t\t 0.841\n",
102
      "SVT          0.398 \t\t 0.961\n",
103
      "TRIGEMINY    0.783 \t\t 0.987\n",
104
      "VT           0.500 \t\t 0.992\n",
105
      "WENCKEBACH   0.496 \t\t 0.962\n",
106
      "\n",
107
      "All          0.645 \t\t 0.730\n"
108
     ]
109
    }
110
   ],
111
   "source": [
112
    "print \"\\t     Fleiss' kappa  \\t Avg Pairwise\"\n",
113
    "for e, c in enumerate(preproc.classes):\n",
114
    "    binary_revs = [np.reshape(r == e, -1) for r in revs]\n",
115
    "    print \"{:<10}   {:.3f} \\t\\t {:.3f}\".format(\n",
116
    "        c, fleiss_kappa(np.stack(binary_revs, axis=1)),\n",
117
    "        average_pairwise_agreement(binary_revs)) \n",
118
    "print\n",
119
    "ratings = np.hstack([r.reshape(-1, 1) for r in revs])\n",
120
    "print \"{:<10}   {:.3f} \\t\\t {:.3f}\".format(\n",
121
    "        \"All\", fleiss_kappa(ratings),\n",
122
    "        average_pairwise_agreement(revs))"
123
   ]
124
  },
125
  {
126
   "cell_type": "markdown",
127
   "metadata": {},
128
   "source": [
129
    "### Set-level agreements (can only compute for a given rhythm)"
130
   ]
131
  },
132
  {
133
   "cell_type": "code",
134
   "execution_count": 71,
135
   "metadata": {},
136
   "outputs": [
137
    {
138
     "name": "stdout",
139
     "output_type": "stream",
140
     "text": [
141
      "\t     Fleiss' kappa  \t Avg Pairwise\n",
142
      "AF           0.591 \t\t 0.873\n",
143
      "AVB          0.703 \t\t 0.929\n",
144
      "BIGEMINY     0.791 \t\t 0.976\n",
145
      "EAR          0.415 \t\t 0.950\n",
146
      "IVR          0.645 \t\t 0.944\n",
147
      "JUNCTIONAL   0.607 \t\t 0.928\n",
148
      "NOISE        0.625 \t\t 0.924\n",
149
      "SINUS        0.666 \t\t 0.858\n",
150
      "SVT          0.485 \t\t 0.921\n",
151
      "TRIGEMINY    0.732 \t\t 0.971\n",
152
      "VT           0.677 \t\t 0.967\n",
153
      "WENCKEBACH   0.609 \t\t 0.947\n"
154
     ]
155
    }
156
   ],
157
   "source": [
158
    "print \"\\t     Fleiss' kappa  \\t Avg Pairwise\"\n",
159
    "for e, c in enumerate(preproc.classes):\n",
160
    "    binary_revs = [np.any(r == e, axis=1) for r in revs]\n",
161
    "    print \"{:<10}   {:.3f} \\t\\t {:.3f}\".format(\n",
162
    "        c, fleiss_kappa(np.stack(binary_revs, axis=1)),\n",
163
    "        average_pairwise_agreement(binary_revs))   "
164
   ]
165
  },
166
  {
167
   "cell_type": "markdown",
168
   "metadata": {},
169
   "source": [
170
    "### Confusions between \"AFIB\" and \"AFL\" and \"AVB type 2 second degree\" and \"AVB third degree\""
171
   ]
172
  },
173
  {
174
   "cell_type": "code",
175
   "execution_count": null,
176
   "metadata": {},
177
   "outputs": [],
178
   "source": []
179
  }
180
 ],
181
 "metadata": {
182
  "kernelspec": {
183
   "display_name": "Python 2",
184
   "language": "python",
185
   "name": "python2"
186
  },
187
  "language_info": {
188
   "codemirror_mode": {
189
    "name": "ipython",
190
    "version": 2
191
   },
192
   "file_extension": ".py",
193
   "mimetype": "text/x-python",
194
   "name": "python",
195
   "nbconvert_exporter": "python",
196
   "pygments_lexer": "ipython2",
197
   "version": "2.7.12"
198
  }
199
 },
200
 "nbformat": 4,
201
 "nbformat_minor": 2
202
}