{ "cells": [ { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/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", " \"`IPython.html.widgets` has moved to `ipywidgets`.\", ShimWarning)\n" ] } ], "source": [ "import os, sys, csv, gzip\n", "import numpy as np\n", "import pandas as pd\n", "import scipy.sparse as sp\n", "from scipy import io\n", "\n", "import matplotlib.pyplot as plt\n", "from matplotlib import rcParams\n", "rcParams['pdf.fonttype'] = 42 ## Output Type 3 (Type3) or Type 42 (TrueType)\n", "rcParams['font.sans-serif'] = 'Arial'\n", "%matplotlib inline\n", "\n", "from plots import COLORS10, enlarge_tick_fontsize\n", "import seaborn as sns\n", "sns.set_style('whitegrid')\n", "\n", "from sklearn.cross_validation import (StratifiedKFold, cross_val_score)\n", "from sklearn.metrics import *\n", "from sklearn.decomposition import TruncatedSVD\n", "from sklearn import ensemble\n", "from sklearn.pipeline import Pipeline\n", "import xgboost as xgb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 1. Prepare the gene/feature attribute matrices and target class to for supervised machine learning\n", "\n", "Load known Adhesome components from file" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(232, 7)\n" ] }, { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
Official SymbolGene IDProtein nameSwiss-Prot IDSynonymsFunctional CategoryFA
0ACTN187ActininP12814alpha-actininActin regulationIntrinsic Proteins
1CFL11072cofilinP23528CFLActin regulationIntrinsic Proteins
2CORO1B57175coronin 1BQ9BR76coronin-2Actin regulationIntrinsic Proteins
3CTTN2017CortactinQ14247EMS1, AmplaxinActin regulationIntrinsic Proteins
4FLNA2316FilaminP21333endothelial actin-binding protein, ABP-280, al...Actin regulationIntrinsic Proteins
\n", "
" ], "text/plain": [ " Official Symbol Gene ID Protein name Swiss-Prot ID \\\n", "0 ACTN1 87 Actinin P12814 \n", "1 CFL1 1072 cofilin P23528 \n", "2 CORO1B 57175 coronin 1B Q9BR76 \n", "3 CTTN 2017 Cortactin Q14247 \n", "4 FLNA 2316 Filamin P21333 \n", "\n", " Synonyms Functional Category \\\n", "0 alpha-actinin Actin regulation \n", "1 CFL Actin regulation \n", "2 coronin-2 Actin regulation \n", "3 EMS1, Amplaxin Actin regulation \n", "4 endothelial actin-binding protein, ABP-280, al... Actin regulation \n", "\n", " FA \n", "0 Intrinsic Proteins \n", "1 Intrinsic Proteins \n", "2 Intrinsic Proteins \n", "3 Intrinsic Proteins \n", "4 Intrinsic Proteins " ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_labels = pd.read_csv('../data/components.csv')\n", "print df_labels.shape\n", "df_labels.head()" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "These files below were downloaded from [Harmonizome](http://amp.pharm.mssm.edu/Harmonizome/) as the features for genes to predict whether they are adhesome components. \n", "\n", "There are two types datasets: continues and binary. Continues datasets were standardized. " ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": true }, "outputs": [], "source": [ "filenames = [\n", " 'InterPro_gene_attribute_matrix.txt.gz', \n", " 'ENCODE-TF_gene_attribute_matrix.txt.gz',\n", " 'CCLE-GE_gene_attribute_matrix_standardized.txt.gz',\n", " 'Allen-adult-brain_gene_attribute_matrix_standardized.txt.gz',\n", " 'Allen-dev-brain_gene_attribute_matrix_standardized.txt.gz'\n", " ]\n", "basenames = [f.split('_')[0] for f in filenames]\n", "are_continues = ['_standardized' in f for f in filenames]" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": true }, "outputs": [], "source": [ "def read_gene_attribute_matrix(fn):\n", "\t'''\n", "\tReads a gzipped file downloaded from Harmonizome into a pandas.DataFrame,\n", "\twith GeneSym as index. \n", "\t'''\n", "\twith gzip.open(fn) as f:\n", "\t\treader = csv.reader(f, delimiter='\\t')\n", "\t\theader = reader.next()\n", "\t\theader[0] = 'GeneSym'\n", "\t\t# Skip line 2, 3\n", "\t\treader.next()\n", "\t\treader.next()\n", "\n", "\t\t# Remove the second and third columns which are meta data for GeneSym\n", "\t\theader[1:3] = []\n", "\n", "\t\ti = 0\n", "\t\tdf = []\n", "\n", "\t\tif '_standardized' in fn: # continues\n", "\t\t\tfor row in reader:\n", "\t\t\t\trow[1:3] = []\n", "\t\t\t\trow[1:] = map(float, row[1:])\n", "\t\t\t\tdf.append(dict(zip(header, row)))\n", "\t\t\t\ti += 1\n", "\t\t\t\tif i % 2000 == 0:\n", "\t\t\t\t\tprint i\n", "\t\t\tdf = pd.DataFrame().from_records(df)[header]\n", "\t\t\tdf.set_index('GeneSym', inplace=True, verify_integrity=True)\n", "\t\t\t\t\t\n", "\t\telse: # convert values to int and make sparse df\n", "\t\t\tfor row in reader:\n", "\t\t\t\trow[1:3] = []\n", "\t\t\t\trow[1:] = map(lambda x: int(float(x)), row[1:])\n", "\n", "\t\t\t\td = {h: v for h, v in zip(header, row) if v != 0}\n", "\t\t\t\tdf.append(d)\n", "\t\t\t\ti += 1\n", "\t\t\t\tif i % 2000 == 0:\n", "\t\t\t\t\tprint i\n", "\t\t\tdf = pd.DataFrame().from_records(df)[header]\\\n", "\t\t\t\t.set_index('GeneSym', verify_integrity=True)\\\n", "\t\t\t\t.to_sparse(fill_value=0)\n", "\t\t\n", "\treturn df" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2000\n", "4000\n", "6000\n", "8000\n", "10000\n", "12000\n", "14000\n", "16000\n", "18000\n", "InterPro_gene_attribute_matrix.txt.gz (18002, 11015)\n", "2000\n", "4000\n", "6000\n", "8000\n", "10000\n", "12000\n", "14000\n", "16000\n", "18000\n", "20000\n", "22000\n", "ENCODE-TF_gene_attribute_matrix.txt.gz (22845, 1679)\n", "2000\n", "4000\n", "6000\n", "8000\n", "10000\n", "12000\n", "14000\n", "16000\n", "18000\n", "CCLE-GE_gene_attribute_matrix_standardized.txt.gz (18046, 1037)\n", "2000\n", "4000\n", "6000\n", "8000\n", "10000\n", "12000\n", "14000\n", "16000\n", "Allen-adult-brain_gene_attribute_matrix_standardized.txt.gz (17979, 414)\n", "2000\n", "4000\n", "6000\n", "8000\n", "10000\n", "12000\n", "14000\n", "16000\n", "Allen-dev-brain_gene_attribute_matrix_standardized.txt.gz (17241, 492)\n" ] } ], "source": [ "## Parse data files downloaded from Harmonizome \n", "dfs = []\n", "for fn in filenames:\n", " df = read_gene_attribute_matrix('../data/%s' % fn)\n", " print fn, df.shape\n", " dfs.append(df)" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(13464, 14637)\n" ] } ], "source": [ "## INNER JOIN all feature dfs \n", "df_joined = reduce(lambda a, b: pd.merge(a, b, left_index=True, right_index=True, how='inner'), \n", " dfs)\n", "print df_joined.shape" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "216\n", "(13464, 1)\n" ] }, { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
y
GeneSym
NUSAP10
WEE10
BUB1B0
ASPM0
TTK0
\n", "
" ], "text/plain": [ " y\n", "GeneSym \n", "NUSAP1 0\n", "WEE1 0\n", "BUB1B 0\n", "ASPM 0\n", "TTK 0" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "## Create y \n", "RNG = 2016\n", "y = np.in1d(df_joined.index, df_labels['Official Symbol']).astype(np.int8)\n", "print y.sum()\n", "## Make CV\n", "cv = StratifiedKFold(y, n_folds=3, shuffle=True, random_state=RNG)\n", "## Export y\n", "df_labels = pd.DataFrame({'y': y, 'GeneSym': df_joined.index}).set_index('GeneSym')\n", "print df_labels.shape\n", "df_labels.to_csv('../data/Adhesomes.csv')\n", "df_labels.head()" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": true }, "outputs": [], "source": [ "## Keep only the shared genes across the 4 datasets\n", "dfs = [df.ix[df_joined.index] for df in dfs]" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": true }, "outputs": [], "source": [ "## Export processed matrices in dfs\n", "feature_names = {} # To store feature names\n", "i = 0\n", "for basename, df in zip(basenames, dfs):\n", " feature_names[basename] = df.columns.tolist()\n", " if are_continues[i]:\n", " np.save('../data/%s_shared' % basename, df.values)\n", " else: # sparse matrix\n", " io.mmwrite('../data/%s_shared.mtx' % basename, sp.csr_matrix(df.values))\n", " i += 1\n", "\n", "del df_joined\n", "del dfs, df" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 2. Load preprocessed matrices and perform classifications" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Number of known adhesome components: 216\n", "Ratio of negative labels over positive labels: 61.3333\n" ] } ], "source": [ "# Load from matrices files generated above\n", "Xs = []\n", "for i, basename in enumerate(basenames):\n", " if are_continues[i]:\n", " Xs.append(np.load('../data/%s_shared.npy' % basename))\n", " else:\n", " Xs.append(io.mmread('../data/%s_shared.mtx' % basename).tocsr())\n", "\n", "df_labels = pd.read_csv('../data/Adhesomes.csv')\n", "y = df_labels['y'].values\n", "ratio = float(np.sum(y == 0)) / np.sum(y==1)\n", "print 'Number of known adhesome components: %d' % y.sum()\n", "print 'Ratio of negative labels over positive labels: %.4f' % ratio" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Perform dimentionality reduction using `TruncatedSVD` for all the matrices" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "collapsed": false }, "outputs": [], "source": [ "all_loadings = [] # collect loading matrices from SVD\n", "for i, basename in enumerate(basenames):\n", " svd = TruncatedSVD(n_components=60, random_state=RNG)\n", " Xs[i] = svd.fit_transform(Xs[i])\n", " all_loadings.append(svd.components_)\n", "\n", "X_combined = np.hstack(Xs)" ] }, { "cell_type": "code", "execution_count": 13, "metadata": { "collapsed": true }, "outputs": [], "source": [ "## Helper functions for evaluating classifiers\n", "def cross_val_predictions(est, X, y, cv):\n", "\t'''to get out-of-sample predictions and scores'''\n", "\ty_preds = np.zeros(y.shape)\n", "\ty_probas = np.zeros(y.shape)\n", "\tfor train_idx, valid_idx in cv:\n", "\t\tprint X[train_idx].shape, y[train_idx].shape\n", "\t\test.fit(X[train_idx], y[train_idx])\n", "\t\ty_preds[valid_idx] = est.predict(X[valid_idx])\n", "\t\ty_probas[valid_idx] = est.predict_proba(X[valid_idx])[:,1]\n", "\treturn y_preds, y_probas\n", "\n", "\n", "def plot_roc(ests, Xs, y, cv, ax, colors=None, labels=None):\n", "\tall_labels = []\n", "\ttotal = len(labels)\n", "\n", "\tif type(ests) == list and type(Xs) != list:\n", "\t\ttotal = len(ests)\n", "\t\tXs = [Xs]*total\n", "\telif type(ests) != list and type(Xs) == list:\n", "\t\tests = [ests]*total\n", "\t\n", "\tfor i in range(total):\n", "\t\tX = Xs[i]\n", "\t\test = ests[i]\n", "\t\t\n", "\t\tlabel = labels[i]\n", "\t\tcolor = colors[i]\n", "\t\tall_labels.extend([label] * len(cv))\n", "\n", "\t\ty_preds, y_probas = cross_val_predictions(est, X, y, cv)\n", "\t\tfpr, tpr, _ = roc_curve(y, y_probas)\n", "\t\tscore = auc(fpr, tpr)\n", "\t\tax.plot(fpr, tpr, label=label + ' (AUC=%.3f)' % score, color=color, lw=2)\n", "\n", "\tax.set_xlabel('False Positive Rate', fontsize=16)\n", "\tax.set_ylabel('True Positive Rate', fontsize=16)\n", "\n", "\tenlarge_tick_fontsize(ax, 12)\n", "\tax.legend(loc='lower right')\n", "\treturn" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Estimate the number of rounds of boosting using early stopping for a single feature matrix InterPro: The boosting classifier will stop if the validation score does not improve in 50 rounds." ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0]\ttrain-auc:0.820459+0.0229896\ttest-auc:0.745151+0.0077069\n", "[10]\ttrain-auc:0.93892+0.0027836\ttest-auc:0.841864+0.0117731\n", "[20]\ttrain-auc:0.952989+0.0036986\ttest-auc:0.849968+0.00316156\n", "[30]\ttrain-auc:0.96102+0.00424137\ttest-auc:0.855808+0.00361613\n", "[40]\ttrain-auc:0.966086+0.00261812\ttest-auc:0.8555+0.00428185\n", "[50]\ttrain-auc:0.969816+0.0013973\ttest-auc:0.854981+0.00503997\n", "[60]\ttrain-auc:0.972845+0.00152091\ttest-auc:0.853563+0.00605039\n", "[70]\ttrain-auc:0.975211+0.0018458\ttest-auc:0.852767+0.00601178\n", "[80]\ttrain-auc:0.977073+0.00187863\ttest-auc:0.851972+0.00606561\n", " test-auc-mean test-auc-std train-auc-mean train-auc-std\n", "35 0.856751 0.002450 0.963063 0.003304\n", "36 0.856716 0.003180 0.963542 0.002999\n", "37 0.856693 0.002257 0.964056 0.003098\n", "38 0.855968 0.001767 0.964853 0.002845\n", "39 0.856858 0.004342 0.965392 0.002660\n" ] } ], "source": [ "dtrain = xgb.DMatrix(Xs[0], label=y)\n", "\n", "param = {\n", " 'max_depth':10, 'eta':0.05, 'silent':1, 'objective':'binary:logistic',\n", " 'subsample': 0.4, 'colsample_bytree': 0.6,\n", " 'min_child_weight': 50,\n", " 'scale_pos_weight': ratio,\n", " 'nthread': 6\n", "}\n", "\n", "num_round = 5000\n", "scores = xgb.cv(param, dtrain, num_round, \n", " folds=cv,\n", " early_stopping_rounds=50,\n", " metrics='auc', seed=RNG,\n", " verbose_eval=10)\n", "\n", "print scores.tail()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Estimate the number of rounds of boosting using early stopping for the combined feature matrix." ] }, { "cell_type": "code", "execution_count": 15, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[0]\ttrain-auc:0.81481+0.00187584\ttest-auc:0.72085+0.0264555\n", "[10]\ttrain-auc:0.964683+0.00209533\ttest-auc:0.845875+0.0139989\n", "[20]\ttrain-auc:0.979513+0.00218351\ttest-auc:0.855574+0.00475015\n", "[30]\ttrain-auc:0.987437+0.00264669\ttest-auc:0.857632+0.00750839\n", "[40]\ttrain-auc:0.991936+0.00301162\ttest-auc:0.856888+0.00569661\n", "[50]\ttrain-auc:0.994006+0.0026162\ttest-auc:0.856431+0.00527264\n", "[60]\ttrain-auc:0.99581+0.00202458\ttest-auc:0.854646+0.00611534\n", "[70]\ttrain-auc:0.99678+0.00180488\ttest-auc:0.857454+0.00583333\n", "[80]\ttrain-auc:0.997784+0.00116644\ttest-auc:0.859574+0.00635607\n", "[90]\ttrain-auc:0.998488+0.000746378\ttest-auc:0.86078+0.00654498\n", "[100]\ttrain-auc:0.998812+0.000706678\ttest-auc:0.86345+0.00309085\n", "[110]\ttrain-auc:0.999146+0.000535133\ttest-auc:0.865704+0.00372815\n", "[120]\ttrain-auc:0.999369+0.000407981\ttest-auc:0.865754+0.00513564\n", "[130]\ttrain-auc:0.999508+0.00032021\ttest-auc:0.866895+0.00405058\n", "[140]\ttrain-auc:0.999609+0.000283679\ttest-auc:0.867821+0.00577482\n", "[150]\ttrain-auc:0.999665+0.000224317\ttest-auc:0.868358+0.00396938\n", "[160]\ttrain-auc:0.999714+0.000197435\ttest-auc:0.86945+0.00463421\n", "[170]\ttrain-auc:0.999764+0.000184588\ttest-auc:0.867881+0.00504133\n", "[180]\ttrain-auc:0.99979+0.000183194\ttest-auc:0.865975+0.00461011\n", "[190]\ttrain-auc:0.999819+0.000146981\ttest-auc:0.866868+0.00410002\n", "[200]\ttrain-auc:0.999842+0.000113291\ttest-auc:0.866867+0.00400328\n", " test-auc-mean test-auc-std train-auc-mean train-auc-std\n", "155 0.869587 0.003839 0.999685 0.000215\n", "156 0.869491 0.003843 0.999693 0.000212\n", "157 0.869433 0.003842 0.999691 0.000223\n", "158 0.869687 0.003719 0.999699 0.000208\n", "159 0.869809 0.003790 0.999698 0.000210\n" ] } ], "source": [ "dtrain = xgb.DMatrix(X_combined, label=y)\n", "\n", "param = {\n", " 'max_depth':12, 'eta':0.05, 'silent':1, 'objective':'binary:logistic',\n", " 'subsample': 0.4, 'colsample_bytree': 0.4,\n", " 'min_child_weight': 50,\n", " 'scale_pos_weight': ratio,\n", " 'nthread': 6\n", "}\n", "\n", "num_round = 5000\n", "scores = xgb.cv(param, dtrain, num_round, \n", " folds=cv,\n", " early_stopping_rounds=50,\n", " metrics='auc', seed=RNG,\n", " verbose_eval=10)\n", "\n", "print scores.tail()\n" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Plot the ROC curves to evaluate the predictive performance of the GBM classifiers" ] }, { "cell_type": "code", "execution_count": 16, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 60) (8976,)\n", "(8976, 300) (8976,)\n", "(8976, 300) (8976,)\n", "(8976, 300) (8976,)\n" ] }, { "data": { "image/png": "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\nxx9/zNatW+WykJAQpk2bhqOjIw4ODvTp04cTJ068VT+A6sUgY18A+Pv7880339C+fXsaNGhA165d\nWbVqFa9fv5brODk5ERYWxqFDh+T7yxiyDAgIYMKECTRv3pwGDRowZMgQ/Pz83tpOQdEiRiSCd0pq\naiqpqanyZ4VCga6uLqGhobRs2ZLhw4dTpkwZbt26hbu7O1FRUUybNi3L9mbMmMHTp0+ZOXMmlpaW\nREREcOnSJRITE+Xrubq6EhQUxJdffkmdOnW4ceMGP//8M9HR0cycOTPP9xASEgKo1IITEhJwcXEh\nNjaWadOmYWlpyYEDB5gxYwZJSUkMGjQoV3ZmZsGCBUyfPh2lUsnChQuBrHM+9OnTh6lTpxIUFKSm\nzHv48GF0dHRwdnYG4OnTpwwaNAgzMzPc3NwwMTHB29ubr7/+mnXr1uHk5JTnvnjy5AmAmoz406dP\nsbW1pU+fPhgbG3P//n1+/vlnQkJCWLlyJQDr1q1j7Nix1K1bl6+//hqAihUrAnDnzh2GDRuGvb09\n33//Pfr6+uzevZvRo0eze/du7O3t82ynoIgpKLVJQcli3759Guqitra20tChQzXqKpVKKSUlRfr5\n55+lZs2aqR375JNP1HJKN2zYUNq+fXuW1/Xy8pJsbW2lK1euqJWvX79esre3lyIjI7O129bWVlq5\ncqWUkpIiJSUlSdevX5e6du0qNWzYUAoPD5e2b98u2draSn/99ZfaeaNGjZIcHR0lpVKZKztDQkIk\nW1tbycvLSy4bPny41v5J78snT55IkiRJiYmJUpMmTaQVK1ao1evVq5c0btw4+fPs2bMlR0dH6dWr\nV2r1Ro8eLfXu3Tvbfrh06ZJka2srnT9/XkpJSZFiY2Ol48ePS40bN5aGDx+e5Xnpf8v9+/dLdnZ2\natf+5JNPpOnTp2ucM2LECKl79+5SSkqKXJaWliZ169ZN+uKLL7K1U/B+IkYkgnfKunXr1Cbb09+y\nw8PDWbt2LefOnePFixfyqEWhUBAZGZll/nQHBwd+/fVXlEolLVq0oE6dOmrJec6dO0flypVp1KiR\n2kioVatWrF69mhs3buT4Jv7LL7/wyy+/yJ9tbW3ZuHEj5ubmXLlyBUtLS5o1a6Z2jrOzMxcvXiQw\nMJDatWvnaGd+MDAwoEuXLhw6dIipU6cCqoRD9+7dY/z48XK9c+fO0b59e4yMjNT6onXr1ixfvpz4\n+PgcM925urqqfXZ0dGT16tVqZXFxcaxfv55jx47x7NkztWsFBwfToEGDLNtPSkrCz8+PCRMmAKid\n6+joyOHDh7O1T/B+IhyJ4J1Sp04djcl2pVLJxIkTiYiI4KuvvqJmzZoYGBhw/PhxNmzYoBZbz8zq\n1atZu3Ytv/76K0uWLMHc3JzBgwfzxRdfoFAoiIqKIiwsTGs4RKFQEB0dnaPNAwYMYMiQIejq6mJl\nZaUWxomOjsbc3FzjnPQVVent52Rnfunduzf79u3j8uXLtGjRggMHDmBkZMSnn34q14mKisLLywsv\nLy+N8xUKBa9evcrRkcyfP5/69esTExPDnj178PX15fr163To0EGuM3v2bC5evMikSZOoW7cuZcqU\n4ebNmyxcuJDk5ORs24+OjiYtLY1169axbt06rXYKPjyEIxEUOI8fP+bOnTssX75cjucDnDx5Msdz\nTUxM+O677/juu+8IDg7Gy8sLd3d3TExMGDJkCBUqVKBq1ar89NNPWs+vXLlyjtcwNzfPMi5fvnx5\ngoODNcojIiLk47mxM780b96cypUrc/DgQZo3b87hw4fp0qULpUuXlutUrFiRpk2bMnbsWK1taHOI\nmalRo4bcF46OjowYMYLZs2fj6+tLuXLleP36NadOneLrr7/GxcVFPi8gICBX91GuXDl0dHQYNmwY\nffr0ydU5gvcf4UgEBU5SUhIAurq6cllKSgqHDh3K0xtojRo1mDJlCrt37yYwMBCAdu3acfz4ccqU\nKVMg+1WaN2/OsWPHuHbtGo0bN5bLDx8+jJmZGTY2NrmyUxulS5fm5cuXubbF2dmZnTt38umnnxIe\nHq6RMrZt27Zcv34dGxubd7b/xc3Njb59+/Lrr78yZcoUOUVrxr8loHUUVLp0aflvn07ZsmVp0qQJ\nAQEBfPzxx2IEUkwQjkRQ4NSqVYvKlSuzevVqdHV10dXVZevWrSgUimyX6MbGxjJq1Ch69erFRx99\nRKlSpTh58iTR0dG0bt0aUD1cPT09GTVqFGPGjMHW1pbk5GRCQkI4ffo069atw8DA4K1t79evH9u2\nbePrr79m8uTJWFhYcOjQIS5cuMCiRYtQKBS5slMbNjY27Nq1Cx8fH6pVq4aRkREfffRRlvV79+7N\nL7/8wvz586lcuTLNmzdXO/7NN98wcOBAhg0bxvDhw6lcuTIxMTHcv3+f0NBQlixZkuf7t7Ozo3Pn\nzmzbto2RI0diYmJCw4YN2bx5M+bm5lSsWJF9+/YRHh6u9f78/Pz43//+h6mpKSYmJlSpUoXZs2cz\nbNgwXF1dGTBgAGZmZrx8+ZK7d++iVCqzXcUneD8RjkTwzsjq7bJUqVL8/PPPLFy4kJkzZ1KhQgX6\n9++PpaUl3333XZbt6evrY29vz549e3jy5Ak6OjrUrFmTFStWyBPoenp6bNq0CQ8PD/744w9CQ0Mp\nW7Ys1tbWtG/fnlKlSuXrnsqUKcOOHTtYvnw5K1asID4+npo1a6qF6XJjpzbGjh3Lw4cPmTt3LgkJ\nCTRv3pxt27YB2vuyZs2a1KtXjzt37jBu3DiN41ZWVuzbtw93d3dWrlxJVFQUFSpUkJfq5kRWf79v\nvvmG48ePs3HjRmbOnMmKFStYsGABCxcuxMDAgO7du9O/f395Aj2dqVOnMm/ePCZPnkxSUhJ9+/bl\nhx9+4OOPP2bv3r2sW7eO77//ntjYWExMTLC3t2fw4ME52il4/xA52wUCgUCQL8TOdoFAIBDkC+FI\nBAKBQJAvhCMRCAQCQb4QjkQgEAgE+UI4EoFAIBDkC+FIBAKBQJAvhCMRCAQCQb4QjkQgEAgE+eL/\nAb/d4FAuftJ8AAAAAElFTkSuQmCC\n", "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "Xs.append(X_combined)\n", "basenames.append('Combined')\n", "\n", "# optimized GBM classifiers\n", "xgbc = xgb.XGBClassifier(seed=RNG, n_estimators=39, learning_rate=0.05,\n", " max_depth=10, colsample_bytree=0.6, subsample=0.4, min_child_weight=50,\n", " gamma=0, max_delta_step=0, nthread=6, silent=True, scale_pos_weight=ratio)\n", "\n", "xgbc2 = xgb.XGBClassifier(seed=RNG, n_estimators=159, learning_rate=0.05,\n", " max_depth=12, colsample_bytree=0.4, subsample=0.4, min_child_weight=50,\n", " gamma=0, max_delta_step=0, nthread=6, silent=True, scale_pos_weight=ratio)\n", "\n", "clfs = [xgbc] * 5 + [xgbc2]\n", "\n", "fig, ax = plt.subplots(figsize=(6,6))\n", "plot_roc(clfs, Xs, y, cv, ax, colors=COLORS10, labels=basenames)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 3. Apply the GBM classifier to all the datasets to generate predictions " ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(12117, 300) (12117,)\n", "(12117, 300) (12117,)\n", "(12117, 300) (12117,)\n", "(12117, 300) (12117,)\n", "(12117, 300) (12117,)\n", "(12117, 300) (12117,)\n", "(12118, 300) (12118,)\n", "(12118, 300) (12118,)\n", "(12119, 300) (12119,)\n", "(12119, 300) (12119,)\n" ] } ], "source": [ "RNG = 20160628\n", "xgbc2 = xgb.XGBClassifier(seed=RNG, n_estimators=160, learning_rate=0.05,\n", " max_depth=12, colsample_bytree=0.4, subsample=0.4, min_child_weight=50,\n", " gamma=0, max_delta_step=0, nthread=8, silent=True, scale_pos_weight=ratio)\n", "\n", "cv = StratifiedKFold(y, n_folds=10, shuffle=True, random_state=RNG)\n", "\n", "## Get out-of-fold predictions\n", "y_preds, y_probas = cross_val_predictions(xgbc2, X_combined, y, cv)\n", "\n", "## Get predictions on training fold\n", "xgbc2.fit(X_combined, y)\n", "y_probas_on_train = xgbc2.predict_proba(X_combined)[:, 1]\n" ] }, { "cell_type": "code", "execution_count": 18, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
GeneSymyOOF_predsOOF_probastrain_probas
0NUSAP1000.0245950.027813
1WEE1000.0408200.036656
2BUB1B000.0524950.024476
3ASPM000.0508910.046398
4TTK000.0929960.039838
\n", "
" ], "text/plain": [ " GeneSym y OOF_preds OOF_probas train_probas\n", "0 NUSAP1 0 0 0.024595 0.027813\n", "1 WEE1 0 0 0.040820 0.036656\n", "2 BUB1B 0 0 0.052495 0.024476\n", "3 ASPM 0 0 0.050891 0.046398\n", "4 TTK 0 0 0.092996 0.039838" ] }, "execution_count": 18, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_labels['OOF_preds'] = y_preds\n", "df_labels['OOF_probas'] = y_probas\n", "df_labels['train_probas'] = y_probas_on_train\n", "\n", "df_labels.head()" ] }, { "cell_type": "code", "execution_count": 19, "metadata": { "collapsed": true }, "outputs": [], "source": [ "df_labels.to_csv('../XGB160_on_combined_predictions.csv')" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# 4. Interpret the classifier by feature importance" ] }, { "cell_type": "code", "execution_count": 20, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "(300,)\n" ] } ], "source": [ "## Get the feature_importances_ from the fitted GBM\n", "feature_importances = xgbc2.feature_importances_\n", "print feature_importances.shape" ] }, { "cell_type": "code", "execution_count": 21, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "There are 14637 features across these datasets used for the prediction\n" ] } ], "source": [ "## Count the number of original features\n", "n_features = sum(map(len, feature_names.values()))\n", "print 'There are %d features across these datasets used for the prediction' % n_features" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Map feature importances on the SVD components back to original feature space by dot product between the feature importance vector and the loading matrix:" ] }, { "cell_type": "code", "execution_count": 22, "metadata": { "collapsed": false }, "outputs": [], "source": [ "all_feature_names = []\n", "all_feature_fis = []\n", "datasets = []\n", "for i, basename in enumerate(basenames[:-1]):\n", " fi = feature_importances[i*60:(i+1)*60]\n", " loadings = all_loadings[i]\n", " original_feature_fis = np.dot(fi, loadings)\n", " original_feature_names = feature_names[basename]\n", " \n", " datasets.extend([basename] * len(original_feature_names))\n", " all_feature_fis.extend( original_feature_fis.tolist() )\n", " all_feature_names.extend( original_feature_names )\n", "\n", "# Create a DataFrame of feature importances\n", "df_feature_importances = pd.DataFrame({\n", " 'dataset': datasets,\n", " 'feature': all_feature_names, \n", " 'feature_importance': all_feature_fis}) " ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Examine the most predictive features for adhesome components:" ] }, { "cell_type": "code", "execution_count": 23, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datasetfeaturefeature_importance
10351InterProUbiquitin-related domain0.008553
7372InterProProtein kinase-like domain0.007375
875InterProArmadillo-type fold0.007230
7369InterProProtein kinase domain0.006197
2466InterProDeath-like domain0.005954
1214InterProC2 domain0.005682
14582Allen-dev-brainprimary auditory cortex (core)_3 yrs_M_129800.005443
4473InterProImmunoglobulin-like fold0.005171
6930InterProPleckstrin homology-like domain0.005047
10811InterProZinc finger, C2H2-like0.004638
7370InterProProtein kinase, ATP binding site0.004525
1915InterProConcanavalin A-like lectin/glucanase domain0.004418
10808InterProZinc finger, C2H20.004306
14004Allen-adult-brainEdinger-Westphal nucleus, right0.004265
10864InterProZinc finger, RING/FYVE/PHD-type0.004254
10862InterProZinc finger, RING-type0.003937
10779InterProZinc finger C2H2-type/integrase DNA-binding do...0.003906
874InterProArmadillo-like helical0.003886
14150Allen-dev-brainhippocampus (hippocampal formation)_8 pcw_M_130580.003770
3694InterProGalactose-binding domain-like0.003763
\n", "
" ], "text/plain": [ " dataset feature \\\n", "10351 InterPro Ubiquitin-related domain \n", "7372 InterPro Protein kinase-like domain \n", "875 InterPro Armadillo-type fold \n", "7369 InterPro Protein kinase domain \n", "2466 InterPro Death-like domain \n", "1214 InterPro C2 domain \n", "14582 Allen-dev-brain primary auditory cortex (core)_3 yrs_M_12980 \n", "4473 InterPro Immunoglobulin-like fold \n", "6930 InterPro Pleckstrin homology-like domain \n", "10811 InterPro Zinc finger, C2H2-like \n", "7370 InterPro Protein kinase, ATP binding site \n", "1915 InterPro Concanavalin A-like lectin/glucanase domain \n", "10808 InterPro Zinc finger, C2H2 \n", "14004 Allen-adult-brain Edinger-Westphal nucleus, right \n", "10864 InterPro Zinc finger, RING/FYVE/PHD-type \n", "10862 InterPro Zinc finger, RING-type \n", "10779 InterPro Zinc finger C2H2-type/integrase DNA-binding do... \n", "874 InterPro Armadillo-like helical \n", "14150 Allen-dev-brain hippocampus (hippocampal formation)_8 pcw_M_13058 \n", "3694 InterPro Galactose-binding domain-like \n", "\n", " feature_importance \n", "10351 0.008553 \n", "7372 0.007375 \n", "875 0.007230 \n", "7369 0.006197 \n", "2466 0.005954 \n", "1214 0.005682 \n", "14582 0.005443 \n", "4473 0.005171 \n", "6930 0.005047 \n", "10811 0.004638 \n", "7370 0.004525 \n", "1915 0.004418 \n", "10808 0.004306 \n", "14004 0.004265 \n", "10864 0.004254 \n", "10862 0.003937 \n", "10779 0.003906 \n", "874 0.003886 \n", "14150 0.003770 \n", "3694 0.003763 " ] }, "execution_count": 23, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_feature_importances.sort('feature_importance', ascending=False).head(20)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Examine the most predictive features in ENCODE-TF dataset for adhesome components:" ] }, { "cell_type": "code", "execution_count": 24, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
datasetfeaturefeature_importance
11518ENCODE-TFFOXA1_HepG2_hg19_20.003254
11526ENCODE-TFFOXA2_HepG2_hg19_20.003180
12170ENCODE-TFPOLR2AphosphoS5_G1E_mm9_20.003103
11517ENCODE-TFFOXA1_HepG2_hg19_10.003064
12169ENCODE-TFPOLR2AphosphoS5_G1E_mm9_10.002839
\n", "
" ], "text/plain": [ " dataset feature feature_importance\n", "11518 ENCODE-TF FOXA1_HepG2_hg19_2 0.003254\n", "11526 ENCODE-TF FOXA2_HepG2_hg19_2 0.003180\n", "12170 ENCODE-TF POLR2AphosphoS5_G1E_mm9_2 0.003103\n", "11517 ENCODE-TF FOXA1_HepG2_hg19_1 0.003064\n", "12169 ENCODE-TF POLR2AphosphoS5_G1E_mm9_1 0.002839" ] }, "execution_count": 24, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_feature_importances.query('dataset == \"ENCODE-TF\"').sort('feature_importance', ascending=False).head(5)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Write the full feature importance table to a file and provide a link to this file." ] }, { "cell_type": "code", "execution_count": 25, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/html": [ "feature_importances.csv
" ], "text/plain": [ "/Users/zichen/Documents/Zichen_Projects/Adhesome/adhesome-prediction/feature_importances.csv" ] }, "execution_count": 25, "metadata": {}, "output_type": "execute_result" } ], "source": [ "df_feature_importances.to_csv('feature_importances.csv')\n", "\n", "from IPython.display import FileLink\n", "FileLink('feature_importances.csv')" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.6" } }, "nbformat": 4, "nbformat_minor": 0 }