├── .gitignore ├── Binary-Classification-Pipeline.ipynb ├── LICENSE ├── Main.ipynb ├── Overfit_plot.ipynb ├── README.md ├── datasets └── .gitignore ├── prepare_data.ipynb ├── requirements.txt ├── resample_forest.py └── utils.py /.gitignore: -------------------------------------------------------------------------------- 1 | datasets/* 2 | *.pyc 3 | .ipynb_checkpoints 4 | venv/ 5 | -------------------------------------------------------------------------------- /Binary-Classification-Pipeline.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "# Binary Classification Pipeline Hands-on\n", 8 | "\n", 9 | "---\n", 10 | "## _Zichen Wang_\n", 11 | "## Ma'ayan Lab\n", 12 | "## Data Mining and Network Analysis (Fall 2016)\n", 13 | "## _Nov. 15, 2016_\n", 14 | "---\n", 15 | "\n", 16 | "\n", 17 | "# Pipeline for typical single label classification analysis\n", 18 | "\n", 19 | "1. Data cleaning: obtain the data and clean it (X, y)\n", 20 | "1. Transformations: normalization, scaling\n", 21 | "1. Feature extraction\n", 22 | "1. Partition data to training and test sets\n", 23 | " + Feature selection\n", 24 | " + Train classifier \n", 25 | " + Evaluate classifier \n", 26 | "1. Apply classifier to new data\n", 27 | "\n", 28 | "---\n", 29 | "\n", 30 | "## 1. Data cleaning: obtain the data and clean it (X, y)" 31 | ] 32 | }, 33 | { 34 | "cell_type": "code", 35 | "execution_count": 1, 36 | "metadata": { 37 | "collapsed": false 38 | }, 39 | "outputs": [ 40 | { 41 | "name": "stderr", 42 | "output_type": "stream", 43 | "text": [ 44 | "/Library/Python/2.7/site-packages/IPython/html.py:14: ShimWarning: The `IPython.html` package has been deprecated. You should import from `notebook` instead. `IPython.html.widgets` has moved to `ipywidgets`.\n", 45 | " \"`IPython.html.widgets` has moved to `ipywidgets`.\", ShimWarning)\n" 46 | ] 47 | } 48 | ], 49 | "source": [ 50 | "from __future__ import division\n", 51 | "import numpy as np\n", 52 | "RNG = 10\n", 53 | "np.random.seed(RNG)\n", 54 | "\n", 55 | "from sklearn.datasets import make_classification\n", 56 | "\n", 57 | "import matplotlib.pyplot as plt\n", 58 | "from matplotlib import rcParams\n", 59 | "rcParams['pdf.fonttype'] = 42 ## Output Type 3 (Type3) or Type 42 (TrueType)\n", 60 | "rcParams['font.sans-serif'] = 'Arial'\n", 61 | "import seaborn as sns\n", 62 | "sns.set_style(\"whitegrid\")\n", 63 | "%matplotlib inline" 64 | ] 65 | }, 66 | { 67 | "cell_type": "code", 68 | "execution_count": 2, 69 | "metadata": { 70 | "collapsed": false 71 | }, 72 | "outputs": [ 73 | { 74 | "name": "stdout", 75 | "output_type": "stream", 76 | "text": [ 77 | "Shape of X: (1000, 20) shape of y: (1000,)\n" 78 | ] 79 | } 80 | ], 81 | "source": [ 82 | "# Create synthetic data\n", 83 | "X, y = make_classification(n_classes=2, class_sep=2, \n", 84 | " weights=[0.1, 0.9], # the ratios of the two classes\n", 85 | " n_informative=3, n_redundant=4, flip_y=0.02,\n", 86 | " n_features=20, n_clusters_per_class=1,\n", 87 | " n_samples=1000, random_state=RNG)\n", 88 | "\n", 89 | "# Force them to be on different scales\n", 90 | "X = np.multiply(X, np.arange(20)) + np.arange(20)\n", 91 | "\n", 92 | "print 'Shape of X: ', X.shape, 'shape of y:', y.shape" 93 | ] 94 | }, 95 | { 96 | "cell_type": "code", 97 | "execution_count": 3, 98 | "metadata": { 99 | "collapsed": false 100 | }, 101 | "outputs": [ 102 | { 103 | "data": { 104 | "image/png": "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\nAAAASUVORK5CYII=\n", 105 | "text/plain": [ 106 | "" 107 | ] 108 | }, 109 | "metadata": {}, 110 | "output_type": "display_data" 111 | } 112 | ], 113 | "source": [ 114 | "# Examine the distribution of the 10 features over all the samples\n", 115 | "fig, ax = plt.subplots()\n", 116 | "for j in range(20):\n", 117 | " ax = sns.kdeplot(X[:,j], ax=ax, label='feature%d' % j)\n", 118 | "\n", 119 | "ax.set_ylabel('Density')\n", 120 | "ax.set_xlabel('Values')\n", 121 | "plt.show()" 122 | ] 123 | }, 124 | { 125 | "cell_type": "markdown", 126 | "metadata": {}, 127 | "source": [ 128 | "## 2. Transformations (normalization, scaling)\n", 129 | "\n", 130 | "- Standard scaling (Z-score)\n", 131 | "- Min-Max scaling\n", 132 | "- Robust scaling" 133 | ] 134 | }, 135 | { 136 | "cell_type": "code", 137 | "execution_count": 4, 138 | "metadata": { 139 | "collapsed": false 140 | }, 141 | "outputs": [ 142 | { 143 | "data": { 144 | "image/png": "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\n", 145 | "text/plain": [ 146 | "" 147 | ] 148 | }, 149 | "metadata": {}, 150 | "output_type": "display_data" 151 | } 152 | ], 153 | "source": [ 154 | "from sklearn.preprocessing import StandardScaler\n", 155 | "# Scale the features using z-score\n", 156 | "scl = StandardScaler()\n", 157 | "X = scl.fit_transform(X)\n", 158 | "# Examine the distribution of the 10 features over all the samples again\n", 159 | "fig, ax = plt.subplots()\n", 160 | "for j in range(20):\n", 161 | " ax = sns.kdeplot(X[:,j], ax=ax, label='feature%d' % j)\n", 162 | "\n", 163 | "ax.set_ylabel('Density')\n", 164 | "ax.set_xlabel('Values')\n", 165 | "plt.show()" 166 | ] 167 | }, 168 | { 169 | "cell_type": "markdown", 170 | "metadata": {}, 171 | "source": [ 172 | "## 3. Feature extraction (dimensionality reduction)\n", 173 | "\n", 174 | "Reduce the number of features required to describe the structure of the data" 175 | ] 176 | }, 177 | { 178 | "cell_type": "code", 179 | "execution_count": 5, 180 | "metadata": { 181 | "collapsed": false 182 | }, 183 | "outputs": [ 184 | { 185 | "name": "stdout", 186 | "output_type": "stream", 187 | "text": [ 188 | "Shape of X after PCA to the first 10 dimensions: (1000, 10)\n" 189 | ] 190 | } 191 | ], 192 | "source": [ 193 | "from sklearn.decomposition import PCA\n", 194 | "\n", 195 | "## Use PCA to reduce the dimensionality \n", 196 | "pca = PCA(n_components=10)\n", 197 | "X = pca.fit_transform(X)\n", 198 | "print 'Shape of X after PCA to the first 10 dimensions: ', X.shape" 199 | ] 200 | }, 201 | { 202 | "cell_type": "code", 203 | "execution_count": 6, 204 | "metadata": { 205 | "collapsed": false 206 | }, 207 | "outputs": [ 208 | { 209 | "name": "stderr", 210 | "output_type": "stream", 211 | "text": [ 212 | "/System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/matplotlib/collections.py:548: FutureWarning: elementwise comparison failed; returning scalar instead, but in the future will perform elementwise comparison\n", 213 | " if self._edgecolors == 'face':\n" 214 | ] 215 | }, 216 | { 217 | "data": { 218 | "image/png": "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\n5Ox2Ozt27OD2228/Yd9FixZx6NAhQkJCcLvdvPXWW0yaNAm32010dDRjx47lvffeo7CwEIPBQM+e\nPVEqlUyePJl3332XxsZGkQkS6OqXnJzMqlWruOqqq8SkV2pqKocOHUKlUtHS0oJKpRJVmCdjyJAh\npKen09jYKHKWExMTsVqtaLVa9Ho9PXr0EBNmiYmJNDU1iUwWlUoleov079+fsLAwLBaL8PYtFgsa\njQaDwUBTUxN1dXWi0jEQmggODhYefFBQEHfccYewr7y8nKKiIpHq2NzcTFlZGVqtltjYWFGMExIS\ngs/nw2q1ClFTqVSo1WpRul9YWIjX6xUPoYBdAwcOJDQ0lMjISOFJB+Y2Bg8ezMKFC8nLy+PQoUNY\nLBbcbrcIjen1ehITE4UoRkZGsmbNGvFmE1h6Tq1WiwlUtVrNpk2bmDNnDqGhoeKtrKamBq1Wy9at\nW2ltbaV3796YzWaCgoIIDQ0lKCiIiIiIE1Ytmjx5MmazGbvdjl6vR6fTnZCeeHx4qrS0lJaWFlHt\nCu1VyC6Xi8cee4yQkBD69u3LggULOtUnZu/evSxfvpy2tjbGjx9/SayPKsW8Gzh48CDPPPOM8CCz\ns7NZsGDBWaVeBZokBfD5fERFRZ1038rKSuEx+/1+/vOf/3DgwAH8fj9XXHGF8IwdDgcOh4PIyEim\nTp3K888/T48ePdBoNFRXV+NyuVAqlbS1tVFSUkJkZCQNDQ1CzO+99148Hg+bN28W+eSPPvooU6ZM\nOWnb1smTJ2OxWNi5cyeXX345ZrMZpVLJ8OHD0el0qNVqEhMTGTRoEF9++SVqtZrhw4dTUlJCQ0OD\nsDsqKorExER++9vf8s4771BcXIzP58PtduN2u2lsbBTzA4EHACDE9YorrhCx6uOFaMeOHSQkJFBR\nUYHL5aKyshK/34/H40GlUtGzZ08xKVlXV4fH4xGxeY1GI4Q2KCiI5uZm8XkHPgefzyceetHR0Qwe\nPBiXy4VGo8Hr9bJixQqOHj0qvHm32y284MBDYe/evaSmpuJwODh06BBWq1W0YfD5fKhUKhETLy8v\nx2q1olAo2LZtGzfeeCMrV66ksbERpVKJx+PBarXidrsJCgoScesBAwZgMBiIjIw8ITtn5syZWK1W\nDh8+jNFoZMaMGSxevBir1YrP52PQoEHCK4f/zQk1NDSIjJ3APRo4cCBqtZrS0lKWL1/Or3/96zP+\n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\n", 219 | "text/plain": [ 220 | "" 221 | ] 222 | }, 223 | "metadata": {}, 224 | "output_type": "display_data" 225 | } 226 | ], 227 | "source": [ 228 | "## PCA can also be used to visualize the data\n", 229 | "plt.scatter(X[:, 0], X[:, 1], c=y, alpha=0.7)\n", 230 | "plt.show()" 231 | ] 232 | }, 233 | { 234 | "cell_type": "markdown", 235 | "metadata": {}, 236 | "source": [ 237 | "## 4. Partition the data (Straitification matters!)\n", 238 | "\n", 239 | "- Train-test split\n", 240 | "- Train-valid-test split\n", 241 | "- Cross-validation (CV)" 242 | ] 243 | }, 244 | { 245 | "cell_type": "code", 246 | "execution_count": 7, 247 | "metadata": { 248 | "collapsed": false 249 | }, 250 | "outputs": [ 251 | { 252 | "name": "stdout", 253 | "output_type": "stream", 254 | "text": [ 255 | "Before spliting:\n", 256 | "(1000, 10) (1000,) 0.894\n", 257 | "After spliting:\n", 258 | "(700, 10) (700,) 0.882857142857\n", 259 | "(300, 10) (300,) 0.92\n" 260 | ] 261 | } 262 | ], 263 | "source": [ 264 | "from sklearn.cross_validation import StratifiedKFold, train_test_split\n", 265 | "\n", 266 | "X_train, X_test, y_train, y_test = train_test_split(X, y, \n", 267 | " test_size=0.3, \n", 268 | " stratify=None, ## Change this\n", 269 | " random_state=RNG)\n", 270 | "\n", 271 | "print 'Before spliting:'\n", 272 | "print X.shape, y.shape, y.sum()/y.shape[0]\n", 273 | "\n", 274 | "print 'After spliting:'\n", 275 | "print X_train.shape, y_train.shape, y_train.sum()/y_train.shape[0]\n", 276 | "print X_test.shape, y_test.shape, y_test.sum()/y_test.shape[0]" 277 | ] 278 | }, 279 | { 280 | "cell_type": "markdown", 281 | "metadata": {}, 282 | "source": [ 283 | "### 4.a. Feature selection\n", 284 | "### 4.b. Train classifier" 285 | ] 286 | }, 287 | { 288 | "cell_type": "code", 289 | "execution_count": 8, 290 | "metadata": { 291 | "collapsed": true 292 | }, 293 | "outputs": [], 294 | "source": [ 295 | "from sklearn.feature_selection import f_classif, SelectKBest\n", 296 | "from sklearn.linear_model import LogisticRegression\n", 297 | "\n", 298 | "from sklearn.pipeline import Pipeline\n", 299 | "\n", 300 | "## Initiate a FS-Logit pipeline\n", 301 | "fs = SelectKBest(f_classif, k=2)\n", 302 | "logit = LogisticRegression()\n", 303 | "\n", 304 | "pipeline = Pipeline([\n", 305 | " ('fs', fs),\n", 306 | " ('logit', logit)\n", 307 | " ])\n" 308 | ] 309 | }, 310 | { 311 | "cell_type": "code", 312 | "execution_count": 9, 313 | "metadata": { 314 | "collapsed": false 315 | }, 316 | "outputs": [ 317 | { 318 | "name": "stdout", 319 | "output_type": "stream", 320 | "text": [ 321 | "(300,) (300, 2)\n" 322 | ] 323 | } 324 | ], 325 | "source": [ 326 | "# Train classifier\n", 327 | "pipeline.fit(X_train, y_train)\n", 328 | "# Get prediction on test set\n", 329 | "y_test_preds = pipeline.predict(X_test)\n", 330 | "y_test_probas = pipeline.predict_proba(X_test)\n", 331 | "print y_test_preds.shape, y_test_probas.shape" 332 | ] 333 | }, 334 | { 335 | "cell_type": "code", 336 | "execution_count": 10, 337 | "metadata": { 338 | "collapsed": false 339 | }, 340 | "outputs": [ 341 | { 342 | "name": "stdout", 343 | "output_type": "stream", 344 | "text": [ 345 | "Accuracy: 0.98000\n", 346 | "F1 score: 0.98909\n", 347 | "AUROC: 0.93825\n", 348 | "AUPRC: 0.98502\n" 349 | ] 350 | } 351 | ], 352 | "source": [ 353 | "from sklearn.metrics import roc_auc_score, average_precision_score, f1_score, accuracy_score\n", 354 | "\n", 355 | "# Evaluate predictions\n", 356 | "print 'Accuracy: %.5f' % accuracy_score(y_test, y_test_preds)\n", 357 | "print 'F1 score: %.5f' % f1_score(y_test, y_test_preds)\n", 358 | "print 'AUROC: %.5f' % roc_auc_score(y_test, y_test_probas[:, 1])\n", 359 | "print 'AUPRC: %.5f' % average_precision_score(y_test, y_test_probas[:, 1])\n", 360 | "\n", 361 | "## Results from not straitified split\n", 362 | "# Accuracy: 0.98000\n", 363 | "# F1 score: 0.98909\n", 364 | "# AUROC: 0.93825\n", 365 | "# AUPRC: 0.98502\n", 366 | "\n", 367 | "## Results from straitified split\n", 368 | "# Accuracy: 0.99000\n", 369 | "# F1 score: 0.99443\n", 370 | "# AUROC: 0.94018\n", 371 | "# AUPRC: 0.98791" 372 | ] 373 | }, 374 | { 375 | "cell_type": "code", 376 | "execution_count": 11, 377 | "metadata": { 378 | "collapsed": false 379 | }, 380 | "outputs": [ 381 | { 382 | "data": { 383 | "image/png": "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\n", 384 | "text/plain": [ 385 | "" 386 | ] 387 | }, 388 | "metadata": {}, 389 | "output_type": "display_data" 390 | } 391 | ], 392 | "source": [ 393 | "# To plot ROC and PRC\n", 394 | "from sklearn.metrics import roc_curve, precision_recall_curve\n", 395 | "\n", 396 | "# Compute FPR, TPR, Precision by iterating classification thresholds\n", 397 | "fpr, tpr, thresholds = roc_curve(y_test, y_test_probas[:, 1])\n", 398 | "precision, recall, thresholds = precision_recall_curve(y_test, y_test_probas[:, 1])\n", 399 | "\n", 400 | "# Plot\n", 401 | "fig, axes = plt.subplots(1, 2)\n", 402 | "axes[0].plot(fpr, tpr)\n", 403 | "axes[0].set_xlabel('FPR')\n", 404 | "axes[0].set_ylabel('TPR')\n", 405 | "axes[0].set_title('ROC')\n", 406 | "\n", 407 | "axes[1].plot(recall, precision)\n", 408 | "axes[1].set_xlabel('Recall')\n", 409 | "axes[1].set_ylabel('Precision')\n", 410 | "axes[1].set_title('PRC')\n", 411 | "\n", 412 | "axes[0].set_xlim([-.05, 1.05])\n", 413 | "axes[0].set_ylim([-.05, 1.05])\n", 414 | "axes[1].set_xlim([-.05, 1.05])\n", 415 | "axes[1].set_ylim([-.05, 1.05])\n", 416 | "\n", 417 | "fig.tight_layout()\n", 418 | "plt.show()" 419 | ] 420 | }, 421 | { 422 | "cell_type": "markdown", 423 | "metadata": {}, 424 | "source": [ 425 | "## Recommended reading materials\n", 426 | "\n", 427 | "0. \"Points of Significance\" series in _Nature Methods_\n", 428 | " + [Logistic regression](http://www.nature.com/nmeth/journal/v13/n7/full/nmeth.3904.html)\n", 429 | " + [Classification evaluation](http://www.nature.com/nmeth/journal/v13/n8/full/nmeth.3945.html)\n", 430 | " + [Model selection and overfitting](http://www.nature.com/nmeth/journal/v13/n9/full/nmeth.3968.html)\n", 431 | "\n", 432 | "0. [The Elements of Statistical Learning](http://statweb.stanford.edu/~tibs/ElemStatLearn/) by Hastie T, Tibshirani R, and Friedman J." 433 | ] 434 | } 435 | ], 436 | "metadata": { 437 | "kernelspec": { 438 | "display_name": "Python 2", 439 | "language": "python", 440 | "name": "python2" 441 | }, 442 | "language_info": { 443 | "codemirror_mode": { 444 | "name": "ipython", 445 | "version": 2 446 | }, 447 | "file_extension": ".py", 448 | "mimetype": "text/x-python", 449 | "name": "python", 450 | "nbconvert_exporter": "python", 451 | "pygments_lexer": "ipython2", 452 | "version": "2.7.10" 453 | } 454 | }, 455 | "nbformat": 4, 456 | "nbformat_minor": 0 457 | } 458 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Attribution-ShareAlike 4.0 International 2 | 3 | ======================================================================= 4 | 5 | Creative Commons Corporation ("Creative Commons") is not a law firm and 6 | does not provide legal services or legal advice. Distribution of 7 | Creative Commons public licenses does not create a lawyer-client or 8 | other relationship. Creative Commons makes its licenses and related 9 | information available on an "as-is" basis. Creative Commons gives no 10 | warranties regarding its licenses, any material licensed under their 11 | terms and conditions, or any related information. Creative Commons 12 | disclaims all liability for damages resulting from their use to the 13 | fullest extent possible. 14 | 15 | Using Creative Commons Public Licenses 16 | 17 | Creative Commons public licenses provide a standard set of terms and 18 | conditions that creators and other rights holders may use to share 19 | original works of authorship and other material subject to copyright 20 | and certain other rights specified in the public license below. The 21 | following considerations are for informational purposes only, are not 22 | exhaustive, and do not form part of our licenses. 23 | 24 | Considerations for licensors: Our public licenses are 25 | intended for use by those authorized to give the public 26 | permission to use material in ways otherwise restricted by 27 | copyright and certain other rights. Our licenses are 28 | irrevocable. Licensors should read and understand the terms 29 | and conditions of the license they choose before applying it. 30 | Licensors should also secure all rights necessary before 31 | applying our licenses so that the public can reuse the 32 | material as expected. Licensors should clearly mark any 33 | material not subject to the license. This includes other CC- 34 | licensed material, or material used under an exception or 35 | limitation to copyright. More considerations for licensors: 36 | wiki.creativecommons.org/Considerations_for_licensors 37 | 38 | Considerations for the public: By using one of our public 39 | licenses, a licensor grants the public permission to use the 40 | licensed material under specified terms and conditions. If 41 | the licensor's permission is not necessary for any reason--for 42 | example, because of any applicable exception or limitation to 43 | copyright--then that use is not regulated by the license. Our 44 | licenses grant only permissions under copyright and certain 45 | other rights that a licensor has authority to grant. Use of 46 | the licensed material may still be restricted for other 47 | reasons, including because others have copyright or other 48 | rights in the material. A licensor may make special requests, 49 | such as asking that all changes be marked or described. 50 | Although not required by our licenses, you are encouraged to 51 | respect those requests where reasonable. More_considerations 52 | for the public: 53 | wiki.creativecommons.org/Considerations_for_licensees 54 | 55 | ======================================================================= 56 | 57 | Creative Commons Attribution-ShareAlike 4.0 International Public 58 | License 59 | 60 | By exercising the Licensed Rights (defined below), You accept and agree 61 | to be bound by the terms and conditions of this Creative Commons 62 | Attribution-ShareAlike 4.0 International Public License ("Public 63 | License"). To the extent this Public License may be interpreted as a 64 | contract, You are granted the Licensed Rights in consideration of Your 65 | acceptance of these terms and conditions, and the Licensor grants You 66 | such rights in consideration of benefits the Licensor receives from 67 | making the Licensed Material available under these terms and 68 | conditions. 69 | 70 | 71 | Section 1 -- Definitions. 72 | 73 | a. Adapted Material means material subject to Copyright and Similar 74 | Rights that is derived from or based upon the Licensed Material 75 | and in which the Licensed Material is translated, altered, 76 | arranged, transformed, or otherwise modified in a manner requiring 77 | permission under the Copyright and Similar Rights held by the 78 | Licensor. For purposes of this Public License, where the Licensed 79 | Material is a musical work, performance, or sound recording, 80 | Adapted Material is always produced where the Licensed Material is 81 | synched in timed relation with a moving image. 82 | 83 | b. Adapter's License means the license You apply to Your Copyright 84 | and Similar Rights in Your contributions to Adapted Material in 85 | accordance with the terms and conditions of this Public License. 86 | 87 | c. BY-SA Compatible License means a license listed at 88 | creativecommons.org/compatiblelicenses, approved by Creative 89 | Commons as essentially the equivalent of this Public License. 90 | 91 | d. Copyright and Similar Rights means copyright and/or similar rights 92 | closely related to copyright including, without limitation, 93 | performance, broadcast, sound recording, and Sui Generis Database 94 | Rights, without regard to how the rights are labeled or 95 | categorized. For purposes of this Public License, the rights 96 | specified in Section 2(b)(1)-(2) are not Copyright and Similar 97 | Rights. 98 | 99 | e. Effective Technological Measures means those measures that, in the 100 | absence of proper authority, may not be circumvented under laws 101 | fulfilling obligations under Article 11 of the WIPO Copyright 102 | Treaty adopted on December 20, 1996, and/or similar international 103 | agreements. 104 | 105 | f. Exceptions and Limitations means fair use, fair dealing, and/or 106 | any other exception or limitation to Copyright and Similar Rights 107 | that applies to Your use of the Licensed Material. 108 | 109 | g. License Elements means the license attributes listed in the name 110 | of a Creative Commons Public License. The License Elements of this 111 | Public License are Attribution and ShareAlike. 112 | 113 | h. Licensed Material means the artistic or literary work, database, 114 | or other material to which the Licensor applied this Public 115 | License. 116 | 117 | i. Licensed Rights means the rights granted to You subject to the 118 | terms and conditions of this Public License, which are limited to 119 | all Copyright and Similar Rights that apply to Your use of the 120 | Licensed Material and that the Licensor has authority to license. 121 | 122 | j. Licensor means the individual(s) or entity(ies) granting rights 123 | under this Public License. 124 | 125 | k. Share means to provide material to the public by any means or 126 | process that requires permission under the Licensed Rights, such 127 | as reproduction, public display, public performance, distribution, 128 | dissemination, communication, or importation, and to make material 129 | available to the public including in ways that members of the 130 | public may access the material from a place and at a time 131 | individually chosen by them. 132 | 133 | l. Sui Generis Database Rights means rights other than copyright 134 | resulting from Directive 96/9/EC of the European Parliament and of 135 | the Council of 11 March 1996 on the legal protection of databases, 136 | as amended and/or succeeded, as well as other essentially 137 | equivalent rights anywhere in the world. 138 | 139 | m. You means the individual or entity exercising the Licensed Rights 140 | under this Public License. Your has a corresponding meaning. 141 | 142 | 143 | Section 2 -- Scope. 144 | 145 | a. License grant. 146 | 147 | 1. Subject to the terms and conditions of this Public License, 148 | the Licensor hereby grants You a worldwide, royalty-free, 149 | non-sublicensable, non-exclusive, irrevocable license to 150 | exercise the Licensed Rights in the Licensed Material to: 151 | 152 | a. reproduce and Share the Licensed Material, in whole or 153 | in part; and 154 | 155 | b. produce, reproduce, and Share Adapted Material. 156 | 157 | 2. Exceptions and Limitations. For the avoidance of doubt, where 158 | Exceptions and Limitations apply to Your use, this Public 159 | License does not apply, and You do not need to comply with 160 | its terms and conditions. 161 | 162 | 3. Term. The term of this Public License is specified in Section 163 | 6(a). 164 | 165 | 4. Media and formats; technical modifications allowed. The 166 | Licensor authorizes You to exercise the Licensed Rights in 167 | all media and formats whether now known or hereafter created, 168 | and to make technical modifications necessary to do so. The 169 | Licensor waives and/or agrees not to assert any right or 170 | authority to forbid You from making technical modifications 171 | necessary to exercise the Licensed Rights, including 172 | technical modifications necessary to circumvent Effective 173 | Technological Measures. For purposes of this Public License, 174 | simply making modifications authorized by this Section 2(a) 175 | (4) never produces Adapted Material. 176 | 177 | 5. Downstream recipients. 178 | 179 | a. Offer from the Licensor -- Licensed Material. Every 180 | recipient of the Licensed Material automatically 181 | receives an offer from the Licensor to exercise the 182 | Licensed Rights under the terms and conditions of this 183 | Public License. 184 | 185 | b. Additional offer from the Licensor -- Adapted Material. 186 | Every recipient of Adapted Material from You 187 | automatically receives an offer from the Licensor to 188 | exercise the Licensed Rights in the Adapted Material 189 | under the conditions of the Adapter's License You apply. 190 | 191 | c. No downstream restrictions. You may not offer or impose 192 | any additional or different terms or conditions on, or 193 | apply any Effective Technological Measures to, the 194 | Licensed Material if doing so restricts exercise of the 195 | Licensed Rights by any recipient of the Licensed 196 | Material. 197 | 198 | 6. No endorsement. Nothing in this Public License constitutes or 199 | may be construed as permission to assert or imply that You 200 | are, or that Your use of the Licensed Material is, connected 201 | with, or sponsored, endorsed, or granted official status by, 202 | the Licensor or others designated to receive attribution as 203 | provided in Section 3(a)(1)(A)(i). 204 | 205 | b. Other rights. 206 | 207 | 1. Moral rights, such as the right of integrity, are not 208 | licensed under this Public License, nor are publicity, 209 | privacy, and/or other similar personality rights; however, to 210 | the extent possible, the Licensor waives and/or agrees not to 211 | assert any such rights held by the Licensor to the limited 212 | extent necessary to allow You to exercise the Licensed 213 | Rights, but not otherwise. 214 | 215 | 2. Patent and trademark rights are not licensed under this 216 | Public License. 217 | 218 | 3. To the extent possible, the Licensor waives any right to 219 | collect royalties from You for the exercise of the Licensed 220 | Rights, whether directly or through a collecting society 221 | under any voluntary or waivable statutory or compulsory 222 | licensing scheme. In all other cases the Licensor expressly 223 | reserves any right to collect such royalties. 224 | 225 | 226 | Section 3 -- License Conditions. 227 | 228 | Your exercise of the Licensed Rights is expressly made subject to the 229 | following conditions. 230 | 231 | a. Attribution. 232 | 233 | 1. If You Share the Licensed Material (including in modified 234 | form), You must: 235 | 236 | a. retain the following if it is supplied by the Licensor 237 | with the Licensed Material: 238 | 239 | i. identification of the creator(s) of the Licensed 240 | Material and any others designated to receive 241 | attribution, in any reasonable manner requested by 242 | the Licensor (including by pseudonym if 243 | designated); 244 | 245 | ii. a copyright notice; 246 | 247 | iii. a notice that refers to this Public License; 248 | 249 | iv. a notice that refers to the disclaimer of 250 | warranties; 251 | 252 | v. a URI or hyperlink to the Licensed Material to the 253 | extent reasonably practicable; 254 | 255 | b. indicate if You modified the Licensed Material and 256 | retain an indication of any previous modifications; and 257 | 258 | c. indicate the Licensed Material is licensed under this 259 | Public License, and include the text of, or the URI or 260 | hyperlink to, this Public License. 261 | 262 | 2. You may satisfy the conditions in Section 3(a)(1) in any 263 | reasonable manner based on the medium, means, and context in 264 | which You Share the Licensed Material. For example, it may be 265 | reasonable to satisfy the conditions by providing a URI or 266 | hyperlink to a resource that includes the required 267 | information. 268 | 269 | 3. If requested by the Licensor, You must remove any of the 270 | information required by Section 3(a)(1)(A) to the extent 271 | reasonably practicable. 272 | 273 | b. ShareAlike. 274 | 275 | In addition to the conditions in Section 3(a), if You Share 276 | Adapted Material You produce, the following conditions also apply. 277 | 278 | 1. The Adapter's License You apply must be a Creative Commons 279 | license with the same License Elements, this version or 280 | later, or a BY-SA Compatible License. 281 | 282 | 2. You must include the text of, or the URI or hyperlink to, the 283 | Adapter's License You apply. You may satisfy this condition 284 | in any reasonable manner based on the medium, means, and 285 | context in which You Share Adapted Material. 286 | 287 | 3. You may not offer or impose any additional or different terms 288 | or conditions on, or apply any Effective Technological 289 | Measures to, Adapted Material that restrict exercise of the 290 | rights granted under the Adapter's License You apply. 291 | 292 | 293 | Section 4 -- Sui Generis Database Rights. 294 | 295 | Where the Licensed Rights include Sui Generis Database Rights that 296 | apply to Your use of the Licensed Material: 297 | 298 | a. for the avoidance of doubt, Section 2(a)(1) grants You the right 299 | to extract, reuse, reproduce, and Share all or a substantial 300 | portion of the contents of the database; 301 | 302 | b. if You include all or a substantial portion of the database 303 | contents in a database in which You have Sui Generis Database 304 | Rights, then the database in which You have Sui Generis Database 305 | Rights (but not its individual contents) is Adapted Material, 306 | 307 | including for purposes of Section 3(b); and 308 | c. You must comply with the conditions in Section 3(a) if You Share 309 | all or a substantial portion of the contents of the database. 310 | 311 | For the avoidance of doubt, this Section 4 supplements and does not 312 | replace Your obligations under this Public License where the Licensed 313 | Rights include other Copyright and Similar Rights. 314 | 315 | 316 | Section 5 -- Disclaimer of Warranties and Limitation of Liability. 317 | 318 | a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE 319 | EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS 320 | AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF 321 | ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, 322 | IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, 323 | WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR 324 | PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, 325 | ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT 326 | KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT 327 | ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. 328 | 329 | b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE 330 | TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, 331 | NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, 332 | INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, 333 | COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR 334 | USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN 335 | ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR 336 | DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR 337 | IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. 338 | 339 | c. The disclaimer of warranties and limitation of liability provided 340 | above shall be interpreted in a manner that, to the extent 341 | possible, most closely approximates an absolute disclaimer and 342 | waiver of all liability. 343 | 344 | 345 | Section 6 -- Term and Termination. 346 | 347 | a. This Public License applies for the term of the Copyright and 348 | Similar Rights licensed here. However, if You fail to comply with 349 | this Public License, then Your rights under this Public License 350 | terminate automatically. 351 | 352 | b. Where Your right to use the Licensed Material has terminated under 353 | Section 6(a), it reinstates: 354 | 355 | 1. automatically as of the date the violation is cured, provided 356 | it is cured within 30 days of Your discovery of the 357 | violation; or 358 | 359 | 2. upon express reinstatement by the Licensor. 360 | 361 | For the avoidance of doubt, this Section 6(b) does not affect any 362 | right the Licensor may have to seek remedies for Your violations 363 | of this Public License. 364 | 365 | c. For the avoidance of doubt, the Licensor may also offer the 366 | Licensed Material under separate terms or conditions or stop 367 | distributing the Licensed Material at any time; however, doing so 368 | will not terminate this Public License. 369 | 370 | d. Sections 1, 5, 6, 7, and 8 survive termination of this Public 371 | License. 372 | 373 | 374 | Section 7 -- Other Terms and Conditions. 375 | 376 | a. The Licensor shall not be bound by any additional or different 377 | terms or conditions communicated by You unless expressly agreed. 378 | 379 | b. Any arrangements, understandings, or agreements regarding the 380 | Licensed Material not stated herein are separate from and 381 | independent of the terms and conditions of this Public License. 382 | 383 | 384 | Section 8 -- Interpretation. 385 | 386 | a. For the avoidance of doubt, this Public License does not, and 387 | shall not be interpreted to, reduce, limit, restrict, or impose 388 | conditions on any use of the Licensed Material that could lawfully 389 | be made without permission under this Public License. 390 | 391 | b. To the extent possible, if any provision of this Public License is 392 | deemed unenforceable, it shall be automatically reformed to the 393 | minimum extent necessary to make it enforceable. If the provision 394 | cannot be reformed, it shall be severed from this Public License 395 | without affecting the enforceability of the remaining terms and 396 | conditions. 397 | 398 | c. No term or condition of this Public License will be waived and no 399 | failure to comply consented to unless expressly agreed to by the 400 | Licensor. 401 | 402 | d. Nothing in this Public License constitutes or may be interpreted 403 | as a limitation upon, or waiver of, any privileges and immunities 404 | that apply to the Licensor or You, including from the legal 405 | processes of any jurisdiction or authority. 406 | 407 | 408 | ======================================================================= 409 | 410 | Creative Commons is not a party to its public 411 | licenses. Notwithstanding, Creative Commons may elect to apply one of 412 | its public licenses to material it publishes and in those instances 413 | will be considered the “Licensor.” The text of the Creative Commons 414 | public licenses is dedicated to the public domain under the CC0 Public 415 | Domain Dedication. Except for the limited purpose of indicating that 416 | material is shared under a Creative Commons public license or as 417 | otherwise permitted by the Creative Commons policies published at 418 | creativecommons.org/policies, Creative Commons does not authorize the 419 | use of the trademark "Creative Commons" or any other trademark or logo 420 | of Creative Commons without its prior written consent including, 421 | without limitation, in connection with any unauthorized modifications 422 | to any of its public licenses or any other arrangements, 423 | understandings, or agreements concerning use of licensed material. For 424 | the avoidance of doubt, this paragraph does not form part of the 425 | public licenses. 426 | 427 | Creative Commons may be contacted at creativecommons.org. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Practical tips for class imbalance in binary classification 2 | #### _Zichen Wang_ 3 | 4 | A [blog post](https://medium.com/@wangzc921/practical-tips-for-class-imbalance-in-binary-classification-6ee29bcdb8a7?source=friends_link&sk=16c43640eab3817a8de3cb15eedb181a) was writen based on this tutorial. 5 | 6 | ## Requirements 7 | To run the notebook, install modules on Python2.7 in [requirements.txt](https://github.com/wangz10/class_imbalance/blob/master/requirements.txt). 8 | 9 | ` 10 | pip install -r requirements.txt 11 | ` 12 | -------------------------------------------------------------------------------- /datasets/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | 3 | !.gitignore -------------------------------------------------------------------------------- /prepare_data.ipynb: -------------------------------------------------------------------------------- 1 | { 2 | "cells": [ 3 | { 4 | "cell_type": "markdown", 5 | "metadata": {}, 6 | "source": [ 7 | "## Datasets used\n", 8 | "1. Synthetic data\n", 9 | "2. [Titanic survivors](https://www.kaggle.com/c/titanic/data)\n", 10 | "3. [Breast Cancer Wisconsin (Diagnostic) Data Set](https://archive.ics.uci.edu/ml/datasets/Breast+Cancer+Wisconsin+(Diagnostic))\n", 11 | "4. Harmonizome\n", 12 | " + ProteomicsDB Cell Type and Tissue Protein Expression Profiles ([Gene-Attribute Matrix Cleaned](http://amp.pharm.mssm.edu/static/hdfs/harmonizome/data/proteomicsdb/gene_attribute_matrix_cleaned.txt.gz))\n", 13 | " + [HGNC gene family](http://www.genenames.org/cgi-bin/genefamilies/download-all/tsv)\n" 14 | ] 15 | }, 16 | { 17 | "cell_type": "code", 18 | "execution_count": 1, 19 | "metadata": { 20 | "collapsed": true 21 | }, 22 | "outputs": [], 23 | "source": [ 24 | "import pandas as pd\n", 25 | "from utils import *\n" 26 | ] 27 | }, 28 | { 29 | "cell_type": "code", 30 | "execution_count": 2, 31 | "metadata": { 32 | "collapsed": false 33 | }, 34 | "outputs": [ 35 | { 36 | "name": "stdout", 37 | "output_type": "stream", 38 | "text": [ 39 | "(1000, 20) (1000,)\n" 40 | ] 41 | } 42 | ], 43 | "source": [ 44 | "## Synthetic data\n", 45 | "X, y = make_classification(n_classes=2, class_sep=2, weights=[0.1, 0.9],\n", 46 | "\tn_informative=3, n_redundant=1, flip_y=0,\n", 47 | "\tn_features=20, n_clusters_per_class=1,\n", 48 | "\tn_samples=1000, random_state=10)\n", 49 | "print X.shape, y.shape" 50 | ] 51 | }, 52 | { 53 | "cell_type": "code", 54 | "execution_count": 3, 55 | "metadata": { 56 | "collapsed": false 57 | }, 58 | "outputs": [ 59 | { 60 | "name": "stdout", 61 | "output_type": "stream", 62 | "text": [ 63 | "(891, 12)\n" 64 | ] 65 | }, 66 | { 67 | "data": { 68 | "text/html": [ 69 | "
\n", 70 | "\n", 71 | " \n", 72 | " \n", 73 | " \n", 74 | " \n", 75 | " \n", 76 | " \n", 77 | " \n", 78 | " \n", 79 | " \n", 80 | " \n", 81 | " \n", 82 | " \n", 83 | " \n", 84 | " \n", 85 | " \n", 86 | " \n", 87 | " \n", 88 | " \n", 89 | " \n", 90 | " \n", 91 | " \n", 92 | " \n", 93 | " \n", 94 | " \n", 95 | " \n", 96 | " \n", 97 | " \n", 98 | " \n", 99 | " \n", 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 | " \n", 152 | " \n", 153 | " \n", 154 | " \n", 155 | " \n", 156 | " \n", 157 | " \n", 158 | " \n", 159 | " \n", 160 | " \n", 161 | " \n", 162 | " \n", 163 | " \n", 164 | " \n", 165 | "
PassengerIdSurvivedPclassNameSexAgeSibSpParchTicketFareCabinEmbarked
0103Braund, Mr. Owen Harrismale2210A/5 211717.2500NaNS
1211Cumings, Mrs. John Bradley (Florence Briggs Th...female3810PC 1759971.2833C85C
2313Heikkinen, Miss. Lainafemale2600STON/O2. 31012827.9250NaNS
3411Futrelle, Mrs. Jacques Heath (Lily May Peel)female351011380353.1000C123S
4503Allen, Mr. William Henrymale35003734508.0500NaNS
\n", 166 | "
" 167 | ], 168 | "text/plain": [ 169 | " PassengerId Survived Pclass \\\n", 170 | "0 1 0 3 \n", 171 | "1 2 1 1 \n", 172 | "2 3 1 3 \n", 173 | "3 4 1 1 \n", 174 | "4 5 0 3 \n", 175 | "\n", 176 | " Name Sex Age SibSp \\\n", 177 | "0 Braund, Mr. Owen Harris male 22 1 \n", 178 | "1 Cumings, Mrs. John Bradley (Florence Briggs Th... female 38 1 \n", 179 | "2 Heikkinen, Miss. Laina female 26 0 \n", 180 | "3 Futrelle, Mrs. Jacques Heath (Lily May Peel) female 35 1 \n", 181 | "4 Allen, Mr. William Henry male 35 0 \n", 182 | "\n", 183 | " Parch Ticket Fare Cabin Embarked \n", 184 | "0 0 A/5 21171 7.2500 NaN S \n", 185 | "1 0 PC 17599 71.2833 C85 C \n", 186 | "2 0 STON/O2. 3101282 7.9250 NaN S \n", 187 | "3 0 113803 53.1000 C123 S \n", 188 | "4 0 373450 8.0500 NaN S " 189 | ] 190 | }, 191 | "execution_count": 3, 192 | "metadata": {}, 193 | "output_type": "execute_result" 194 | } 195 | ], 196 | "source": [ 197 | "## Load Titanic\n", 198 | "titanic = pd.read_csv('datasets/Titanic/train.csv')\n", 199 | "print titanic.shape\n", 200 | "titanic.head()\n" 201 | ] 202 | }, 203 | { 204 | "cell_type": "code", 205 | "execution_count": 4, 206 | "metadata": { 207 | "collapsed": false 208 | }, 209 | "outputs": [ 210 | { 211 | "name": "stdout", 212 | "output_type": "stream", 213 | "text": [ 214 | "342\n", 215 | "0.383838383838\n" 216 | ] 217 | } 218 | ], 219 | "source": [ 220 | "## Examine class ratio\n", 221 | "print titanic['Survived'].sum()\n", 222 | "print titanic['Survived'].sum()/float(titanic.shape[0])" 223 | ] 224 | }, 225 | { 226 | "cell_type": "code", 227 | "execution_count": 5, 228 | "metadata": { 229 | "collapsed": false 230 | }, 231 | "outputs": [ 232 | { 233 | "name": "stdout", 234 | "output_type": "stream", 235 | "text": [ 236 | "(891, 8) (891,)\n" 237 | ] 238 | }, 239 | { 240 | "name": "stderr", 241 | "output_type": "stream", 242 | "text": [ 243 | "/Library/Python/2.7/site-packages/numpy-1.10.4-py2.7-macosx-10.10-intel.egg/numpy/lib/arraysetops.py:200: FutureWarning: numpy not_equal will not check object identity in the future. The comparison did not return the same result as suggested by the identity (`is`)) and will change.\n", 244 | " flag = np.concatenate(([True], aux[1:] != aux[:-1]))\n" 245 | ] 246 | } 247 | ], 248 | "source": [ 249 | "## Process features\n", 250 | "from sklearn.preprocessing import LabelEncoder\n", 251 | "le = LabelEncoder()\n", 252 | "for col in ['Sex', 'Cabin', 'Embarked']:\n", 253 | " titanic[col] = le.fit_transform(titanic[col])\n", 254 | "\n", 255 | "## Split df into X and y and convert to numpy.array\n", 256 | "X = titanic.drop(['PassengerId', 'Survived', 'Name', 'Ticket'], axis=1).values\n", 257 | "y = titanic['Survived'].values\n", 258 | "print X.shape, y.shape" 259 | ] 260 | }, 261 | { 262 | "cell_type": "code", 263 | "execution_count": null, 264 | "metadata": { 265 | "collapsed": true 266 | }, 267 | "outputs": [], 268 | "source": [] 269 | }, 270 | { 271 | "cell_type": "code", 272 | "execution_count": 6, 273 | "metadata": { 274 | "collapsed": false 275 | }, 276 | "outputs": [ 277 | { 278 | "name": "stdout", 279 | "output_type": "stream", 280 | "text": [ 281 | "(198, 35)\n" 282 | ] 283 | }, 284 | { 285 | "data": { 286 | "text/html": [ 287 | "
\n", 288 | "\n", 289 | " \n", 290 | " \n", 291 | " \n", 292 | " \n", 293 | " \n", 294 | " \n", 295 | " \n", 296 | " \n", 297 | " \n", 298 | " \n", 299 | " \n", 300 | " \n", 301 | " \n", 302 | " \n", 303 | " \n", 304 | " \n", 305 | " \n", 306 | " \n", 307 | " \n", 308 | " \n", 309 | " \n", 310 | " \n", 311 | " \n", 312 | " \n", 313 | " \n", 314 | " \n", 315 | " \n", 316 | " \n", 317 | " \n", 318 | " \n", 319 | " \n", 320 | " \n", 321 | " \n", 322 | " \n", 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 | " \n", 375 | " \n", 376 | " \n", 377 | " \n", 378 | " \n", 379 | " \n", 380 | " \n", 381 | " \n", 382 | " \n", 383 | " \n", 384 | " \n", 385 | " \n", 386 | " \n", 387 | " \n", 388 | " \n", 389 | " \n", 390 | " \n", 391 | " \n", 392 | " \n", 393 | " \n", 394 | " \n", 395 | " \n", 396 | " \n", 397 | " \n", 398 | " \n", 399 | " \n", 400 | " \n", 401 | " \n", 402 | " \n", 403 | " \n", 404 | " \n", 405 | " \n", 406 | " \n", 407 | " \n", 408 | " \n", 409 | " \n", 410 | " \n", 411 | " \n", 412 | " \n", 413 | " \n", 414 | " \n", 415 | " \n", 416 | " \n", 417 | " \n", 418 | " \n", 419 | " \n", 420 | " \n", 421 | " \n", 422 | " \n", 423 | " \n", 424 | " \n", 425 | " \n", 426 | " \n", 427 | " \n", 428 | " \n", 429 | " \n", 430 | " \n", 431 | " \n", 432 | " \n", 433 | " \n", 434 | " \n", 435 | " \n", 436 | " \n", 437 | "
IDoutcomeAttr0Attr1Attr2Attr3Attr4Attr5Attr6Attr7...Attr23Attr24Attr25Attr26Attr27Attr28Attr29Attr30Attr31Attr32
0119513N3118.0227.60117.501013.00.094890.10360.1086...139.701436.00.11950.19260.31400.11700.26770.081135.05
18423N6117.9910.38122.801001.00.118400.27760.3001...184.602019.00.16220.66560.71190.26540.46010.118903.02
2842517N11621.3717.44137.501373.00.088360.11890.1255...159.101949.00.11880.34490.34140.20320.43340.090672.50
3843483N12311.4220.3877.58386.10.142500.28390.2414...98.87567.70.20980.86630.68690.25750.66380.173002.00
4843584R2720.2914.34135.101297.00.100300.13280.1980...152.201575.00.13740.20500.40000.16250.23640.076783.50
\n", 438 | "

5 rows × 35 columns

\n", 439 | "
" 440 | ], 441 | "text/plain": [ 442 | " ID outcome Attr0 Attr1 Attr2 Attr3 Attr4 Attr5 Attr6 \\\n", 443 | "0 119513 N 31 18.02 27.60 117.50 1013.0 0.09489 0.1036 \n", 444 | "1 8423 N 61 17.99 10.38 122.80 1001.0 0.11840 0.2776 \n", 445 | "2 842517 N 116 21.37 17.44 137.50 1373.0 0.08836 0.1189 \n", 446 | "3 843483 N 123 11.42 20.38 77.58 386.1 0.14250 0.2839 \n", 447 | "4 843584 R 27 20.29 14.34 135.10 1297.0 0.10030 0.1328 \n", 448 | "\n", 449 | " Attr7 ... Attr23 Attr24 Attr25 Attr26 Attr27 Attr28 Attr29 \\\n", 450 | "0 0.1086 ... 139.70 1436.0 0.1195 0.1926 0.3140 0.1170 0.2677 \n", 451 | "1 0.3001 ... 184.60 2019.0 0.1622 0.6656 0.7119 0.2654 0.4601 \n", 452 | "2 0.1255 ... 159.10 1949.0 0.1188 0.3449 0.3414 0.2032 0.4334 \n", 453 | "3 0.2414 ... 98.87 567.7 0.2098 0.8663 0.6869 0.2575 0.6638 \n", 454 | "4 0.1980 ... 152.20 1575.0 0.1374 0.2050 0.4000 0.1625 0.2364 \n", 455 | "\n", 456 | " Attr30 Attr31 Attr32 \n", 457 | "0 0.08113 5.0 5 \n", 458 | "1 0.11890 3.0 2 \n", 459 | "2 0.09067 2.5 0 \n", 460 | "3 0.17300 2.0 0 \n", 461 | "4 0.07678 3.5 0 \n", 462 | "\n", 463 | "[5 rows x 35 columns]" 464 | ] 465 | }, 466 | "execution_count": 6, 467 | "metadata": {}, 468 | "output_type": "execute_result" 469 | } 470 | ], 471 | "source": [ 472 | "## Load breast cancer data\n", 473 | "bc = pd.read_csv('datasets/wpbc.data', \n", 474 | " names=['ID', 'outcome'] + ['Attr%s'%i for i in range(33)])\n", 475 | "print bc.shape\n", 476 | "bc.head()" 477 | ] 478 | }, 479 | { 480 | "cell_type": "code", 481 | "execution_count": 7, 482 | "metadata": { 483 | "collapsed": false 484 | }, 485 | "outputs": [ 486 | { 487 | "name": "stdout", 488 | "output_type": "stream", 489 | "text": [ 490 | "N 151\n", 491 | "R 47\n", 492 | "dtype: int64\n" 493 | ] 494 | } 495 | ], 496 | "source": [ 497 | "print bc['outcome'].value_counts()" 498 | ] 499 | }, 500 | { 501 | "cell_type": "code", 502 | "execution_count": 32, 503 | "metadata": { 504 | "collapsed": false 505 | }, 506 | "outputs": [ 507 | { 508 | "name": "stdout", 509 | "output_type": "stream", 510 | "text": [ 511 | "(198, 33) (198,)\n", 512 | "0.237373737374\n" 513 | ] 514 | } 515 | ], 516 | "source": [ 517 | "## Split df into X and y and convert to numpy.array\n", 518 | "X = bc.drop(['ID', 'outcome'], axis=1)\n", 519 | "y = bc['outcome'].map({'N':0, 'R':1})\n", 520 | "\n", 521 | "X = X.values\n", 522 | "y = y.values\n", 523 | "\n", 524 | "print X.shape, y.shape\n", 525 | "print y.sum()/float(y.shape[0])" 526 | ] 527 | }, 528 | { 529 | "cell_type": "code", 530 | "execution_count": 8, 531 | "metadata": { 532 | "collapsed": false 533 | }, 534 | "outputs": [ 535 | { 536 | "name": "stdout", 537 | "output_type": "stream", 538 | "text": [ 539 | "(2776, 56)\n" 540 | ] 541 | }, 542 | { 543 | "data": { 544 | "text/html": [ 545 | "
\n", 546 | "\n", 547 | " \n", 548 | " \n", 549 | " \n", 550 | " \n", 551 | " \n", 552 | " \n", 553 | " \n", 554 | " \n", 555 | " \n", 556 | " \n", 557 | " \n", 558 | " \n", 559 | " \n", 560 | " \n", 561 | " \n", 562 | " \n", 563 | " \n", 564 | " \n", 565 | " \n", 566 | " \n", 567 | " \n", 568 | " \n", 569 | " \n", 570 | " \n", 571 | " \n", 572 | " \n", 573 | " \n", 574 | " \n", 575 | " \n", 576 | " \n", 577 | " \n", 578 | " \n", 579 | " \n", 580 | " \n", 581 | " \n", 582 | " \n", 583 | " \n", 584 | " \n", 585 | " \n", 586 | " \n", 587 | " \n", 588 | " \n", 589 | " \n", 590 | " \n", 591 | " \n", 592 | " \n", 593 | " \n", 594 | " \n", 595 | " \n", 596 | " \n", 597 | " \n", 598 | " \n", 599 | " \n", 600 | " \n", 601 | " \n", 602 | " \n", 603 | " \n", 604 | " \n", 605 | " \n", 606 | " \n", 607 | " \n", 608 | " \n", 609 | " \n", 610 | " \n", 611 | " \n", 612 | " \n", 613 | " \n", 614 | " \n", 615 | " \n", 616 | " \n", 617 | " \n", 618 | " \n", 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 | " \n", 671 | " \n", 672 | " \n", 673 | " \n", 674 | " \n", 675 | " \n", 676 | " \n", 677 | " \n", 678 | " \n", 679 | " \n", 680 | " \n", 681 | " \n", 682 | " \n", 683 | " \n", 684 | " \n", 685 | " \n", 686 | " \n", 687 | " \n", 688 | " \n", 689 | " \n", 690 | " \n", 691 | " \n", 692 | " \n", 693 | " \n", 694 | " \n", 695 | "
GeneSymUniprotAccGeneID/Brenda Tissue Ontology BTO:3867516155682806193818...115813631078763255311297762892417914
0LOC102724985Q6P9961027249855.0173554.8305925.7833365.0494404.8580414.6057084.868083...5.3953174.7348844.8356344.6598314.6431504.3762224.0264394.6599613.9298214.854218
1PDXDC1H3BU11230424.7441594.6014335.2671984.7411684.5713144.5186104.565993...4.8940144.4033764.4405974.4722974.4790504.2167823.8935324.5201783.7252624.458436
2COG5Q9UP83104664.2133854.2133855.7592064.5280634.0350774.3595304.309750...4.6348784.7999394.5107104.0482403.9247634.0417284.1356294.7158164.0929424.545271
3HEXAH3BU8530734.5356384.7406345.1185284.1813804.7317744.6659794.865457...4.7082744.9377034.5984005.2907275.4238424.1541583.8579235.1158234.3694585.008221
4HEXBH0Y9B630744.6055204.5912396.2948824.1396865.4719964.4428325.214406...5.1396104.9791315.6546245.2787585.2835254.9720134.5361245.3886054.5763185.425797
\n", 696 | "

5 rows × 56 columns

\n", 697 | "
" 698 | ], 699 | "text/plain": [ 700 | " GeneSym UniprotAcc GeneID/Brenda Tissue Ontology BTO: 38 \\\n", 701 | "0 LOC102724985 Q6P996 102724985 5.017355 \n", 702 | "1 PDXDC1 H3BU11 23042 4.744159 \n", 703 | "2 COG5 Q9UP83 10466 4.213385 \n", 704 | "3 HEXA H3BU85 3073 4.535638 \n", 705 | "4 HEXB H0Y9B6 3074 4.605520 \n", 706 | "\n", 707 | " 675 1615 568 2806 1938 18 ... \\\n", 708 | "0 4.830592 5.783336 5.049440 4.858041 4.605708 4.868083 ... \n", 709 | "1 4.601433 5.267198 4.741168 4.571314 4.518610 4.565993 ... \n", 710 | "2 4.213385 5.759206 4.528063 4.035077 4.359530 4.309750 ... \n", 711 | "3 4.740634 5.118528 4.181380 4.731774 4.665979 4.865457 ... \n", 712 | "4 4.591239 6.294882 4.139686 5.471996 4.442832 5.214406 ... \n", 713 | "\n", 714 | " 1158 1363 1078 763 2553 1129 776 \\\n", 715 | "0 5.395317 4.734884 4.835634 4.659831 4.643150 4.376222 4.026439 \n", 716 | "1 4.894014 4.403376 4.440597 4.472297 4.479050 4.216782 3.893532 \n", 717 | "2 4.634878 4.799939 4.510710 4.048240 3.924763 4.041728 4.135629 \n", 718 | "3 4.708274 4.937703 4.598400 5.290727 5.423842 4.154158 3.857923 \n", 719 | "4 5.139610 4.979131 5.654624 5.278758 5.283525 4.972013 4.536124 \n", 720 | "\n", 721 | " 289 2417 914 \n", 722 | "0 4.659961 3.929821 4.854218 \n", 723 | "1 4.520178 3.725262 4.458436 \n", 724 | "2 4.715816 4.092942 4.545271 \n", 725 | "3 5.115823 4.369458 5.008221 \n", 726 | "4 5.388605 4.576318 5.425797 \n", 727 | "\n", 728 | "[5 rows x 56 columns]" 729 | ] 730 | }, 731 | "execution_count": 8, 732 | "metadata": {}, 733 | "output_type": "execute_result" 734 | } 735 | ], 736 | "source": [ 737 | "## Load ProteomicsDB data\n", 738 | "proteome = pd.read_csv('datasets/Harmonizome/gene_attribute_matrix_cleaned.txt.gz', \n", 739 | " sep='\\t', compression='gzip', skiprows=2)\n", 740 | "print proteome.shape\n", 741 | "proteome.head()" 742 | ] 743 | }, 744 | { 745 | "cell_type": "code", 746 | "execution_count": 9, 747 | "metadata": { 748 | "collapsed": false 749 | }, 750 | "outputs": [ 751 | { 752 | "name": "stdout", 753 | "output_type": "stream", 754 | "text": [ 755 | "(20086, 12)\n" 756 | ] 757 | }, 758 | { 759 | "data": { 760 | "text/html": [ 761 | "
\n", 762 | "\n", 763 | " \n", 764 | " \n", 765 | " \n", 766 | " \n", 767 | " \n", 768 | " \n", 769 | " \n", 770 | " \n", 771 | " \n", 772 | " \n", 773 | " \n", 774 | " \n", 775 | " \n", 776 | " \n", 777 | " \n", 778 | " \n", 779 | " \n", 780 | " \n", 781 | " \n", 782 | " \n", 783 | " \n", 784 | " \n", 785 | " \n", 786 | " \n", 787 | " \n", 788 | " \n", 789 | " \n", 790 | " \n", 791 | " \n", 792 | " \n", 793 | " \n", 794 | " \n", 795 | " \n", 796 | " \n", 797 | " \n", 798 | " \n", 799 | " \n", 800 | " \n", 801 | " \n", 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 | " \n", 854 | " \n", 855 | " \n", 856 | " \n", 857 | "
HGNC IDApproved SymbolApproved NameStatusPrevious SymbolsSynonymsChromosomeAccession NumbersRefSeq IDsGene Family TagGene family descriptionGene family ID
0324AGPAT11-acylglycerol-3-phosphate O-acyltransferase 1ApprovedNaNLPAAT-alpha6p21.3U56417NM_006411AGPAT1-acylglycerol-3-phosphate O-acyltransferases46
1325AGPAT21-acylglycerol-3-phosphate O-acyltransferase 2ApprovedBSCLLPAAT-beta9q34.3AF000237NM_006412AGPAT1-acylglycerol-3-phosphate O-acyltransferases46
2326AGPAT31-acylglycerol-3-phosphate O-acyltransferase 3ApprovedNaNLPAAT-gamma21q22.3AF156774NM_020132AGPAT1-acylglycerol-3-phosphate O-acyltransferases46
320885AGPAT41-acylglycerol-3-phosphate O-acyltransferase 4ApprovedNaNLPAAT-delta, dJ473J16.26q25.3AF156776NM_020133AGPAT1-acylglycerol-3-phosphate O-acyltransferases46
420886AGPAT51-acylglycerol-3-phosphate O-acyltransferase 5ApprovedNaNFLJ11210, LPAAT-e, LPAAT-epsilon8p23.1AF375789NM_018361AGPAT1-acylglycerol-3-phosphate O-acyltransferases46
\n", 858 | "
" 859 | ], 860 | "text/plain": [ 861 | " HGNC ID Approved Symbol Approved Name \\\n", 862 | "0 324 AGPAT1 1-acylglycerol-3-phosphate O-acyltransferase 1 \n", 863 | "1 325 AGPAT2 1-acylglycerol-3-phosphate O-acyltransferase 2 \n", 864 | "2 326 AGPAT3 1-acylglycerol-3-phosphate O-acyltransferase 3 \n", 865 | "3 20885 AGPAT4 1-acylglycerol-3-phosphate O-acyltransferase 4 \n", 866 | "4 20886 AGPAT5 1-acylglycerol-3-phosphate O-acyltransferase 5 \n", 867 | "\n", 868 | " Status Previous Symbols Synonyms Chromosome \\\n", 869 | "0 Approved NaN LPAAT-alpha 6p21.3 \n", 870 | "1 Approved BSCL LPAAT-beta 9q34.3 \n", 871 | "2 Approved NaN LPAAT-gamma 21q22.3 \n", 872 | "3 Approved NaN LPAAT-delta, dJ473J16.2 6q25.3 \n", 873 | "4 Approved NaN FLJ11210, LPAAT-e, LPAAT-epsilon 8p23.1 \n", 874 | "\n", 875 | " Accession Numbers RefSeq IDs Gene Family Tag \\\n", 876 | "0 U56417 NM_006411 AGPAT \n", 877 | "1 AF000237 NM_006412 AGPAT \n", 878 | "2 AF156774 NM_020132 AGPAT \n", 879 | "3 AF156776 NM_020133 AGPAT \n", 880 | "4 AF375789 NM_018361 AGPAT \n", 881 | "\n", 882 | " Gene family description Gene family ID \n", 883 | "0 1-acylglycerol-3-phosphate O-acyltransferases 46 \n", 884 | "1 1-acylglycerol-3-phosphate O-acyltransferases 46 \n", 885 | "2 1-acylglycerol-3-phosphate O-acyltransferases 46 \n", 886 | "3 1-acylglycerol-3-phosphate O-acyltransferases 46 \n", 887 | "4 1-acylglycerol-3-phosphate O-acyltransferases 46 " 888 | ] 889 | }, 890 | "execution_count": 9, 891 | "metadata": {}, 892 | "output_type": "execute_result" 893 | } 894 | ], 895 | "source": [ 896 | "## Load HGNC gene family \n", 897 | "gene_family = pd.read_csv('datasets/Harmonizome/HGNC_gene_family.txt',sep='\\t')\n", 898 | "print gene_family.shape\n", 899 | "gene_family.head()" 900 | ] 901 | }, 902 | { 903 | "cell_type": "code", 904 | "execution_count": 10, 905 | "metadata": { 906 | "collapsed": false 907 | }, 908 | "outputs": [ 909 | { 910 | "name": "stdout", 911 | "output_type": "stream", 912 | "text": [ 913 | "MicroRNAs 1777\n", 914 | "Zinc fingers C2H2-type 720\n", 915 | "RNAs, 7SL, cytoplasmic 689\n", 916 | "Cytoplasmic transfer RNAs 588\n", 917 | "Solute carriers 395\n", 918 | "CD molecules 394\n", 919 | "Small nucleolar RNAs, C/D box 326\n", 920 | "Ring finger proteins 275\n", 921 | "WD repeat domain containing 262\n", 922 | "Immunoglobulin-like domain containing 245\n", 923 | "Ankyrin repeat domain containing 242\n", 924 | "Endogenous ligands 236\n", 925 | "EF-hand domain containing 222\n", 926 | "RNA binding motif containing 213\n", 927 | "Long non-coding RNAs 211\n", 928 | "Pleckstrin homology domain containing 206\n", 929 | "Immunoglobulin heavy locus at 14q32.33 185\n", 930 | "Protein phosphatase 1 regulatory subunits 181\n", 931 | "V-set domain containing 163\n", 932 | "I-set domain containing 161\n", 933 | "Fibronectin type III domain containing 153\n", 934 | "PDZ domain containing 152\n", 935 | "Small nucleolar RNAs, H/ACA box 142\n", 936 | "BTB domain containing 134\n", 937 | "Olfactory receptors, family 4 129\n", 938 | "Vomeronasal receptors 129\n", 939 | "T-cell receptor alpha locus at 14q11.2 117\n", 940 | "Histones 116\n", 941 | "Tetratricopeptide repeat domain containing 115\n", 942 | "Piwi-interacting RNA clusters 114\n", 943 | " ... \n", 944 | "Platelet-activating factor receptor 1\n", 945 | "ATP binding cassette subfamily E 1\n", 946 | "Cytochrome P450 family 17 1\n", 947 | "Cytochrome P450 family 24 1\n", 948 | "Cystatins, type 3 1\n", 949 | "UDP-glucose ceramide glucosyltransferases 1\n", 950 | "Myosins, class XIX 1\n", 951 | "Olfactory receptors, family 55 1\n", 952 | "Succinate receptor 1\n", 953 | "Chloride channels, ATP-gated CFTR 1\n", 954 | "Histone deacetylases, class IV 1\n", 955 | "Zinc activated channels 1\n", 956 | "RAN family GTPases 1\n", 957 | "Myosins, class XVI 1\n", 958 | "Sodium leak channels, non selective 1\n", 959 | "G protein-coupled estrogen receptor 1\n", 960 | "Myosins, class VI 1\n", 961 | "Cytochrome P450 family 39 1\n", 962 | "G protein-coupled bile acid receptor 1\n", 963 | "Hydrogen voltage gated channels 1\n", 964 | "Chemokine (X-C motif) receptor 1\n", 965 | "Cytochrome P450 family 5 1\n", 966 | "Chemokine (C-X-3-C motif) receptor 1\n", 967 | "Oxoglutarate receptor 1\n", 968 | "Class II Cys-based phosphatases 1\n", 969 | "Ubiquitin specific peptidase like 1\n", 970 | "Lipid phosphatases 1\n", 971 | "Myosins, class X 1\n", 972 | "Cytochrome P450 family 19 1\n", 973 | "Adhesion G protein-coupled receptors, subfamily V 1\n", 974 | "dtype: int64\n" 975 | ] 976 | } 977 | ], 978 | "source": [ 979 | "print gene_family['Gene family description'].value_counts()" 980 | ] 981 | }, 982 | { 983 | "cell_type": "code", 984 | "execution_count": 11, 985 | "metadata": { 986 | "collapsed": false 987 | }, 988 | "outputs": [ 989 | { 990 | "name": "stdout", 991 | "output_type": "stream", 992 | "text": [ 993 | "['6-phosphofructo-2-kinases/fructose-2,6-biphosphatases', 'A-kinase anchoring proteins', 'Adenylate kinases', 'C2 domain containing protein kinases', 'CDC like kinases', 'Cyclin-dependent kinases', 'Death-associated protein kinases', 'Diacylglycerol kinases', 'Erb-b2 receptor tyrosine kinases', 'Glycerol kinases', 'MAP kinase phosphatases', 'Membrane-associated guanylate kinases', 'Mitogen-activated protein kinase kinase kinase kinases', 'Mitogen-activated protein kinase kinase kinases', 'Mitogen-activated protein kinase kinases', 'mitogen-activated protein kinase-activated protein kinases', 'Mitogen-activated protein kinases', 'MOB kinase activators', 'Phosphatidylinositol 3-kinase subunits', 'Receptor Tyrosine Kinases', 'SCY1-like, kinase-like proteins', 'Type I receptor serine/threonine kinases', 'Type II receptor serine/threonine kinases']\n", 994 | "273\n" 995 | ] 996 | } 997 | ], 998 | "source": [ 999 | "# Count kinases\n", 1000 | "print filter(lambda x: 'kinase' in x.lower(), gene_family['Gene family description'].unique())\n", 1001 | "print len(filter(lambda x: 'kinase' in x.lower(), gene_family['Gene family description']))" 1002 | ] 1003 | }, 1004 | { 1005 | "cell_type": "code", 1006 | "execution_count": 12, 1007 | "metadata": { 1008 | "collapsed": false 1009 | }, 1010 | "outputs": [ 1011 | { 1012 | "name": "stdout", 1013 | "output_type": "stream", 1014 | "text": [ 1015 | "['E2F transcription factors', 'General transcription factors', 'Kruppel-like transcription factors', 'Sp transcription factors', 'TEA domain transcription factors', 'Transcription factor Dp family']\n", 1016 | "66\n" 1017 | ] 1018 | } 1019 | ], 1020 | "source": [ 1021 | "# Count TF\n", 1022 | "print filter(lambda x: 'transcription factor' in x.lower(), gene_family['Gene family description'].unique())\n", 1023 | "print len(filter(lambda x: 'transcription factor' in x.lower(), gene_family['Gene family description']))" 1024 | ] 1025 | }, 1026 | { 1027 | "cell_type": "code", 1028 | "execution_count": 13, 1029 | "metadata": { 1030 | "collapsed": false 1031 | }, 1032 | "outputs": [ 1033 | { 1034 | "name": "stdout", 1035 | "output_type": "stream", 1036 | "text": [ 1037 | "(20086, 1)\n", 1038 | "(2776, 53)\n", 1039 | "(1863, 54)\n" 1040 | ] 1041 | } 1042 | ], 1043 | "source": [ 1044 | "# Inner join with proteome data\n", 1045 | "gene_family = gene_family[['Approved Symbol', 'Gene family description']]\n", 1046 | "gene_family.set_index('Approved Symbol', inplace=True)\n", 1047 | "print gene_family.shape\n", 1048 | "\n", 1049 | "proteome = proteome.drop(['UniprotAcc', 'GeneID/Brenda Tissue Ontology BTO:'], axis=1)\n", 1050 | "proteome.set_index('GeneSym', inplace=True)\n", 1051 | "print proteome.shape\n", 1052 | "\n", 1053 | "proteome = proteome.merge(gene_family, left_index=True, right_index=True, how='inner')\n", 1054 | "print proteome.shape" 1055 | ] 1056 | }, 1057 | { 1058 | "cell_type": "code", 1059 | "execution_count": 14, 1060 | "metadata": { 1061 | "collapsed": false 1062 | }, 1063 | "outputs": [ 1064 | { 1065 | "name": "stdout", 1066 | "output_type": "stream", 1067 | "text": [ 1068 | "Index([u'38', u'675', u'1615', u'568', u'2806', u'1938', u'18', u'4860', u'200001', u'200005', u'3884', u'3323', u'1939', u'2178', u'200004', u'1961', u'200002', u'1908', u'200003', u'179', u'4189', u'2696', u'599', u'1321', u'7', u'93', u'975', u'773', u'200043', u'1008', u'661', u'567', u'1890', u'269', u'200034', u'200045', u'2805', u'1061', u'664', u'562', u'1175', u'759', u'988', u'1158', u'1363', u'1078', u'763', u'2553', u'1129', u'776', u'289', u'2417', u'914'], dtype='object')\n", 1069 | "34 (1863,) (1863, 53)\n" 1070 | ] 1071 | } 1072 | ], 1073 | "source": [ 1074 | "# Split X and y\n", 1075 | "X = proteome.drop(['Gene family description'], axis=1)\n", 1076 | "print X.columns\n", 1077 | "X = X.values\n", 1078 | "y = proteome['Gene family description']\n", 1079 | "y = map(lambda x: 'kinase' in x.lower(), y)\n", 1080 | "y = np.array(y, dtype=np.int64)\n", 1081 | "print y.sum(), y.shape, X.shape\n" 1082 | ] 1083 | } 1084 | ], 1085 | "metadata": { 1086 | "kernelspec": { 1087 | "display_name": "Python 2", 1088 | "language": "python", 1089 | "name": "python2" 1090 | }, 1091 | "language_info": { 1092 | "codemirror_mode": { 1093 | "name": "ipython", 1094 | "version": 2 1095 | }, 1096 | "file_extension": ".py", 1097 | "mimetype": "text/x-python", 1098 | "name": "python", 1099 | "nbconvert_exporter": "python", 1100 | "pygments_lexer": "ipython2", 1101 | "version": "2.7.6" 1102 | } 1103 | }, 1104 | "nbformat": 4, 1105 | "nbformat_minor": 0 1106 | } 1107 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.10.4 2 | scipy==0.16.1 3 | matplotlib==1.3.1 4 | scikit-learn==0.17 5 | pandas==0.16.0 6 | seaborn==0.7.0 7 | joblib==0.8.4 8 | imbalanced-learn==0.3.3 9 | xgboost==0.72.1 10 | -------------------------------------------------------------------------------- /resample_forest.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Implementation of Forest ensembles with up, down sampling for each tree 3 | ''' 4 | from joblib import Parallel, delayed 5 | from imblearn.under_sampling import RandomUnderSampler as UnderSampler 6 | from imblearn.over_sampling import RandomOverSampler as OverSampler 7 | 8 | from sklearn.base import BaseEstimator, MetaEstimatorMixin, clone 9 | from sklearn.tree import DecisionTreeClassifier, ExtraTreeClassifier 10 | from sklearn.utils import check_random_state, as_float_array, _get_n_jobs 11 | 12 | from utils import * 13 | 14 | 15 | MAX_INT = np.iinfo(np.int32).max 16 | 17 | class BootstrapSampler(object): 18 | """A very simple BootstrapSampler having a fit_sample method""" 19 | def __init__(self, random_state=None): 20 | self.random_state = random_state 21 | 22 | def fit_sample(self, X, y): 23 | n_samples = X.shape[0] 24 | random_instance = check_random_state(self.random_state) 25 | sample_indices = random_instance.randint(0, n_samples, n_samples) 26 | return X[sample_indices], y[sample_indices] 27 | 28 | def _partition_estimators(n_estimators, n_jobs): 29 | """Private function used to partition estimators between jobs.""" 30 | # Compute the number of jobs 31 | n_jobs = min(_get_n_jobs(n_jobs), n_estimators) 32 | 33 | # Partition estimators between jobs 34 | n_estimators_per_job = (n_estimators // n_jobs) * np.ones(n_jobs, dtype=np.int) 35 | n_estimators_per_job[:n_estimators % n_jobs] += 1 36 | starts = np.cumsum(n_estimators_per_job) 37 | 38 | return n_jobs, n_estimators_per_job.tolist(), [0] + starts.tolist() 39 | 40 | 41 | def _parallel_build_trees(tree, forest, X, y): 42 | if forest.sampling is None: 43 | sampler = BootstrapSampler(random_state=tree.random_state) 44 | elif forest.sampling == 'up': 45 | sampler = OverSampler(random_state=tree.random_state) 46 | elif forest.sampling == 'down': 47 | sampler = UnderSampler(random_state=tree.random_state) 48 | 49 | X_sample, y_sample = sampler.fit_sample(X, y) 50 | tree.fit(X_sample, y_sample, check_input=False) 51 | return tree 52 | 53 | def _parallel_helper(obj, methodname, *args, **kwargs): 54 | """Private helper to workaround Python 2 pickle limitations""" 55 | return getattr(obj, methodname)(*args, **kwargs) 56 | 57 | 58 | class ResampleForestClassifier(BaseEstimator, MetaEstimatorMixin): 59 | """docstring for ResampleForestClassifier""" 60 | def __init__(self, base_estimator, 61 | n_estimators=10, 62 | sampling=None, 63 | n_jobs=1, 64 | random_state=None, 65 | verbose=False, 66 | **sampler_kwargs 67 | ): 68 | 69 | self.base_estimator = base_estimator 70 | self.n_estimators = n_estimators 71 | self.sampling = sampling 72 | self.n_jobs = n_jobs 73 | self.random_state = random_state 74 | self.verbose = verbose 75 | 76 | self.estimators_ = [] 77 | 78 | 79 | def fit(self, X, y): 80 | random_state = check_random_state(self.random_state) 81 | trees = [] 82 | for i in range(self.n_estimators): 83 | tree = clone(self.base_estimator) 84 | tree.set_params(random_state=random_state.randint(MAX_INT)) 85 | trees.append(tree) 86 | 87 | trees = Parallel(n_jobs=self.n_jobs, verbose=self.verbose, backend='threading')( 88 | delayed(_parallel_build_trees)( 89 | t, self, X, y) for t in trees 90 | ) 91 | # Collect trained trees 92 | self.estimators_.extend(trees) 93 | # 94 | self.classes_ = np.unique(y) 95 | return self 96 | 97 | def predict_proba(self, X): 98 | # Assign chunk of trees to jobs 99 | n_jobs, _, _ = _partition_estimators(self.n_estimators, self.n_jobs) 100 | 101 | # Parallel loop 102 | all_proba = Parallel(n_jobs=n_jobs, verbose=self.verbose, backend='threading')( 103 | delayed(_parallel_helper)( 104 | e, 'predict_proba', X) 105 | for e in self.estimators_) 106 | 107 | # Reduce 108 | proba = all_proba[0] 109 | for j in range(1, len(all_proba)): 110 | proba += all_proba[j] 111 | 112 | proba /= len(self.estimators_) 113 | return proba 114 | 115 | def predict(self, X): 116 | proba = self.predict_proba(X) 117 | return self.classes_.take(np.argmax(proba, axis=1), axis=0) 118 | 119 | 120 | -------------------------------------------------------------------------------- /utils.py: -------------------------------------------------------------------------------- 1 | import sys 2 | import numpy as np 3 | RNG = 10 4 | np.random.seed(RNG) 5 | import pandas as pd 6 | 7 | from sklearn.utils import resample 8 | from sklearn.datasets import make_classification 9 | from sklearn.preprocessing import LabelEncoder 10 | from sklearn.decomposition import PCA 11 | 12 | from imblearn.under_sampling import RandomUnderSampler as UnderSampler 13 | from imblearn.over_sampling import RandomOverSampler as OverSampler 14 | 15 | 16 | import matplotlib.pyplot as plt 17 | from matplotlib import rcParams 18 | rcParams['pdf.fonttype'] = 42 ## Output Type 3 (Type3) or Type 42 (TrueType) 19 | rcParams['font.sans-serif'] = 'Arial' 20 | import seaborn as sns 21 | sns.set_style("whitegrid") 22 | sns.set_context('talk') 23 | 24 | 25 | COLORS10 = [ 26 | '#1f77b4', 27 | '#ff7f0e', 28 | '#2ca02c', 29 | '#d62728', 30 | '#9467bd', 31 | '#8c564b', 32 | '#e377c2', 33 | '#7f7f7f', 34 | '#bcbd22', 35 | '#17becf', 36 | ] 37 | 38 | ## Data loaders 39 | def load_synthetic_data(): 40 | X, y = make_classification(n_classes=2, class_sep=2, weights=[0.95, 0.05], 41 | n_informative=2, n_redundant=5, flip_y=0.05, 42 | n_features=50, n_clusters_per_class=1, 43 | n_samples=1000, random_state=RNG) 44 | return X, y 45 | 46 | def load_titanic(): 47 | titanic = pd.read_csv('datasets/Titanic/train.csv') 48 | ## Process features 49 | from sklearn.preprocessing import LabelEncoder 50 | le = LabelEncoder() 51 | for col in ['Sex', 'Cabin', 'Embarked']: 52 | titanic[col] = le.fit_transform(titanic[col]) 53 | 54 | ## Split df into X and y and convert to numpy.array 55 | X = titanic.drop(['PassengerId', 'Survived', 'Name', 'Ticket'], axis=1).fillna(-1).values 56 | y = titanic['Survived'].values 57 | print X.shape, y.shape 58 | return X, y 59 | 60 | def load_wpbc(): 61 | bc = pd.read_csv('datasets/wpbc.data', 62 | names=['ID', 'outcome'] + ['Attr%s'%i for i in range(33)]) 63 | bc = bc.replace('?', -1) 64 | ## Split df into X and y and convert to numpy.array 65 | X = bc.drop(['ID', 'outcome'], axis=1) 66 | y = bc['outcome'].map({'N':0, 'R':1}) 67 | 68 | X = X.values 69 | y = y.values 70 | return X, y 71 | 72 | def load_proteomics(): 73 | proteome = pd.read_csv('datasets/Harmonizome/gene_attribute_matrix_cleaned.txt.gz', 74 | sep='\t', compression='gzip', skiprows=2) 75 | ## Load HGNC gene family 76 | gene_family = pd.read_csv('datasets/Harmonizome/HGNC_gene_family.txt',sep='\t') 77 | # Left join with proteome data 78 | gene_family = gene_family[['Approved Symbol', 'Gene family description']] 79 | gene_family.set_index('Approved Symbol', inplace=True) 80 | 81 | proteome = proteome.drop(['UniprotAcc', 'GeneID/Brenda Tissue Ontology BTO:'], axis=1) 82 | proteome.set_index('GeneSym', inplace=True) 83 | 84 | proteome = proteome.merge(gene_family, left_index=True, right_index=True, how='inner') 85 | 86 | # Split X and y 87 | X = proteome.drop(['Gene family description'], axis=1) 88 | X = X.values 89 | y = proteome['Gene family description'] 90 | y = map(lambda x: 'kinase' in x.lower(), y) 91 | y = np.array(y, dtype=np.int64) 92 | return X, y 93 | 94 | def pca_plot(X, y): 95 | pca = PCA(n_components = 2) 96 | X_pc = pca.fit_transform(X) 97 | 98 | fig, ax = plt.subplots() 99 | mask = y==0 100 | ax.scatter(X_pc[mask, 0], X_pc[mask, 1], color=COLORS10[0], label='Class 0', alpha=0.5 ,s=20) 101 | ax.scatter(X_pc[~mask, 0], X_pc[~mask, 1], color=COLORS10[1], label='Class 1', alpha=0.5 ,s=20) 102 | ax.set_xlabel('PC1') 103 | ax.set_ylabel('PC2') 104 | ax.legend(loc='best') 105 | return fig 106 | 107 | 108 | --------------------------------------------------------------------------------