-
-
Save bibekiit/939d11b8427256fe7bbc7c7980ca7344 to your computer and use it in GitHub Desktop.
Clinical Grade Sleep Tracking from Heart Rate using Z3Score-HRV API
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
{ | |
"cells": [ | |
{ | |
"cell_type": "code", | |
"execution_count": 110, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"import requests\n", | |
"import patoolib\n", | |
"import pyedflib\n", | |
"import pandas as pd\n", | |
"import numpy as np\n", | |
"from tqdm import tqdm\n", | |
"from requests import post\n", | |
"from pyndf import create_ndf_from_ecg\n", | |
"from sklearn.metrics import cohen_kappa_score" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# lets download the ISRUC subgroup 3 dataset, comprises of 10 healthy subjects\n", | |
"# You can use multi-threading to speed this up, but I had all night to download!\n", | |
"for i in range(10):\n", | |
" url = \"http://dataset.isr.uc.pt/ISRUC_Sleep/subgroupIII/%d.rar\" %(i+1)\n", | |
" response = requests.get(url, stream=True)\n", | |
" filename = str(i+1) + \".rar\"\n", | |
" print(\"Downloading %s\" %(filename))\n", | |
" with open(filename, \"wb\") as handle:\n", | |
" for data in tqdm(response.iter_content()):\n", | |
" handle.write(data)\n", | |
" print(\"unzipping...\")\n", | |
" patoolib.extract_archive(filename, outdir=\".\")\n", | |
" print('removing the zip file')\n", | |
" os.remove(str(i+1) + \".rar\")" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": null, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# license key\n", | |
"serverURL = 'https://z3score.com/api/v4'\n", | |
"email = r'[email protected]'\n", | |
"key = r'yourAccessKey'" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 94, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "stream", | |
"name": "stdout", | |
"text": "Scoring: 1\\1.rec\nScoring: 2\\2.rec\nScoring: 3\\3.rec\nScoring: 4\\4.rec\nScoring: 5\\5.rec\nScoring: 6\\6.rec\nScoring: 7\\7.rec\nScoring: 8\\8.rec\nScoring: 9\\9.rec\nScoring: 10\\10.rec\n" | |
} | |
], | |
"source": [ | |
"# Now lets score all the files\n", | |
"for i in range(1,11):\n", | |
" filename = '%d\\\\%d.rec' %(i,i)\n", | |
" print('Scoring: %s' %(filename))\n", | |
" edf_file = pyedflib.EdfReader(filename)\n", | |
" labels = edf_file.getSignalLabels()\n", | |
" try:\n", | |
" idx = labels.index('X2')\n", | |
" except ValueError:\n", | |
" print('ECG channel not found')\n", | |
" continue\n", | |
"\n", | |
" fs = edf_file.getSampleFrequency(idx)\n", | |
" ecg = np.asarray(edf_file.readSignal(idx))*10\n", | |
" edf_file._close()\n", | |
" stream = create_ndf_from_ecg(ecg, fs)\n", | |
" response = post(serverURL+'/hrv', files={'file': ('stream.ndf', stream)}, data={'email':email, 'key':key})\n", | |
" data = response.json()\n", | |
" auto_scores = np.array(data['message'])\n", | |
" savefile = '%d\\\\%d_auto.csv' %(i,i)\n", | |
" np.savetxt(savefile, auto_scores, fmt=\"%d\", delimiter=',')" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 119, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# compare accuracy\n", | |
"# Wake, Light Sleep, Deep Sleep & REM\n", | |
"df = pd.DataFrame(columns=['Accuracy 1','Accuracy 2','kappa 1', 'kappa 2'])\n", | |
"for i in range(1,11):\n", | |
" expert1 = '%d\\\\%d_1.txt' %(i,i)\n", | |
" expert2 = '%d\\\\%d_2.txt' %(i,i)\n", | |
" auto = '%d\\\\%d_auto.csv' %(i,i)\n", | |
"\n", | |
" exp_score1 = np.genfromtxt(expert1, delimiter=',')\n", | |
" exp_score2 = np.genfromtxt(expert2, delimiter=',')\n", | |
" auto_score = np.genfromtxt(auto, delimiter=',')\n", | |
"\n", | |
" num_epochs = min(auto_score.size, exp_score1.size, exp_score2.size)\n", | |
"\n", | |
" auto_score = auto_score[0:num_epochs,0]\n", | |
" exp_score1 = exp_score1[0:num_epochs]\n", | |
" exp_score2 = exp_score2[0:num_epochs]\n", | |
" exp_score1[exp_score1==1] = 2\n", | |
" exp_score2[exp_score2==1] = 2\n", | |
"\n", | |
" accuracy1 = np.sum(exp_score1 == auto_score)*100.0/num_epochs\n", | |
" accuracy2 = np.sum(exp_score2 == auto_score)*100.0/num_epochs\n", | |
" kappa1 = cohen_kappa_score(exp_score1, auto_score)\n", | |
" kappa2 = cohen_kappa_score(exp_score2, auto_score)\n", | |
" df = df.append({'Accuracy 1':accuracy1, 'Accuracy 2':accuracy2, 'kappa 1':kappa1, 'kappa 2':kappa2}, ignore_index=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 120, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "Accuracy 1 70.967779\nAccuracy 2 72.601184\nkappa 1 0.556185\nkappa 2 0.579426\ndtype: float64" | |
}, | |
"metadata": {}, | |
"execution_count": 120 | |
} | |
], | |
"source": [ | |
"df.mean()" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 121, | |
"metadata": {}, | |
"outputs": [], | |
"source": [ | |
"# compare accuracy\n", | |
"# Wake, NREM & REM\n", | |
"df = pd.DataFrame(columns=['Accuracy 1','Accuracy 2','kappa 1', 'kappa 2'])\n", | |
"for i in range(1,11):\n", | |
" expert1 = '%d\\\\%d_1.txt' %(i,i)\n", | |
" expert2 = '%d\\\\%d_2.txt' %(i,i)\n", | |
" auto = '%d\\\\%d_auto.csv' %(i,i)\n", | |
"\n", | |
" exp_score1 = np.genfromtxt(expert1, delimiter=',')\n", | |
" exp_score2 = np.genfromtxt(expert2, delimiter=',')\n", | |
" auto_score = np.genfromtxt(auto, delimiter=',')\n", | |
"\n", | |
" num_epochs = min(auto_score.size, exp_score1.size, exp_score2.size)\n", | |
"\n", | |
" auto_score = auto_score[0:num_epochs,0]\n", | |
" exp_score1 = exp_score1[0:num_epochs]\n", | |
" exp_score2 = exp_score2[0:num_epochs]\n", | |
" exp_score1[exp_score1==1] = 2\n", | |
" exp_score2[exp_score2==1] = 2\n", | |
" exp_score1[exp_score1==3] = 2\n", | |
" exp_score2[exp_score2==3] = 2\n", | |
" auto_score[auto_score==3] = 2\n", | |
"\n", | |
" accuracy1 = np.sum(exp_score1 == auto_score)*100.0/num_epochs\n", | |
" accuracy2 = np.sum(exp_score2 == auto_score)*100.0/num_epochs\n", | |
" kappa1 = cohen_kappa_score(exp_score1, auto_score)\n", | |
" kappa2 = cohen_kappa_score(exp_score2, auto_score)\n", | |
" df = df.append({'Accuracy 1':accuracy1, 'Accuracy 2':accuracy2, 'kappa 1':kappa1, 'kappa 2':kappa2}, ignore_index=True)" | |
] | |
}, | |
{ | |
"cell_type": "code", | |
"execution_count": 122, | |
"metadata": {}, | |
"outputs": [ | |
{ | |
"output_type": "execute_result", | |
"data": { | |
"text/plain": "Accuracy 1 82.520431\nAccuracy 2 83.576178\nkappa 1 0.608654\nkappa 2 0.631983\ndtype: float64" | |
}, | |
"metadata": {}, | |
"execution_count": 122 | |
} | |
], | |
"source": [ | |
"df.mean()" | |
] | |
} | |
], | |
"metadata": { | |
"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.6.10-final" | |
}, | |
"orig_nbformat": 2, | |
"kernelspec": { | |
"name": "python361064bitdevenvvenvcd022a983f794dd1941c299f2f977cbf", | |
"display_name": "Python 3.6.10 64-bit ('devenv': venv)" | |
} | |
}, | |
"nbformat": 4, | |
"nbformat_minor": 2 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment