diff --git a/explore/number-of-components/number_of_pca_components.ipynb b/explore/number-of-components/number_of_pca_components.ipynb
new file mode 100644
index 0000000..5491ebf
--- /dev/null
+++ b/explore/number-of-components/number_of_pca_components.ipynb
@@ -0,0 +1,2790 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Explore how many PCA Components to Keep and Hyperparameter Tuning"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Takeaways after running this notebook:\n",
+ "1. The accurace gain by searching over a larger range of n_components seems to be small (~1%-2% gain in testing AUROC on average), even when the range of n_components is selected for each query based on a heuristic around class balance.\n",
+ "2. There is a similar accurace gain when only the largest value in the range is used \n",
+ "2. There is a larger performance gain if the l1_ratio is changed from 0.15 to 0 and the range of alpha is expanded (~5%-7% gain in testing AUROC on average) there isn't much performance gain if these parameters are changed independent of each other."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "__Purpose__\n",
+ "\n",
+ "As described in issue #106 (https://github.com/cognoma/machine-learning/issues/106), searching over a large range of n_components (number of PCA components) causes issues with both speed and memory and may also cause issues with overfitting. This notebook is an attempt to explore the relationship between the number of components returned by PCA, the other hyperparameters and classifier performance (AUROC). Ideally, we will be able to automatically select a range of n_components to search across based on the specifics of the query. The assumption is that for the lower number of positive samples (and/or the less total samples)... the less n-components to include (i.e. a query with only 40 positive samples would use a classifer that does GridSearchCV with n_components = [30, 40, 50] whereas a query with 1,000 positive samples would use a classifier that does GridSearchCV with n_components = [100, 200, 300] _just random numbers for purpose of illustration_). This notebook attempts to provide some basis for selecting the range of n_components.\n",
+ "\n",
+ "\n",
+ "__Assumptions/Notes:__\n",
+ "\n",
+ "This notebook differs from the current classifier in a number of ways including:\n",
+ "1. In this notebook, PCA is performed on the entire training set prior to cross-validation rather than performed on each individual cross-validation split. This is done for simplicity and to save time and memory.\n",
+ "2. In this notebook, the covariates data is not used (for now at least).\n",
+ "\n",
+ "\n",
+ "__To Do:__\n",
+ "\n",
+ "1. Evaluate queries that only use a subset of diseases or a single disease.\n",
+ "2. Try to include the covariates data and see how that affects things.\n",
+ "3. Some additional evaluation and... select a final setup."
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Outline:\n",
+ "1. Imports, constants and load the data\n",
+ "2. Test Train split and perform PCA\n",
+ "3. Build the querry set\n",
+ "4. Evaluate queries with all samples (i.e. all diseases) and varying number of positives\n",
+ " - a. Define some helper functions\n",
+ " - b. See how the parameters are related using the current setup\n",
+ " - c. Evaluate how changing some of the parameters effects performance\n",
+ "5. TO DO: Evaluate queries that only use a subset of diseases or a single disease\n"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Imports, constants and load the data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import time\n",
+ "\n",
+ "from sklearn.decomposition import PCA\n",
+ "from sklearn.linear_model import SGDClassifier\n",
+ "from sklearn.metrics import roc_auc_score, roc_curve\n",
+ "from sklearn.model_selection import train_test_split, StratifiedKFold\n",
+ "from dask_searchcv import GridSearchCV\n",
+ "from sklearn.pipeline import Pipeline, FeatureUnion\n",
+ "from sklearn.preprocessing import StandardScaler, FunctionTransformer\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import seaborn as sns\n",
+ "from sklearn.feature_selection import SelectKBest\n",
+ "from IPython.display import display"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "RANDOMSEED = 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wall time: 6.22 s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# Load the data\n",
+ "try: \n",
+ " path = os.path.join('download', 'expression-matrix.pkl')\n",
+ " X = pd.read_pickle(path)\n",
+ "except:\n",
+ " path = os.path.join('download', 'expression-matrix.tsv.bz2')\n",
+ " X = pd.read_table(path, index_col=0)\n",
+ "\n",
+ "try:\n",
+ " path = os.path.join('download', 'mutation-matrix.pkl')\n",
+ " y = pd.read_pickle(path)\n",
+ "except:\n",
+ " path = os.path.join('download', 'mutation-matrix.tsv.bz2')\n",
+ " y = pd.read_table(path, index_col=0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2. Test Train split and perform PCA"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# Test Train split\n",
+ "X_train, X_test, y_train_allgenes, y_test_allgenes = train_test_split(X, y, test_size=0.2, random_state=RANDOMSEED)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wall time: 1min 12s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "scaler = StandardScaler()\n",
+ "pca = PCA(n_components = 1000, random_state = RANDOMSEED)\n",
+ "scaler.fit(X_train)\n",
+ "X_train_scaled = scaler.transform(X_train)\n",
+ "pca.fit(X_train_scaled)\n",
+ "X_train = pca.transform(X_train_scaled)\n",
+ "\n",
+ "X_test_scaled = scaler.transform(X_test)\n",
+ "X_test = pca.transform(X_test_scaled)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3. Build the query set"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# List of genes to iterate over (from brankaj's notebook: \n",
+ "# https://github.com/cognoma/machine-learning/blob/master/explore/Classifier_results-different_genes.ipynb)\n",
+ "genes_LungCancer = {\n",
+ " '207': 'AKT1', \n",
+ " '238': 'ALK', \n",
+ " '673': 'BRAF', \n",
+ " '4921':'DDR2',\n",
+ " '1956':'EGFR',\n",
+ " '2064':'ERBB2',\n",
+ " '3845':'KRAS',\n",
+ " '5604':'MAP2K1',\n",
+ " '4893':'NRAS',\n",
+ " '5290':'PIK3CA',\n",
+ " '5728':'PTEN',\n",
+ " '5979':'RET',\n",
+ " # '6016':'RIT1', (removed because too few positives)\n",
+ " '6098':'ROS1',\n",
+ "}\n",
+ "\n",
+ "genes_TumorSuppressors = {\n",
+ " '324': 'APC', \n",
+ " '672': 'BRCA1', \n",
+ " '675': 'BRCA2',\n",
+ " '1029':'CDKN2A',\n",
+ " '1630':'DCC',\n",
+ " '4089':'SMAD4',\n",
+ " '4087':'SMAD2',\n",
+ " '4221':'MEN1',\n",
+ " '4763':'NF1',\n",
+ " '4771':'NF2',\n",
+ " '7157':'TP53', \n",
+ " '5728':'PTEN', \n",
+ " '5925':'RB1',\n",
+ " '7428':'VHL',\n",
+ " '7486':'WRN',\n",
+ " '7490':'WT1',\n",
+ "}\n",
+ "\n",
+ "genes_Oncogenes = {\n",
+ " #'5155':'PDGFB', #growth factor (removed because too few positives)\n",
+ " '5159':'PDGFRB', #growth factor \n",
+ " '3791':'KDR', #receptor tyrosine kinases\n",
+ " '25':'ABL1', #Cytoplasmic tyrosine kinases\n",
+ " '6714':'SRC', #Cytoplasmic tyrosine kinases\n",
+ " '5894':'RAF1',#cytoplasmic serine kinases\n",
+ " '3265':'HRAS',#regulatory GTPases\n",
+ " '4609':'MYC',#Transcription factors\n",
+ " #'2353':'FOS',#Transcription factors (removed because too few positives)\n",
+ " \n",
+ "}\n",
+ "\n",
+ "list_of_genes = (list(genes_LungCancer.keys()) + list(genes_TumorSuppressors.keys()) + \n",
+ " list(genes_Oncogenes.keys()))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "list_of_genes_positives = []\n",
+ "for gene in list_of_genes:\n",
+ " y_temp = y_train_allgenes[gene]\n",
+ " list_of_genes_positives.append(y_temp.value_counts(True)[1]*len(y_train_allgenes))\n",
+ "list_of_genes = [gene for _,gene in sorted(zip(list_of_genes_positives, list_of_genes))]"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 4. Evaluate queries with all samples (i.e. all diseases) and varying number of positives"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 4.a. Define some helper functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def variance_scorer(x, y):\n",
+ " \"\"\" \n",
+ " Get the variance for each column of X.\n",
+ " \n",
+ " Because principal components have decreasing variance\n",
+ " (i.e. PC4 has less variance than PC3 which has less variance\n",
+ " than PC2 etc.), we can use this function in SelectKBest to select\n",
+ " only the top X number of principal components.\n",
+ " \n",
+ " \"\"\"\n",
+ " scores = [np.var(column) for column in x.T]\n",
+ " return scores, np.array([np.NaN]*len(scores))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def evaluate_classifier(X_train, X_test,\n",
+ " y, y_train_allgenes, y_test_allgenes,\n",
+ " list_of_genes,\n",
+ " set_k_range, k_function,\n",
+ " alpha_range, \n",
+ " l1_ratio):\n",
+ " \n",
+ " ''' Run a classifier setup on a set of queries.\n",
+ " \n",
+ " Loop through each query; train and test the classifier using the\n",
+ " hyperparameters input as parameters; populate the metrics dictionary\n",
+ " with some metrics of which parameters were selected and how well\n",
+ " the classifier did for that query.\n",
+ " '''\n",
+ " \n",
+ " # A dictionary to hold the performance metrics.\n",
+ " metrics_dict = {}\n",
+ " \n",
+ " # Loop through each query; train and test the classifer; populate the metrics dictionary.\n",
+ " for gene in list_of_genes:\n",
+ " \n",
+ " # Train and test the classifier.\n",
+ " \n",
+ " y_gene = y[gene]\n",
+ " y_train = y_train_allgenes[gene]\n",
+ " y_test = y_test_allgenes[gene]\n",
+ " num_positives = int(y_gene.value_counts(True)[1]*len(y_gene))\n",
+ " if set_k_range:\n",
+ " k_range = set_k_range\n",
+ " else:\n",
+ " k_range = k_function(num_positives) \n",
+ " # Parameter Sweep for Hyperparameters\n",
+ " param_grid = {\n",
+ " 'select__k': k_range,\n",
+ " 'classify__loss': ['log'],\n",
+ " 'classify__penalty': ['elasticnet'],\n",
+ " 'classify__alpha': alpha_range,\n",
+ " 'classify__l1_ratio': l1_ratio,\n",
+ " }\n",
+ " pipeline = Pipeline(steps=[\n",
+ " ('select', SelectKBest(variance_scorer)),\n",
+ " ('classify', SGDClassifier(random_state=RANDOMSEED, class_weight='balanced'))\n",
+ " ])\n",
+ " cv_pipeline = GridSearchCV(estimator=pipeline, \n",
+ " param_grid=param_grid,\n",
+ " n_jobs=1, \n",
+ " scoring='roc_auc')\n",
+ " cv_pipeline.fit(X=X_train, y=y_train)\n",
+ " y_pred_train = cv_pipeline.decision_function(X_train)\n",
+ " y_pred_test = cv_pipeline.decision_function(X_test)\n",
+ " # Get ROC info.\n",
+ " def get_threshold_metrics(y_true, y_pred):\n",
+ " roc_columns = ['fpr', 'tpr', 'threshold']\n",
+ " roc_items = zip(roc_columns, roc_curve(y_true, y_pred))\n",
+ " roc_df = pd.DataFrame.from_items(roc_items)\n",
+ " auroc = roc_auc_score(y_true, y_pred)\n",
+ " return {'auroc': auroc, 'roc_df': roc_df}\n",
+ " metrics_train = get_threshold_metrics(y_train, y_pred_train)\n",
+ " metrics_test = get_threshold_metrics(y_test, y_pred_test)\n",
+ "\n",
+ " # Populate the metrics dictionary.\n",
+ "\n",
+ " # Get metrics for the classifier.\n",
+ " overfit = metrics_train['auroc'] - metrics_test['auroc']\n",
+ " # Understand how the parameter grid worked... any params at the edge?\n",
+ " if cv_pipeline.best_params_['select__k'] == min(param_grid['select__k']):\n",
+ " n_comp_status = 'min'\n",
+ " elif cv_pipeline.best_params_['select__k'] == max(param_grid['select__k']):\n",
+ " n_comp_status = 'max'\n",
+ " else:\n",
+ " n_comp_status = 'OK'\n",
+ " if cv_pipeline.best_params_['classify__alpha'] == min(param_grid['classify__alpha']):\n",
+ " alpha_status = 'min'\n",
+ " elif cv_pipeline.best_params_['classify__alpha'] == max(param_grid['classify__alpha']):\n",
+ " alpha_status = 'max'\n",
+ " else:\n",
+ " alpha_status = 'OK'\n",
+ " metrics = {'num_positive': num_positives,\n",
+ " 'train_auroc': metrics_train['auroc'], \n",
+ " 'test_auroc': metrics_test['auroc'],\n",
+ " 'n_components': cv_pipeline.best_params_['select__k'], \n",
+ " 'alpha': cv_pipeline.best_params_['classify__alpha'],\n",
+ " 'overfit': overfit,\n",
+ " 'n_comp_status': n_comp_status,\n",
+ " 'alpha_status': alpha_status\n",
+ " }\n",
+ " # Add the metrics to the dictonary.\n",
+ " metrics_dict[gene] = metrics\n",
+ " # Change the metrics dict into a formatted pandas dataframe.\n",
+ " metrics_df = pd.DataFrame(metrics_dict)\n",
+ " metrics_df = metrics_df.T\n",
+ " metrics_df.sort_values(by='num_positive', ascending=True, inplace=True)\n",
+ " metrics_df = metrics_df[['num_positive', 'n_components','n_comp_status', 'alpha', 'alpha_status','train_auroc', 'test_auroc', 'overfit']]\n",
+ " \n",
+ " return(metrics_df)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def display_stats(metrics_df, metrics_df_tocompare = None, verbose = True):\n",
+ " if verbose:\n",
+ " display(metrics_df)\n",
+ " # Summary for metrics_df \n",
+ " metrics_df.loc['mean'] = metrics_df.mean()\n",
+ " metrics_df.loc['median'] = metrics_df.median()\n",
+ " metrics_df_summary = metrics_df.loc[['mean', 'median']]\n",
+ " metrics_df_summary = metrics_df_summary[['num_positive', 'n_components', 'alpha', 'train_auroc', 'test_auroc','overfit']]\n",
+ " display(metrics_df_summary)\n",
+ " if metrics_df_tocompare is not None:\n",
+ " # Summary for metrics_df_tocompare\n",
+ " metrics_df_tocompare.loc['mean'] = metrics_df_tocompare.mean()\n",
+ " metrics_df_tocompare.loc['median'] = metrics_df_tocompare.median()\n",
+ " metrics_df_to_compare_summary = metrics_df_tocompare.loc[['mean', 'median']]\n",
+ " # Evaluate the improvement\n",
+ " mean_testing_auroc_improvement = metrics_df_summary['test_auroc']['mean'] - metrics_df_to_compare_summary['test_auroc']['mean']\n",
+ " median_testing_auroc_improvement = metrics_df_summary['test_auroc']['median'] - metrics_df_to_compare_summary['test_auroc']['median']\n",
+ " mean_overfit_reduction = metrics_df_to_compare_summary['overfit']['mean'] - metrics_df_summary['overfit']['mean']\n",
+ " median_overfit_reduction = metrics_df_to_compare_summary['overfit']['median'] - metrics_df_summary['overfit']['median']\n",
+ " print('Mean testing Auroc improved by {:.2f}%'.format(mean_testing_auroc_improvement*100))\n",
+ " print('Median testing Auroc improved by {:.2f}%'.format(median_testing_auroc_improvement*100))\n",
+ " print('Mean overfitting reduced by {:.1f}%'.format(mean_overfit_reduction*100))\n",
+ " print('Median overfitting reduced by {:.1f}%'.format(median_overfit_reduction*100))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 4.b. See how the parameters are related using the current setup"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "
\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " n_comp_status | \n",
+ " alpha | \n",
+ " alpha_status | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 6714 | \n",
+ " 34 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.689502 | \n",
+ " 0.564129 | \n",
+ " 0.125373 | \n",
+ "
\n",
+ " \n",
+ " 4609 | \n",
+ " 37 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.744421 | \n",
+ " 0.443182 | \n",
+ " 0.301239 | \n",
+ "
\n",
+ " \n",
+ " 207 | \n",
+ " 38 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.628019 | \n",
+ " 0.395891 | \n",
+ " 0.232128 | \n",
+ "
\n",
+ " \n",
+ " 5894 | \n",
+ " 42 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.75881 | \n",
+ " 0.672984 | \n",
+ " 0.0858264 | \n",
+ "
\n",
+ " \n",
+ " 4087 | \n",
+ " 48 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.757118 | \n",
+ " 0.733031 | \n",
+ " 0.0240868 | \n",
+ "
\n",
+ " \n",
+ " 5604 | \n",
+ " 55 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.907156 | \n",
+ " 0.508406 | \n",
+ " 0.39875 | \n",
+ "
\n",
+ " \n",
+ " 4221 | \n",
+ " 57 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.726585 | \n",
+ " 0.606066 | \n",
+ " 0.12052 | \n",
+ "
\n",
+ " \n",
+ " 7490 | \n",
+ " 58 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.729814 | \n",
+ " 0.565093 | \n",
+ " 0.164721 | \n",
+ "
\n",
+ " \n",
+ " 4771 | \n",
+ " 79 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.871729 | \n",
+ " 0.767271 | \n",
+ " 0.104459 | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " 80 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.729904 | \n",
+ " 0.54043 | \n",
+ " 0.189474 | \n",
+ "
\n",
+ " \n",
+ " 4921 | \n",
+ " 85 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.650832 | \n",
+ " 0.487645 | \n",
+ " 0.163187 | \n",
+ "
\n",
+ " \n",
+ " 5159 | \n",
+ " 91 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.767125 | \n",
+ " 0.628415 | \n",
+ " 0.138711 | \n",
+ "
\n",
+ " \n",
+ " 7486 | \n",
+ " 104 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.655899 | \n",
+ " 0.561093 | \n",
+ " 0.0948058 | \n",
+ "
\n",
+ " \n",
+ " 3265 | \n",
+ " 112 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.796264 | \n",
+ " 0.869321 | \n",
+ " -0.0730568 | \n",
+ "
\n",
+ " \n",
+ " 5979 | \n",
+ " 117 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.699525 | \n",
+ " 0.548448 | \n",
+ " 0.151076 | \n",
+ "
\n",
+ " \n",
+ " 4893 | \n",
+ " 117 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.843235 | \n",
+ " 0.782702 | \n",
+ " 0.0605324 | \n",
+ "
\n",
+ " \n",
+ " 7428 | \n",
+ " 135 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.972091 | \n",
+ " 0.966344 | \n",
+ " 0.00574742 | \n",
+ "
\n",
+ " \n",
+ " 672 | \n",
+ " 136 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.613924 | \n",
+ " 0.62016 | \n",
+ " -0.00623589 | \n",
+ "
\n",
+ " \n",
+ " 238 | \n",
+ " 138 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.658907 | \n",
+ " 0.540739 | \n",
+ " 0.118167 | \n",
+ "
\n",
+ " \n",
+ " 2064 | \n",
+ " 153 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.827951 | \n",
+ " 0.7313 | \n",
+ " 0.0966513 | \n",
+ "
\n",
+ " \n",
+ " 3791 | \n",
+ " 169 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.700755 | \n",
+ " 0.62616 | \n",
+ " 0.0745953 | \n",
+ "
\n",
+ " \n",
+ " 4089 | \n",
+ " 185 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.853877 | \n",
+ " 0.892832 | \n",
+ " -0.0389552 | \n",
+ "
\n",
+ " \n",
+ " 6098 | \n",
+ " 188 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.774783 | \n",
+ " 0.742351 | \n",
+ " 0.0324319 | \n",
+ "
\n",
+ " \n",
+ " 1956 | \n",
+ " 231 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.820551 | \n",
+ " 0.760429 | \n",
+ " 0.0601219 | \n",
+ "
\n",
+ " \n",
+ " 1630 | \n",
+ " 235 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.734492 | \n",
+ " 0.673222 | \n",
+ " 0.0612695 | \n",
+ "
\n",
+ " \n",
+ " 675 | \n",
+ " 237 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.620436 | \n",
+ " 0.645226 | \n",
+ " -0.0247902 | \n",
+ "
\n",
+ " \n",
+ " 5925 | \n",
+ " 263 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.820783 | \n",
+ " 0.760005 | \n",
+ " 0.0607777 | \n",
+ "
\n",
+ " \n",
+ " 1029 | \n",
+ " 274 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.813853 | \n",
+ " 0.825692 | \n",
+ " -0.0118388 | \n",
+ "
\n",
+ " \n",
+ " 5728 | \n",
+ " 279 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.755646 | \n",
+ " 0.716968 | \n",
+ " 0.0386786 | \n",
+ "
\n",
+ " \n",
+ " 4763 | \n",
+ " 316 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.704367 | \n",
+ " 0.708792 | \n",
+ " -0.00442577 | \n",
+ "
\n",
+ " \n",
+ " 324 | \n",
+ " 423 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.851976 | \n",
+ " 0.84182 | \n",
+ " 0.0101554 | \n",
+ "
\n",
+ " \n",
+ " 673 | \n",
+ " 500 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.917088 | \n",
+ " 0.927095 | \n",
+ " -0.0100076 | \n",
+ "
\n",
+ " \n",
+ " 3845 | \n",
+ " 527 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.928241 | \n",
+ " 0.915307 | \n",
+ " 0.012934 | \n",
+ "
\n",
+ " \n",
+ " 5290 | \n",
+ " 853 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.802165 | \n",
+ " 0.799111 | \n",
+ " 0.00305423 | \n",
+ "
\n",
+ " \n",
+ " 7157 | \n",
+ " 2587 | \n",
+ " 100 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.893914 | \n",
+ " 0.88026 | \n",
+ " 0.0136536 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components n_comp_status alpha alpha_status train_auroc \\\n",
+ "6714 34 50 min 0.01 OK 0.689502 \n",
+ "4609 37 50 min 0.01 OK 0.744421 \n",
+ "207 38 50 min 0.01 OK 0.628019 \n",
+ "5894 42 50 min 1 max 0.75881 \n",
+ "4087 48 100 max 0.01 OK 0.757118 \n",
+ "5604 55 100 max 0.1 OK 0.907156 \n",
+ "4221 57 50 min 0.01 OK 0.726585 \n",
+ "7490 58 50 min 0.01 OK 0.729814 \n",
+ "4771 79 100 max 0.01 OK 0.871729 \n",
+ "25 80 100 max 0.001 min 0.729904 \n",
+ "4921 85 100 max 1 max 0.650832 \n",
+ "5159 91 100 max 0.1 OK 0.767125 \n",
+ "7486 104 50 min 0.1 OK 0.655899 \n",
+ "3265 112 100 max 1 max 0.796264 \n",
+ "5979 117 100 max 0.001 min 0.699525 \n",
+ "4893 117 100 max 0.1 OK 0.843235 \n",
+ "7428 135 100 max 0.001 min 0.972091 \n",
+ "672 136 100 max 1 max 0.613924 \n",
+ "238 138 50 min 0.001 min 0.658907 \n",
+ "2064 153 100 max 0.1 OK 0.827951 \n",
+ "3791 169 50 min 1 max 0.700755 \n",
+ "4089 185 100 max 1 max 0.853877 \n",
+ "6098 188 100 max 1 max 0.774783 \n",
+ "1956 231 50 min 1 max 0.820551 \n",
+ "1630 235 100 max 1 max 0.734492 \n",
+ "675 237 100 max 1 max 0.620436 \n",
+ "5925 263 50 min 1 max 0.820783 \n",
+ "1029 274 50 min 1 max 0.813853 \n",
+ "5728 279 100 max 1 max 0.755646 \n",
+ "4763 316 100 max 1 max 0.704367 \n",
+ "324 423 50 min 1 max 0.851976 \n",
+ "673 500 100 max 1 max 0.917088 \n",
+ "3845 527 50 min 0.1 OK 0.928241 \n",
+ "5290 853 100 max 1 max 0.802165 \n",
+ "7157 2587 100 max 1 max 0.893914 \n",
+ "\n",
+ " test_auroc overfit \n",
+ "6714 0.564129 0.125373 \n",
+ "4609 0.443182 0.301239 \n",
+ "207 0.395891 0.232128 \n",
+ "5894 0.672984 0.0858264 \n",
+ "4087 0.733031 0.0240868 \n",
+ "5604 0.508406 0.39875 \n",
+ "4221 0.606066 0.12052 \n",
+ "7490 0.565093 0.164721 \n",
+ "4771 0.767271 0.104459 \n",
+ "25 0.54043 0.189474 \n",
+ "4921 0.487645 0.163187 \n",
+ "5159 0.628415 0.138711 \n",
+ "7486 0.561093 0.0948058 \n",
+ "3265 0.869321 -0.0730568 \n",
+ "5979 0.548448 0.151076 \n",
+ "4893 0.782702 0.0605324 \n",
+ "7428 0.966344 0.00574742 \n",
+ "672 0.62016 -0.00623589 \n",
+ "238 0.540739 0.118167 \n",
+ "2064 0.7313 0.0966513 \n",
+ "3791 0.62616 0.0745953 \n",
+ "4089 0.892832 -0.0389552 \n",
+ "6098 0.742351 0.0324319 \n",
+ "1956 0.760429 0.0601219 \n",
+ "1630 0.673222 0.0612695 \n",
+ "675 0.645226 -0.0247902 \n",
+ "5925 0.760005 0.0607777 \n",
+ "1029 0.825692 -0.0118388 \n",
+ "5728 0.716968 0.0386786 \n",
+ "4763 0.708792 -0.00442577 \n",
+ "324 0.84182 0.0101554 \n",
+ "673 0.927095 -0.0100076 \n",
+ "3845 0.915307 0.012934 \n",
+ "5290 0.799111 0.00305423 \n",
+ "7157 0.88026 0.0136536 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 80 | \n",
+ " 0.533543 | \n",
+ " 0.77205 | \n",
+ " 0.692798 | \n",
+ " 0.0792519 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 100 | \n",
+ " 0.766771 | \n",
+ " 0.762968 | \n",
+ " 0.700795 | \n",
+ " 0.0610236 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 80 0.533543 0.77205 0.692798 0.0792519\n",
+ "median 137 100 0.766771 0.762968 0.700795 0.0610236"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wall time: 1min 7s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "metrics_df_current_setup = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [50, 100],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df_current_setup, metrics_df_tocompare = None)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nbf2gvundQqWK+umDtbtuu+3JK0mauGan0i1Z1y/9NU49Zq5RfPKNXEjs/pKvXdW8yaP1zMC39cZH\nsxUYEqplM6dm2+7UkYP64dt56jvmIw14/wsFhd6llXM+dUJi12fwMDj9x1VQTP7u4Ze6asuMr7R9\n/jJnR3FLm7fvVpUK5VTmrlBJUvsnmmrpmo2yWLL+CzB38Uq1atpIjzesl2X9zn0H5eFh1LOvDlXL\nHv310ZdfKS0tLdfyu4Mtv8WpSngJlS6e0b1t16CGlv+yP8sY3xNeQouje8i/UEHdSjXr4tUkFfEp\nJEka2PoR9W+Z0SG7lJgikzktW7cN0paDJ1UlLESlgzM6Me3qV9Py7b9lHeewEC0e8mzmOF9LVhHf\nQtbXfz58Spt/O6429armen538FPced0TGqjwYv6SpDY1y2nFvhPZvi9uppr11qIt6vdojSzr45Ou\na/2h05oU1TDXMru7g7t+Vli5SgouGSZJqvd4S+3Y8H22MQ8rV1GDPp6jQr5+SjXd0rUrl+TrX9gZ\nkeFGmOb+XWzfoZKkSo/Ud3IS93T+4mWVKB5oXQ4JDlTy9etKuX4jy1T3m32flyT9tHNPlv3T0tJU\nt2Y1DejZVTdNJvUeMkp+PoXUtXWL3DkAN3A+IUkhRf2tyyFF/JV806SUm6YsU90FPDy0dvdhDZ+7\nUgU8PfRi8waSJIPBIE8PgwZ9sVSrdx1U42rlVSakWLb3ye/OJyQppMifxrnw7+N8y5Sl+C7g4aG1\ne45o+LzVGePcrK4k6eK1ZL27cL0+fqGVFmz5Ndfzu4MLidcVEpD5vVA8wEcpt1KVYjJnmeoeuXyb\nnq4RofLFi2TZP9jfR++1eTDX8uYFVy9dVJGg4tblwkHBunk9RbduXM821e3h6ak9P23U/A/flWeB\nAnq8Q7fcjgs3Y1Nn8tChQ+rYsaNatGihadOmad26dY7OBTeTbkm/7Xqj0bbmd9vmTTSkT3d5eRVQ\ngJ+vnmn9hFZv/vm/jOj2/tpB+IPxNvc6a1y9vNaP6avezeqr90dfKf1Pc4Sjn2mh9WP66tr1m5r6\nl6lZ3GGcDdk/y42rltP6mF7q3bSOek9ZKJPZrIEzV2hAq4YKLpz9XDRkSP+bMfYwZH6Wv/rlsDyN\nBj11b0RuxcrTLH89T+B3hr/5jq5a50G9/eUSNW3/nKYNf03p6bf/js/PnD3F7XbT3CNHjtTo0aNV\n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\n6OhoRUVFqUuXLjpx4sRtt3vrrbc0duy/uybEpmLSYDDovvvuU2Jiopo3b25zJ8RV1K9VXb8eOKzj\np89JkuYtWaXG9Wyfejp8/KQmfz5PaWlpunnrluZ8u0LNHq73zzsC/yHr5/jM75/jpd+rcV3bP8eP\nPVhH3238STdvmWSxWLTmx59VtWKEo+K6rfq1qunX3/40zstWq3HdnF0l/MueA3qg+v9kMGTvtEGq\nV62Sfj1yXCfOXZQkzVu9WY1rV8myzdXkFD07fLKa3F9NY195Vt5eXtbXDp86pw++WqG09HTdNJk0\n97uNerxujVw9BlfV7rkX9O4ns/TuJ7MU88F0HT6wV+dOn5Qkfb/kG9Wu92C2fZITr2lYv166/8FG\n+r+3RsqroO1/OMF1rV69WiaTSfPmzdOrr76qMWPGZNsmNjZWhw79+6aCTedMms1mvffee6pdu7Z+\n+uknpaam/us3zk2BRQsrZsBL6jdirFLNZoWFhmj0wL7ae/CI3ho/5R+v0n6xSzvFTP5UT/V4VeY0\ns5o+VFdtIh/NpfRAhsCihRXzWm/1e3u8UlPNCisZotED+mjvoaMZn+Mp791x/w5PNNW1pGS1eWmg\n0tPTdU+5snq9Z9dcSu8+AosUVkz/XuoXMzHz+2LAixnjPPETLfwo+xfyX504c16lQoJyIa17Cizs\nr5heHfV/E2bIbE5TWEigRr3UWXuPnlT0tFh9887rmvf9Zp27lKDV2/Zo9bbM838/e/MlvdjmcY2c\nsUAtB4yROS1NTR+4V20a173DO+ZPhYsWU+8Bb2n8sEEym80qUbKUXnoj49z1owcPaOrYkXr3k1la\ntfgbXbp4Qds2/aBtm36w7v/W2A/lX7iwk9K7PleaZr6d7du368EHM/54uPfee7V3b9bzu3fs2KHd\nu3crKipKx44d+1fvZbD83UkVf3L8+HFt3rxZbdu21erVq1W1alWFhYX9026SpLRTe/55I9jNI6yq\nehnKODtGnjbFclxpJ3Y7O0ae5lG6uiQpLW6Hk5PkbR5la8q8c6WzY+RpnjUe164zV/95Q9jt3lKu\ncZ/L5NkjnB1Bfp2i//a1IUOG6LHHHlPDhg0lSQ8//LBWr14tT09PXbx4UYMGDdIHH3ygFStW6Nix\nY3rttdfszmFTZ3LmzJmKjs4IHBkZqddff13vvvuu3W8KAADgzlzp1jy34+fnp5SUFOtyenq6PD0z\n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\nB9X9VceOHXn66aeLPqC7zJAhQ3K9V+rMmTMdYiS73LvsqZvZ1u7pyqSIiIiINUq9/LmtQ+DKig9s\nHQLgAANwRERERMR+3RPd3CIiIiL/JKO6uc1UmRQRERERq6kyKSIiIlJAGoCTRZVJEREREbGakkkR\nERERsZq6uUVEREQKSN3cWVSZFBERERGrqTIpIiIiUkCmTFUm/6TKpIiIiIhYTcmkiIiIiFhN3dwi\nIiIiBaQBOFlUmRQRERERq6kyKSIiIlJAqkxmUWVSRERERKymZFJERERErKZubhEREZECUjd3FlUm\nRURERMRqqkyKiIiIFJDJaLR1CHZDlUkRERERsZqSSRERERGxmrq5RURERApIA3CyqDIpIiIiIlZT\nZVJERESkgFSZzKLKpIiIiIhYTcmkiIiIiFhN3dwiIiIiBWRUN7eZKpMiIiIiYjUlkyIiIiJiNXVz\ni4iIiBSQKVPd3H9SZVJERERErKbKpIiIiEgB6T6TWVSZFBERERGrKZkUEREREaupm1tERESkgNTN\nnUWVSRERERGxmiqTIiIiIgWkymQWVSZFRERExGpKJkVERETEaurmFhERESkgdXNnUWVSRERERKxm\nMJlMJlsHISIiIiKOSZVJEREREbGakkkRERERsZqSSRERERGxmpJJEREREbGakkkRERERsZqSSRER\nERGx2v8Byc0k+rtOSkgAAAAASUVORK5CYII=\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Show how some of these metrics/parameters might be related\n",
+ "metrics_df_for_correlations = metrics_df_current_setup[['num_positive', 'n_components', 'alpha', 'train_auroc', 'test_auroc', 'overfit']]\n",
+ "plt.figure(figsize=(12,12))\n",
+ "plt.title('Correlations', y=1.05, size=15)\n",
+ "sns.heatmap(metrics_df_for_correlations.astype(float).corr(),linewidths=0.1,vmax=1.0, square=True, annot=True)\n",
+ "sns.plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 4.c. Evaluate how changing some of the parameters effects performance\n",
+ "\n",
+ "The three things I'd like to evaluate are n_components, alpha and l1_ratio\n",
+ "\n",
+ "My thoughts, going from easiest to most difficult to evaluate...\n",
+ " - alpha: just make the range larger if a lot of queries are at max or min (i.e. at the edge of the gridsearch space\n",
+ " - l1_ratio: the two values that we've discussed are 0 and 0.15... just try both for different setups\n",
+ " - n_components: try lists of varying size, try functions to auto select"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "#### Try all combos of:\n",
+ "#### k_range = [10, 20, 40, 80, 160, 320, 640]\n",
+ "#### alpha_range = [10** x for x in range(-10,10)]\n",
+ "#### and l1_ratio = 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 261.143 | \n",
+ " 0.347371 | \n",
+ " 0.793946 | \n",
+ " 0.705682 | \n",
+ " 0.0882634 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 160 | \n",
+ " 0.1 | \n",
+ " 0.787152 | \n",
+ " 0.707957 | \n",
+ " 0.0707356 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 261.143 0.347371 0.793946 0.705682 0.0882634\n",
+ "median 137 160 0.1 0.787152 0.707957 0.0707356"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 1.27%\n",
+ "Median testing Auroc improved by 0.72%\n",
+ "Mean overfitting reduced by -1.0%\n",
+ "Median overfitting reduced by -1.0%\n",
+ "Wall time: 5min 4s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k_range\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [10, 20, 40, 80, 160, 320, 640],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 640 | \n",
+ " 0.538429 | \n",
+ " 0.833917 | \n",
+ " 0.709258 | \n",
+ " 0.124658 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 640 | \n",
+ " 0.769214 | \n",
+ " 0.852768 | \n",
+ " 0.713322 | \n",
+ " 0.0894777 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 640 0.538429 0.833917 0.709258 0.124658\n",
+ "median 137 640 0.769214 0.852768 0.713322 0.0894777"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 1.62%\n",
+ "Median testing Auroc improved by 1.25%\n",
+ "Mean overfitting reduced by -4.6%\n",
+ "Median overfitting reduced by -2.8%\n",
+ "Wall time: 2min 6s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k_max. Test if a range is even any better than just the largest number...\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [640],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Interesting, but maybe not too suprising. Looks like the range as opposed to just the max helps with overfitting but actually hurts with overall accurace"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 85.7143 | \n",
+ " 0.494457 | \n",
+ " 0.776175 | \n",
+ " 0.6947 | \n",
+ " 0.0814751 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 100 | \n",
+ " 0.297229 | \n",
+ " 0.776817 | \n",
+ " 0.687523 | \n",
+ " 0.0524966 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 85.7143 0.494457 0.776175 0.6947 0.0814751\n",
+ "median 137 100 0.297229 0.776817 0.687523 0.0524966"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 0.17%\n",
+ "Median testing Auroc improved by -1.33%\n",
+ "Mean overfitting reduced by -0.3%\n",
+ "Median overfitting reduced by 0.9%\n",
+ "Wall time: 1min 4s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# l1_ratio\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [50, 100],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 78.5714 | \n",
+ " 2.69206 | \n",
+ " 0.7786 | \n",
+ " 0.70246 | \n",
+ " 0.0761406 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 100 | \n",
+ " 1 | \n",
+ " 0.774517 | \n",
+ " 0.699582 | \n",
+ " 0.0584197 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 78.5714 2.69206 0.7786 0.70246 0.0761406\n",
+ "median 137 100 1 0.774517 0.699582 0.0584197"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 0.94%\n",
+ "Median testing Auroc improved by -0.12%\n",
+ "Mean overfitting reduced by 0.3%\n",
+ "Median overfitting reduced by 0.3%\n",
+ "Wall time: 3min 7s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# alpha_range\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [50, 100],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 94.2857 | \n",
+ " 346141 | \n",
+ " 0.829757 | \n",
+ " 0.763774 | \n",
+ " 0.0659825 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 100 | \n",
+ " 55 | \n",
+ " 0.830814 | \n",
+ " 0.75685 | \n",
+ " 0.0418654 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 94.2857 346141 0.829757 0.763774 0.0659825\n",
+ "median 137 100 55 0.830814 0.75685 0.0418654"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 7.08%\n",
+ "Median testing Auroc improved by 5.61%\n",
+ "Mean overfitting reduced by 1.3%\n",
+ "Median overfitting reduced by 1.9%\n",
+ "Wall time: 2min 54s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# alpha_range and l1_ratio\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [50, 100],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 226.286 | \n",
+ " 1.68035 | \n",
+ " 0.777703 | \n",
+ " 0.691562 | \n",
+ " 0.0861411 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 160 | \n",
+ " 0.1 | \n",
+ " 0.763551 | \n",
+ " 0.669836 | \n",
+ " 0.0685817 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 226.286 1.68035 0.777703 0.691562 0.0861411\n",
+ "median 137 160 0.1 0.763551 0.669836 0.0685817"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by -0.15%\n",
+ "Median testing Auroc improved by -3.10%\n",
+ "Mean overfitting reduced by -0.7%\n",
+ "Median overfitting reduced by -0.8%\n",
+ "Wall time: 19min 20s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# alpha_range and k_range\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [10, 20, 40, 80, 160, 320, 640],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 347.714 | \n",
+ " 0.537914 | \n",
+ " 0.825945 | \n",
+ " 0.709964 | \n",
+ " 0.115981 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 320 | \n",
+ " 0.768957 | \n",
+ " 0.86 | \n",
+ " 0.718275 | \n",
+ " 0.10949 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 347.714 0.537914 0.825945 0.709964 0.115981\n",
+ "median 137 320 0.768957 0.86 0.718275 0.10949"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 1.69%\n",
+ "Median testing Auroc improved by 1.75%\n",
+ "Mean overfitting reduced by -3.7%\n",
+ "Median overfitting reduced by -4.8%\n",
+ "Wall time: 5min 12s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k_range and l1_ratio\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [10, 20, 40, 80, 160, 320, 640],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 382.286 | \n",
+ " 3.14305e+06 | \n",
+ " 0.851795 | \n",
+ " 0.77483 | \n",
+ " 0.0769651 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 320 | \n",
+ " 10 | \n",
+ " 0.868835 | \n",
+ " 0.758737 | \n",
+ " 0.0592118 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc \\\n",
+ "mean 256.657 382.286 3.14305e+06 0.851795 0.77483 \n",
+ "median 137 320 10 0.868835 0.758737 \n",
+ "\n",
+ " overfit \n",
+ "mean 0.0769651 \n",
+ "median 0.0592118 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 8.18%\n",
+ "Median testing Auroc improved by 5.79%\n",
+ "Mean overfitting reduced by 0.2%\n",
+ "Median overfitting reduced by 0.2%\n",
+ "Wall time: 17min 21s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# All three: k_range, alpha_range and l1_ratio\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [10, 20, 40, 80, 160, 320, 640],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 640 | \n",
+ " 3.14889e+07 | \n",
+ " 0.870003 | \n",
+ " 0.771827 | \n",
+ " 0.0981763 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 640 | \n",
+ " 55 | \n",
+ " 0.872664 | \n",
+ " 0.755183 | \n",
+ " 0.0634218 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc \\\n",
+ "mean 256.657 640 3.14889e+07 0.870003 0.771827 \n",
+ "median 137 640 55 0.872664 0.755183 \n",
+ "\n",
+ " overfit \n",
+ "mean 0.0981763 \n",
+ "median 0.0634218 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 7.88%\n",
+ "Median testing Auroc improved by 5.44%\n",
+ "Mean overfitting reduced by -1.9%\n",
+ "Median overfitting reduced by -0.2%\n",
+ "Wall time: 7min 13s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# All three: k_range, alpha_range and l1_ratio... Again this time only use the max of the k_range\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = [640],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "With the larger aplha range and l1_ratio it looks like having the range of k as opposed to just the max helps with both overall performance as well as overfitting"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### Use a function to automatically select the parameter space to search"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# k_range function\n",
+ "def k_func(num_positives):\n",
+ " if num_positives < 50:\n",
+ " k_range = [6, 8, 10, 14, 20, 28]\n",
+ " elif num_positives < 100:\n",
+ " k_range = [10, 15, 20, 30, 50, 80]\n",
+ " elif num_positives < 200:\n",
+ " k_range = [15, 25, 50, 75, 100, 175]\n",
+ " elif num_positives < 500:\n",
+ " k_range = [60, 100, 150, 250, 400] # Tried 30, 60, 100, 150\n",
+ " else:\n",
+ " k_range = [100, 200, 400, 800]\n",
+ " return(k_range)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 23,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 166.314 | \n",
+ " 0.464371 | \n",
+ " 0.753238 | \n",
+ " 0.695742 | \n",
+ " 0.0574961 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 100 | \n",
+ " 0.1 | \n",
+ " 0.755169 | \n",
+ " 0.691246 | \n",
+ " 0.0582237 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 166.314 0.464371 0.753238 0.695742 0.0574961\n",
+ "median 137 100 0.1 0.755169 0.691246 0.0582237"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 0.27%\n",
+ "Median testing Auroc improved by -0.95%\n",
+ "Mean overfitting reduced by 2.1%\n",
+ "Median overfitting reduced by 0.3%\n",
+ "Wall time: 3min 42s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k_range func\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = None,\n",
+ " k_function = k_func,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 24,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 169.6 | \n",
+ " 1.4526 | \n",
+ " 0.766604 | \n",
+ " 0.7085 | \n",
+ " 0.0581044 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 80 | \n",
+ " 0.1 | \n",
+ " 0.761007 | \n",
+ " 0.705845 | \n",
+ " 0.0491028 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc overfit\n",
+ "mean 256.657 169.6 1.4526 0.766604 0.7085 0.0581044\n",
+ "median 137 80 0.1 0.761007 0.705845 0.0491028"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 1.55%\n",
+ "Median testing Auroc improved by 0.50%\n",
+ "Mean overfitting reduced by 2.1%\n",
+ "Median overfitting reduced by 1.2%\n",
+ "Wall time: 11min 20s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k_range func with larger alpha range\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = None,\n",
+ " k_function = k_func,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 25,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " n_comp_status | \n",
+ " alpha | \n",
+ " alpha_status | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 6714 | \n",
+ " 34 | \n",
+ " 28 | \n",
+ " max | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.771098 | \n",
+ " 0.574074 | \n",
+ " 0.197024 | \n",
+ "
\n",
+ " \n",
+ " 4609 | \n",
+ " 37 | \n",
+ " 20 | \n",
+ " OK | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.816241 | \n",
+ " 0.582438 | \n",
+ " 0.233803 | \n",
+ "
\n",
+ " \n",
+ " 207 | \n",
+ " 38 | \n",
+ " 28 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.774728 | \n",
+ " 0.74957 | \n",
+ " 0.0251575 | \n",
+ "
\n",
+ " \n",
+ " 5894 | \n",
+ " 42 | \n",
+ " 14 | \n",
+ " OK | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.741009 | \n",
+ " 0.702819 | \n",
+ " 0.0381898 | \n",
+ "
\n",
+ " \n",
+ " 4087 | \n",
+ " 48 | \n",
+ " 14 | \n",
+ " OK | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.768437 | \n",
+ " 0.742946 | \n",
+ " 0.0254908 | \n",
+ "
\n",
+ " \n",
+ " 5604 | \n",
+ " 55 | \n",
+ " 80 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.926328 | \n",
+ " 0.703114 | \n",
+ " 0.223214 | \n",
+ "
\n",
+ " \n",
+ " 4221 | \n",
+ " 57 | \n",
+ " 30 | \n",
+ " OK | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.722205 | \n",
+ " 0.587625 | \n",
+ " 0.13458 | \n",
+ "
\n",
+ " \n",
+ " 7490 | \n",
+ " 58 | \n",
+ " 20 | \n",
+ " OK | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.715819 | \n",
+ " 0.718188 | \n",
+ " -0.00236926 | \n",
+ "
\n",
+ " \n",
+ " 4771 | \n",
+ " 79 | \n",
+ " 80 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.857419 | \n",
+ " 0.818807 | \n",
+ " 0.0386118 | \n",
+ "
\n",
+ " \n",
+ " 25 | \n",
+ " 80 | \n",
+ " 80 | \n",
+ " max | \n",
+ " 1000000000 | \n",
+ " max | \n",
+ " 0.704129 | \n",
+ " 0.706623 | \n",
+ " -0.00249354 | \n",
+ "
\n",
+ " \n",
+ " 4921 | \n",
+ " 85 | \n",
+ " 80 | \n",
+ " max | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.728736 | \n",
+ " 0.761327 | \n",
+ " -0.0325916 | \n",
+ "
\n",
+ " \n",
+ " 5159 | \n",
+ " 91 | \n",
+ " 50 | \n",
+ " OK | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.823755 | \n",
+ " 0.67047 | \n",
+ " 0.153284 | \n",
+ "
\n",
+ " \n",
+ " 7486 | \n",
+ " 104 | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 10000000 | \n",
+ " OK | \n",
+ " 0.70726 | \n",
+ " 0.659344 | \n",
+ " 0.0479152 | \n",
+ "
\n",
+ " \n",
+ " 3265 | \n",
+ " 112 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.960569 | \n",
+ " 0.957638 | \n",
+ " 0.00293089 | \n",
+ "
\n",
+ " \n",
+ " 5979 | \n",
+ " 117 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.869715 | \n",
+ " 0.693356 | \n",
+ " 0.176359 | \n",
+ "
\n",
+ " \n",
+ " 4893 | \n",
+ " 117 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.898487 | \n",
+ " 0.812942 | \n",
+ " 0.0855446 | \n",
+ "
\n",
+ " \n",
+ " 7428 | \n",
+ " 135 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 1e-05 | \n",
+ " OK | \n",
+ " 0.991725 | \n",
+ " 0.983379 | \n",
+ " 0.00834692 | \n",
+ "
\n",
+ " \n",
+ " 672 | \n",
+ " 136 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.789882 | \n",
+ " 0.725919 | \n",
+ " 0.0639631 | \n",
+ "
\n",
+ " \n",
+ " 238 | \n",
+ " 138 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.792941 | \n",
+ " 0.716417 | \n",
+ " 0.0765236 | \n",
+ "
\n",
+ " \n",
+ " 2064 | \n",
+ " 153 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.825144 | \n",
+ " 0.766363 | \n",
+ " 0.058781 | \n",
+ "
\n",
+ " \n",
+ " 3791 | \n",
+ " 169 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.787689 | \n",
+ " 0.73986 | \n",
+ " 0.047829 | \n",
+ "
\n",
+ " \n",
+ " 4089 | \n",
+ " 185 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.876471 | \n",
+ " 0.906917 | \n",
+ " -0.030446 | \n",
+ "
\n",
+ " \n",
+ " 6098 | \n",
+ " 188 | \n",
+ " 175 | \n",
+ " max | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.762345 | \n",
+ " 0.747748 | \n",
+ " 0.0145974 | \n",
+ "
\n",
+ " \n",
+ " 1956 | \n",
+ " 231 | \n",
+ " 250 | \n",
+ " OK | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.91148 | \n",
+ " 0.853169 | \n",
+ " 0.0583107 | \n",
+ "
\n",
+ " \n",
+ " 1630 | \n",
+ " 235 | \n",
+ " 400 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.790046 | \n",
+ " 0.732253 | \n",
+ " 0.0577937 | \n",
+ "
\n",
+ " \n",
+ " 675 | \n",
+ " 237 | \n",
+ " 400 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.837864 | \n",
+ " 0.70386 | \n",
+ " 0.134004 | \n",
+ "
\n",
+ " \n",
+ " 5925 | \n",
+ " 263 | \n",
+ " 400 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.928683 | \n",
+ " 0.872011 | \n",
+ " 0.0566725 | \n",
+ "
\n",
+ " \n",
+ " 1029 | \n",
+ " 274 | \n",
+ " 400 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.925013 | \n",
+ " 0.874314 | \n",
+ " 0.0506987 | \n",
+ "
\n",
+ " \n",
+ " 5728 | \n",
+ " 279 | \n",
+ " 400 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.904708 | \n",
+ " 0.838317 | \n",
+ " 0.0663911 | \n",
+ "
\n",
+ " \n",
+ " 4763 | \n",
+ " 316 | \n",
+ " 250 | \n",
+ " OK | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.813683 | \n",
+ " 0.788081 | \n",
+ " 0.0256023 | \n",
+ "
\n",
+ " \n",
+ " 324 | \n",
+ " 423 | \n",
+ " 150 | \n",
+ " OK | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.914517 | \n",
+ " 0.877411 | \n",
+ " 0.0371053 | \n",
+ "
\n",
+ " \n",
+ " 673 | \n",
+ " 500 | \n",
+ " 800 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.96102 | \n",
+ " 0.952072 | \n",
+ " 0.00894727 | \n",
+ "
\n",
+ " \n",
+ " 3845 | \n",
+ " 527 | \n",
+ " 400 | \n",
+ " OK | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.960236 | \n",
+ " 0.946846 | \n",
+ " 0.0133901 | \n",
+ "
\n",
+ " \n",
+ " 5290 | \n",
+ " 853 | \n",
+ " 800 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.877066 | \n",
+ " 0.862998 | \n",
+ " 0.0140685 | \n",
+ "
\n",
+ " \n",
+ " 7157 | \n",
+ " 2587 | \n",
+ " 800 | \n",
+ " max | \n",
+ " 1 | \n",
+ " OK | \n",
+ " 0.954474 | \n",
+ " 0.927714 | \n",
+ " 0.0267597 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components n_comp_status alpha alpha_status \\\n",
+ "6714 34 28 max 1000 OK \n",
+ "4609 37 20 OK 1000 OK \n",
+ "207 38 28 max 100 OK \n",
+ "5894 42 14 OK 1000 OK \n",
+ "4087 48 14 OK 1000 OK \n",
+ "5604 55 80 max 10 OK \n",
+ "4221 57 30 OK 1000 OK \n",
+ "7490 58 20 OK 1000 OK \n",
+ "4771 79 80 max 100 OK \n",
+ "25 80 80 max 1000000000 max \n",
+ "4921 85 80 max 1000 OK \n",
+ "5159 91 50 OK 10 OK \n",
+ "7486 104 100 OK 10000000 OK \n",
+ "3265 112 175 max 10 OK \n",
+ "5979 117 175 max 10 OK \n",
+ "4893 117 175 max 10 OK \n",
+ "7428 135 175 max 1e-05 OK \n",
+ "672 136 175 max 100 OK \n",
+ "238 138 175 max 100 OK \n",
+ "2064 153 175 max 100 OK \n",
+ "3791 169 175 max 100 OK \n",
+ "4089 185 175 max 100 OK \n",
+ "6098 188 175 max 1000 OK \n",
+ "1956 231 250 OK 10 OK \n",
+ "1630 235 400 max 100 OK \n",
+ "675 237 400 max 10 OK \n",
+ "5925 263 400 max 10 OK \n",
+ "1029 274 400 max 10 OK \n",
+ "5728 279 400 max 10 OK \n",
+ "4763 316 250 OK 10 OK \n",
+ "324 423 150 OK 10 OK \n",
+ "673 500 800 max 10 OK \n",
+ "3845 527 400 OK 10 OK \n",
+ "5290 853 800 max 10 OK \n",
+ "7157 2587 800 max 1 OK \n",
+ "\n",
+ " train_auroc test_auroc overfit \n",
+ "6714 0.771098 0.574074 0.197024 \n",
+ "4609 0.816241 0.582438 0.233803 \n",
+ "207 0.774728 0.74957 0.0251575 \n",
+ "5894 0.741009 0.702819 0.0381898 \n",
+ "4087 0.768437 0.742946 0.0254908 \n",
+ "5604 0.926328 0.703114 0.223214 \n",
+ "4221 0.722205 0.587625 0.13458 \n",
+ "7490 0.715819 0.718188 -0.00236926 \n",
+ "4771 0.857419 0.818807 0.0386118 \n",
+ "25 0.704129 0.706623 -0.00249354 \n",
+ "4921 0.728736 0.761327 -0.0325916 \n",
+ "5159 0.823755 0.67047 0.153284 \n",
+ "7486 0.70726 0.659344 0.0479152 \n",
+ "3265 0.960569 0.957638 0.00293089 \n",
+ "5979 0.869715 0.693356 0.176359 \n",
+ "4893 0.898487 0.812942 0.0855446 \n",
+ "7428 0.991725 0.983379 0.00834692 \n",
+ "672 0.789882 0.725919 0.0639631 \n",
+ "238 0.792941 0.716417 0.0765236 \n",
+ "2064 0.825144 0.766363 0.058781 \n",
+ "3791 0.787689 0.73986 0.047829 \n",
+ "4089 0.876471 0.906917 -0.030446 \n",
+ "6098 0.762345 0.747748 0.0145974 \n",
+ "1956 0.91148 0.853169 0.0583107 \n",
+ "1630 0.790046 0.732253 0.0577937 \n",
+ "675 0.837864 0.70386 0.134004 \n",
+ "5925 0.928683 0.872011 0.0566725 \n",
+ "1029 0.925013 0.874314 0.0506987 \n",
+ "5728 0.904708 0.838317 0.0663911 \n",
+ "4763 0.813683 0.788081 0.0256023 \n",
+ "324 0.914517 0.877411 0.0371053 \n",
+ "673 0.96102 0.952072 0.00894727 \n",
+ "3845 0.960236 0.946846 0.0133901 \n",
+ "5290 0.877066 0.862998 0.0140685 \n",
+ "7157 0.954474 0.927714 0.0267597 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_positive | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 256.657 | \n",
+ " 223.543 | \n",
+ " 2.88574e+07 | \n",
+ " 0.839741 | \n",
+ " 0.778769 | \n",
+ " 0.0609711 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 137 | \n",
+ " 175 | \n",
+ " 100 | \n",
+ " 0.831504 | \n",
+ " 0.755449 | \n",
+ " 0.0478721 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_positive n_components alpha train_auroc test_auroc \\\n",
+ "mean 256.657 223.543 2.88574e+07 0.839741 0.778769 \n",
+ "median 137 175 100 0.831504 0.755449 \n",
+ "\n",
+ " overfit \n",
+ "mean 0.0609711 \n",
+ "median 0.0478721 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 8.57%\n",
+ "Median testing Auroc improved by 5.47%\n",
+ "Mean overfitting reduced by 1.8%\n",
+ "Median overfitting reduced by 1.3%\n",
+ "Wall time: 10min 9s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k_range func with larger alpha range and l1_ratio = 0\n",
+ "metrics_df = evaluate_classifier(X_train = X_train,\n",
+ " X_test = X_test,\n",
+ " y = y,\n",
+ " y_train_allgenes = y_train_allgenes,\n",
+ " y_test_allgenes = y_test_allgenes,\n",
+ " list_of_genes = list_of_genes,\n",
+ " set_k_range = None,\n",
+ " k_function = k_func,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup)"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.5.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/explore/number-of-components/number_of_pca_components.py b/explore/number-of-components/number_of_pca_components.py
new file mode 100644
index 0000000..e5587e1
--- /dev/null
+++ b/explore/number-of-components/number_of_pca_components.py
@@ -0,0 +1,436 @@
+
+# coding: utf-8
+
+# # Explore how many PCA Components to Keep and Hyperparameter Tuning
+
+# ## Takeaways after running this notebook:
+# 1. The accurace gain by searching over a larger range of n_components seems to be small (~1%-2% gain in testing AUROC on average), even when the range of n_components is selected for each query based on a heuristic around class balance.
+# 2. There is a similar accurace gain when only the largest value in the range is used
+# 2. There is a larger performance gain if the l1_ratio is changed from 0.15 to 0 and the range of alpha is expanded (~5%-7% gain in testing AUROC on average) there isn't much performance gain if these parameters are changed independent of each other.
+
+# __Purpose__
+#
+# As described in issue #106 (https://github.com/cognoma/machine-learning/issues/106), searching over a large range of n_components (number of PCA components) causes issues with both speed and memory and may also cause issues with overfitting. This notebook is an attempt to explore the relationship between the number of components returned by PCA, the other hyperparameters and classifier performance (AUROC). Ideally, we will be able to automatically select a range of n_components to search across based on the specifics of the query. The assumption is that for the lower number of positive samples (and/or the less total samples)... the less n-components to include (i.e. a query with only 40 positive samples would use a classifer that does GridSearchCV with n_components = [30, 40, 50] whereas a query with 1,000 positive samples would use a classifier that does GridSearchCV with n_components = [100, 200, 300] _just random numbers for purpose of illustration_). This notebook attempts to provide some basis for selecting the range of n_components.
+#
+#
+# __Assumptions/Notes:__
+#
+# This notebook differs from the current classifier in a number of ways including:
+# 1. In this notebook, PCA is performed on the entire training set prior to cross-validation rather than performed on each individual cross-validation split. This is done for simplicity and to save time and memory.
+# 2. In this notebook, the covariates data is not used (for now at least).
+#
+#
+# __To Do:__
+#
+# 1. Evaluate queries that only use a subset of diseases or a single disease.
+# 2. Try to include the covariates data and see how that affects things.
+# 3. Some additional evaluation and... select a final setup.
+
+# ## Outline:
+# 1. Imports, constants and load the data
+# 2. Test Train split and perform PCA
+# 3. Build the querry set
+# 4. Evaluate queries with all samples (i.e. all diseases) and varying number of positives
+# - a. Define some helper functions
+# - b. See how the parameters are related using the current setup
+# - c. Evaluate how changing some of the parameters effects performance
+# 5. TO DO: Evaluate queries that only use a subset of diseases or a single disease
+#
+
+# ## 1. Imports, constants and load the data
+
+# In[1]:
+
+
+import os
+import time
+
+from sklearn.decomposition import PCA
+from sklearn.linear_model import SGDClassifier
+from sklearn.metrics import roc_auc_score, roc_curve
+from sklearn.model_selection import train_test_split, StratifiedKFold
+from dask_searchcv import GridSearchCV
+from sklearn.pipeline import Pipeline, FeatureUnion
+from sklearn.preprocessing import StandardScaler, FunctionTransformer
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import seaborn as sns
+from sklearn.feature_selection import SelectKBest
+from IPython.display import display
+
+
+# In[2]:
+
+
+RANDOMSEED = 0
+
+
+# In[3]:
+
+
+get_ipython().run_cell_magic('time', '', "# Load the data\ntry: \n path = os.path.join('download', 'expression-matrix.pkl')\n X = pd.read_pickle(path)\nexcept:\n path = os.path.join('download', 'expression-matrix.tsv.bz2')\n X = pd.read_table(path, index_col=0)\n\ntry:\n path = os.path.join('download', 'mutation-matrix.pkl')\n y = pd.read_pickle(path)\nexcept:\n path = os.path.join('download', 'mutation-matrix.tsv.bz2')\n y = pd.read_table(path, index_col=0)")
+
+
+# ## 2. Test Train split and perform PCA
+
+# In[4]:
+
+
+# Test Train split
+X_train, X_test, y_train_allgenes, y_test_allgenes = train_test_split(X, y, test_size=0.2, random_state=RANDOMSEED)
+
+
+# In[5]:
+
+
+get_ipython().run_cell_magic('time', '', 'scaler = StandardScaler()\npca = PCA(n_components = 1000, random_state = RANDOMSEED)\nscaler.fit(X_train)\nX_train_scaled = scaler.transform(X_train)\npca.fit(X_train_scaled)\nX_train = pca.transform(X_train_scaled)\n\nX_test_scaled = scaler.transform(X_test)\nX_test = pca.transform(X_test_scaled)')
+
+
+# ## 3. Build the query set
+
+# In[6]:
+
+
+# List of genes to iterate over (from brankaj's notebook:
+# https://github.com/cognoma/machine-learning/blob/master/explore/Classifier_results-different_genes.ipynb)
+genes_LungCancer = {
+ '207': 'AKT1',
+ '238': 'ALK',
+ '673': 'BRAF',
+ '4921':'DDR2',
+ '1956':'EGFR',
+ '2064':'ERBB2',
+ '3845':'KRAS',
+ '5604':'MAP2K1',
+ '4893':'NRAS',
+ '5290':'PIK3CA',
+ '5728':'PTEN',
+ '5979':'RET',
+ # '6016':'RIT1', (removed because too few positives)
+ '6098':'ROS1',
+}
+
+genes_TumorSuppressors = {
+ '324': 'APC',
+ '672': 'BRCA1',
+ '675': 'BRCA2',
+ '1029':'CDKN2A',
+ '1630':'DCC',
+ '4089':'SMAD4',
+ '4087':'SMAD2',
+ '4221':'MEN1',
+ '4763':'NF1',
+ '4771':'NF2',
+ '7157':'TP53',
+ '5728':'PTEN',
+ '5925':'RB1',
+ '7428':'VHL',
+ '7486':'WRN',
+ '7490':'WT1',
+}
+
+genes_Oncogenes = {
+ #'5155':'PDGFB', #growth factor (removed because too few positives)
+ '5159':'PDGFRB', #growth factor
+ '3791':'KDR', #receptor tyrosine kinases
+ '25':'ABL1', #Cytoplasmic tyrosine kinases
+ '6714':'SRC', #Cytoplasmic tyrosine kinases
+ '5894':'RAF1',#cytoplasmic serine kinases
+ '3265':'HRAS',#regulatory GTPases
+ '4609':'MYC',#Transcription factors
+ #'2353':'FOS',#Transcription factors (removed because too few positives)
+
+}
+
+list_of_genes = (list(genes_LungCancer.keys()) + list(genes_TumorSuppressors.keys()) +
+ list(genes_Oncogenes.keys()))
+
+
+# In[7]:
+
+
+list_of_genes_positives = []
+for gene in list_of_genes:
+ y_temp = y_train_allgenes[gene]
+ list_of_genes_positives.append(y_temp.value_counts(True)[1]*len(y_train_allgenes))
+list_of_genes = [gene for _,gene in sorted(zip(list_of_genes_positives, list_of_genes))]
+
+
+# ## 4. Evaluate queries with all samples (i.e. all diseases) and varying number of positives
+
+# ### 4.a. Define some helper functions
+
+# In[8]:
+
+
+def variance_scorer(x, y):
+ """
+ Get the variance for each column of X.
+
+ Because principal components have decreasing variance
+ (i.e. PC4 has less variance than PC3 which has less variance
+ than PC2 etc.), we can use this function in SelectKBest to select
+ only the top X number of principal components.
+
+ """
+ scores = [np.var(column) for column in x.T]
+ return scores, np.array([np.NaN]*len(scores))
+
+
+# In[9]:
+
+
+def evaluate_classifier(X_train, X_test,
+ y, y_train_allgenes, y_test_allgenes,
+ list_of_genes,
+ set_k_range, k_function,
+ alpha_range,
+ l1_ratio):
+
+ ''' Run a classifier setup on a set of queries.
+
+ Loop through each query; train and test the classifier using the
+ hyperparameters input as parameters; populate the metrics dictionary
+ with some metrics of which parameters were selected and how well
+ the classifier did for that query.
+ '''
+
+ # A dictionary to hold the performance metrics.
+ metrics_dict = {}
+
+ # Loop through each query; train and test the classifer; populate the metrics dictionary.
+ for gene in list_of_genes:
+
+ # Train and test the classifier.
+
+ y_gene = y[gene]
+ y_train = y_train_allgenes[gene]
+ y_test = y_test_allgenes[gene]
+ num_positives = int(y_gene.value_counts(True)[1]*len(y_gene))
+ if set_k_range:
+ k_range = set_k_range
+ else:
+ k_range = k_function(num_positives)
+ # Parameter Sweep for Hyperparameters
+ param_grid = {
+ 'select__k': k_range,
+ 'classify__loss': ['log'],
+ 'classify__penalty': ['elasticnet'],
+ 'classify__alpha': alpha_range,
+ 'classify__l1_ratio': l1_ratio,
+ }
+ pipeline = Pipeline(steps=[
+ ('select', SelectKBest(variance_scorer)),
+ ('classify', SGDClassifier(random_state=RANDOMSEED, class_weight='balanced'))
+ ])
+ cv_pipeline = GridSearchCV(estimator=pipeline,
+ param_grid=param_grid,
+ n_jobs=1,
+ scoring='roc_auc')
+ cv_pipeline.fit(X=X_train, y=y_train)
+ y_pred_train = cv_pipeline.decision_function(X_train)
+ y_pred_test = cv_pipeline.decision_function(X_test)
+ # Get ROC info.
+ def get_threshold_metrics(y_true, y_pred):
+ roc_columns = ['fpr', 'tpr', 'threshold']
+ roc_items = zip(roc_columns, roc_curve(y_true, y_pred))
+ roc_df = pd.DataFrame.from_items(roc_items)
+ auroc = roc_auc_score(y_true, y_pred)
+ return {'auroc': auroc, 'roc_df': roc_df}
+ metrics_train = get_threshold_metrics(y_train, y_pred_train)
+ metrics_test = get_threshold_metrics(y_test, y_pred_test)
+
+ # Populate the metrics dictionary.
+
+ # Get metrics for the classifier.
+ overfit = metrics_train['auroc'] - metrics_test['auroc']
+ # Understand how the parameter grid worked... any params at the edge?
+ if cv_pipeline.best_params_['select__k'] == min(param_grid['select__k']):
+ n_comp_status = 'min'
+ elif cv_pipeline.best_params_['select__k'] == max(param_grid['select__k']):
+ n_comp_status = 'max'
+ else:
+ n_comp_status = 'OK'
+ if cv_pipeline.best_params_['classify__alpha'] == min(param_grid['classify__alpha']):
+ alpha_status = 'min'
+ elif cv_pipeline.best_params_['classify__alpha'] == max(param_grid['classify__alpha']):
+ alpha_status = 'max'
+ else:
+ alpha_status = 'OK'
+ metrics = {'num_positive': num_positives,
+ 'train_auroc': metrics_train['auroc'],
+ 'test_auroc': metrics_test['auroc'],
+ 'n_components': cv_pipeline.best_params_['select__k'],
+ 'alpha': cv_pipeline.best_params_['classify__alpha'],
+ 'overfit': overfit,
+ 'n_comp_status': n_comp_status,
+ 'alpha_status': alpha_status
+ }
+ # Add the metrics to the dictonary.
+ metrics_dict[gene] = metrics
+ # Change the metrics dict into a formatted pandas dataframe.
+ metrics_df = pd.DataFrame(metrics_dict)
+ metrics_df = metrics_df.T
+ metrics_df.sort_values(by='num_positive', ascending=True, inplace=True)
+ metrics_df = metrics_df[['num_positive', 'n_components','n_comp_status', 'alpha', 'alpha_status','train_auroc', 'test_auroc', 'overfit']]
+
+ return(metrics_df)
+
+
+# In[10]:
+
+
+def display_stats(metrics_df, metrics_df_tocompare = None, verbose = True):
+ if verbose:
+ display(metrics_df)
+ # Summary for metrics_df
+ metrics_df.loc['mean'] = metrics_df.mean()
+ metrics_df.loc['median'] = metrics_df.median()
+ metrics_df_summary = metrics_df.loc[['mean', 'median']]
+ metrics_df_summary = metrics_df_summary[['num_positive', 'n_components', 'alpha', 'train_auroc', 'test_auroc','overfit']]
+ display(metrics_df_summary)
+ if metrics_df_tocompare is not None:
+ # Summary for metrics_df_tocompare
+ metrics_df_tocompare.loc['mean'] = metrics_df_tocompare.mean()
+ metrics_df_tocompare.loc['median'] = metrics_df_tocompare.median()
+ metrics_df_to_compare_summary = metrics_df_tocompare.loc[['mean', 'median']]
+ # Evaluate the improvement
+ mean_testing_auroc_improvement = metrics_df_summary['test_auroc']['mean'] - metrics_df_to_compare_summary['test_auroc']['mean']
+ median_testing_auroc_improvement = metrics_df_summary['test_auroc']['median'] - metrics_df_to_compare_summary['test_auroc']['median']
+ mean_overfit_reduction = metrics_df_to_compare_summary['overfit']['mean'] - metrics_df_summary['overfit']['mean']
+ median_overfit_reduction = metrics_df_to_compare_summary['overfit']['median'] - metrics_df_summary['overfit']['median']
+ print('Mean testing Auroc improved by {:.2f}%'.format(mean_testing_auroc_improvement*100))
+ print('Median testing Auroc improved by {:.2f}%'.format(median_testing_auroc_improvement*100))
+ print('Mean overfitting reduced by {:.1f}%'.format(mean_overfit_reduction*100))
+ print('Median overfitting reduced by {:.1f}%'.format(median_overfit_reduction*100))
+
+
+# ### 4.b. See how the parameters are related using the current setup
+
+# In[11]:
+
+
+get_ipython().run_cell_magic('time', '', 'metrics_df_current_setup = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [50, 100],\n k_function = None,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df_current_setup, metrics_df_tocompare = None)')
+
+
+# In[12]:
+
+
+# Show how some of these metrics/parameters might be related
+metrics_df_for_correlations = metrics_df_current_setup[['num_positive', 'n_components', 'alpha', 'train_auroc', 'test_auroc', 'overfit']]
+plt.figure(figsize=(12,12))
+plt.title('Correlations', y=1.05, size=15)
+sns.heatmap(metrics_df_for_correlations.astype(float).corr(),linewidths=0.1,vmax=1.0, square=True, annot=True)
+sns.plt.show()
+
+
+# ### 4.c. Evaluate how changing some of the parameters effects performance
+#
+# The three things I'd like to evaluate are n_components, alpha and l1_ratio
+#
+# My thoughts, going from easiest to most difficult to evaluate...
+# - alpha: just make the range larger if a lot of queries are at max or min (i.e. at the edge of the gridsearch space
+# - l1_ratio: the two values that we've discussed are 0 and 0.15... just try both for different setups
+# - n_components: try lists of varying size, try functions to auto select
+
+# #### Try all combos of:
+# #### k_range = [10, 20, 40, 80, 160, 320, 640]
+# #### alpha_range = [10** x for x in range(-10,10)]
+# #### and l1_ratio = 0
+
+# In[13]:
+
+
+get_ipython().run_cell_magic('time', '', '# k_range\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [10, 20, 40, 80, 160, 320, 640],\n k_function = None,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[14]:
+
+
+get_ipython().run_cell_magic('time', '', '# k_max. Test if a range is even any better than just the largest number...\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [640],\n k_function = None,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# Interesting, but maybe not too suprising. Looks like the range as opposed to just the max helps with overfitting but actually hurts with overall accurace
+
+# In[15]:
+
+
+get_ipython().run_cell_magic('time', '', '# l1_ratio\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [50, 100],\n k_function = None,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[16]:
+
+
+get_ipython().run_cell_magic('time', '', '# alpha_range\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [50, 100],\n k_function = None,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[17]:
+
+
+get_ipython().run_cell_magic('time', '', '# alpha_range and l1_ratio\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [50, 100],\n k_function = None,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[18]:
+
+
+get_ipython().run_cell_magic('time', '', '# alpha_range and k_range\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [10, 20, 40, 80, 160, 320, 640],\n k_function = None,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[19]:
+
+
+get_ipython().run_cell_magic('time', '', '# k_range and l1_ratio\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [10, 20, 40, 80, 160, 320, 640],\n k_function = None,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[20]:
+
+
+get_ipython().run_cell_magic('time', '', '# All three: k_range, alpha_range and l1_ratio\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [10, 20, 40, 80, 160, 320, 640],\n k_function = None,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[21]:
+
+
+get_ipython().run_cell_magic('time', '', '# All three: k_range, alpha_range and l1_ratio... Again this time only use the max of the k_range\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = [640],\n k_function = None,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# With the larger aplha range and l1_ratio it looks like having the range of k as opposed to just the max helps with both overall performance as well as overfitting
+
+# ### Use a function to automatically select the parameter space to search
+
+# In[22]:
+
+
+# k_range function
+def k_func(num_positives):
+ if num_positives < 50:
+ k_range = [6, 8, 10, 14, 20, 28]
+ elif num_positives < 100:
+ k_range = [10, 15, 20, 30, 50, 80]
+ elif num_positives < 200:
+ k_range = [15, 25, 50, 75, 100, 175]
+ elif num_positives < 500:
+ k_range = [60, 100, 150, 250, 400] # Tried 30, 60, 100, 150
+ else:
+ k_range = [100, 200, 400, 800]
+ return(k_range)
+
+
+# In[23]:
+
+
+get_ipython().run_cell_magic('time', '', '# k_range func\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = None,\n k_function = k_func,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[24]:
+
+
+get_ipython().run_cell_magic('time', '', '# k_range func with larger alpha range\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = None,\n k_function = k_func,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[25]:
+
+
+get_ipython().run_cell_magic('time', '', '# k_range func with larger alpha range and l1_ratio = 0\nmetrics_df = evaluate_classifier(X_train = X_train,\n X_test = X_test,\n y = y,\n y_train_allgenes = y_train_allgenes,\n y_test_allgenes = y_test_allgenes,\n list_of_genes = list_of_genes,\n set_k_range = None,\n k_function = k_func,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup)')
+
diff --git a/explore/number-of-components/number_of_pca_components_(subset_by_disease).ipynb b/explore/number-of-components/number_of_pca_components_(subset_by_disease).ipynb
new file mode 100644
index 0000000..bfe18e8
--- /dev/null
+++ b/explore/number-of-components/number_of_pca_components_(subset_by_disease).ipynb
@@ -0,0 +1,4207 @@
+{
+ "cells": [
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "# Explore how many PCA Components to Keep and Hyperparameter Tuning \n",
+ "# (Queries with subset of the diseases)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "__Purpose__\n",
+ "\n",
+ "Address issue #106 (https://github.com/cognoma/machine-learning/issues/106). Evaluate queries that don't inlcude all the samples but rather subset the samples by disease(s).\n",
+ "\n",
+ "__Assumptions/Notes:__\n",
+ "\n",
+ "This notebook differs from the current classifier in a number of ways including:\n",
+ "1. In this notebook, PCA is performed on the entire training set prior to cross-validation rather than performed on each individual cross-validation split. This is done for simplicity and to save time and memory.\n",
+ "2. In this notebook, the covariates data is not used (for now at least).\n",
+ "\n",
+ "\n",
+ "__To Do:__\n",
+ "\n",
+ "1. Some additional evaluation and... select a final setup.\n",
+ "2. _We could also try to add the covariates data into this evaluation and see how that changes things but I'm not planning on doing that at this point._"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## Outline:\n",
+ "1. Imports, constants and load the data\n",
+ "2. Build the querry set\n",
+ " * List of genes\n",
+ " * Summary stats for each gene-disease combo\n",
+ " * Generate a set of queries\n",
+ "3. Evaluate queries with a subset of diseases and varying number of positives\n",
+ " - a. Define some helper functions\n",
+ " - b. See how the parameters are related using the current setup\n",
+ " - c. Evaluate how changing some of the parameters effects performance\n",
+ " - d. See if we can use a function to automatically select the number of components"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 1. Imports, constants and load the data"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 1,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "import os\n",
+ "import time\n",
+ "import random\n",
+ "import math\n",
+ "\n",
+ "from sklearn.decomposition import PCA\n",
+ "from sklearn.linear_model import SGDClassifier\n",
+ "from sklearn.metrics import roc_auc_score, roc_curve\n",
+ "from sklearn.model_selection import train_test_split, StratifiedKFold\n",
+ "from dask_searchcv import GridSearchCV\n",
+ "from sklearn.pipeline import Pipeline, FeatureUnion\n",
+ "from sklearn.preprocessing import StandardScaler, FunctionTransformer\n",
+ "import matplotlib.pyplot as plt\n",
+ "import numpy as np\n",
+ "import pandas as pd\n",
+ "import seaborn as sns\n",
+ "from sklearn.feature_selection import SelectKBest"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 2,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "RANDOMSEED = 0"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 3,
+ "metadata": {
+ "scrolled": true
+ },
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wall time: 7.6 s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# Load the data\n",
+ "try: \n",
+ " path = os.path.join('download', 'expression-matrix.pkl')\n",
+ " X = pd.read_pickle(path)\n",
+ "except:\n",
+ " path = os.path.join('download', 'expression-matrix.tsv.bz2')\n",
+ " X = pd.read_table(path, index_col=0)\n",
+ "\n",
+ "try:\n",
+ " path = os.path.join('download', 'mutation-matrix.pkl')\n",
+ " y = pd.read_pickle(path)\n",
+ "except:\n",
+ " path = os.path.join('download', 'mutation-matrix.tsv.bz2')\n",
+ " y = pd.read_table(path, index_col=0)\n",
+ " \n",
+ "path = os.path.join('download', 'covariates.tsv')\n",
+ "covariates = pd.read_table(path,index_col=0)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 2. Build the query set"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 4,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "# List of genes to iterate over (from brankaj's notebook: \n",
+ "# https://github.com/cognoma/machine-learning/blob/master/explore/Classifier_results-different_genes.ipynb)\n",
+ "genes_LungCancer = {\n",
+ " '207': 'AKT1', \n",
+ " '238': 'ALK', \n",
+ " '673': 'BRAF', \n",
+ " '4921':'DDR2',\n",
+ " '1956':'EGFR',\n",
+ " '2064':'ERBB2',\n",
+ " '3845':'KRAS',\n",
+ " '5604':'MAP2K1',\n",
+ " '4893':'NRAS',\n",
+ " '5290':'PIK3CA',\n",
+ " '5728':'PTEN',\n",
+ " '5979':'RET',\n",
+ " # '6016':'RIT1', (removed because too few positives)\n",
+ " '6098':'ROS1',\n",
+ "}\n",
+ "\n",
+ "genes_TumorSuppressors = {\n",
+ " '324': 'APC', \n",
+ " '672': 'BRCA1', \n",
+ " '675': 'BRCA2',\n",
+ " '1029':'CDKN2A',\n",
+ " '1630':'DCC',\n",
+ " '4089':'SMAD4',\n",
+ " '4087':'SMAD2',\n",
+ " '4221':'MEN1',\n",
+ " '4763':'NF1',\n",
+ " '4771':'NF2',\n",
+ " '7157':'TP53', \n",
+ " '5728':'PTEN', \n",
+ " '5925':'RB1',\n",
+ " '7428':'VHL',\n",
+ " '7486':'WRN',\n",
+ " '7490':'WT1',\n",
+ "}\n",
+ "\n",
+ "genes_Oncogenes = {\n",
+ " #'5155':'PDGFB', #growth factor (removed because too few positives)\n",
+ " '5159':'PDGFRB', #growth factor \n",
+ " '3791':'KDR', #receptor tyrosine kinases\n",
+ " '25':'ABL1', #Cytoplasmic tyrosine kinases\n",
+ " '6714':'SRC', #Cytoplasmic tyrosine kinases\n",
+ " '5894':'RAF1',#cytoplasmic serine kinases\n",
+ " '3265':'HRAS',#regulatory GTPases\n",
+ " '4609':'MYC',#Transcription factors\n",
+ " #'2353':'FOS',#Transcription factors (removed because too few positives)\n",
+ " \n",
+ "}\n",
+ "\n",
+ "list_of_genes = (list(genes_LungCancer.keys()) + list(genes_TumorSuppressors.keys()) + \n",
+ " list(genes_Oncogenes.keys()))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "Create a dictionary of {gene: \n",
+ "{disease: \n",
+ "{total: #, positive: #, negative: #}, ..."
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 5,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wall time: 3.49 s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "disease_list_acronyms = [col for col in covariates.columns if col.startswith('acronym_')]\n",
+ "disease_list = [disease.strip('acronym_') for disease in disease_list_acronyms]\n",
+ "gene_dict = {}\n",
+ "for gene in list_of_genes:\n",
+ " # Subset by gene.\n",
+ " y_gene = y[gene] \n",
+ " gene_dict[gene] = dict.fromkeys(disease_list)\n",
+ " for disease in disease_list:\n",
+ " # Subset by disease.\n",
+ " disease_cols = [col for col in disease_list_acronyms if col.endswith(disease)]\n",
+ " has_disease = covariates[disease_cols].max(axis=1) > 0\n",
+ " disease_cols = covariates[has_disease]\n",
+ " y_gene_disease = y_gene[y_gene.index.isin(disease_cols.index)]\n",
+ " # Get query stats.\n",
+ " stats = {}\n",
+ " stats['total'] = y_gene_disease.shape[0]\n",
+ " stats['positive'] = y_gene_disease.sum()\n",
+ " stats['negative'] = stats['total'] - stats['positive']\n",
+ " gene_dict[gene][disease] = stats"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 6,
+ "metadata": {},
+ "outputs": [
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "There are 106 queries in the list.\n"
+ ]
+ }
+ ],
+ "source": [
+ "'''Randomly iterate through gene/disease(s) combinations to create a list\n",
+ "of queries that we can use for analysis. Something like:\n",
+ "[ [gene, [disease1, disease2, etc], {total: #, negative: #, positive: #}], ]\n",
+ "\n",
+ "Try to provide general coverage of the\n",
+ "different possibilities of class balance and total sample size while using\n",
+ "the following constraints:\n",
+ "1. All queries should have at least 20 positives.\n",
+ "2. Only use one gene per query (for simplicity).\n",
+ "'''\n",
+ "\n",
+ "def generate_queries(randomseed = 0, positive_bound = 20):\n",
+ " random.seed(randomseed)\n",
+ " queries = []\n",
+ " keys_gene = list(gene_dict.keys())\n",
+ " random.shuffle(keys_gene)\n",
+ " for gene in keys_gene:\n",
+ " keys_disease = list(gene_dict[gene].keys())\n",
+ " random.shuffle(keys_disease)\n",
+ " total_total, total_positives, total_negatives = 0, 0, 0\n",
+ " diseases = []\n",
+ " for disease in keys_disease:\n",
+ " if total_positives < positive_bound:\n",
+ " total_total += gene_dict[gene][disease]['total']\n",
+ " total_positives += gene_dict[gene][disease]['positive']\n",
+ " diseases.append(disease)\n",
+ "\n",
+ " total_negatives = total_total - total_positives\n",
+ " num_diseases = len(diseases)\n",
+ " query = [gene, diseases, {'total': total_total, 'positive': total_positives, 'negative': total_negatives}]\n",
+ " if query[2]['positive'] >= positive_bound:\n",
+ " queries.append(query)\n",
+ " return(queries)\n",
+ "\n",
+ "query_list1 = generate_queries(randomseed = 0, positive_bound = 20)\n",
+ "query_list2 = generate_queries(randomseed = 1, positive_bound = 60)\n",
+ "query_list3 = generate_queries(randomseed = 2, positive_bound = 100)\n",
+ "query_list4 = generate_queries(randomseed = 3, positive_bound = 200)\n",
+ "query_list5 = generate_queries(randomseed = 4, positive_bound = 400)\n",
+ "query_list6 = generate_queries(randomseed = 5, positive_bound = 500)\n",
+ "query_list = query_list1 + query_list2 + query_list3 + query_list4 + query_list5 + query_list6\n",
+ "print('There are ' + str(len(query_list)) + ' queries in the list.')"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 7,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nB1wZq1Pi/ukpAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "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\nFxERaYH+P7t5tQnGyQPDAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Visuallize our query set to make sure it's not too skewed\n",
+ "number_of_diseases =[]\n",
+ "for query in query_list:\n",
+ " number_of_diseases.append(len(query[1]))\n",
+ "number_of_diseases.sort()\n",
+ "plt.plot(number_of_diseases)\n",
+ "plt.ylabel('number of diseases')\n",
+ "plt.title('Diseases')\n",
+ "plt.show()\n",
+ "\n",
+ "number_of_samples =[]\n",
+ "for query in query_list:\n",
+ " number_of_samples.append(query[2]['total'])\n",
+ "number_of_samples.sort()\n",
+ "plt.plot(number_of_samples)\n",
+ "plt.title('Samples')\n",
+ "plt.ylabel('number of samples')\n",
+ "plt.show()\n",
+ "\n",
+ "number_of_positives =[]\n",
+ "for query in query_list:\n",
+ " number_of_positives.append(query[2]['positive'])\n",
+ "number_of_positives.sort()\n",
+ "plt.plot(number_of_positives)\n",
+ "plt.title('Positives')\n",
+ "plt.ylabel('number of positives')\n",
+ "plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 3. Evaluate queries with different subsets of diseases and varying number of positives"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.a. Define some helper functions"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 8,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def variance_scorer(x, y):\n",
+ " \"\"\" \n",
+ " Get the variance for each column of X.\n",
+ " \n",
+ " Because principal components have decreasing variance\n",
+ " (i.e. PC4 has less variance than PC3 which has less variance\n",
+ " than PC2 etc.), we can use this function in SelectKBest to select\n",
+ " only the top X number of principal components.\n",
+ " \n",
+ " \"\"\"\n",
+ " scores = [np.var(column) for column in x.T]\n",
+ " return scores, np.array([np.NaN]*len(scores))"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 9,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def evaluate_classifier(X,\n",
+ " y,\n",
+ " list_of_queries,\n",
+ " set_k_range, k_function,\n",
+ " alpha_range, \n",
+ " l1_ratio):\n",
+ " \n",
+ " ''' Run a classifier setup on a set of queries.\n",
+ " \n",
+ " Loop through each query; train and test the classifier using the\n",
+ " hyperparameters input as parameters; populate the metrics dictionary\n",
+ " with some metrics of which parameters were selected and how well\n",
+ " the classifier did for that query.\n",
+ " '''\n",
+ " \n",
+ " # A dictionary to hold the performance metrics.\n",
+ " metrics_dict = {}\n",
+ " \n",
+ " # Loop through each query; train and test the classifer; populate the metrics dictionary.\n",
+ " for query in list_of_queries:\n",
+ " num_samples = query[2]['total']\n",
+ " num_positives = query[2]['positive']\n",
+ " \n",
+ " # Subset by gene.\n",
+ " y_query = y[query[0]]\n",
+ " # Subset by diseases.\n",
+ " disease_cols = [col for col in covariates.columns if col.endswith(tuple(query[1]))]\n",
+ " has_disease = covariates[disease_cols].max(axis=1) > 0\n",
+ " covariates_query = covariates[has_disease]\n",
+ " X_query = X[X.index.isin(covariates_query.index)]\n",
+ " y_query = y_query[y_query.index.isin(covariates_query.index)]\n",
+ " \n",
+ " # Test Train split\n",
+ " test_size = 0.2\n",
+ " X_train, X_test, y_train, y_test = train_test_split(X_query, y_query, stratify=y_query, test_size=test_size, random_state=RANDOMSEED)\n",
+ " # PCA.\n",
+ " scaler = StandardScaler()\n",
+ " if query[2]['total']*(1-test_size)*(1-(1/3)) > 350:\n",
+ " n_comp = 350\n",
+ " else:\n",
+ " n_comp = int(query[2]['total']*(1-test_size) - 1)\n",
+ " pca = PCA(n_components = n_comp, random_state = RANDOMSEED)\n",
+ " scaler.fit(X_train)\n",
+ " X_train_scaled = scaler.transform(X_train)\n",
+ " pca.fit(X_train_scaled)\n",
+ " X_train = pca.transform(X_train_scaled)\n",
+ " X_test_scaled = scaler.transform(X_test)\n",
+ " X_test = pca.transform(X_test_scaled)\n",
+ " \n",
+ " if set_k_range:\n",
+ " k_range = set_k_range\n",
+ " else:\n",
+ " k_range = k_function(num_samples=num_samples,\n",
+ " num_positives=num_positives,\n",
+ " ) \n",
+ " # Parameter Sweep for Hyperparameters\n",
+ " param_grid = {\n",
+ " 'select__k': k_range,\n",
+ " 'classify__loss': ['log'],\n",
+ " 'classify__penalty': ['elasticnet'],\n",
+ " 'classify__alpha': alpha_range,\n",
+ " 'classify__l1_ratio': l1_ratio,\n",
+ " }\n",
+ " pipeline = Pipeline(steps=[\n",
+ " ('select', SelectKBest(variance_scorer)),\n",
+ " ('classify', SGDClassifier(random_state=RANDOMSEED, class_weight='balanced'))\n",
+ " ])\n",
+ " cv_pipeline = GridSearchCV(estimator=pipeline, \n",
+ " param_grid=param_grid,\n",
+ " n_jobs=1, \n",
+ " scoring='roc_auc')\n",
+ " cv_pipeline.fit(X=X_train, y=y_train)\n",
+ " y_pred_train = cv_pipeline.decision_function(X_train)\n",
+ " y_pred_test = cv_pipeline.decision_function(X_test)\n",
+ " # Get ROC info.\n",
+ " def get_threshold_metrics(y_true, y_pred):\n",
+ " roc_columns = ['fpr', 'tpr', 'threshold']\n",
+ " roc_items = zip(roc_columns, roc_curve(y_true, y_pred))\n",
+ " roc_df = pd.DataFrame.from_items(roc_items)\n",
+ " auroc = roc_auc_score(y_true, y_pred)\n",
+ " return {'auroc': auroc, 'roc_df': roc_df}\n",
+ " metrics_train = get_threshold_metrics(y_train, y_pred_train)\n",
+ " metrics_test = get_threshold_metrics(y_test, y_pred_test)\n",
+ "\n",
+ " # Populate the metrics dictionary.\n",
+ " # Get metrics for the classifier.\n",
+ " overfit = metrics_train['auroc'] - metrics_test['auroc']\n",
+ " # Understand how the parameter grid worked... any params at the edge?\n",
+ " if cv_pipeline.best_params_['select__k'] == min(param_grid['select__k']):\n",
+ " n_comp_status = 'min'\n",
+ " elif cv_pipeline.best_params_['select__k'] == max(param_grid['select__k']):\n",
+ " n_comp_status = 'max'\n",
+ " else:\n",
+ " n_comp_status = 'OK'\n",
+ " if cv_pipeline.best_params_['classify__alpha'] == min(param_grid['classify__alpha']):\n",
+ " alpha_status = 'min'\n",
+ " elif cv_pipeline.best_params_['classify__alpha'] == max(param_grid['classify__alpha']):\n",
+ " alpha_status = 'max'\n",
+ " else:\n",
+ " alpha_status = 'OK'\n",
+ " metrics = {'num_samples': num_samples,\n",
+ " 'num_positive': num_positives,\n",
+ " 'balance': num_positives/num_samples,\n",
+ " 'train_auroc': metrics_train['auroc'], \n",
+ " 'test_auroc': metrics_test['auroc'],\n",
+ " 'n_components': cv_pipeline.best_params_['select__k'], \n",
+ " 'alpha': cv_pipeline.best_params_['classify__alpha'],\n",
+ " 'overfit': overfit,\n",
+ " 'n_comp_status': n_comp_status,\n",
+ " 'alpha_status': alpha_status\n",
+ " }\n",
+ " # Add the metrics to the dictonary.\n",
+ " metrics_dict[query[0]+str(query[2]['total'])] = metrics\n",
+ " # Change the metrics dict into a formatted pandas dataframe.\n",
+ " metrics_df = pd.DataFrame(metrics_dict)\n",
+ " metrics_df = metrics_df.T\n",
+ " metrics_df.sort_values(by='num_positive', ascending=True, inplace=True)\n",
+ " metrics_df = metrics_df[['num_samples', 'num_positive', 'balance', 'n_components','n_comp_status', 'alpha', 'alpha_status','train_auroc', 'test_auroc', 'overfit']]\n",
+ " \n",
+ " return(metrics_df)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 10,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def display_stats(metrics_df, metrics_df_tocompare = None, verbose = True):\n",
+ " if verbose:\n",
+ " display(metrics_df)\n",
+ " # Summary for metrics_df \n",
+ " metrics_df.loc['mean'] = metrics_df.mean()\n",
+ " metrics_df.loc['median'] = metrics_df.median()\n",
+ " metrics_df_summary = metrics_df.loc[['mean', 'median']]\n",
+ " metrics_df_summary = metrics_df_summary[['num_samples', 'num_positive', 'balance', 'n_components', 'alpha', 'train_auroc', 'test_auroc','overfit']]\n",
+ " display(metrics_df_summary)\n",
+ " if metrics_df_tocompare is not None:\n",
+ " # Summary for metrics_df_tocompare\n",
+ " metrics_df_tocompare.loc['mean'] = metrics_df_tocompare.mean()\n",
+ " metrics_df_tocompare.loc['median'] = metrics_df_tocompare.median()\n",
+ " metrics_df_to_compare_summary = metrics_df_tocompare.loc[['mean', 'median']]\n",
+ " # Evaluate the improvement\n",
+ " mean_testing_auroc_improvement = metrics_df_summary['test_auroc']['mean'] - metrics_df_to_compare_summary['test_auroc']['mean']\n",
+ " median_testing_auroc_improvement = metrics_df_summary['test_auroc']['median'] - metrics_df_to_compare_summary['test_auroc']['median']\n",
+ " mean_overfit_reduction = metrics_df_to_compare_summary['overfit']['mean'] - metrics_df_summary['overfit']['mean']\n",
+ " median_overfit_reduction = metrics_df_to_compare_summary['overfit']['median'] - metrics_df_summary['overfit']['median']\n",
+ " print('Mean testing Auroc improved by {:.2f}%'.format(mean_testing_auroc_improvement*100))\n",
+ " print('Median testing Auroc improved by {:.2f}%'.format(median_testing_auroc_improvement*100))\n",
+ " print('Mean overfitting reduced by {:.1f}%'.format(mean_overfit_reduction*100))\n",
+ " print('Median overfitting reduced by {:.1f}%'.format(median_overfit_reduction*100))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.b. See how the parameters are related using the current setup"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 11,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " n_comp_status | \n",
+ " alpha | \n",
+ " alpha_status | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 58944691 | \n",
+ " 4691 | \n",
+ " 20 | \n",
+ " 0.00426348 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.782923 | \n",
+ " 0.74492 | \n",
+ " 0.0380031 | \n",
+ "
\n",
+ " \n",
+ " 74861460 | \n",
+ " 1460 | \n",
+ " 20 | \n",
+ " 0.0136986 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.817329 | \n",
+ " 0.600694 | \n",
+ " 0.216634 | \n",
+ "
\n",
+ " \n",
+ " 251283 | \n",
+ " 1283 | \n",
+ " 20 | \n",
+ " 0.0155885 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.800495 | \n",
+ " 0.508893 | \n",
+ " 0.291602 | \n",
+ "
\n",
+ " \n",
+ " 51592405 | \n",
+ " 2405 | \n",
+ " 21 | \n",
+ " 0.00873181 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.761282 | \n",
+ " 0.707547 | \n",
+ " 0.0537348 | \n",
+ "
\n",
+ " \n",
+ " 4763502 | \n",
+ " 502 | \n",
+ " 21 | \n",
+ " 0.0418327 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.774203 | \n",
+ " 0.25 | \n",
+ " 0.524203 | \n",
+ "
\n",
+ " \n",
+ " 56043310 | \n",
+ " 3310 | \n",
+ " 21 | \n",
+ " 0.00634441 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.765153 | \n",
+ " 0.659195 | \n",
+ " 0.105959 | \n",
+ "
\n",
+ " \n",
+ " 20641064 | \n",
+ " 1064 | \n",
+ " 21 | \n",
+ " 0.0197368 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.684652 | \n",
+ " 0.328947 | \n",
+ " 0.355705 | \n",
+ "
\n",
+ " \n",
+ " 1956951 | \n",
+ " 951 | \n",
+ " 21 | \n",
+ " 0.022082 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.909588 | \n",
+ " 0.895722 | \n",
+ " 0.0138656 | \n",
+ "
\n",
+ " \n",
+ " 74903360 | \n",
+ " 3360 | \n",
+ " 21 | \n",
+ " 0.00625 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.702381 | \n",
+ " 0.593563 | \n",
+ " 0.108818 | \n",
+ "
\n",
+ " \n",
+ " 59791559 | \n",
+ " 1559 | \n",
+ " 21 | \n",
+ " 0.0134702 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.856815 | \n",
+ " 0.842532 | \n",
+ " 0.0142825 | \n",
+ "
\n",
+ " \n",
+ " 47712813 | \n",
+ " 2813 | \n",
+ " 21 | \n",
+ " 0.00746534 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.827375 | \n",
+ " 0.57737 | \n",
+ " 0.250005 | \n",
+ "
\n",
+ " \n",
+ " 46093624 | \n",
+ " 3624 | \n",
+ " 22 | \n",
+ " 0.00607064 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.640422 | \n",
+ " 0.408807 | \n",
+ " 0.231615 | \n",
+ "
\n",
+ " \n",
+ " 67145174 | \n",
+ " 5174 | \n",
+ " 22 | \n",
+ " 0.00425203 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.696595 | \n",
+ " 0.630213 | \n",
+ " 0.0663813 | \n",
+ "
\n",
+ " \n",
+ " 673774 | \n",
+ " 774 | \n",
+ " 22 | \n",
+ " 0.0284238 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.843964 | \n",
+ " 0.817881 | \n",
+ " 0.026083 | \n",
+ "
\n",
+ " \n",
+ " 40873727 | \n",
+ " 3727 | \n",
+ " 22 | \n",
+ " 0.00590287 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.579837 | \n",
+ " 0.584569 | \n",
+ " -0.00473223 | \n",
+ "
\n",
+ " \n",
+ " 2074011 | \n",
+ " 4011 | \n",
+ " 23 | \n",
+ " 0.00573423 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.791884 | \n",
+ " 0.918797 | \n",
+ " -0.126913 | \n",
+ "
\n",
+ " \n",
+ " 7157331 | \n",
+ " 331 | \n",
+ " 23 | \n",
+ " 0.0694864 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.834688 | \n",
+ " 0.683871 | \n",
+ " 0.150817 | \n",
+ "
\n",
+ " \n",
+ " 60981740 | \n",
+ " 1740 | \n",
+ " 24 | \n",
+ " 0.0137931 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.713535 | \n",
+ " 0.405831 | \n",
+ " 0.307705 | \n",
+ "
\n",
+ " \n",
+ " 49211918 | \n",
+ " 1918 | \n",
+ " 24 | \n",
+ " 0.012513 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.726003 | \n",
+ " 0.77467 | \n",
+ " -0.0486671 | \n",
+ "
\n",
+ " \n",
+ " 37911502 | \n",
+ " 1502 | \n",
+ " 25 | \n",
+ " 0.0166445 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.808637 | \n",
+ " 0.84527 | \n",
+ " -0.0366335 | \n",
+ "
\n",
+ " \n",
+ " 42212708 | \n",
+ " 2708 | \n",
+ " 26 | \n",
+ " 0.00960118 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.856765 | \n",
+ " 0.472998 | \n",
+ " 0.383767 | \n",
+ "
\n",
+ " \n",
+ " 5728769 | \n",
+ " 769 | \n",
+ " 26 | \n",
+ " 0.0338101 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.886965 | \n",
+ " 0.92349 | \n",
+ " -0.036525 | \n",
+ "
\n",
+ " \n",
+ " 6751044 | \n",
+ " 1044 | \n",
+ " 26 | \n",
+ " 0.0249042 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.892769 | \n",
+ " 0.760784 | \n",
+ " 0.131985 | \n",
+ "
\n",
+ " \n",
+ " 6721239 | \n",
+ " 1239 | \n",
+ " 27 | \n",
+ " 0.0217918 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.631297 | \n",
+ " 0.685597 | \n",
+ " -0.0542992 | \n",
+ "
\n",
+ " \n",
+ " 2381528 | \n",
+ " 1528 | \n",
+ " 31 | \n",
+ " 0.020288 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.683542 | \n",
+ " 0.551111 | \n",
+ " 0.132431 | \n",
+ "
\n",
+ " \n",
+ " 3265502 | \n",
+ " 502 | \n",
+ " 31 | \n",
+ " 0.061753 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.972553 | \n",
+ " 0.866667 | \n",
+ " 0.105887 | \n",
+ "
\n",
+ " \n",
+ " 48931566 | \n",
+ " 1566 | \n",
+ " 33 | \n",
+ " 0.0210728 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.876302 | \n",
+ " 0.863192 | \n",
+ " 0.0131097 | \n",
+ "
\n",
+ " \n",
+ " 59251891 | \n",
+ " 1891 | \n",
+ " 37 | \n",
+ " 0.0195664 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.749618 | \n",
+ " 0.657834 | \n",
+ " 0.0917835 | \n",
+ "
\n",
+ " \n",
+ " 10291371 | \n",
+ " 1371 | \n",
+ " 37 | \n",
+ " 0.0269876 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.601626 | \n",
+ " 0.439765 | \n",
+ " 0.161861 | \n",
+ "
\n",
+ " \n",
+ " 1630687 | \n",
+ " 687 | \n",
+ " 40 | \n",
+ " 0.0582242 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.771639 | \n",
+ " 0.667308 | \n",
+ " 0.104332 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 74281897 | \n",
+ " 1897 | \n",
+ " 123 | \n",
+ " 0.0648392 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.982454 | \n",
+ " 0.940056 | \n",
+ " 0.0423975 | \n",
+ "
\n",
+ " \n",
+ " 74283618 | \n",
+ " 3618 | \n",
+ " 125 | \n",
+ " 0.0345495 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.984603 | \n",
+ " 0.960801 | \n",
+ " 0.0238016 | \n",
+ "
\n",
+ " \n",
+ " 20645727 | \n",
+ " 5727 | \n",
+ " 126 | \n",
+ " 0.022001 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.775 | \n",
+ " 0.688528 | \n",
+ " 0.0864719 | \n",
+ "
\n",
+ " \n",
+ " 10291657 | \n",
+ " 1657 | \n",
+ " 127 | \n",
+ " 0.0766445 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.88398 | \n",
+ " 0.869967 | \n",
+ " 0.0140128 | \n",
+ "
\n",
+ " \n",
+ " 37914907 | \n",
+ " 4907 | \n",
+ " 127 | \n",
+ " 0.0258814 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.735143 | \n",
+ " 0.649446 | \n",
+ " 0.0856966 | \n",
+ "
\n",
+ " \n",
+ " 3845977 | \n",
+ " 977 | \n",
+ " 129 | \n",
+ " 0.132037 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.877724 | \n",
+ " 0.809729 | \n",
+ " 0.0679958 | \n",
+ "
\n",
+ " \n",
+ " 7157214 | \n",
+ " 214 | \n",
+ " 145 | \n",
+ " 0.67757 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.893574 | \n",
+ " 0.655172 | \n",
+ " 0.238401 | \n",
+ "
\n",
+ " \n",
+ " 10293699 | \n",
+ " 3699 | \n",
+ " 180 | \n",
+ " 0.0486618 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.895897 | \n",
+ " 0.890191 | \n",
+ " 0.0057065 | \n",
+ "
\n",
+ " \n",
+ " 6756299 | \n",
+ " 6299 | \n",
+ " 200 | \n",
+ " 0.0317511 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.702508 | \n",
+ " 0.611045 | \n",
+ " 0.0914631 | \n",
+ "
\n",
+ " \n",
+ " 52902178 | \n",
+ " 2178 | \n",
+ " 200 | \n",
+ " 0.0918274 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.710983 | \n",
+ " 0.679861 | \n",
+ " 0.0311218 | \n",
+ "
\n",
+ " \n",
+ " 38453433 | \n",
+ " 3433 | \n",
+ " 204 | \n",
+ " 0.0594232 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.954642 | \n",
+ " 0.959903 | \n",
+ " -0.00526127 | \n",
+ "
\n",
+ " \n",
+ " 57284327 | \n",
+ " 4327 | \n",
+ " 208 | \n",
+ " 0.0480703 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.737891 | \n",
+ " 0.771816 | \n",
+ " -0.0339252 | \n",
+ "
\n",
+ " \n",
+ " 59255055 | \n",
+ " 5055 | \n",
+ " 210 | \n",
+ " 0.041543 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.802516 | \n",
+ " 0.774387 | \n",
+ " 0.0281295 | \n",
+ "
\n",
+ " \n",
+ " 19566525 | \n",
+ " 6525 | \n",
+ " 215 | \n",
+ " 0.0329502 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.836085 | \n",
+ " 0.748185 | \n",
+ " 0.0879003 | \n",
+ "
\n",
+ " \n",
+ " 3241566 | \n",
+ " 1566 | \n",
+ " 218 | \n",
+ " 0.139208 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.925639 | \n",
+ " 0.881229 | \n",
+ " 0.0444103 | \n",
+ "
\n",
+ " \n",
+ " 16306753 | \n",
+ " 6753 | \n",
+ " 221 | \n",
+ " 0.0327262 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.713161 | \n",
+ " 0.666864 | \n",
+ " 0.0462971 | \n",
+ "
\n",
+ " \n",
+ " 47635733 | \n",
+ " 5733 | \n",
+ " 240 | \n",
+ " 0.0418629 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.701727 | \n",
+ " 0.690476 | \n",
+ " 0.0112513 | \n",
+ "
\n",
+ " \n",
+ " 10295881 | \n",
+ " 5881 | \n",
+ " 267 | \n",
+ " 0.0454004 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.84765 | \n",
+ " 0.852951 | \n",
+ " -0.00530103 | \n",
+ "
\n",
+ " \n",
+ " 3243430 | \n",
+ " 3430 | \n",
+ " 270 | \n",
+ " 0.0787172 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.824933 | \n",
+ " 0.791842 | \n",
+ " 0.0330905 | \n",
+ "
\n",
+ " \n",
+ " 71571090 | \n",
+ " 1090 | \n",
+ " 318 | \n",
+ " 0.291743 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.829466 | \n",
+ " 0.826603 | \n",
+ " 0.00286332 | \n",
+ "
\n",
+ " \n",
+ " 6734374 | \n",
+ " 4374 | \n",
+ " 401 | \n",
+ " 0.0916781 | \n",
+ " 20 | \n",
+ " min | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.940301 | \n",
+ " 0.934182 | \n",
+ " 0.00611882 | \n",
+ "
\n",
+ " \n",
+ " 52905130 | \n",
+ " 5130 | \n",
+ " 413 | \n",
+ " 0.0805068 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " min | \n",
+ " 0.642355 | \n",
+ " 0.660249 | \n",
+ " -0.0178934 | \n",
+ "
\n",
+ " \n",
+ " 3246956 | \n",
+ " 6956 | \n",
+ " 414 | \n",
+ " 0.059517 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.876185 | \n",
+ " 0.862895 | \n",
+ " 0.01329 | \n",
+ "
\n",
+ " \n",
+ " 6735286 | \n",
+ " 5286 | \n",
+ " 462 | \n",
+ " 0.0874007 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.941026 | \n",
+ " 0.934816 | \n",
+ " 0.00620965 | \n",
+ "
\n",
+ " \n",
+ " 38455657 | \n",
+ " 5657 | \n",
+ " 467 | \n",
+ " 0.0825526 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.928862 | \n",
+ " 0.929254 | \n",
+ " -0.000391796 | \n",
+ "
\n",
+ " \n",
+ " 38455925 | \n",
+ " 5925 | \n",
+ " 500 | \n",
+ " 0.0843882 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.937897 | \n",
+ " 0.93447 | \n",
+ " 0.00342684 | \n",
+ "
\n",
+ " \n",
+ " 6736820 | \n",
+ " 6820 | \n",
+ " 500 | \n",
+ " 0.0733138 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.916291 | \n",
+ " 0.919691 | \n",
+ " -0.00340091 | \n",
+ "
\n",
+ " \n",
+ " 71572135 | \n",
+ " 2135 | \n",
+ " 501 | \n",
+ " 0.23466 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.887948 | \n",
+ " 0.893028 | \n",
+ " -0.00507907 | \n",
+ "
\n",
+ " \n",
+ " 52905973 | \n",
+ " 5973 | \n",
+ " 510 | \n",
+ " 0.0853842 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.788651 | \n",
+ " 0.759414 | \n",
+ " 0.0292372 | \n",
+ "
\n",
+ " \n",
+ " 71572073 | \n",
+ " 2073 | \n",
+ " 580 | \n",
+ " 0.279788 | \n",
+ " 40 | \n",
+ " max | \n",
+ " 1 | \n",
+ " max | \n",
+ " 0.868897 | \n",
+ " 0.871555 | \n",
+ " -0.00265732 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
106 rows × 10 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components n_comp_status \\\n",
+ "58944691 4691 20 0.00426348 40 max \n",
+ "74861460 1460 20 0.0136986 20 min \n",
+ "251283 1283 20 0.0155885 20 min \n",
+ "51592405 2405 21 0.00873181 20 min \n",
+ "4763502 502 21 0.0418327 20 min \n",
+ "56043310 3310 21 0.00634441 20 min \n",
+ "20641064 1064 21 0.0197368 20 min \n",
+ "1956951 951 21 0.022082 40 max \n",
+ "74903360 3360 21 0.00625 20 min \n",
+ "59791559 1559 21 0.0134702 40 max \n",
+ "47712813 2813 21 0.00746534 40 max \n",
+ "46093624 3624 22 0.00607064 40 max \n",
+ "67145174 5174 22 0.00425203 20 min \n",
+ "673774 774 22 0.0284238 20 min \n",
+ "40873727 3727 22 0.00590287 40 max \n",
+ "2074011 4011 23 0.00573423 20 min \n",
+ "7157331 331 23 0.0694864 40 max \n",
+ "60981740 1740 24 0.0137931 40 max \n",
+ "49211918 1918 24 0.012513 40 max \n",
+ "37911502 1502 25 0.0166445 40 max \n",
+ "42212708 2708 26 0.00960118 40 max \n",
+ "5728769 769 26 0.0338101 40 max \n",
+ "6751044 1044 26 0.0249042 40 max \n",
+ "6721239 1239 27 0.0217918 20 min \n",
+ "2381528 1528 31 0.020288 20 min \n",
+ "3265502 502 31 0.061753 40 max \n",
+ "48931566 1566 33 0.0210728 20 min \n",
+ "59251891 1891 37 0.0195664 20 min \n",
+ "10291371 1371 37 0.0269876 40 max \n",
+ "1630687 687 40 0.0582242 20 min \n",
+ "... ... ... ... ... ... \n",
+ "74281897 1897 123 0.0648392 40 max \n",
+ "74283618 3618 125 0.0345495 40 max \n",
+ "20645727 5727 126 0.022001 20 min \n",
+ "10291657 1657 127 0.0766445 40 max \n",
+ "37914907 4907 127 0.0258814 40 max \n",
+ "3845977 977 129 0.132037 40 max \n",
+ "7157214 214 145 0.67757 40 max \n",
+ "10293699 3699 180 0.0486618 40 max \n",
+ "6756299 6299 200 0.0317511 40 max \n",
+ "52902178 2178 200 0.0918274 20 min \n",
+ "38453433 3433 204 0.0594232 20 min \n",
+ "57284327 4327 208 0.0480703 40 max \n",
+ "59255055 5055 210 0.041543 40 max \n",
+ "19566525 6525 215 0.0329502 40 max \n",
+ "3241566 1566 218 0.139208 40 max \n",
+ "16306753 6753 221 0.0327262 40 max \n",
+ "47635733 5733 240 0.0418629 40 max \n",
+ "10295881 5881 267 0.0454004 40 max \n",
+ "3243430 3430 270 0.0787172 20 min \n",
+ "71571090 1090 318 0.291743 40 max \n",
+ "6734374 4374 401 0.0916781 20 min \n",
+ "52905130 5130 413 0.0805068 40 max \n",
+ "3246956 6956 414 0.059517 40 max \n",
+ "6735286 5286 462 0.0874007 40 max \n",
+ "38455657 5657 467 0.0825526 40 max \n",
+ "38455925 5925 500 0.0843882 40 max \n",
+ "6736820 6820 500 0.0733138 40 max \n",
+ "71572135 2135 501 0.23466 40 max \n",
+ "52905973 5973 510 0.0853842 40 max \n",
+ "71572073 2073 580 0.279788 40 max \n",
+ "\n",
+ " alpha alpha_status train_auroc test_auroc overfit \n",
+ "58944691 0.001 min 0.782923 0.74492 0.0380031 \n",
+ "74861460 0.01 OK 0.817329 0.600694 0.216634 \n",
+ "251283 0.001 min 0.800495 0.508893 0.291602 \n",
+ "51592405 1 max 0.761282 0.707547 0.0537348 \n",
+ "4763502 0.001 min 0.774203 0.25 0.524203 \n",
+ "56043310 0.001 min 0.765153 0.659195 0.105959 \n",
+ "20641064 0.001 min 0.684652 0.328947 0.355705 \n",
+ "1956951 0.001 min 0.909588 0.895722 0.0138656 \n",
+ "74903360 0.1 OK 0.702381 0.593563 0.108818 \n",
+ "59791559 0.001 min 0.856815 0.842532 0.0142825 \n",
+ "47712813 0.01 OK 0.827375 0.57737 0.250005 \n",
+ "46093624 0.01 OK 0.640422 0.408807 0.231615 \n",
+ "67145174 0.01 OK 0.696595 0.630213 0.0663813 \n",
+ "673774 0.01 OK 0.843964 0.817881 0.026083 \n",
+ "40873727 1 max 0.579837 0.584569 -0.00473223 \n",
+ "2074011 1 max 0.791884 0.918797 -0.126913 \n",
+ "7157331 0.1 OK 0.834688 0.683871 0.150817 \n",
+ "60981740 0.01 OK 0.713535 0.405831 0.307705 \n",
+ "49211918 0.001 min 0.726003 0.77467 -0.0486671 \n",
+ "37911502 0.001 min 0.808637 0.84527 -0.0366335 \n",
+ "42212708 0.01 OK 0.856765 0.472998 0.383767 \n",
+ "5728769 0.001 min 0.886965 0.92349 -0.036525 \n",
+ "6751044 0.1 OK 0.892769 0.760784 0.131985 \n",
+ "6721239 0.001 min 0.631297 0.685597 -0.0542992 \n",
+ "2381528 1 max 0.683542 0.551111 0.132431 \n",
+ "3265502 0.1 OK 0.972553 0.866667 0.105887 \n",
+ "48931566 1 max 0.876302 0.863192 0.0131097 \n",
+ "59251891 0.1 OK 0.749618 0.657834 0.0917835 \n",
+ "10291371 0.01 OK 0.601626 0.439765 0.161861 \n",
+ "1630687 0.01 OK 0.771639 0.667308 0.104332 \n",
+ "... ... ... ... ... ... \n",
+ "74281897 1 max 0.982454 0.940056 0.0423975 \n",
+ "74283618 1 max 0.984603 0.960801 0.0238016 \n",
+ "20645727 1 max 0.775 0.688528 0.0864719 \n",
+ "10291657 1 max 0.88398 0.869967 0.0140128 \n",
+ "37914907 1 max 0.735143 0.649446 0.0856966 \n",
+ "3845977 1 max 0.877724 0.809729 0.0679958 \n",
+ "7157214 0.001 min 0.893574 0.655172 0.238401 \n",
+ "10293699 1 max 0.895897 0.890191 0.0057065 \n",
+ "6756299 0.1 OK 0.702508 0.611045 0.0914631 \n",
+ "52902178 0.1 OK 0.710983 0.679861 0.0311218 \n",
+ "38453433 1 max 0.954642 0.959903 -0.00526127 \n",
+ "57284327 1 max 0.737891 0.771816 -0.0339252 \n",
+ "59255055 0.1 OK 0.802516 0.774387 0.0281295 \n",
+ "19566525 1 max 0.836085 0.748185 0.0879003 \n",
+ "3241566 1 max 0.925639 0.881229 0.0444103 \n",
+ "16306753 1 max 0.713161 0.666864 0.0462971 \n",
+ "47635733 1 max 0.701727 0.690476 0.0112513 \n",
+ "10295881 1 max 0.84765 0.852951 -0.00530103 \n",
+ "3243430 0.1 OK 0.824933 0.791842 0.0330905 \n",
+ "71571090 1 max 0.829466 0.826603 0.00286332 \n",
+ "6734374 1 max 0.940301 0.934182 0.00611882 \n",
+ "52905130 0.001 min 0.642355 0.660249 -0.0178934 \n",
+ "3246956 1 max 0.876185 0.862895 0.01329 \n",
+ "6735286 1 max 0.941026 0.934816 0.00620965 \n",
+ "38455657 1 max 0.928862 0.929254 -0.000391796 \n",
+ "38455925 1 max 0.937897 0.93447 0.00342684 \n",
+ "6736820 1 max 0.916291 0.919691 -0.00340091 \n",
+ "71572135 1 max 0.887948 0.893028 -0.00507907 \n",
+ "52905973 1 max 0.788651 0.759414 0.0292372 \n",
+ "71572073 1 max 0.868897 0.871555 -0.00265732 \n",
+ "\n",
+ "[106 rows x 10 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 3041.51 | \n",
+ " 124.623 | \n",
+ " 0.0639019 | \n",
+ " 32.2642 | \n",
+ " 0.484962 | \n",
+ " 0.789995 | \n",
+ " 0.722518 | \n",
+ " 0.0674771 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 2627 | \n",
+ " 81 | \n",
+ " 0.0318417 | \n",
+ " 40 | \n",
+ " 0.1 | \n",
+ " 0.791884 | \n",
+ " 0.726322 | \n",
+ " 0.0456447 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components alpha train_auroc \\\n",
+ "mean 3041.51 124.623 0.0639019 32.2642 0.484962 0.789995 \n",
+ "median 2627 81 0.0318417 40 0.1 0.791884 \n",
+ "\n",
+ " test_auroc overfit \n",
+ "mean 0.722518 0.0674771 \n",
+ "median 0.726322 0.0456447 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Wall time: 31min 44s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "metrics_df_current_setup = evaluate_classifier(X = X,\n",
+ " y = y,\n",
+ " list_of_queries = query_list,\n",
+ " set_k_range = [20, 40],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df_current_setup, metrics_df_tocompare = None)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 12,
+ "metadata": {
+ "scrolled": false
+ },
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAA1sAAAN0CAYAAABCxjLmAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzs3Xt8zvX/x/Hntc0OdjR2wpyPJYrOkSgpdKBCERJSSdFB\ncmaMnJOcDTkT5RhtzpKczyEtZzY2bMOuXbuu3x/7/sYadq18tl3zuN9uu91cn+v92ef5+fTps+u1\n92Emm81mEwAAAADgrnLK7QAAAAAAkB9RbAEAAACAASi2AAAAAMAAFFsAAAAAYACKLQAAAAAwAMUW\nAAAAABjAJbcDAAAAAMj7OppK5XaEbBlv+zu3I9CzBQAAAABGoNgCAAAAAANQbAEAAACAAZizBQAA\nACBLzqbcTuB46NkCAAAAAANQbAEAAACAARhGCAAAACBLzibGEWYXPVsAAAAAYACKLQAAAAAwAMUW\nAAAAABiAOVsAAAAAssTS79lHzxYAAAAAGIBiCwAAAAAMwDBCAAAAAFli6ffso2cLAAAAAAxAsQUA\nAAAABqDYAgAAAAADMGcLAAAAQJZY+j376NkCAAAAAANQbAEAAACAARhGCAAAACBLLP2effRsAQAA\nAIABKLYAAAAAwAAMIwQAAACQJVYjzD56tgDAAGazWZMnT9arr76qhx56SE8++aQ6duyoffv25XiW\nMWPGqF69ena3P3v2rJYvX57++u2331aPHj2MiAYAQL5GzxYA3GXXrl1Tq1atFB8fr86dO6tatWpK\nSkrSjBkz1KJFC02cOFGPP/54bse8ra+++kpBQUFq2LChpLRizcWFHxcAAGQXPz0B4C4bNWqU/v77\nby1btkxBQUHp2wcPHqyLFy9qwIABWrZsmUx5dFUnm82W4bWfn18uJQEAwLExjBAA7iKz2axFixbp\n9ddfz1Bo/b/evXtr+PDhMplMOnPmjLp06aLHH39cDz30kD744AOdPHkyvW3dunU1ZMgQ1a9fX48/\n/rgOHDhwy21ms1mDBw9WzZo1Vb16dbVs2VK7d+++bcatW7eqZcuWeuihh1SlShW98sor2rBhgyTp\nyy+/1JYtW7R48WJVrFhRUuZhhNu3b0/f/8knn1RYWJiuXbsmSTp16pQqVqyoVatWqXHjxqpSpYrq\n16+vyMjI9P13796t5s2b68EHH9Rjjz2mzz//XJcuXfpvFx4AYDhnk8mhvvICii0AuItOnjypK1eu\nqFq1ard8PzQ0VJUqVVJiYqLefPNNXb58WVOmTNH333+vhIQEtWzZUgkJCent58yZowEDBmjChAmq\nXLnyLbd98cUX2rZtm0aNGqUffvhBjz/+uN5++21FR0dnOv7Zs2fVvn171ahRQ0uWLNHChQsVEhKi\nbt26yWw2q0ePHnr44Yf14osvatOmTZn237Nnj9q0aaMHHnhACxcuVHh4uKKiotSlS5cM7b7++mt1\n6dJFy5cvV+XKldWtWzddvXpVqampev/99/XEE09o2bJlmjhxovbt26chQ4b8l8sOAECexDBCALiL\nrly5Ikny8fG5Y7uffvpJV65c0YgRI9KH6Y0ePVp169bVkiVL1KJFC0lpvVuPPvpohn1v3nb8+HGt\nXLlSy5YtU/ny5SVJnTp10o4dOxQREaH+/ftn2DclJUUff/yx2rZtmz6MsU2bNmrdurUuXryokJAQ\nFShQQO7u7goICMiUe+rUqapSpYq6desmSSpbtqz69u2rDh066OjRo/Lw8JAkvfvuu3r66aclSR07\ndtTKlSv1559/qkSJEoqPj1eRIkVUrFgxFS9eXGPHjlVKSoqdVxgAAMdBsQUAd1GhQoUkKcthcUeP\nHlXp0qUzzIfy9/dX2bJldeTIkfRtoaGhmfa9edvBgwclSU2bNs3Qxmw2y2w2Z9q3RIkSevXVVzV9\n+nQdPnxYx48f16FDhyRJqampWZ2ejh49qtq1a2fY9vDDD6e/V7VqVUlS6dKl09/38vKSlFbo+fn5\n6Z133lH//v01ZswYPfXUU6pTp47q16+f5bEBALmLIXHZR7EFAHdRiRIlVLhwYe3Zs0cNGjTI9P7W\nrVsVEREhf3//W+5vtVpVoECB9Ndubm6Z2ty87f/bzp07V+7u7hnaubq6Ztr3yJEjatGihapVq6Yn\nnnhCDRo0kMViUceOHe06v38eQ7qxoMbNKxbefA7/bNetWze1aNFC69ev16ZNm9S9e3fNnz9fM2bM\nsCsDAACOggIVAO4iJycnNW7cWD/88IPOnz+f4T2bzaaJEycqOjpaDz30kKKjozP0gMXFxSk6Olpl\ny5a1+3j/P3Tw4sWLKlmyZPrXtGnTFBUVlan9vHnzFBISosmTJ+vdd99VrVq10nP+fzF0p1USy5Yt\nq127dmXYtmPHjvT3snLixAn16dNHAQEBatGihcaNG6chQ4Zo69atunjxon0nDQCAg6DYAoC77IMP\nPlDx4sX11ltvadmyZTp58qR27dqlzp07a9u2bRo4cKBefvll+fv7q2vXrjpw4IAOHDigrl27ysfH\nJ/3vW9mjZMmSatCggXr16qX169frxIkTGjlypObOnXvL4ic4OFinT5/W5s2bdfr0af30008aOXKk\nJKUPO/T09NSpU6d0+vTpTPu3b98+fUGLv/76Sxs3blS/fv1Uu3Ztu4qtQoUKaeXKlerbt6+OHTum\nY8eOaeXKlSpRokT6EEwAAPILii0AuMs8PT01c+ZMNWrUSN9++60aNWqkjz76SFarVfPmzdPDDz8s\nNzc3TZkyRa6urmrZsqVat24tb29vzZo1K8vFNf4pLCxMtWvX1ldffaVGjRppw4YNGjNmjJ544olM\nbVu1aqV69eqpS5cuevnllzVr1iz169dPBQsW1L59+yRJLVq0UHR0tBo0aKDY2NgM+1eoUEHjx4/X\n77//rpdfflndu3dXvXr1NHr0aLuyent7a9KkSTp58qSaNm2q119/XWazWRMnTpSTEz+SACAvy+2l\n3B1x6XeT7Z9/vRIAAAAA/mFgwfK5HSFbelw9mtsR6NkCAAAAACOwGiEAAACALDnnjZF5DoWeLQAA\nAAAwAMUWAAAAABiAYYQAAAAAspRXVvhzJPRsAQAAAIABKLYAAAAAwAAUWwAAAABgAOZsAQAAAMgS\nS79nHz1bAAAAAGAAii0AAAAAMADDCAEAAABkiaXfs4+eLQAAAAAwAMUWAAAAABiAYgsAAAAADMCc\nLQAAAABZYun37KNnCwAAAAAMQLEFAAAAAAZgGCEAAACALLH0e/bRswUAAAAABqDYAgAAAAADMIwQ\nAAAAQJZYjTD76NkCAAAAAANQbAEAAACAASi2AAAAAMAAzNkCAAAAkCXmbGUfPVsAAAAAYACKLQAA\nAAAwAMMIAQAAAGTJ2cQ4wuyiZwsAAAAADECxBQAAAAAGYBghAAAAgCyxGmH20bMFAAAAAAag2AIA\nAAAAA1BsAQAAAIABmLMFAAAAIEss/Z599GwBAAAAgAEotgAAAADAAAwjBAAAAJAlln7PPnq2AAAA\nAMAAFFsAAAAAYADDhxF2NJUy+hD3tPG2v3Ulondux8jXfN7pr6nbT+R2jHyt7cMlJEmp0TtzOUn+\n5ly6ui5N/Cq3Y+Rrfh0GacfJS7kdI1+rEeqn5ASusdHcvP206nBMbsfI1+pXDMztCMgBzNkCAAAA\nkCWWfs8+hhECAAAAgAEotgAAAADAAAwjBAAAAJAlln7PPnq2AAAAAMAAFFsAAAAA7ilWq1W9e/dW\ns2bN9Pbbb+v48eMZ3l+yZIkaN26s1157TbNnz/7Xx2EYIQAAAIAs5afVCCMjI2U2mzVv3jzt3r1b\ngwcP1rhx49Lf//rrr7Vs2TIVLFhQDRs2VMOGDeXr65vt41BsAQAAALin7NixQ7Vq1ZIkPfjgg9q/\nf3+G9ytWrKiEhAS5uLjIZrPJ9C8LTYotAAAAAPeUxMREeXl5pb92dnaWxWKRi0taeVS+fHm99tpr\n8vDwUL169eTj4/OvjsOcLQAAAAD3FC8vLyUlJaW/tlqt6YXWH3/8oXXr1ikqKkpr1qxRXFycVq5c\n+a+OQ7EFAAAAIEtOJpNDfd1J9erVtWHDBknS7t27VaFChfT3vL295e7uLjc3Nzk7O8vf319Xrlz5\nV9eMYYQAAAAA7in16tXT5s2b1bx5c9lsNg0aNEhLly7V1atX1axZMzVr1kxvvfWWChQooBIlSqhx\n48b/6jgUWwAAAADuKU5OTurfv3+GbWXLlk3/95tvvqk333zzPx+HYgsAAABAlkzO+Wfp95zCnC0A\nAAAAMADFFgAAAAAYgGILAAAAAAzAnC0AAAAAWXJizla20bMFAAAAAAag2AIAAAAAAzCMEAAAAECW\nTM7002QXVwwAAAAADECxBQAAAAAGYBghAAAAgCyZWI0w2+jZAgAAAAADUGwBAAAAgAEotgAAAADA\nAMzZAgAAAJAlJ+ZsZRs9WwAAAABgAIotAAAAADAAwwgBAAAAZMnkRD9NdnHFAAAAAMAAFFsAAAAA\nYACKLQAAAAAwAHO2AAAAAGSJpd+zj54tAAAAADAAxRYAAAAAGIBhhAAAAACyZGIYYbbRswUAAAAA\nBqBn6x9aRwzTmf2H9cvwSbkdxeFs+vOMxq7fK3OqVeUDfNWzwaPycitwy7brjpxS32Vbta7ra5Kk\n6ykWfb16pw6ei5PVZlOVkML64vnqci/ALfpPx3Zt1fp5U5RqSVFAaGm92P5TuRX0zNRux+oftSty\nmUwmk/wCQ/RCuy7y9C0kSdr5yxLtXbdSKeZkBZeuoBfbd5VLAdecPpU8a/3WnRoZMVfmFIsqlC6h\nsC4d5OVZMFM7m82mHsPHq1ypULV9vZEk6ZOwkTp+5nx6m9PnYvTIA5U1tt/nOZbfEWz666zGbdwv\nc6pV5QJ81eP5Grd9Xqw/elp9f96utR+9IklKTE5R2KodOh6XIKvNpob3l1SrRyvmZHyHseu3TZo7\nZZwsKWaFlimnDp/2UEFPr0ztNkWu1LL5M2UymeTq5q7WH36qMhUry5x8XRHfDNVfhw/JarOqXKX7\n9U7nz+Xq5p4LZ5M3bNi0SaO/HSez2awK5cupX68e8vLysqtNQmKi+vQPU/Tfx2WzWfVyw4Zq26aV\nJOny5csKHzpcf/0VrevJyWrfto1eatggN04xTzqw7VctnTFBFkuKipYsqzc7fymPW/zs27Z2laIW\nz5HJZFIBN3e93v5jlShfSdbUVC2YMFJ/HtgtSbq/xhN65Z0PZDLRUwNj0bP1P8GVyuqTqNmq0bRh\nbkdxSPFXr6v/it81pPFT+qFDAxXz89K36/bcsu2JuASNXrNHVtuNbRFbDinVatXstvU1p219JVtS\nNW3LoRxK7ziuXrmkFROH6dVPeqv9sAj5BYZo/bwpmdqdiz6i35cv1Nt9R+vdIZNUKLiYNi6cLkk6\nvG2jdqz+Uc26D1G7IZNlMSdr+8pFOX0qeVbcpSvqMWKCRvXqohVTRig0JFAjIuZkanfsxGm1/TJM\nP2/8LcP2UT27aPF3g7X4u8Hq/3F7eXt5qmentjkV3yHEX01W2M87FP7y41rQtr6K+Xrqu437b9n2\nRHyCvtmwTzbbjQfGhM0HFOjtoTlt6mlay7patOcv7TtzMafiO4wrl+I1YViYPukTruHTFigopJjm\nTv4uU7szJ49r9sQx6hY+WuETZurVFu9oZN9ukqQfZ01TamqqwifO1JCJs2Q2J+unOdNz+Ezyjrj4\nePXqF6YRX4dr6aIFKl6smEZ9+53dbcaOm6CgoEAtnj9Hs2dM0/wfFmnP3n2SpJ59BygoMFDzZ3+v\nid+N0eBhI3Tu/PlMGe5FCZfjNeubcLXtHqae42arcHBRLZ0+PlO786dO6Kdp3+n9vsPUbXSE6jdt\npSnhPSRJ29atUszpk+r+zXR9OXqa/ty/W7s3r8vhM3F8Jmcnh/rKC/JGijzgmQ9baUvEAu2Yvzy3\nozik36LP6b4Qf5Xw95YkvfZQOf188ESGD0hSWg9W76W/6ZNnH8yw/aHQALV96n45mUxydnJSxSA/\nnbtyNcfyO4rofTsUXKaC/IOLS5Ieeu4lHdgclek6B5euoA7Dp8mtoKcsZrMS4y/Iwyvtv82BjZF6\ntMHr8vDykcnJSfXbfqz7az6X4+eSV23euVdVKpRRqWIhkqTmDetp2ZrNma7xnKWr1bjeM3qh1uO3\n/D7mFIu6Dx+n7u+1UkhAYcNzO5Ktx8+rcnAhlSiUdk82qVZGPx+69fOi74pt+rh21Qzbu9apps61\nH5AkXUi8LnOqVZ636RW7l+3dsVVlKlRWSPESkqTnXmqizVE/Z7rOBQoUUPuuX6lQ4SKSpDIVKutS\n/EVZUlJUqeqDatyyrZycnOTk7KxS5SrqwvlzOX4uecWW37aqyn2VVbJE2jVt+noTrViZ8ZreqU23\nz7rq0487S5IuXLggs9ksLy9PXb58Wb/9/rs6dmgnSQoOCtKsaVPl6+ubw2eYN/2xa5tKlK+kwKKh\nkqSaL76q7et/yXQvuxQooDc7dZOvf9q9XKJcJV25FCdLSoqsqVaZk6/JYkmRJcUsiyVFLq6M6IDx\n7B6jZbVaZbPZtGvXLlWtWlWu+ewGnftRH0lSpWefyuUkjun8lWsK8r4xzCrQx0NJySlKMlsyDA0a\n9PN2NXmwrMoH+GXY//HSwen/Pns5SXO2H9FXLzxifHAHk3AxVj7+Aemvvf0DZL52VeZrVzMNJXR2\ncdGR7Zv186QRci5QQDVfby1Jijt7SiFlK2r+kO5KjL+o4hWr6Jk32+foeeRl52IvKvim4igowF+J\nV68p6eq1DEMJe374jiTpt9237pFZtGqtAv0L6bmnuI//Ke154ZH+OtDbQ0lmS6bnRfgvu/Rq1TIq\nF5DxA6fJZJKLyaQ+K37XmiOnVbtcUZX8X+GGG+JizqtwYFD6a/+AQF27mqRrV5MyDCUMCC6qgOCi\nktKGxs4cP1o1nqgllwIFVPXhG79MiD1/VisXzVW7Lt1z7iTymHPnzys46MY1DQoMVGJSkpKSktKH\nEmbVxsXFRd179dEvUWtU95naKlWypA4e+kNFihTW9zNna9OvW2ROMat1yxYqVbJEjp9jXnTpQowK\nFblxTf2KBOj61SRdv3Y1w1DCwkEhKhyU9osym82mxVPGqMqjT8mlQAE99uyL2rV5rXq1aSyrNVWV\nHnxUDzzKZz4Yz66erYEDB2r+/PkaPXq0xo0bp169ehmdCw7mn79d+n/ON42FXrDzqJydTHq5Wpnb\nfp9D5+LUftYaNa1eXrXKFb3rOR2dzWa95XaT063/V67w8FPqPOEHPdWkleYP7i6b1SprqkV/79up\nVz7qqdZhY3U9KUEbFkQYGduhWG9zLztlczjC9MUr1PHNxncjUr5j022eF043nhcLdx9Le148UOq2\n36dfg0e16oOXdOW6WVMYdpzJbe9lJ+dbbr9+7ZpGD/hK50+fVPtPe2R4768jh9T/k/f0/CtvqPrj\nNe96Vkdhtd7u+eCcrTbhA/ppQ+QqXblyReMnT5HFYtHp02fk6eWpGVMn6etBYRo6YpQOHuK+liSb\n9dY/+5xu87Mv+fo1RQzprdizp/Vmp7QhsSvnRsjL108DZyxR/6mLlJR4RWsWzzUsM/D/7OrZ2rdv\nn3r06KG3335b33//vVq3bm10LjiYIJ+C2n/TnInYhGvycXeVh+uNW2zZvr91PcWit6aukiXVqmRL\nqt6aukqj33haAd4eWn3whIas3qHP61XXC/eXzI3TyJM2LpymP3dskSQlX7uqgNDS6e8lxF2Qu6e3\nXN09MuwTf+60ki7Hq3jFKpKkqs/U1+qpo3U9KVFehQqr/MNPpfeE3f/Uc9q8eGYOnU3eFxJQWHv/\n+DP99fkLcfLx8lRBd/sXBDj4Z7RSU616pGplIyI6vCDvgtp/Ni79dWziNfm4F5DHTQviLD9wXNdT\nUtVyRqRS/ve8aDkjUiObPKVjFy6rbBFfBXh5qKCri56vFKq1R0/nxqnkOQumTdDOLRslSVeTklSi\ndNn09+IuxMrT20fuHh6Z9rtw/pyG9fpURUuUUs/h32VYAOPXtasV8c1Qten0mZ56tr7xJ5GHhQQH\nad/+G73ZMbGx8vHxUcGbrumd2mze8pvKlyurwIAAFSxYUC/Wf16/rFmrVxqlLbDzSqO0eeMlQkP1\n0IPVtO/AQd1X+d58jiyfNVn7f98sSbp+NUkhJW/cy5cvXlBBL2+5uWe+l+Niz2vigG4KDi2pjwZ+\nI1c3N0nS3i0b9FqHT+RSoEBaT1fdF7R78zrVbdw8Z04on3Bi6fdss+tXtVarVfv371fx4sVlNpuV\nlJRkdC44mMdLB2v/mYs6EZcgSfph1zE9XT5jz9T01vU0r92Lmt22vka98bTcXJw1u219BXh7KOqP\nkxoWuVNjmtWm0PqHWq+30TvhE/RO+AS93e8bnfnzkOLOnZIk7Y5apnI1nsi0T+KlOP00ZqCuJlyW\nJB3cvEZFQkvJw9tHFR99Wod/36AUc7JsNpuObN+skDIVcvSc8rKnalTV3j+O6u/TZyVJ85ZHqu4T\nD2fre2zfd0iPVbufVa5u47FSgdp/Nk4n4tOeF4v2RKtW2YzPi4gWdTWnTT3NbPWcRjZ5Sm4uzprZ\n6jkFeHko8vBpTd5ySDabTWZLqiKPnNLDJQJz41TynDfavKfwCTMVPmGm+o+ZoqOH9uvsqROSpKil\ni1TjyVqZ9km8clkDPu2oR2rWUeeeAzMUWls3RGnG2BHqPvibe77QkqQnHn9Me/fv1/ETadd0wQ+L\nVKd2LbvbrP4lUuMnTk67d81mrfolUo89/LCKFyuqypUqasmyFZKkixcvas/efbr/Hi20JKlhi3bq\nNjpC3UZHqOvQCTp++IBizpyUJG1a+aMeeCxzD2tSwhV90/0jVXuittp83i+90JKk4mUraNemNZKk\nVItF+7ZuVqmK9+fMyeCeZlfP1iuvvKJ+/fpp0KBBGjp0qJo1a2Z0LjgYf0939W74qL5cvFkpVquK\n+3mpb6PHdPBsnMJWbtPstnf+IT12/V7ZbFLYym3p26oVL6Juz9cwOrpD8fQtpAbvfaYfRw9QqiVF\nhQKLquH7X0iSzv51WD9PGqF3wicotNIDevLVtzQn7DM5OTnJq1BhNenSV5L0UL2XdC0xQdN7fCCb\nzaqgUuVUt8V7uXhWeUthP1+Fde2oLmGjlGKxKDQkSOGff6D9R46p16hJWvzd4Cy/x/HT51QsqEgO\npHVM/gXd1at+DXVfulWWVKuK+XmqzwuP6NC5eA1cvUMzW915wZaPaz+gwZG79Nb0SJlM0tPliqpZ\n9XI5lN5x+Bby13uf99Lo/t1lsVgUFFJM73dLm5/81+FDmjRioMInzFTk0kW6EHNe2zev0/abVmf7\n6uuxmjvlO9lsNk0aMTB9e4X7q+qdzl/k9OnkCYX9/TWgdy992q27UlIsCi1eTAP79dGBg4fUN2yg\nFsyeeds2kvRpl48VNmiwmjR7SyaTSXWfeVot3kz7TDVq2NcaOGSoFixaJKvVpvfatVWV++/LzdPN\nM7z9Cumtj7tr6uBeSrVYVCS4qFp26SlJOnH0D835doi6jY7QppU/Kv7Cee39bYP2/rYhff9OA0ap\nybsfaeHEUQp7v4WcnJxUoVoNPfdai9w6JdxDTLbbTbb5h4SEBJ0+fVolSpRQwYKZ/97M7XQ0lfqX\n0WCP8ba/dSWid27HyNd83umvqdtP5HaMfK3tw2mTwFOjd+ZykvzNuXR1XZr4VW7HyNf8OgzSjpOX\ncjtGvlYj1E/JCVxjo7l5+2nV4ZjcjpGv1a/oeD3yG59wrEVFam3ZnNsR7OvZWrVqlcaNG6fU1FS9\n8MILMplM+uCDD4zOBgAAAAAOy645WxEREZo/f778/Pz0wQcfKDIy0uhcAAAAAODQ7Cq2nJ2d5erq\nKpPJJJPJJI9brGQEAAAAALjBrmGENWrUUNeuXXX+/Hn17t1bDzzwgNG5AAAAAOQh2f2bk7Cz2Ora\ntas2bNig++67T2XLllWdOnWMzgUAAAAADu2Oxda8efMyvPb29lZMTIzmzZvH8u8AAAAAcAd3LLZi\nY2NzKgcAAACAPMzkbMrtCA7njsVWp06dJEk2m02RkZGKjo5W+fLlGUYIAAAAAFmwa5Zbz549tWLF\nCrm5uenHH39UeHi40bkAAAAAwKHZtUDGkSNHtGDBAklS69at1bRpU0NDAQAAAMhbGEaYfXb1bJUo\nUUInT56UJF28eFEhISGGhgIAAAAAR2dXz9bu3bv14osvqmjRojp//rxcXV1Vs2ZNSdKmTZsMDQgA\nAAAAjsiuYisqKsroHAAAAACQr9hVbK1Zs0aLFi1ScnJy+rZJkyYZFgoAAABA3uLkbNcMJNzErmJr\nyJAh6t+/v3x9fY3OAwAAAAD5gl3FVvny5fXYY48ZnQUAAAAA8g27iq1nn31WzZo1U5kyZdK38be2\nAAAAgHsHS79nn13F1vfff6927drJ29vb6DwAAAAAkC/YVWwVKVJEDRo0MDoLAAAAAOQbdhVb7u7u\nevfdd3XffffJZErrPuzatauhwQAAAADAkdlVbNWpU8foHAAAAADyMCcn5mxll13F1ksvvaR9+/bJ\nYrHIZrMpJibG6FwAAAAA4NDsKrY6deqklJQUxcTEKDU1VYGBgWrUqJHR2QAAAADAYdn1Z6Dj4+M1\nZcoUVa1aVYsWLVJycrLRuQAAAADkISZnJ4f6ygvsSuHu7i5Junbtmtzd3dMXyQAAAAAA3Jpdxdbz\nzz+vsWPHqlKlSmratKlcXV2NzgUAAAAADs2uOVstWrSQzWaTyWRS7dq1VbJkSaNzAQAAAMhDnJwZ\n3ZZddvVs/frrr9q4caPWr1+vDz/8UL/88ovRuQAAAADAodlVbI0cOVKlSpXSjBkzNGfOHM2dO9fo\nXAAAAADg0OxeIKNw4cJycXFRQEAAC2QAAAAAQBbsmrPl5eWldu3aqVmzZpo1a5b8/f2NzgUAAAAg\nDzExZyvb7Cq2Ro8erRMnTqhcuXI6cuSI3njjDUnSnj17VK1aNUMDAgAAAIAjsmsYoaurq8qVKydJ\nqlChQvpzEBVmAAAgAElEQVTS78OHDzcuGQAAAAA4MLt6tm7HZrPdrRwAAAAA8jCTs139NLjJf7pi\nLJQBAAAAALdGeQoAAAAABvhPxRbDCAEAAADg1v7TnK2XXnrpbuUAAAAAkIc5sfR7ttlVbI0cOVIL\nFy7MMEdr06ZNatq0qWHBAAAAAMCR2VVsrV+/XmvXrk1f8h0AAAAAcGcmmx0Tr7p3766vvvpK3t7e\nOZEJAAAAQB6zv0XD3I6QLVVmLc/tCPb1bJUvX141a9ZUkSJFZLPZZDKZFBUVZdcBrkT0/k8BcWc+\n7/RXR1Op3I6Rr423/a3kNTNyO0a+5la3lSTJsiP3H4r5mUuNhro08avcjpGv+XUYJPPGubkdI19z\nrdVcl6f0zO0Y+Z7vu2Gav/dMbsfI15pWLZrbEZAD7Cq2VqxYoaioKPn4+BidBwAAAADyBbuKraJF\ni8rDw4M5WwAAAMA9ysmZP9GbXXYVW+fOnVO9evUUGhoqSTKZTJo7l2ESAAAAAHA7di/9DgAAAACw\nn13F1uLFizNt69Sp010PAwAAAAD5hV3FVpEiRSRJNptNBw8elNVqNTQUAAAAgLzF5GzK7QgOx65i\nq3nz5hlet2vXzpAwAAAAAJBf2FVsRUdHp/87JiZGZ87wdxcAAAAA4E7sKrZ69+4tkymt29DNzU1f\nfvmloaEAAAAA5C0mln7PNruuWJMmTRQbG6tTp07p2LFj6tevn9G5AAAAAMCh2dWzNXnyZI0fP14h\nISFG5wEAAACAfMGuYis0NFQlS5Y0OgsAAAAA5Bt2FVvu7u5q166dKleunD53q2vXroYGAwAAAJB3\nmJyYs5VddhVbtWvXNjoHAAAAAOQrdhVbjRs3NjoHAAAAAOQrdhVbAAAAAO5tTiz9nm1cMQAAAAAw\nAMUWAAAAABiAYYQAAAAAsmRiGGG2ccUAAAAAwAAUWwAAAABgAIotAAAAADAAc7YAAAAAZIk5W9nH\nFQMAAAAAA1BsAQAAAIABGEYIAAAAIEsmJ/ppsosrBgAAAAAGoNgCAAAAAANQbAEAAACAAZizBQAA\nACBLJmfn3I7gcOjZAgAAAAADUGwBAAAAgAEYRggAAAAgSyZn+mmyiysGAAAAAAag2AIAAAAAAzCM\nEAAAAECWnJzop8kurhgAAAAAGIBiCwAAAAAMcM8MI9z05xmNXb9X5lSrygf4qmeDR+XlVuCWbdcd\nOaW+y7ZqXdfXJEnXUyz6evVOHTwXJ6vNpiohhfXF89XlXuCeuXx3VeuIYTqz/7B+GT4pt6M4nA37\njmr0T+tkTrGoQvFA9WvZSF4ebhnazFm3TfM37JRkUmiAn/q0aKjCPp7p75+Lu6KWX0doQc/2KuRV\nMIfPwDGs33VQo+Yul9liUYXQohrQoZm8CrpnaLN003ZNXbZWJpNJHq6u6t66saqUCZUk1XyvlwL9\nfdPbtm1YR41q1sjRc8jrNv11VuM27pc51apyAb7q8XyN2z6T1x89rb4/b9faj16RJCUmpyhs1Q4d\nj0uQ1WZTw/tLqtWjFXMyvsPZsPeIRv0QqRSLReWLB6l/m1fk5ZHxnp69Zqvmr9smk0wqHlhIfVu9\nrMI+XrmU2DFsOnZW323YJ7MlVeUC/dTzhYdv/9ni6Gn1W/671n7SWNL/7uOV2/R3XIJsNpsaVCml\n1o9Vysn4DuXwji36ZfZkWVJSFFyyjF59/3O5F/TM1O63lYv1++qfZDKZ5B9UVK90/ExevoWUkpys\nZVNG6dSfh2WzWRVavrIavfuJCri53eJowN1zT/RsxV+9rv4rfteQxk/phw4NVMzPS9+u23PLtifi\nEjR6zR5ZbTe2RWw5pFSrVbPb1tectvWVbEnVtC2Hcih9/hFcqaw+iZqtGk0b5nYUhxSXkKReM5Zp\nRIfXtLTf+ypepJBG/bgmQ5uDx89q+i9bNePz1lrcu4NKBPpr7NL16e8v+W2v2gyfoZjLiTkd32HE\nXUlUzwlzNeqTNlo+vLuKB/lrxNxlGdpEn4nRsNlLNbHbe1oU/pnee/U5fTwyIv09H8+CWhT+WfoX\nhVZG8VeTFfbzDoW//LgWtK2vYr6e+m7j/lu2PRGfoG827JPNduOhPGHzAQV6e2hOm3qa1rKuFu35\nS/vOXMyp+A4nLiFJvSJ+1MgPmmnpwM4qHlBIo36IzNDmwN9nNH3Vr/r+y3Za3P9DlQwsrG//8XxB\nRvFXkzVg5TYNfuUJLWz/oor5emrs+n23bHsiLkHfrN0j60338fiN+xXoXVBz29bXtLef06Jdx7T3\nNPfxrSRdvqTF332tNz/rp0++maFCQSH6ZdbETO1OHzuszUvnqUPYt/poRIQKhxRX1NypkqT1i2Yq\nNTVVHw6brE7DpijFbNaGxbNy+lQcnsnZyaG+8oK8kcJgv0Wf030h/irh7y1Jeu2hcvr54IkMP7yl\ntB6s3kt/0yfPPphh+0OhAWr71P1yMpnk7OSkikF+Onflao7lzy+e+bCVtkQs0I75y3M7ikPaciha\nVUqFqGSgvySp6dPVteL3Axnu4/tKhmhp//fl7eGu5BSLYi4lyNfTQ5IUcylBa/cc0dhOzXIlv6P4\nde9hVSkTqpIhAZKk5s89peWbd2a4zq4FXNS/fTMFFPKRJN1fJlQXLiXIbLFo95G/5exkUpuwsWrc\nbai+W7RKqVZrrpxLXrX1+HlVDi6kEoXSnslNqpXRz4du/Uzuu2KbPq5dNcP2rnWqqXPtByRJFxKv\ny5xqledtehMg/XrgmO4vVVQlgwpLkpo984iWb92b4XrfX6qolg3sLO+C7kpOSVHMpSvyo+f7jrZG\nn9N9wYVu+mxRVj8fPH7L+7jP8t/1SZ2Mny0+ffZBda6Tdm9fSEq7j2/XK3av+3PvNhUrW1GFQ4pL\nkh59/hXt2RiV6VoXK1tRn3wzU+6eXkoxm3Ul7oIKeqc9p0vdV1XPvPa2nJyc5OTsrJDS5XTpwvkc\nPxfce+6JcXDnr1xTkPeNHxqBPh5KSk5RktmS4cE26OftavJgWZUP8Muw/+Olg9P/ffZykuZsP6Kv\nXnjE+OD5zNyP+kiSKj37VC4ncUzn4q8o+H8f7iUpyM9HideTlXTdnGEoYQFnZ63ZfVh9Zy6Xq4uz\nPnyptiQp0M9bI997PcdzO5qzcZcUXPjGMyDI31eJ164r6Vpy+lDCYgH+KhaQVvTabDZ9PfMn1alx\nv1xdXGSxpuqJByros7de1nVzit4fOkleHu5q9WLtXDmfvCjtmeyR/jrQ20NJZkumZ3L4L7v0atUy\nKhfgm2F/k8kkF5NJfVb8rjVHTqt2uaIq+b/CDZmdi7us4JuGtQYV8lHitWQlXU/OMJSwgIuzonYd\nUt/pS9KeHa/UzY24DuN8wjUF3vzZ4nb38aodalytjMoF3vo+7r1sq9YcPqVnyhdTSX/u41u5fCFW\nvkUC01/7FA5Q8rUkJV+7mmkoobOLiw7+vkk/jR8qZxdXPdvsHUlSuWo3Prddij2nLct/0CvvfZoz\nJ4B7ml09W0eOHNFbb72lRo0aaeLEiVq7dq3Rue6qf/7m4/85m0zp/16w86icnUx6uVqZ236fQ+fi\n1H7WGjWtXl61yhW96zmBO7Fab30fOzmZMm2r+2BFbRjWVR0bPa2O38y57b7IzJaN63z1erK6jp6h\nE+cvqH/7tB7DN+o+oa9aN5FrARf5eHqodYPaitp266FF9yqbbvNMvukaL9x9LO2Z/ECp236ffg0e\n1aoPXtKV62ZNYWj3bd3uZ+CtlnB+9qHK2jiqm95/+Rm9N/J7WemVvS2rHZ8tFu76U85OTnq5aunb\nfp/+jR7T6o9e0eXrZk359eBdz5kf2Gy3vg9vtwz5fY/WVPepP6lu09aaHvZFhvv49LHDmtzrYz32\nwquqWOMJQ/LmZ7k9LDDfDiMcOHCgwsPDVahQIb3++usaM2aM0bnuqiCfgrqQeC39dWzCNfm4u8rD\n9UbH3rJ9f+vg2Ti9NXWVPlmwQcmWVL01dZViE9L2W33whDrNXa9OtavqnSfvy/FzAEL8fRR701yr\nmEsJ8inoroJurunbTsTEaeefJ9NfN36yms7GXdaVq9cE+4QU8VPspSvpr2PiLsvH00MF3TNOoj5z\nIV4t+n4jZyeTInp+IJ//DddcsnG7Dp84k97OZpNcnJ1zJryDCPIuqAtJ19NfxyZek497AXnctOjQ\n8gPHdehcvFrOiFSXRZuVbElVyxmRik28pt/+PqfY/z3TC7q66PlKoTocE5/j5+Eogv19FXs5If11\n2rPDI+Oz4/xF7Tx6PP1145rVdfbiJV25el24tWCfgrp4832c8L/7+J+fLc7FqcW01eqycKOSLalq\nMW21YhOuaUv0ufTPGAVdXVS/cgn9cZ77+P9FzZ2qsZ+109jP2mlH1AolxN+Yz5YQFysPT2+5untk\n2Ofi2dM6fujGL7eq13lRl2LP63pS2v2/d/MaTR/wueq1aK/aTVrmzIngnmd3yVeyZMm0lV38/eXp\nmXn1l7zs8dLB2n/mok7Epf3P9sOuY3q6fMaeqemt62leuxc1u219jXrjabm5OGt22/oK8PZQ1B8n\nNSxyp8Y0q60X7i+ZG6cA6InKZbQ3+oyOx8RJkhZs3Kk61SpkaBN7OVFfTFms+MS0OYXLf9+vckUD\nmHuRDU8+UFF7jx7X8bOxkqR5Ub+qbo0qGdpcSkxSmwFjVe+RqhrWuZXcXW98aD166qy+XfCzUq1W\nXTebNWf1Jr3wRMa5Gve6x0oFav/ZOJ2IT3smL9oTrVplMz6TI1rU1Zw29TSz1XMa2eQpubk4a2ar\n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\nvcbHy0sN69XWkeP580PqzOmf6LVXW+q1V1vqu2XfKi4uzrotNjZG/v7+8vKyvQeHhoXdsd3p06d0\n4cIFTZk8Ua+92lJLlyzWurVrNHrkCCVdv66fN/z1jGiFihVVtlw5nTjxu/EHmUsVKeSnuGvJ1uWY\nq0ny9yogrwLu1nXn4hK199QF63LjRx/QxYTrunbzlpbvOqrjF/76d7BYLHJzzR0fXHKLIkGFFZtw\n1bp8+Uqi/H295f1fk5BciI1XmwEfyNXVRXNH9pL/33rIV27aqTeHT1Gvtk3VuXnDHMuemxUJC1Xs\n3+4BMbGx8vf3l/ff7hX3arNl23bFxMZKkry9vfV8g2d19Ldjunb9umZ/Ptf2Cx2LRW5u+WaQFxzE\nrmIrMTFRzZs3l5ubm6pVq6Z0Jxm3Xbv563pj7Ey9MXam2o74UBdOHFX8pT8lSfvWL1eZ6o9n2icp\nMV7ffTRaN65n3ECPbNmgoIgS8vLzV/lH/6Vjv/6i1JTbslgsOr5ri4qUKpejx5RbPV6xlA6cvqCz\nMRkfMr/ZtEdPPWh7bmKvJunfn32rhKQbkqQVvx5SmfBgBTDrIHKRJx55SAeOHtPZPzM+hEb/sEb1\nnnjU7v3X/LxZn8xbKIvFopSUVK35eYtqPpw/v63u3LWb5i+I1vwF0fps7jwdOnhQ585l9DYtXbxY\ntevUzbRPzccev2O7KlUf1A8rV1tfr2mz5qr/bAMNGjpMLq6uiho5XPv37ZMknTp5UmfOnFGlylVy\n7Fhzm8fLFdeBs5d0NjZRkrR420HVrVzKpk3ctWT1m79KCUkZX3it3HNMZcICFeDjpROX4vXJ6u1K\nS0/XrVSzFm45oGcfKpvjx5Gb1XroAR04fkpnLlyWJEWv+UX1Hn3Qpk3i9WS1HzxB9R97SBN7d7KZ\naXDN1t0a82m0Ph3WXS/8y/57TF73+GM1deDQIZ09d06S9M2SpXqqTm2726z9cZ1mzPr0P/fgFK35\ncZ1qPvKIfLy9Ff3NYq3b8JMk6ehvx3Tw8BHVeiLzZ0HgfrK7nD95MuOb2UuXLmUa9uEMfAoWUsPO\nfbRs6iilmVNVKCRcjbr+W5J08dQxrZ49SW+MnamIClX0ROPWWhDVRy4uLvItFKimPYdLkh5+5kXd\nTLquLwZ1k8WSrtASZVSvTWcHHlXuEejvo1HtXlDvWUuUmpamiKBCGv36Szp89oKGz1+hbwZ1UvWy\n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\n1af7u/Lx8VWVqg8qKChIC+bP1/atW5SamqJXX2un4pGROXqMTotntrLNrjN2+fJlnThxQqdPn9bA\ngQN19OhRo3PdV+n/9U3I/3Nxzd4F88W3K9Xl1Sb3I1KeY0m/yzl2MWVad+PWbfWaOk/nLsdpZKeW\nkqQW9R7XwPZN5eHuJn8fL7VvWEfrdx40NLOzsVju3NPn4pK963jcwJ7avGyerl6/rulfLrof0YBs\nSb/r/YJf4vfLXX/v3eEc37h1Wz0/mKFzF2M18p32RkfLM+56Hdv52aJfpzYymUxq+s4gvTtqsp54\nuLLc3fLFd+BZuutniv8qRu/V7uUmTdWrbz95eHjIz89Prdq8po0/b5DZbNaF8+fl4+ujmZ/P1cgx\n7+vDSRP129Ej9/04AMnOYqt3796Ki4vT5MmTVatWLY0ZM8boXPdVkeBAxf5tzPnluHj5+/rI29Pz\nHnvZOnLitNLS0lWjakUjIjq9IkEBik28Zl2Oib8qfx8veXsWsGl3IS5BbYZ/KFcXk+YM7iZ/n4xv\nWL/ftEvHzl2wtrNYxDd8/6VISLBiryRYl2Nir8jfz1feXvZdx5t37lVMXLwkycfLSw3r1daR4ycN\nyQrcS5HQYMX9/VqOi8vWtYysFQkurNiEq9bly1cS5e/rnfmeHHtFbfqNlauLi+ZG9ZG/b+bJHXBn\nRUIyf7YomI3PFkk3bqrPm6/qhxnj9PmYATKZXFQ8PDTrHfOo2TM+UfvWLdW+dUv98N23iouLs26L\njY2Rn7+/vLxsJ3gJDQu7a7tVK5brxO/HrdssFovc3NwUFJzxuEOjF16SJBWLKK6qDz2kI4fvPKoJ\n+F/ZVWyZTCbVqFFD165dU6NGjZzu28da1avqwG+/68z5i5Kk6BXrVO/xR7L1GrsOHlXNByvJZMrc\nUwPpiSrldeD3szp7MVaSFL1+q+pVr2zTJjEpWa+P+ljP1KiqCe+1k6eHh3Xb739e1LRvVistPV23\nUlK0YO1mPff4Qzl6DLndE488pANHj+nsnxlFafQPa1TviUft3n/Nz5v1ybyFslgsSklJ1Zqft6jm\nw1WNigvc1RM1qmn/kd909s/zkqTo71eqXq07PyuLf6bWQ5V04NhJnfnPTLrRq39WvUdt76mJ15PU\nfuB41X+8mib27SzPAh53eincRa1qVbT/txM6c/6SJCl65XrVe9z+iZ2iV67XR18uliTFJVzV4tU/\n6YW6TxiS1Rl06tLNOpHFrDnzdPjQQf1x7qwkadmSxapdp26mfR597PG7tjt18qRmz5iutLQ03b51\nS0sWRevpZxoovGhRla9QUSuX/yBJir9yRQcP7FeFipVy5DidnsnkXD+5gF391WazWePHj9cjjzyi\n7du3KzU11ehc91VgQEFF9eqinlFTlGo2K6JIqMb27aZDx09qyJTZ+vaT97N8jbPnL1nHtiOzwIJ+\niurcSj2mzpXZnKaI0CCN6fqqDp36Q0NnR2vp2D6KXrdVF+MStG7XQa3b9dcQwc8HdlW3pg00eu5S\nNe43XmZzmhrUfFDNn+LD198FFgpQVN931WP4BzKbzYoID9OY/t116NgJDZ0wTUtnT7nn/n27vqGR\nk2eo8ZvdZTJJ9WrVVNtmTHWLnBdYKEBR/Xuq59AxSk01K6JomMYO7KNDvx3XsPEfasln0xwd0ekF\nBvgr6r031HPc9Izfe2EhGtujgw79fkZDPv5C304ZpoWrftbFuCtat32v1m3fa913zsjeCvDPPMU2\nbAUGFNTonp3VY/TU/3y2CNH7fbrq0PFTGjJ1tr79eOw993/rlZfUb8J0vdilnywWi95+ramqlC+d\nQ+lzt8KFC2vQ0OEa1K+vUlPNKlqsmIaOGCVJOnrksN6PGqkvvo6+Z7s333pLE8eNU9tWLWQ2m1Wv\n/jN6qXHGoyBjJ0zUxHHva9nSxUpPt6hDx7f0QCWKLRjDZPnvqV3u4MyZM9qyZYtatGihdevWqUqV\nKoqIiLDrDdJOM42pkVxLVpN5NzOiGcmteiOZzzvXc4rOxq1oxvDcLqYSDs2R182wnFHqJYaOGsk9\nrLTSfss8VT3uH9cKtZV+apejY+R5LqUe0ZXrNxwdI08L9HO+YbupMWccHSFb3ENKODqCfcMI582b\npzZt2sjDw0MNGzbURx99ZHQuAAAAAHBq9xxG+NVXX2n69OlKTEzU2rVrretLl6abGwAAAMhXmPo9\n2+5ZbLVp00Zt2rTRjBkz1KVLl5zKBAAAAABOz64JMl577TWtXLlSKSkp1nWNGzc2LBQAAAAAODu7\niq1u3bopJCRERYoUkSSmPwcAAADyGQvDCLPNrmLLYrFowoQJRmcBAAAAgDzDrvK0fPny2r9/v1JS\nUqw/AAAAAIC7s6tn69dff9WGDRusyyaTSevXrzcsFAAAAIBcxoVhhNllV7H1/fffS5ISEhIUEBDA\nM1sAAAAAkAW7iq2dO3dqxIgRSktL03PPPafw8HC1aNHC6GwAAAAA4LTs6gucMmWK5s+fr6CgIHXp\n0kULFiwwOhcAAAAAODW7erZcXFyswwcLFCggHx8fo3MBAAAAyE2Y+j3b7DpjxYsX18SJE5WYmKhZ\ns2YpPDzc6FwAAAAA4NTsKrZGjBih8PBwVa9eXd7e3ho1apTRuQAAAADAqdk1jNDV1VWVKlVSmTJl\nJEn79+9XjRo1DA0GAAAAIBdhGGG22VVsvfPOO0pISFCRIkVksVhkMpkotgAAAADgHuwqtq5cuaKF\nCxcanQUAAAAA8gy7+gJLliypy5cvG50FAAAAAPIMu3q29uzZo6eeekqFChWSyWSSJG3evNnQYAAA\nAAByEZ7Zyja7iq01a9YYnQMAAAAA8hS7ytNjx46pWbNmevLJJ9W4cWMdOXLE6FwAAAAA4NTs6tmK\niorS6NGjVaFCBR09elQjRoxgwgwAAAAgH7EwjDDb7D5jFSpUkCRVrFhRbm521WgAAAAAkG/ZVWy5\nuLjop59+0vXr17VhwwZ5eHgYnQsAAAAAnJpdXVRjxozRuHHjNGnSJJUqVUqjRo0yOhcAAACA3IRh\nhNlmV7FVtGhRdenSRadPn1aZMmVUtGhRo3MBAAAAgFOzq9iaPHmyduzYoapVq+rLL79U/fr11bFj\nR6OzAQAAAIDTsqvY2rRpkxYvXiwXFxelpaWpZcuWFFsAAAAAcA92FVthYWFKTk6Wn5+fzGazgoKC\njM4FAAAAIDcxmRydwOnYVWzFxMSoQYMGqlChgk6cOCF3d3e1atVKkvh7WwAAAABwB3YVW1OnTjU6\nBwAAAADkKXYVW1euXNGKFSt0+/Zt67rhw4cblQkAAABAbsPU79lmV7HVr18/derUSf7+/kbnAQAA\nAIA8wa5iKzIyUk2bNjU6CwAAAADkGXYVWw0aNFDPnj1VunRp67p33nnHsFAAAAAA4OzsKra++uor\nPfvsswwjBAAAAPIpC89sZZtdxVZAQIDeeusto7MAAAAAQJ5hV7FVqFAhDR06VA888IBM//ljZi1b\ntjQ0GAAAAAA4M7snyJCkuLg4Q8MAAAAAyKXy0DDC9PR0DR8+XMeOHZOHh4eioqKsNY8kbdiwQR9/\n/LHc3NzUrFkzvfLKK//ofew6Y++8844qV66sAgUKqEKFCkyOAQAAAMBprVu3TikpKYqOjlbv3r31\n/vvvW7elpqZq7Nix+vzzz/Xll18qOjr6H3c62dWzNXHiRJ09e1bVqlXTsmXLtHv3bvXr18+ulxSk\nCwAAIABJREFUN3AtWe0fBYP93Ko3cnSEPM+taEVHR8gXZljOODpCnuceVjrrRvifuFao7egIeZ5L\nqUccHSFfCPTzdnQEwDC7d+9W7doZ9+uHHnpIhw4dsm47efKkihcvroIFC0qSqlevrp07d+r555/P\n9vvYVWzt3LlTCxculCS1b98+W91oibMGZjsU7Bfw1hjOscEC3hqjxKQbjo6RpwX4ZvxCT7100sFJ\n8jb3sNLqYirh6Bh52gzLGZkvHHN0jDzNLby8bq2c7ugYeZ5nw676fNc5R8fI0zo8UtzREbLN8p+5\nG/KCpKQk+fr6WpddXV1lNpvl5uampKQk+fn5Wbf5+PgoKSnpH72PXcMIzWaz0tPTJUkWi8U6SQYA\nAAAAOBtfX18lJydbl9PT0+Xm5nbHbcnJyTbFV3bYVWw1bNhQr776qsaMGaPWrVurYcOG/+jNAAAA\nAMDRqlWrpl9++UWStG/fPpUrV866rXTp0jp79qwSExOVkpKiXbt26eGHH/5H72PXMMIOHTroySef\n1KlTp9SsWTOVL1/+H70ZAAAAADjaM888oy1btqhVq1ayWCwaM2aMfvjhB924cUMtW7ZU//799eab\nb8pisahZs2YKDQ39R+9jV7G1aNEinT59Wv369VOHDh300ksvqXHjxv/oDQEAAAA4H4vF0QnuHxcX\nF40cOdJmXenSf00iVa9ePdWrV+9/fx97Gi1YsEC9e/eWJM2cOVMLFiz4n98YAAAAAPIyu4otFxcX\n6wNj7u7uTJABAAAAAFmwaxjh008/rdatW6tq1ao6fPjwfelSAwAAAOA80vPSOMIcYlex1a1bNz31\n1FM6ffq0GjdurAoVKkiS9u/frwcffNDQgAAAAADgjOwaRihJFStWVMOGDa2FliRNnDjRkFAAAAAA\n4OzsLrbuxEJXIgAAAADckV3DCO+GiTIAAACA/IFuluz7n3q2AAAAAAB3xjBCAAAAADCAXcMIly1b\nppkzZyolJUUWi0Umk0nr16/Xiy++aHQ+AAAAALlAOv0s2WZXsTV79mzNmDFDRYoUsVn/yiuvGBIK\nAAAAAJydXcVWRESEIiMjjc4CAAAAAHmGXcWWp6enOnbsqIoVK1pnIOzVq5ehwQAAAADkHszXkH12\nFVt16tQxOgcAAAAA5Cl2FVtNmjQxOgcAAAAA5Cn8nS0AAAAAMIBdPVsAAAAA8jemfs8+erYAAAAA\nwAAUWwAAAABgAIYRAgAAAMgSowizj54tAAAAADAAxRYAAAAAGIBiCwAAAAAMwDNbAAAAALLE1O/Z\nR88WAAAAABiAYgsAAAAADMAwQgAAAABZslgYR5hd9GwBAAAAgAEotgAAAADAAAwjBAAAAJCldEcH\ncEL0bAEAAACAASi2AAAAAMAAFFsAAAAAYACe2QIAAACQJWZ+zz56tgAAAADAAPmmZ2vzqYuavumQ\nUtLSVSa4oAY9W12+Bdzv2Hbj7+c1fPUu/fTuy5KkpNupilqzW2fjryvdYlGjSpFq92j5nIzvFDjH\nxtm8aZOmT/tIKakpKlOmrAYNHSZfX99/1K5fn94KCg5W3379JUm7du7UR1Mny2w2q0ABT/Xu+29V\nqlw5R44rt9q47VdNmTVXqampKleqpEb26yFfH+9M7SwWiwa/P1llSkbqjVbNbLZdjIlVm669tOSz\naSoUUDCnouc57edM0IVDx/TjxNmOjuJ0Nm7bqSmfzlNKqlnlSkVqVN/37nodDxo3VWVLRuqNlk0k\nSdeTkjVk/Ec6fe5PpVsserlBPXV8tVmmffO7Xw6f1ocrtijFnKZy4UEa3qq+fD0L2LRZsGmfFm05\nIJPJpIigghr6Sn0F+tn+O/T8/AcFF/TVwGZP5WR8p3Jy7w5tjP5MaeZUBUeU1POdequAt0+mdrvX\nLtPedctlMpkUEFJEz3XsKZ+ChfTtlJFKvHze2i4x9pKKV6yqZr1H5eRhIB/KFz1bCTduK2r1bo19\n6TF906GBihb00SebDt2x7bmE6/rwl4M2fyF75pbDCvHz0oLXn9Hc1+pp6f5TOnjhSk7FdwqcY+Mk\nJMQrasQwjR0/Xt8sXaaixYrpk48+/Eftvvxirvbt3WNdTk1N1eAB/TRw8FB9tXCROrzZUcOHDjb8\nmHKz+MSrGvL+ZE0ZNUjL589WsfAwTZ45J1O7k2fO6c2eA7Tmp02Ztn23er3av9tXMXFcw/9UWIXS\n6rH+a1V/pZGjozil+MSrGvzBh5oyYoBWzJuuYkXCNGnWF5nanTz7hzr0Hqw1P2+2Wf/R518pNDhQ\n382ZpujpExX93SrtO/xbTsV3CvFJNzR04VpNfKORvh/YXkUD/TV1+RabNkf+uKx5P+3WvO4ttbRf\nWxUPCtDHq7batJmzfpf2nrqQk9Gdzo1riVo5a4Ia9xiqThPmKCCkiDZGf5ap3aXTx/XrisVqO3yq\n3hw3W4XCimrT4ozrvkmPoXpj7Ey9MXamnuvYS57evnrm9Xdz+lCcXrrFuX5yg3xRbO04e1kVwwqp\neCE/SVLTB0tp9dFzNh/2JelWqlnDV+5U9zpVbdb3eupBvVeniiQpLumWUtLS5XOXHpv8inNsnB3b\ntqviA5VUvHikJKlp8xZavWpVpnObVbtdO3dq29atatKsuXUfd3d3LV+1RuUrVJDFYtH583+qYMH8\n3QuzdeceVapQTpHFikqSWr7cSCvW/ZTpfC9ctlyNn39GDZ6qbbM+Ju6KNmzepunjRuZY5ryo7tvt\ntG3ON9q9aIWjozilrTv3qnL5soosFi5JavXy81qxfmOm63jBshVq8lx9Naj7pM36Ae92Ut+uHSRJ\nsfHxSklNvWOvWH627dg5VY4IVWRwIUnSK7WqauXu32zO8QMRofp+0Ovy8yqg26lmxVxNUoCPl3X7\nr7//oS2/nVHzJ6rkeH5ncvrgboWVKqfCYcUkSQ/Xf1GHt6zPdD2HlSyntybOVQFvH5lTUpSUECcv\nXz+bNmnmVK2Y8YGebttV/oEhOXYMyL/yxTDCy9duKtTvr5tbiJ+XklPMSk4x2wxzG/vjXjWuWkpl\ngm0/bJpMJrmZTBq28ldtOH5edcqEK7KQ7X+8+R3n2DiXL19SaFiodTkkJETJyUlKTk62GSJ4r3Y3\nb97Q5AnjNXXax/p26RKb13dzd9eVK1fUvs2rSkxM1Oix44w/qFzsUkyswkKCrMuhwUFKSr6h5Bs3\nbT5sDurRTZK0Y89+m/1DggI1NSp/9w7eDwvfHSZJqvB0LQcncU4XY+Psuo4Hd+8iSdr+X9exyWSS\nm6ur+o2eqLUbt+rp2o+pZETRnAnvJC4lXFdowF+/p0IL+inpVoqSb6fYDCV0d3XVhoMnNCJ6ndzd\nXNXt+cclSTFXk/TBtxs1vXMTLd52IMfzO5PrV2LlXzjYuuxXOFgpN28o5eaNTEMJXd3cdHzXFq2e\nPUmu7u56snl7m+0Hfl4t30KBKlfD9gsGwCh29WytX79eHTp0ULt27dS2bVu9+OKLRue6ryy6cz+i\nq4vJ+v8X7zspVxeTXqpS4q6vM6Lho1rT7UVdu5Wiz7Ydvd8xnRrn2Dj//c3d/3N1dbWrnSwWDR7Q\nXz1791FQcPAdmwQGBmr56rX6dM4XGjVimM6dPfs/ZXZm6XcZd+Diki8GAiCPsKSn33F9dq/jcYN6\na/N383X1WpKmz4u+H9HyjLvdc11Mmc9xvSpltDGqi7o2eExdZ3yrFLNZ/eatUt8mdRRcMPNzR7Bl\nsdz5ejbd5Xou90gtvTdziWo1badF7w+w+e9h56oleqJxG0NyAndiV8/WlClTNHLkSC1cuFA1a9bU\n1q1bs94pFwn189ahi/HW5dikm/L3dJeX+1+Hv+LwWd1KTdNr89YpNS1dt80Z/39y01o6GXdVpYMK\nKtjXS94ebnq2QoR++v38nd4q3+Ic318zp3+iTb9slCQlJyerdJky1m2xsTHy9/eXl5eXzT6hYWE6\ndOhgpnanT5/ShQsXNGXyREnSlStXlJ6WppTbt9W9Zy/t2rlTdevVkyRVqFhRZcuV04kTv6t4ZKTR\nh5krFQkN1sGjx6zLMXFx8vfzlbeXpwNTAdlTJDRYB44ety7HxF7J1nW8+dc9KlcqUiFBgfLx8lLD\np/+lH39xrt/9Rgsr5KeD5y5Zl2OuJsnfu4C8/zaa41xsouKuJ6taqYxewcY1Kynqmw06fC5G5+Ov\nauKyjPt83PUbSk+3KCXVrOGtnsnZA8mlNi2eqxO7t0mSbt+8oeCIktZt1+Pj5OnjJw9P29+DCZfO\nK/lqgoqVz5jkqWrdBlr7+VTdSk6Sl5+/Lp85ofS0NEVUtH2UAfa76xe7uCu7vuIKCQnRww8/LElq\n2rSpLl++bGio+61miRAduhivcwnXJUlL959W7dLhNm3mtKmnBa8/o/nt6mty01oq4Oaq+e3qK9jX\nS+uOnden247KYrEoxZymdcf/1CPFGef7d5zj+6tz126avyBa8xdE67O583To4EGdO5fR27R08WLV\nrlM30z41H3v8ju2qVH1QP6xcbX29ps2aq/6zDTRo6DC5uLoqauRw7d+3T5J06uRJnTlzRpUq59/n\nB56oUU37j/yms39mFPvR369UvVqPOTgVkD1PPPKwDhw9prN/Zky8EP3DKtWrVdPu/df8vFmffLEw\n456ckqo1P29WzYf5gPp3j5eP1IEzl3Q2NkGS9M3WA6pbubRNm7hryeo3b5USkm5Kklbu/k1ligTq\n4VLhWjusoxb1fU2L+r6mFk9U0bMPl6PQ+pvazV+3TmjRdsSHunDiqOIv/SlJ2rd+ucpUfzzTPkmJ\n8fruo9G6cf2qJOnIlg0KiighLz9/SdK5owcUWekhmUymTPsCRrGrZ8vd3V07d+6U2WzWpk2blJCQ\nYHSu+6qwt6eGNKiuAT/skDktXUUDfDTsuRo6eilBo9fu1vx29e+5f/c6VfT+ur1q/cU6mUzSv8qE\nq2W1MvfcJ7/hHBuncOHCGjJsuAb8u6/MqWYVLVZMw0ZmTFV79MhhjR41UvMXRN+z3d14e3vrg4mT\nNHnieJnNZnm4e2hU1BiFhobec7+8LLBQgKL691TPoWOUmmpWRNEwjR3YR4d+O65h4z/Uks+mOToi\nkKXAQgGK+nd39Rj2vsxmsyLCwzRmQE8dOva7ho6fpqWfTr3n/n27ddDISdPVuMO7MplMqvdkTbVt\n5lyPEBgt0M9bI199Rn3mrlCqOU3FggI0unUDHT53WSOif9Sivq+pWumi6vRMDb358WK5uZgUXNBX\nkztwHrPLp2AhNezcR8umjlKaOVWFQsLVqOu/JUkXTx3T6tmT9MbYmYqoUEVPNG6tBVF95OLiIt9C\ngWrac7j1dRIu/amCQWEOOgrkVyaLHf2Bly9f1qlTpxQcHKypU6fq+eefV8OGDe16g8RZA//nkLi7\ngLfGcI4NFvDWGCUm3XB0jDwtwDfjgf3USycdnCRvcw8rrS6mEo6OkafNsJyR+cKxrBviH3MLL69b\nK6c7Okae59mwqz7fdc7RMfK0Do8Ud3SEbDsXn+ToCNlSvHDmv0ma0+zq2QoKClJMTIwSEhLUtm1b\nul8BAAAAIAt2FVvvvfeerl27puD/zGRmMplUo0YNQ4MBAAAAgDOzq9hKSEjQ119/bXQWAAAAALkU\nkxFmn12zEYaHh+vixYtGZwEAAACAPOOePVtPPpnx17VTUlK0evVqFSxY0Pq81ubNm41PBwAAAABO\n6p7FFgUVAAAAAPwzdg0j3LNnj15++WU9+eSTatq0qY4ePWp0LgAAAAC5SLrF4lQ/uYFdE2RERUVp\n4sSJKlOmjI4fP66hQ4dq4cKFRmcDAAAAAKdlV8+Wn5+fypQpI0kqV66cPD09DQ0FAAAAAM7Orp6t\nwMBADRo0SI899pgOHz6s9PR0RUdHS5JatmxpaEAAAAAAjpc7BuY5F7uKrVKlSkmSzp49K19fXz36\n6KOKjY01NBgAAAAAOLN7FlunT5+WJDVq1CjTtpIlSxqTCAAAAADygHsWW0OHDpUk69/W+n+pqala\nsGCBcakAAAAAwMnds9j68ssvJUkLFizQ3LlzlZqamrGTm12jDwEAAADkEek8tJVtds1G+PXXX+vL\nL79UnTp1NHbsWJUtW9boXAAAAADg1OwqtkJCQhQSEqLk5GTVrFlT165dMzoXAAAAADg1u8YD+vn5\nad26dTKZTFq4cKESExONzgUAAAAgF7EwjDDb7OrZioqKUnh4uHr16qUzZ85o8ODBRucCAAAAAKdm\nV8+Wr6+vHnjgAUlS//79DQ0EAAAAAHkB0woCAAAAyFK6GEeYXXYNIwQAAAAAZA/FFgAAAAAYgGIL\nAAAAAAzAM1sAAAAAssTU79lHzxYAAAAAGIBiCwAAAAAMwDBCAAAAAFlKZxhhttGzBQAAAAAGoNgC\nAAAAAANQbAEAAACAAXhmCwAAAECWmPo9++jZAgAAAAADUGwBAAAAgAEYRggAAAAgS+liHGF20bMF\nAAAAAAag2AIAAAAAAzCMEAAAAECWmI0w++jZAgAAAAADUGwBAAAAgAEotgAAAADAACaLhdGXAAAA\nAO5t3/lER0fIloeKBjg6gvETZOz+w7n+UZxN9YgApWxa6OgYeZpH7Va6ufxjR8fI07xeeFuSlPbb\nJgcnydtcK9SW+cIxR8fI09zCy6uLqYSjY+RpMyxntKHqo46OkefVO/Cr4q/fcHSMPK2wn7ejIyAH\nMIwQAAAAAAzA1O8AAAAAspSW7ugEzoeeLQAAAAAwAMUWAAAAABiAYgsAAAAADMAzWwAAAACylM5f\njMo2erYAAAAAwAAUWwAAAABgAIYRAgAAAMhSGsMIs42eLQAAAAAwAMUWAAAAABiAYYQAAAAAssRs\nhNlHzxYAAAAAGIBiCwAAAAAMQLEFAAAAAAbgmS0AAAAAWUpLd3QC50PPFgAAAAAYgGILAAAAAAzA\nMEIAAAAAWWLq9+yjZwsAAAAADECxBQAAAAAGoNgCAAAAAAPwzBYAAACALKXxzFa20bMFAAAAAAag\n2AIAAAAAAzCMEAAAAECW0hlFmG30bAEAAACAASi2AAAAAMAADCMEAAAAkKU0xhFmGz1bAAAAAGAA\nii0AAAAAMADFFgAAAAAYgGe2AAAAAGQp3cIzW9lFzxYAAAAAGIBiCwAAAAAMwDBCAAAAAFlKYxRh\nttGzBQAAAAAGoNgCAAAAAAPkq2GEe7dv1sLPpsucmqKIUmX0Vu9B8vbxzdRu87pVWr5ovkwmkzwK\neKr9271VqnxFpdy+pTkfjtepY0eVbklXmQqV9MZ7feVRwNMBR5O7/XLguKYsWadUs1lli4Vq5Osv\ny9fL9jx9vWGHFv28UyaZVCykkIa3e0mB/pn/PfCXX46c1kcrtyrFnKayRYI0vOXT8vUsYNNm4eb9\nWrT1oEwmKSKwoIa2eFqF/bwlSU8NnaXggn+d4/Z1q6lR9Qo5egzOYOOuA5o8b4lSUs0qV6KYot59\nXb7eXjZtvv95m+Z8u0YymeTl4aGBnV5V5bIlrNsvxsbr1X+P0bdTh6mQv18OH0Hut3HbTk35dF7G\nOS4VqVF935Ovj3emdhaLRYPGTVXZkpF6o2UTSdL1pGQNGf+RTp/7U+kWi15uUE8dX22W04eQZ7Sf\nM0EXDh3TjxNnOzqK0wmsXUulu3eTycNDycdP6OiwKKUlJ1u3h73YUBFtW1uX3fx8VSAkRFueeUGp\n8fHW9ZUnjVNKbKyOj52Qo/lzsy2bN2n6tI+UmpKi0mXLatCQYfLxzfwZ4V7tnq//lIJDQqxt27Rt\nrwbPN7Qu//DdMm38+SdNmDzV+ANCvpVverauJSZo5oQo9Rg2VhPnfqPQIkW18NNPMrW78MdZfT3r\nI/UbO1VjZ85X4zZvaPLwfpKkZV/NVVpamsbOmq9xs75SSsptfbfgixw+ktwv/nqyhsxZpsndWuqH\n0e+pWHAhTVmyzqbN4TMX9MWarfqyf0d9O/JtRYYEatqyDQ5K7Bzik25oWPQ6TWjfSN/1b6digQU1\ndcVWmzZH/ojRFz/v0RfvttCSvq+peFCAPl69XZJ0JiZBfl6eWtS7tfWHQiuz+KvXNejDOZrSv5tW\nTh+tiLBgTZq3xKbN6T8vacLcxZo1rIe+nTJMnV9ppPfe/+t+8t2GrWo7cJxi4hNzOr5TiE+8qsEf\nfKgpIwZoxbzpKlYkTJNmZb6Xnjz7hzr0Hqw1P2+2Wf/R518pNDhQ382ZpujpExX93SrtO/xbTsXP\nM8IqlFaP9V+r+iuNHB3FKbkXClDFUUN0sFd/7XiphW7+eV6le7xt0+bSDyu185XXtPOV17SrdXul\nxF3R8bHjbQqt4m+0VUC1h3I6fq6WkBCv0SOGaewH4xW9dJmKFi2mT6Z9mK12Z8+ckZ+/v+Z9HW39\n+f9C6+rVqxo3JkqTxo+ThanMsyXdYnGqn9wg3xRbB3bvUKlyFVWkWHFJUv0Xm2rL+tWZ/iNzd3dX\np14DVSgwSJJUqlxFJSZckTk1VRWqPqQmr3WQi4uLXFxdVaJMecVdvpTjx5LbbT18UpVKhCsyNFCS\n1LJuDa3YccDmXFcqEa7lo9+Tn7enbqemKibxmgJ8M3+rjb9sO3ZOlSJCFRkcIElq8UQVrdpzzOa8\nPhARou8HtJOfVwHdTjUr5mqyCvpk9CjuO3NRri4mdfxkiVpM+Eoz1+5QWnq6Q44lN9uy97Aqlymh\nEuGhkqRWz9XV8o07bM6zh7ubRr3TXsGFM/4tKpcpobjEq0pJNSvmSqLW79irGUO6OyS/M9i6c68q\nly+ryGLhkqRWLz+vFes3ZrofL1i2Qk2eq68GdZ+0WT/g3U7q27WDJCk2Pl4pqal37BXDvdV9u522\nzflGuxetcHQUp1T48Zq6duiIbp77Q5J0ftEShTV87q7tI99or5T4eF1Y/K11XUCN6gqs9bjOf7PU\n8LzO5Nft21XxgUqKKB4pSWravIXWrFqV6R5xr3YHD+yXi4ur3u7cSa+1ekWfzZ6ptLQ0SdL6H9cq\nKChY7/bombMHhnwpy2GEKSkpOnnypCpWrKh169apTp06cnd3z4ls91V8zGUFhoRalwsHh+jmjWTd\nvJFsM5QwOCxcwWEZHwAsFovmz5iq6o/Xlpu7u6o+8pi1Xezli1q1dKE69hyQcwfhJC7FX1VY4YLW\n5dBC/kq6eVvJt27bDCV0d3PV+r1HNfyL7+Xh5qq3X67niLhO43JiksIC/rpWQwv6KulWipJvp9gM\nJXR3ddWGgyc1ctF6ubu5qutzGddtWnq6HitXXD1frKVbqWl699Pv5ePpodf+9XCOH0tudikuXmFB\nha3LoUGFlHTjppJv3rIOJSwaGqSioRlfyFgsFo37PFr1ajwkD3c3hQQG6MMBb9/xtZHhYmycwkKC\nrMuhwUFKSr6h5Bs3bYqmwd27SJK279lvs7/JZJKbq6v6jZ6otRu36unaj6lkRNGcCZ+HLHx3mCSp\nwtO1HJzEOXmGher2pRjr8u3LMXLz85Wrj4/NUEJJcg8oqIj2rbWzZTvrOo/gIJXr10v7urynoi2a\n5lhuZ3D58iWFhP71mS04JETJyUm6kZxsM5TwXu3S0tL0aM2aeqd7T92+fVu9u78rHx9ftWrdRk2b\nt5Akrfjh+5w7KORbWfZs9enTR0eOHJEknT59Wv379zc8lBHu1pXo4uJ6x/W3bt7U1FEDdfn/2Lvv\n8Car94/j73TvQltaRluULUtFBJEhS/wC+mXIliEqgn6ZIiJ7L2UoIFOmyCpLZSiypwwVmbI30pbS\nlrZ0J78/qtVaSlp/Jm3K53VdveiTnKe5z9NDmjvnPic3r9Ot/5AM9106d4bRfbvTqFlrqjxX64Hn\nP8qympK3s8s83Bo8/QR7PxnIO/+tS/dpX2DUTEuWshrD9obM17V+pZLsGvM2PV6qzrvzNmA0mnj1\nuYoMbPECTg4OeLk60+mFp9l54qKlw7Y5WT9XZL7O9xMS6ffRHK79Fs7onl0sHVq+Ycri//mDrvHD\nTBrSn31fLSP6Xiyzl676N0ITyb4sxqvJmJrptqKtWnBn5x4Sbt4CwOBgT8WPxnH+o2kk3YmwaJi2\nyGjM4nnY3j7b7Zq1aMl7Awbi5OSEp6cn7V/ryO5dWq7w/5VqNNnUV15g9i9baGgor76atvC4W7du\nhIWFmTkj7whZPJdB3TsyqHtHdm7+iqiIO+n33b0TjrunFy6urpnOuxN6m5F93sLOzo6hU2bh7vHn\n4vYDO7cyYWBv2r31P5p3eN0a3bA5hX28CY+OST8Oi4rBy80VN2en9NuuhUbw0/mr6cctalXht4go\n7t1PsGqstqRIQU/u3Pvz3dKw6Fi8XJ1xdf5zpvnanSh+vnQr/bh5tfL8FhnDvfgENh49w7lbf/4f\nMJlMONg/+M2GR1mRQj6ER0anH4dGROHl4Ybb3zYiuRUewWsDJ2BvZ8fise/jpTLYbCsSUIjwiD/X\nrISFR+Dl6YGba/Y2G9p3+CfCfn+B6u7qSpMGdTh9Xm8ciHUl/HYbp0K+6cfO/oVIjo7GGJ/575j/\nSy/y24Zv0o89y5fHpVhRSr3fl2dXL6No65b4v/Qi5UYOyXTuo2LenFl07tCWzh3a8s1X64m48+ff\nq/DwMDy9vHD922u2woULZ9luy6aNXDh/Lv0+k8mEg8MjtS+c5BFmky2DwcDly5cBuHbtmk3NPLR+\nvTsT5i5jwtxljJ6xgPNnTvLbjWsAbP9mHc88XzvTObH3ohnTvwfP1qpH76HjMuw0eGjPdpZ+NpVB\nE6dTs8FLVuuHrXm+QkmOX7zB1dC0F0Ordx2h3lNlM7QJj45lwLw1RMakJQ+bfjhOqWL+Wrf1EDXK\nBHP86m2uhqdturDm4AnqViyRoc2de3EMXLaFyNh4ADb/dJZShX0p4O7Khdt3mfXtD6QajSQkp7By\n/3EaPVXa6v3I62o+VYHjZy9y5VYoAKu+3UX9ahkXr0fFxNJl8Mc0rFGFKQO64/KXNxL1NNERAAAg\nAElEQVTEvOerPs3xM2e5eiPtjYFV32yhfs3q2T7/u137mLVkJSaTiaSkZL7btY/qT1e2VLgiD3T3\n4CG8K1fENTgIgKKtW3Jn555M7Rw8PXELDiT6l+Ppt907foIDjV5J3zzjVsg6wr77nl9HjrNa/HnN\n2z3eTd/IYv6ipZw8eYLr19LelF2/dg11Xqib6Zxqz9XIst2lixeZP2c2qampJCQksGb1Khq+qNdu\nYn1mU/xBgwbRr18/7ty5g7+/P6NGjbJGXP8674I+dB8wjE9HDyIlJYWAIsV4Z2Bavfqls2eYP3Uc\nE+YuY9s367gTFsrR/bs4un9X+vmDP/qMlQtmYTKZmD/1zyfDMhUq07X3B9buTp7m6+XBmK7NeW/2\nKpJTUgny92H8Gy04deUmI5Z8zZoR7/BMmeK83aQ2b3y8GHt7Owp5e/Lp/9rnduh5mo+nG6PavciA\nJZtJTk0l0NebsR0acep6KKNWb2d1/w5UKVGMtxo+y1uz12JvZ0chL3emdU3baax7o2pMXLeb1pO/\nJDnVyItPlqZl9Qq53Ku8x7eAF2N7d6XfpNkkp6QQVNifCX3f4OT5Kwz7bAnrPxnByi27+O1OBNt+\n+JltP/ycfu6i0f0poI8vMMu3YAHGftCHviMmkpKSQlDRwowf1I+TZ88z/OOZrPv84dswD3j3DUZP\nnU3zN3phMBioX6s6nV59xUrRi6RJvhvJmWFjqDhlInaODsRfv8npISPxLP8E5UYO4UibjgC4BgeS\nGH4HU0rm8kJ5MB8fH4YOH8nggQNITk6hWGAgw0eNAeDM6VNMGDuapctXPbTdm2+/zeRJk+jYrjUp\nKSnUb/gi/23eIje7lS/klR3+bInBlI09LyMjI7l+/TqBgYH4+PiYa57Bj9e19bElPRNUgKS9K3M7\njHzNqXY74jd+ltth5GuuL6dtKJH6695cjiR/sy9Xm5RbZ3M7jHzNoWhZehgey+0w8rU5pivsqFwt\nt8PI9+ofP8zdmPu5HUa+9sdnYNqStSdumW+Uh7xaqWhuh2C+jHDz5s20a9eOuXPn0rZtW7766itr\nxCUiIiIiImLTzJYRLlmyhHXr1uHu7k5sbCxdunShWbNm1ohNRERERETEZplNtgwGA+7u7gB4eHjg\n7Oxs5gwREREREclvUrVkK8fMJltBQUFMnDiRqlWrcvToUYKDg60Rl4iIiIiIiE0zu2Zr3LhxBAUF\nceDAAYKCghgzZow14hIREREREbFpZme2evTowcKFC60Ri4iIiIiI5FHa+j3nzCZbXl5ebN++ncce\neww7u7SJsMcff9zigYmIiIiIiNgys8lWREQEixcvTj82GAwsXbrUkjGJiIiIiIjYPLPJ1hdffGGN\nOERERERERPIVs8lW/fr1MRgM6ceenp5s2LDBokGJiIiIiEjeYjRqzVZOmU22vv32WwBMJhMnT55M\nPxYREREREZGsmd363cnJCScnJ5ydnXnmmWc4ffq0NeISERERERGxaWZntqZMmZJeRhgWFpa+I6GI\niIiIiDw6UlVFmGNmk60SJUqkf1+uXDlq165t0YBERERERETyA7PTVK+88gqPPfYYgYGB+Pn5sXv3\nbmvEJSIiIiIiYtPMzmz17NmT5ORkwsLCSE1Nxd/fn5dfftkasYmIiIiISB5hNKmOMKfMzmxFRkay\nYMECKleuzLp160hMTLRGXCIiIiIiIjbNbLLl4uICQHx8PC4uLhk+c0tEREREREQezGyy1ahRIz77\n7DPKlStHmzZtcHJyskZcIiIiIiIiNs3smq3XXnsNk8mEwWDghRdeoHjx4gBs27aNhg0bWjxAERER\nERHJfalas5Vj2frQrD9KB8uWLZteVrh06VLLRSUiIiIiImLj/vEnFJuU2YqIiIiIiGTJbBlhVrRR\nhoiIiIjIo8No1GRLTv3jmS0RERERERHJmsoIRURERERELOAflxF27dr134xDRERERETysFTNteSY\n2WRrzpw5fP755+m7EALs27eP+vXrWzQwERERERERW2Y22dq8eTN79+7F1dXVGvGIiIiIiIjkC2bX\nbAUGBmaY1RIRERERERHzzM5sJScn88orr1CmTBkgbcv3KVOmWDwwERERERHJO4zaIC/HzCZb3bp1\ns0YcIiIiIiIi+UqWydbOnTupV68ely9fznRftWrVLBqUiIiIiIiIrcsy2YqKigIgPDzcasGIiIiI\niEjelKoywhzLMtlq0aIFAD179iQsLIyUlBRMJhNhYWFWC05ERERERMQaEhISGDBgABEREbi7uzNp\n0iR8fHwytTMajbz99ts0aNCA9u3bP/Rnml2zNXjwYI4dO0Z8fDwJCQkEBQWxevXqf94LERERERGR\n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\nsXhQIiIiIiIits7s1u/BwcG0bduWQYMGMXPmTMqWLWuNuEREREREJA/Rmq2cM5tsTZgwgbi4ONzd\n3alYsSKFChWyRlwiIiIiIiI2zWyydf78eUaMGMG9e/f473//S+nSpalXr541YhMREREREbFZZtds\njR07lgkTJlCwYEFatWrFjBkzrBGXiIiIiIjkISajyaa+8oJsfWhW8eLFMRgM+Pj44O7ubumYRERE\nREREbJ7ZZMvb25uVK1cSHx/Ppk2b8Pb2tkZcIiIiIiIiNs3smq0yZcpw8+ZNfHx8OHnyJD4+PtaI\nS0RERERE8hBjHinNsyVZJlshISGsWbOGixcvUrJkSQCOHj2qz9kSERERERHJBoPJZHpgipqUlERY\nWBhz586lR48eANjZ2eHr64uTk5NVgxQRERERkdxV75M9uR1CjuzsWye3Q8h6ZsvJyYnAwEDGjBnz\n/3qA786G/b/Ol4d7qaw/q4/fyu0w8rU2lYuSGBOV22Hka86eBQCIiLmfy5Hkb76ebiw8ei23w8jX\n3qgazF2NY4vy8XTj6SFbcjuMfO/ncY3pYXgst8PI1+aYruR2CGIFZtdsiYiIiIiIZFEQJw+Rra3f\nRUREREREJGeUbImIiIiIiFiAyghFRERERMQsk7Z+zzHNbImIiIiIiFiAki0RERERERELULIlIiIi\nIiJiAVqzJSIiIiIiZhm1ZivHNLMlIiIiIiJiAUq2RERERERELEBlhCIiIiIiYpbJmNsR2B7NbImI\niIiIiFiAki0RERERERELUBmhiIiIiIiYZTJpN8Kc0syWiIiIiIiIBSjZEhERERERsQAlWyIiIiIi\nIhagNVsiIiIiImKW0ag1WzmlmS0RERERERELULIlIiIiIiJiASojFBERERERs0wqI8wxzWyJiIiI\niIhYgJItERERERERC1CyJSIiIiIiYgFasyUiIiIiImZpzVbOaWZLRERERETEApRsiYiIiIiIWIDK\nCEVERERExCyjSWWEOaWZLREREREREQtQsiUiIiIiImIBKiMUERERERGztBthzmlmS0RERERExAKU\nbImIiIiIiFiAki0REREREREL0JotERERERExS2u2ck4zWyIiIiIiIhagZEtERERERMQCVEYoIiIi\nIiJmGVVGmGOa2RIREREREbGAR2pm69SRA3yzdC4pKckULV6S9r0/xNXNPVO7Izu/Y/v6FRgMBhyd\n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\na1u/zzFdye0QcuzJDzfndgg58svE3H+j6KHJ1rJly+jYsSPHjh3jqaee+kcPkJeSrfworyVb+VFu\nJ1uPgryQbD0K8lqylR/lhWQrv8tryVZ+ZYvJlq2xxWSr0ge2tePjiY9y/+MAHjol88UXXxAYGMi0\nadP44IMPMmyh+KDZLhEREREREUnz0GRrwIABbN26lYiICDZu3JjhPiVbIiIiIiIiWXtostWwYUMa\nNmzIhg0baN68ubViEhERERERsXkP/ZytP6xZs8bScYiIiIiISB5mMpps6isvyNY2eklJSTRv3pzH\nH388/QNqp0yZYtHAREREREREbFm2kq3333/f0nGIiIiIiIjkK9lKtsqXL8/8+fMJCwujXr16lC2r\nD5sVEREREXmU5JXSPFuSrTVbgwcPJigoiKtXr+Ln58eQIUMsHZeIiIiIiIhNy1ayFRUVRatWrXBw\ncKBKlSoYjUZLxyUiIiIiImLTspVsAVy8eBGA27dvY29vb7GARERERERE8oNsrdkaOnQogwcP5uLF\ni/Tu3ZsRI0ZYOi4REREREclDjCat2cqpbCVb165dY8WKFenbvouIiIiIiMjDZSt7OnjwIM2aNWPa\ntGlcv37d0jGJiIiIiIjYvGzNbA0bNoykpCS2b9/O6NGjSU5OZvHixRYOTURERERE8gpt/Z5z2a4L\nPH78OPv27SMiIoIaNWpYMiYRERERERGbl62ZrSZNmhAQEEDNmjXp378/Pj4+lo5LRERERETEpmVr\nZqtnz57cunWLn376ibZt2/LVV19ZOi4REREREclDTEaTTX3lBdma2VqyZAnr1q3D3d2d2NhYunTp\nQrNmzSwdm4iIiIiIiM3K1syWwWDA3d0dAA8PD5ydnS0alIiIiIiIiK3L1sxWUFAQEydOpGrVqhw9\nepTg4GBLxyUiIiIiImLTspVsTZgwgVWrVnHgwAFKlixJ//79LR2XiIiIiIjkIcY8sg7KlmQr2XJw\ncOC1116zdCwiIiIiIiL5RrY/Z0tERERERESyL1szWyIiIiIi8mgzmVRGmFOa2RIREREREbEAJVsi\nIiIiIiIWoGRLRERERETEArRmS0REREREzDLl863fExISGDBgABEREbi7uzNp0iR8fHwytFm4cCEb\nN27EYDDQo0cPXnzxxYf+TM1siYiIiIjII2/FihWUKVOG5cuX07x5c2bNmpXh/nv37rF06VJWrlzJ\nwoULGT9+vNmfqWRLREREREQeeT/++CO1a9cGoE6dOhw8eDDD/a6urhQtWpT4+Hji4+MxGAxmf6bK\nCEVERERExCxjPiojDAkJYcmSJRlu8/X1xdPTEwB3d3diYmIynVekSBGaNm1Kamoq3bt3N/s4SrZE\nREREROSR0rp1a1q3bp3htp49exIXFwdAXFwcXl5eGe7fs2cPYWFhbN++HYA333yTKlWqULly5Swf\nR2WEIiIiIiLyyKtSpQq7d+8G0hKrZ555JsP93t7euLi44OTkhLOzM56enty7d++hP1MzWyIiIiIi\nYpbJmJrbIVhU+/btGThwIO3bt8fR0ZEpU6YAsGjRIoKDg2nQoAEHDhygTZs22NnZUaVKFWrWrPnQ\nn6lkS0REREREHnmurq5Mnz490+1du3ZN/75379707t072z9TZYQiIiIiIiIWoGRLRERERETEAlRG\nKCIiIiIiZuX3NVuWoJktERERERERCzCYTKb88+lkIiIiIiJiEcXfWJ7bIeTI1YUdcjsElRGKiIiI\niIh5KiPMOZURioiIiIiIWICSLREREREREQtQsiUiIiIiImIBWrMlIiIiIiJmmVK1ZiunNLMlIiIi\nIiJiAUq2RERERERELEDJloXMmDGDFStW5HYY+UK/fv1ISkri1q1b7NixA4Bx48Zx69atXI7MMtat\nW8fkyZPNtjt06BD9+vWzQkSSm5YtW5bbIVhcp06duHjxYpb316xZ04rR5C2JiYmEhIRkq+26devY\nvn27hSPKv3Jyrf9w5MgRfv31VwtFJP+G77//nkaNGrF06VJ69uwJwNmzZzly5EguR2abTMZUm/rK\nC5RsSZ43bdo0nJyc+OGHH/jpp58AGDJkCEWLFs3lyEQsb/bs2bkdguSi8PDwbCcALVu2pEGDBhaO\nKP/KybX+w9q1awkLC7NQRPJv2LFjBx9++CGdO3dm5syZAGzdupULFy7kcmTyqMiTG2SsW7eO3bt3\nk5CQwLVr1+jWrRvr169n5MiRlCxZkhUrVnDnzh1atGhBv379KFKkCDdu3KBp06acP3+e06dPU7du\nXd57770H/vzExET69OlDbGws8fHx9OvXj1q1arFs2TK2bt1KfHw8BQsWZObMmWzcuJGdO3eSkJBA\neHg4nTt3Zvv27Zw/f54PPviAhg0b0qBBA5588kmuXbtG6dKlGTduXIbHmzJlCkePHsVoNPL666/T\n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\n8D/7J0sX46MR8AAAAABJRU5ErkJggg==\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "# Show how some of these metrics/parameters might be related\n",
+ "metrics_df_for_correlations = metrics_df_current_setup[['num_samples', 'num_positive', 'balance', 'n_components', 'alpha', 'train_auroc', 'test_auroc', 'overfit']]\n",
+ "plt.figure(figsize=(16,16))\n",
+ "plt.title('Correlations', y=1.05, size=15)\n",
+ "sns.heatmap(metrics_df_for_correlations.astype(float).corr(),linewidths=0.1,vmax=1.0, square=True, annot=True)\n",
+ "sns.plt.show()"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "### 3.c. Evaluate how changing some of the parameters effects performance\n",
+ "\n",
+ " - When a larger range of alpha and an L1_ratio of 0 were used for the queries with all diseases there was a large performance gain (~6%-8%)... will there be a similar performance gain with these queries?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 13,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " n_comp_status | \n",
+ " alpha | \n",
+ " alpha_status | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 58944691 | \n",
+ " 4691 | \n",
+ " 20 | \n",
+ " 0.00426348 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.786302 | \n",
+ " 0.791176 | \n",
+ " -0.00487428 | \n",
+ "
\n",
+ " \n",
+ " 74861460 | \n",
+ " 1460 | \n",
+ " 20 | \n",
+ " 0.0136986 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.887695 | \n",
+ " 0.671007 | \n",
+ " 0.216688 | \n",
+ "
\n",
+ " \n",
+ " 251283 | \n",
+ " 1283 | \n",
+ " 20 | \n",
+ " 0.0155885 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.802908 | \n",
+ " 0.513834 | \n",
+ " 0.289074 | \n",
+ "
\n",
+ " \n",
+ " 51592405 | \n",
+ " 2405 | \n",
+ " 21 | \n",
+ " 0.00873181 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.817391 | \n",
+ " 0.783019 | \n",
+ " 0.0343722 | \n",
+ "
\n",
+ " \n",
+ " 4763502 | \n",
+ " 502 | \n",
+ " 21 | \n",
+ " 0.0418327 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.744026 | \n",
+ " 0.363402 | \n",
+ " 0.380624 | \n",
+ "
\n",
+ " \n",
+ " 56043310 | \n",
+ " 3310 | \n",
+ " 21 | \n",
+ " 0.00634441 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.838196 | \n",
+ " 0.737842 | \n",
+ " 0.100354 | \n",
+ "
\n",
+ " \n",
+ " 20641064 | \n",
+ " 1064 | \n",
+ " 21 | \n",
+ " 0.0197368 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.720906 | \n",
+ " 0.351675 | \n",
+ " 0.369231 | \n",
+ "
\n",
+ " \n",
+ " 1956951 | \n",
+ " 951 | \n",
+ " 21 | \n",
+ " 0.022082 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.891774 | \n",
+ " 0.836898 | \n",
+ " 0.0548758 | \n",
+ "
\n",
+ " \n",
+ " 74903360 | \n",
+ " 3360 | \n",
+ " 21 | \n",
+ " 0.00625 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.590746 | \n",
+ " 0.688623 | \n",
+ " -0.0978768 | \n",
+ "
\n",
+ " \n",
+ " 59791559 | \n",
+ " 1559 | \n",
+ " 21 | \n",
+ " 0.0134702 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1 | \n",
+ " OK | \n",
+ " 0.807987 | \n",
+ " 0.863636 | \n",
+ " -0.0556498 | \n",
+ "
\n",
+ " \n",
+ " 47712813 | \n",
+ " 2813 | \n",
+ " 21 | \n",
+ " 0.00746534 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.836569 | \n",
+ " 0.567084 | \n",
+ " 0.269485 | \n",
+ "
\n",
+ " \n",
+ " 46093624 | \n",
+ " 3624 | \n",
+ " 22 | \n",
+ " 0.00607064 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.868198 | \n",
+ " 0.778086 | \n",
+ " 0.0901118 | \n",
+ "
\n",
+ " \n",
+ " 67145174 | \n",
+ " 5174 | \n",
+ " 22 | \n",
+ " 0.00425203 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1 | \n",
+ " OK | \n",
+ " 0.650638 | \n",
+ " 0.618089 | \n",
+ " 0.0325484 | \n",
+ "
\n",
+ " \n",
+ " 673774 | \n",
+ " 774 | \n",
+ " 22 | \n",
+ " 0.0284238 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 0.001 | \n",
+ " OK | \n",
+ " 0.83814 | \n",
+ " 0.720199 | \n",
+ " 0.117941 | \n",
+ "
\n",
+ " \n",
+ " 40873727 | \n",
+ " 3727 | \n",
+ " 22 | \n",
+ " 0.00590287 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.547681 | \n",
+ " 0.597709 | \n",
+ " -0.0500282 | \n",
+ "
\n",
+ " \n",
+ " 2074011 | \n",
+ " 4011 | \n",
+ " 23 | \n",
+ " 0.00573423 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.805886 | \n",
+ " 0.819549 | \n",
+ " -0.0136624 | \n",
+ "
\n",
+ " \n",
+ " 7157331 | \n",
+ " 331 | \n",
+ " 23 | \n",
+ " 0.0694864 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.661472 | \n",
+ " 0.535484 | \n",
+ " 0.125989 | \n",
+ "
\n",
+ " \n",
+ " 60981740 | \n",
+ " 1740 | \n",
+ " 24 | \n",
+ " 0.0137931 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1 | \n",
+ " OK | \n",
+ " 0.826312 | \n",
+ " 0.278717 | \n",
+ " 0.547595 | \n",
+ "
\n",
+ " \n",
+ " 49211918 | \n",
+ " 1918 | \n",
+ " 24 | \n",
+ " 0.012513 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10000000 | \n",
+ " OK | \n",
+ " 0.781866 | \n",
+ " 0.683377 | \n",
+ " 0.0984882 | \n",
+ "
\n",
+ " \n",
+ " 37911502 | \n",
+ " 1502 | \n",
+ " 25 | \n",
+ " 0.0166445 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 10000 | \n",
+ " OK | \n",
+ " 0.794412 | \n",
+ " 0.816216 | \n",
+ " -0.0218047 | \n",
+ "
\n",
+ " \n",
+ " 42212708 | \n",
+ " 2708 | \n",
+ " 26 | \n",
+ " 0.00960118 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.847819 | \n",
+ " 0.503911 | \n",
+ " 0.343908 | \n",
+ "
\n",
+ " \n",
+ " 5728769 | \n",
+ " 769 | \n",
+ " 26 | \n",
+ " 0.0338101 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.818743 | \n",
+ " 0.955705 | \n",
+ " -0.136962 | \n",
+ "
\n",
+ " \n",
+ " 6751044 | \n",
+ " 1044 | \n",
+ " 26 | \n",
+ " 0.0249042 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 100000 | \n",
+ " OK | \n",
+ " 0.823739 | \n",
+ " 0.876471 | \n",
+ " -0.0527313 | \n",
+ "
\n",
+ " \n",
+ " 6721239 | \n",
+ " 1239 | \n",
+ " 27 | \n",
+ " 0.0217918 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.761891 | \n",
+ " 0.546502 | \n",
+ " 0.215389 | \n",
+ "
\n",
+ " \n",
+ " 2381528 | \n",
+ " 1528 | \n",
+ " 31 | \n",
+ " 0.020288 | \n",
+ " 10 | \n",
+ " min | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.70152 | \n",
+ " 0.782222 | \n",
+ " -0.0807018 | \n",
+ "
\n",
+ " \n",
+ " 3265502 | \n",
+ " 502 | \n",
+ " 31 | \n",
+ " 0.061753 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.945319 | \n",
+ " 0.845614 | \n",
+ " 0.0997051 | \n",
+ "
\n",
+ " \n",
+ " 48931566 | \n",
+ " 1566 | \n",
+ " 33 | \n",
+ " 0.0210728 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.870404 | \n",
+ " 0.941368 | \n",
+ " -0.070964 | \n",
+ "
\n",
+ " \n",
+ " 59251891 | \n",
+ " 1891 | \n",
+ " 37 | \n",
+ " 0.0195664 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1e-07 | \n",
+ " OK | \n",
+ " 0.712686 | \n",
+ " 0.656298 | \n",
+ " 0.0563876 | \n",
+ "
\n",
+ " \n",
+ " 10291371 | \n",
+ " 1371 | \n",
+ " 37 | \n",
+ " 0.0269876 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1 | \n",
+ " OK | \n",
+ " 0.623921 | \n",
+ " 0.460021 | \n",
+ " 0.1639 | \n",
+ "
\n",
+ " \n",
+ " 1630687 | \n",
+ " 687 | \n",
+ " 40 | \n",
+ " 0.0582242 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.830936 | \n",
+ " 0.717308 | \n",
+ " 0.113628 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 74281897 | \n",
+ " 1897 | \n",
+ " 123 | \n",
+ " 0.0648392 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1e-08 | \n",
+ " OK | \n",
+ " 0.979822 | \n",
+ " 0.942423 | \n",
+ " 0.0373994 | \n",
+ "
\n",
+ " \n",
+ " 74283618 | \n",
+ " 3618 | \n",
+ " 125 | \n",
+ " 0.0345495 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 0.0001 | \n",
+ " OK | \n",
+ " 0.979298 | \n",
+ " 0.966237 | \n",
+ " 0.013061 | \n",
+ "
\n",
+ " \n",
+ " 20645727 | \n",
+ " 5727 | \n",
+ " 126 | \n",
+ " 0.022001 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.820492 | \n",
+ " 0.75372 | \n",
+ " 0.0667716 | \n",
+ "
\n",
+ " \n",
+ " 10291657 | \n",
+ " 1657 | \n",
+ " 127 | \n",
+ " 0.0766445 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.890345 | \n",
+ " 0.876482 | \n",
+ " 0.0138631 | \n",
+ "
\n",
+ " \n",
+ " 37914907 | \n",
+ " 4907 | \n",
+ " 127 | \n",
+ " 0.0258814 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.756595 | \n",
+ " 0.693166 | \n",
+ " 0.0634284 | \n",
+ "
\n",
+ " \n",
+ " 3845977 | \n",
+ " 977 | \n",
+ " 129 | \n",
+ " 0.132037 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.892617 | \n",
+ " 0.864932 | \n",
+ " 0.0276847 | \n",
+ "
\n",
+ " \n",
+ " 7157214 | \n",
+ " 214 | \n",
+ " 145 | \n",
+ " 0.67757 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.887304 | \n",
+ " 0.697044 | \n",
+ " 0.19026 | \n",
+ "
\n",
+ " \n",
+ " 10293699 | \n",
+ " 3699 | \n",
+ " 180 | \n",
+ " 0.0486618 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.890103 | \n",
+ " 0.897372 | \n",
+ " -0.00726953 | \n",
+ "
\n",
+ " \n",
+ " 6756299 | \n",
+ " 6299 | \n",
+ " 200 | \n",
+ " 0.0317511 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.724201 | \n",
+ " 0.712275 | \n",
+ " 0.0119261 | \n",
+ "
\n",
+ " \n",
+ " 52902178 | \n",
+ " 2178 | \n",
+ " 200 | \n",
+ " 0.0918274 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.779326 | \n",
+ " 0.787247 | \n",
+ " -0.00792146 | \n",
+ "
\n",
+ " \n",
+ " 38453433 | \n",
+ " 3433 | \n",
+ " 204 | \n",
+ " 0.0594232 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.965454 | \n",
+ " 0.974062 | \n",
+ " -0.00860808 | \n",
+ "
\n",
+ " \n",
+ " 57284327 | \n",
+ " 4327 | \n",
+ " 208 | \n",
+ " 0.0480703 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.707635 | \n",
+ " 0.743816 | \n",
+ " -0.0361817 | \n",
+ "
\n",
+ " \n",
+ " 59255055 | \n",
+ " 5055 | \n",
+ " 210 | \n",
+ " 0.041543 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.829155 | \n",
+ " 0.863974 | \n",
+ " -0.034819 | \n",
+ "
\n",
+ " \n",
+ " 19566525 | \n",
+ " 6525 | \n",
+ " 215 | \n",
+ " 0.0329502 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.814416 | \n",
+ " 0.748609 | \n",
+ " 0.0658078 | \n",
+ "
\n",
+ " \n",
+ " 3241566 | \n",
+ " 1566 | \n",
+ " 218 | \n",
+ " 0.139208 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.936478 | \n",
+ " 0.920118 | \n",
+ " 0.0163599 | \n",
+ "
\n",
+ " \n",
+ " 16306753 | \n",
+ " 6753 | \n",
+ " 221 | \n",
+ " 0.0327262 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.763295 | \n",
+ " 0.729812 | \n",
+ " 0.0334832 | \n",
+ "
\n",
+ " \n",
+ " 47635733 | \n",
+ " 5733 | \n",
+ " 240 | \n",
+ " 0.0418629 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.720949 | \n",
+ " 0.684619 | \n",
+ " 0.0363302 | \n",
+ "
\n",
+ " \n",
+ " 10295881 | \n",
+ " 5881 | \n",
+ " 267 | \n",
+ " 0.0454004 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.835855 | \n",
+ " 0.84862 | \n",
+ " -0.0127648 | \n",
+ "
\n",
+ " \n",
+ " 3243430 | \n",
+ " 3430 | \n",
+ " 270 | \n",
+ " 0.0787172 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.850205 | \n",
+ " 0.830608 | \n",
+ " 0.0195972 | \n",
+ "
\n",
+ " \n",
+ " 71571090 | \n",
+ " 1090 | \n",
+ " 318 | \n",
+ " 0.291743 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.901199 | \n",
+ " 0.877029 | \n",
+ " 0.0241697 | \n",
+ "
\n",
+ " \n",
+ " 6734374 | \n",
+ " 4374 | \n",
+ " 401 | \n",
+ " 0.0916781 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.942762 | \n",
+ " 0.939371 | \n",
+ " 0.0033906 | \n",
+ "
\n",
+ " \n",
+ " 52905130 | \n",
+ " 5130 | \n",
+ " 413 | \n",
+ " 0.0805068 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.789844 | \n",
+ " 0.776297 | \n",
+ " 0.0135473 | \n",
+ "
\n",
+ " \n",
+ " 3246956 | \n",
+ " 6956 | \n",
+ " 414 | \n",
+ " 0.059517 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.876964 | \n",
+ " 0.863126 | \n",
+ " 0.0138382 | \n",
+ "
\n",
+ " \n",
+ " 6735286 | \n",
+ " 5286 | \n",
+ " 462 | \n",
+ " 0.0874007 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.932509 | \n",
+ " 0.939418 | \n",
+ " -0.0069097 | \n",
+ "
\n",
+ " \n",
+ " 38455657 | \n",
+ " 5657 | \n",
+ " 467 | \n",
+ " 0.0825526 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.922765 | \n",
+ " 0.934501 | \n",
+ " -0.0117355 | \n",
+ "
\n",
+ " \n",
+ " 38455925 | \n",
+ " 5925 | \n",
+ " 500 | \n",
+ " 0.0843882 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.92394 | \n",
+ " 0.925659 | \n",
+ " -0.00171889 | \n",
+ "
\n",
+ " \n",
+ " 6736820 | \n",
+ " 6820 | \n",
+ " 500 | \n",
+ " 0.0733138 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.902732 | \n",
+ " 0.912856 | \n",
+ " -0.0101236 | \n",
+ "
\n",
+ " \n",
+ " 71572135 | \n",
+ " 2135 | \n",
+ " 501 | \n",
+ " 0.23466 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.872661 | \n",
+ " 0.885535 | \n",
+ " -0.0128737 | \n",
+ "
\n",
+ " \n",
+ " 52905973 | \n",
+ " 5973 | \n",
+ " 510 | \n",
+ " 0.0853842 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.763811 | \n",
+ " 0.760714 | \n",
+ " 0.00309695 | \n",
+ "
\n",
+ " \n",
+ " 71572073 | \n",
+ " 2073 | \n",
+ " 580 | \n",
+ " 0.279788 | \n",
+ " 20 | \n",
+ " max | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.875455 | \n",
+ " 0.878503 | \n",
+ " -0.0030482 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
106 rows × 10 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components n_comp_status \\\n",
+ "58944691 4691 20 0.00426348 20 max \n",
+ "74861460 1460 20 0.0136986 20 max \n",
+ "251283 1283 20 0.0155885 20 max \n",
+ "51592405 2405 21 0.00873181 20 max \n",
+ "4763502 502 21 0.0418327 10 min \n",
+ "56043310 3310 21 0.00634441 10 min \n",
+ "20641064 1064 21 0.0197368 20 max \n",
+ "1956951 951 21 0.022082 20 max \n",
+ "74903360 3360 21 0.00625 10 min \n",
+ "59791559 1559 21 0.0134702 20 max \n",
+ "47712813 2813 21 0.00746534 20 max \n",
+ "46093624 3624 22 0.00607064 20 max \n",
+ "67145174 5174 22 0.00425203 20 max \n",
+ "673774 774 22 0.0284238 20 max \n",
+ "40873727 3727 22 0.00590287 20 max \n",
+ "2074011 4011 23 0.00573423 10 min \n",
+ "7157331 331 23 0.0694864 20 max \n",
+ "60981740 1740 24 0.0137931 20 max \n",
+ "49211918 1918 24 0.012513 20 max \n",
+ "37911502 1502 25 0.0166445 10 min \n",
+ "42212708 2708 26 0.00960118 20 max \n",
+ "5728769 769 26 0.0338101 20 max \n",
+ "6751044 1044 26 0.0249042 10 min \n",
+ "6721239 1239 27 0.0217918 20 max \n",
+ "2381528 1528 31 0.020288 10 min \n",
+ "3265502 502 31 0.061753 20 max \n",
+ "48931566 1566 33 0.0210728 20 max \n",
+ "59251891 1891 37 0.0195664 20 max \n",
+ "10291371 1371 37 0.0269876 20 max \n",
+ "1630687 687 40 0.0582242 20 max \n",
+ "... ... ... ... ... ... \n",
+ "74281897 1897 123 0.0648392 20 max \n",
+ "74283618 3618 125 0.0345495 20 max \n",
+ "20645727 5727 126 0.022001 20 max \n",
+ "10291657 1657 127 0.0766445 20 max \n",
+ "37914907 4907 127 0.0258814 20 max \n",
+ "3845977 977 129 0.132037 20 max \n",
+ "7157214 214 145 0.67757 20 max \n",
+ "10293699 3699 180 0.0486618 20 max \n",
+ "6756299 6299 200 0.0317511 20 max \n",
+ "52902178 2178 200 0.0918274 20 max \n",
+ "38453433 3433 204 0.0594232 20 max \n",
+ "57284327 4327 208 0.0480703 20 max \n",
+ "59255055 5055 210 0.041543 20 max \n",
+ "19566525 6525 215 0.0329502 20 max \n",
+ "3241566 1566 218 0.139208 20 max \n",
+ "16306753 6753 221 0.0327262 20 max \n",
+ "47635733 5733 240 0.0418629 20 max \n",
+ "10295881 5881 267 0.0454004 20 max \n",
+ "3243430 3430 270 0.0787172 20 max \n",
+ "71571090 1090 318 0.291743 20 max \n",
+ "6734374 4374 401 0.0916781 20 max \n",
+ "52905130 5130 413 0.0805068 20 max \n",
+ "3246956 6956 414 0.059517 20 max \n",
+ "6735286 5286 462 0.0874007 20 max \n",
+ "38455657 5657 467 0.0825526 20 max \n",
+ "38455925 5925 500 0.0843882 20 max \n",
+ "6736820 6820 500 0.0733138 20 max \n",
+ "71572135 2135 501 0.23466 20 max \n",
+ "52905973 5973 510 0.0853842 20 max \n",
+ "71572073 2073 580 0.279788 20 max \n",
+ "\n",
+ " alpha alpha_status train_auroc test_auroc overfit \n",
+ "58944691 100 OK 0.786302 0.791176 -0.00487428 \n",
+ "74861460 100 OK 0.887695 0.671007 0.216688 \n",
+ "251283 0.01 OK 0.802908 0.513834 0.289074 \n",
+ "51592405 100 OK 0.817391 0.783019 0.0343722 \n",
+ "4763502 10 OK 0.744026 0.363402 0.380624 \n",
+ "56043310 10 OK 0.838196 0.737842 0.100354 \n",
+ "20641064 1000 OK 0.720906 0.351675 0.369231 \n",
+ "1956951 100 OK 0.891774 0.836898 0.0548758 \n",
+ "74903360 0.1 OK 0.590746 0.688623 -0.0978768 \n",
+ "59791559 1 OK 0.807987 0.863636 -0.0556498 \n",
+ "47712813 100 OK 0.836569 0.567084 0.269485 \n",
+ "46093624 100 OK 0.868198 0.778086 0.0901118 \n",
+ "67145174 1 OK 0.650638 0.618089 0.0325484 \n",
+ "673774 0.001 OK 0.83814 0.720199 0.117941 \n",
+ "40873727 0.1 OK 0.547681 0.597709 -0.0500282 \n",
+ "2074011 100 OK 0.805886 0.819549 -0.0136624 \n",
+ "7157331 0.01 OK 0.661472 0.535484 0.125989 \n",
+ "60981740 1 OK 0.826312 0.278717 0.547595 \n",
+ "49211918 10000000 OK 0.781866 0.683377 0.0984882 \n",
+ "37911502 10000 OK 0.794412 0.816216 -0.0218047 \n",
+ "42212708 100 OK 0.847819 0.503911 0.343908 \n",
+ "5728769 1000000 OK 0.818743 0.955705 -0.136962 \n",
+ "6751044 100000 OK 0.823739 0.876471 -0.0527313 \n",
+ "6721239 1000000 OK 0.761891 0.546502 0.215389 \n",
+ "2381528 1000000 OK 0.70152 0.782222 -0.0807018 \n",
+ "3265502 100 OK 0.945319 0.845614 0.0997051 \n",
+ "48931566 1000 OK 0.870404 0.941368 -0.070964 \n",
+ "59251891 1e-07 OK 0.712686 0.656298 0.0563876 \n",
+ "10291371 1 OK 0.623921 0.460021 0.1639 \n",
+ "1630687 100 OK 0.830936 0.717308 0.113628 \n",
+ "... ... ... ... ... ... \n",
+ "74281897 1e-08 OK 0.979822 0.942423 0.0373994 \n",
+ "74283618 0.0001 OK 0.979298 0.966237 0.013061 \n",
+ "20645727 100 OK 0.820492 0.75372 0.0667716 \n",
+ "10291657 10 OK 0.890345 0.876482 0.0138631 \n",
+ "37914907 100 OK 0.756595 0.693166 0.0634284 \n",
+ "3845977 100 OK 0.892617 0.864932 0.0276847 \n",
+ "7157214 100 OK 0.887304 0.697044 0.19026 \n",
+ "10293699 100 OK 0.890103 0.897372 -0.00726953 \n",
+ "6756299 100 OK 0.724201 0.712275 0.0119261 \n",
+ "52902178 100 OK 0.779326 0.787247 -0.00792146 \n",
+ "38453433 10 OK 0.965454 0.974062 -0.00860808 \n",
+ "57284327 1000 OK 0.707635 0.743816 -0.0361817 \n",
+ "59255055 10 OK 0.829155 0.863974 -0.034819 \n",
+ "19566525 100 OK 0.814416 0.748609 0.0658078 \n",
+ "3241566 10 OK 0.936478 0.920118 0.0163599 \n",
+ "16306753 10 OK 0.763295 0.729812 0.0334832 \n",
+ "47635733 100 OK 0.720949 0.684619 0.0363302 \n",
+ "10295881 10 OK 0.835855 0.84862 -0.0127648 \n",
+ "3243430 10 OK 0.850205 0.830608 0.0195972 \n",
+ "71571090 100 OK 0.901199 0.877029 0.0241697 \n",
+ "6734374 10 OK 0.942762 0.939371 0.0033906 \n",
+ "52905130 10 OK 0.789844 0.776297 0.0135473 \n",
+ "3246956 100 OK 0.876964 0.863126 0.0138382 \n",
+ "6735286 10 OK 0.932509 0.939418 -0.0069097 \n",
+ "38455657 10 OK 0.922765 0.934501 -0.0117355 \n",
+ "38455925 10 OK 0.92394 0.925659 -0.00171889 \n",
+ "6736820 10 OK 0.902732 0.912856 -0.0101236 \n",
+ "71572135 10 OK 0.872661 0.885535 -0.0128737 \n",
+ "52905973 100 OK 0.763811 0.760714 0.00309695 \n",
+ "71572073 10 OK 0.875455 0.878503 -0.0030482 \n",
+ "\n",
+ "[106 rows x 10 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 3041.51 | \n",
+ " 124.623 | \n",
+ " 0.0639019 | \n",
+ " 18.3962 | \n",
+ " 133307 | \n",
+ " 0.80989 | \n",
+ " 0.753168 | \n",
+ " 0.0567219 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 2627 | \n",
+ " 81 | \n",
+ " 0.0318417 | \n",
+ " 20 | \n",
+ " 100 | \n",
+ " 0.814416 | \n",
+ " 0.762338 | \n",
+ " 0.0295182 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components alpha train_auroc \\\n",
+ "mean 3041.51 124.623 0.0639019 18.3962 133307 0.80989 \n",
+ "median 2627 81 0.0318417 20 100 0.814416 \n",
+ "\n",
+ " test_auroc overfit \n",
+ "mean 0.753168 0.0567219 \n",
+ "median 0.762338 0.0295182 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 3.06%\n",
+ "Median testing Auroc improved by 3.60%\n",
+ "Mean overfitting reduced by 1.1%\n",
+ "Median overfitting reduced by 1.6%\n",
+ "Wall time: 45min 40s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# alpha and L1_ratio.\n",
+ "metrics_df = evaluate_classifier(X = X,\n",
+ " y = y,\n",
+ " list_of_queries = query_list,\n",
+ " set_k_range = [10, 20],\n",
+ " k_function = None,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = True)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "## 4.d. Use a function to select k (number of PCA components)\n",
+ "- You can't us n_components (which the select_K is realy just a proxy for in this notebook) larger than the smallest total query size * the test train split ratio * 1-(1/cv) (for example if there is a query that has 100 total samples and you do a 80%/20% split than the training set only has 80 samples in it and if you do 3 fold CV each training fold will only have 80*0.66 (54) samples, so you couldn't do PCA with anymore than 54 components).\n",
+ " - There is a risk of overfitting if you use too many components for more unballanced queries\n",
+ " - It requires less components to capture a reasonable amount of variance for queries with less samples\n",
+ " - We haven't seen much of a clear coorelation with the two hueristics above; understanding them quantitatively has been difficult"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 14,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def k_func(num_samples, num_positives):\n",
+ " ''' Decide the number of PCA components based on a heuristic of total samples and class balance.\n",
+ " '''\n",
+ " # If there are more positives than negatives, set num_positives equal to the number of negatives\n",
+ " num_positives = min(num_positives, num_samples - num_positives)\n",
+ " # Rule of thumb based on number of positives\n",
+ " k = 5 * math.sqrt(num_positives)\n",
+ " # Adjust slightly for total number of samples\n",
+ " k = k * ((num_samples / 7000)**(1./6.))\n",
+ " k = [int(k)]\n",
+ " return(k)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 15,
+ "metadata": {
+ "collapsed": true
+ },
+ "outputs": [],
+ "source": [
+ "def k_func_proposed(num_samples, num_positives):\n",
+ " ''' Simpler function proposed for use.\n",
+ " '''\n",
+ " # If there are more positives than negatives, set num_positives equal to the number of negatives\n",
+ " num_positives = min(num_positives, num_samples - num_positives)\n",
+ " # Rule of thumb based on number of positives\n",
+ " if num_positives > 500:\n",
+ " k = 100\n",
+ " elif num_positives > 250:\n",
+ " k = 50\n",
+ " else:\n",
+ " k = 30\n",
+ " k = [int(k)]\n",
+ " return(k)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "metadata": {},
+ "source": [
+ "What do the k_funcs look like?"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 16,
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def plot_k_func(k_func):\n",
+ " X_plot = [] # number of samples\n",
+ " Y_plot = [] # number of positives\n",
+ " Z_plot = [] # k (number of components in PCA)\n",
+ " for query in query_list:\n",
+ " X_plot.append(query[2]['total'])\n",
+ " Y_plot.append(query[2]['positive'])\n",
+ " Z_plot.append(k_func(query[2]['total'], query[2]['positive']))\n",
+ "\n",
+ "\n",
+ " plt.scatter(X_plot, Z_plot)\n",
+ " plt.title('Number of Components vs. Query Size')\n",
+ " plt.ylabel('K')\n",
+ " plt.xlabel('Total Number of Samples')\n",
+ " plt.show()\n",
+ "\n",
+ " plt.scatter(Y_plot, Z_plot)\n",
+ " plt.title('Number of Components vs. Number of Positives')\n",
+ " plt.ylabel('K')\n",
+ " plt.xlabel('Number of Positives')\n",
+ " plt.show()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 17,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\nYII=\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "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\nAABJRU5ErkJggg==\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_k_func(k_func)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 18,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfIAAAFlCAYAAAAQ8morAAAABHNCSVQICAgIfAhkiAAAAAlwSFlz\nAAALEgAACxIB0t1+/AAAIABJREFUeJzt3XlYlOX+P/D3MzPMgCwKipYZHTdcUkNF3DFIxVIxzdz6\naWZZWnlCWyATcculzFTymGadztEUl8pvp87JzCVLlKxsw0wxM1FkV4ZtZpi5f38QE+sMIAzcw/t1\nXV3Js34+z9zPvOd5ZmAUIYQAERERSUnV0AUQERFR7THIiYiIJMYgJyIikhiDnIiISGIMciIiIokx\nyImIiCTGIKdGJTk5GV26dMHevXvLTH/77bcRFRVVZ/sJDQ3FTz/9VGfbsyU3NxdTpkzB6NGjceDA\ngQrzL1y4gHnz5mHs2LEIDw/H//t//w/ffPONQ2pzpFmzZiErK6vB9n/27Fk8+eSTCAsLw7hx4zB1\n6lR8/vnnDVbPBx98gAkTJiA8PByjR4/GSy+9BL1eDwDYtWsXtm7d2mC1kVw0DV0AUXkqlQpr1qxB\nYGAg2rdv39Dl3LRffvkFmZmZOHjwYIV5v/32Gx5++GGsWrUKQ4cOBQCcOHECc+bMwa5du9C5c2dH\nl1tvjh8/3mD7PnPmDB577DGsWrUKw4YNA1D8AuqZZ55BWloapk2b5tB6fvzxR2zatAnvv/8+WrRo\nAbPZjKVLl2LJkiV47bXXMHXqVIfWQ3JjkFOj4+rqikceeQTPPvss4uLioNVqy8yPiopC586d8eij\nj1b4OTQ0FGPGjMHRo0dx/fp1zJs3D9999x0SExOh0WiwefNmtGnTBgCwc+dOnD17FkajEY888ggm\nTpwIADh8+DA2b94Mk8kEV1dXREZGonfv3oiNjcX333+PtLQ0dOnSBWvXri1T1+eff4433ngDZrMZ\nHh4eePHFF+Hh4YGFCxciNTUV48aNw+7du+Hq6mpd56233sIDDzxgDXEAGDhwIF577TXrcpVtt1ev\nXoiNjcUff/yBy5cvIy0tDb169cLgwYOxf/9+JCcn4/nnn8eYMWMQGxuL8+fPIyMjA5mZmejatSte\nfvlleHh44Pz581i2bBmuX78ORVEwa9Ys3H///UhISMDrr7+O22+/HefPn4fRaMTixYsxYMAAGI1G\nrF27FqdOnYLZbEb37t2xaNEieHh4IDQ0FOPHj8eJEyeQkpKCe++9Fy+88AJefPFFAMDDDz+MrVu3\n4siRI4iLi4OLiwt0Oh2WLVuGTp06WY+BxWJBSEgI3njjDfTs2RMAMH/+fPTr1w/9+/fHSy+9BKPR\nCCEEJk6ciIceesjmmFq/fj1mz55tDXEA6NixI1555RXMnDkTDzzwAD755BMcOHAAW7ZsAVB8xVzy\ns72ee/XqhV9//RXh4eGIi4vDkSNHoFKpUFBQgNDQUHz88cdo2bKldd/p6ekQQqCwsBAAoFar8cwz\nz+D8+fMAgNjYWGRnZ2P27NmYM2eOdb2MjAxoNBp88cUXSE1NxbJly5CSkgKTyYTRo0eXWZaaEEHU\niFy+fFkEBAQIs9kspk2bJlavXi2EEGLbtm0iMjJSCCFEZGSk2LZtm3Wd0j+HhISIlStXCiGE+OST\nT0TXrl3FL7/8IoQQ4sknnxSbN2+2LhcTEyOEEOLatWtiwIAB4ty5c+LixYtizJgxIisrSwghxLlz\n58TgwYNFXl6e2LhxowgLCxMmk6lC3UlJSWLQoEHijz/+EEIIER8fLwYPHiz0er04efKkGD16dKX9\njhkzRhw9erTK42Fruxs3bhQhISEiJydHFBQUiH79+olVq1YJIYQ4ePCgGDlypBBCiI0bN4rg4GCR\nnp4uzGazWLBggVi9erUwmUzinnvuEQcOHLAeh6FDh4rvvvtOnDx5UnTr1k2cOXNGCCHE22+/LR56\n6CEhhBCxsbFi9erVwmKxCCGEeO2116zHMiQkxPqYXbt2TfTs2dNau7+/v8jMzBRFRUXizjvvFKmp\nqUIIIT788EMRFxdXofcNGzaIpUuXCiGEuH79uggKChI5OTnixRdfFFu2bBFCCJGWliYiIiKE2Wyu\n8hgKIUSfPn3ETz/9VOm8oKAgkZiYKN5//33x+OOPW6eX/tlez2+88YZ1vfDwcOtjunfvXjF//vwK\n+zQajWLBggWiW7du4v777xdLly4VR44csW5/48aN1t5L/PHHHyIkJER8/fXXQgghpk+fLg4dOiSE\nEKKwsFBMnz5dfPLJJzaPAzknXpFTo6RSqfDqq69i/PjxGDJkSI3WHTlyJADg9ttvR6tWrdC1a1cA\ngJ+fH27cuGFdbsqUKQCANm3aYMiQIThx4gTUajXS0tIwc+ZM63KKouCPP/4AAAQEBECjqXjanDx5\nEgMGDMDtt98OoPiq2sfHBz///DMURamyVkVRYLFYqpxva7sAMGjQIHh6egIAWrdubb2y9/Pzw/Xr\n163bGTVqFFq1agUAmDhxIlauXIkHHngABoPBerzatGmDkSNH4ssvv0T//v3Rtm1bdOvWDQDQvXt3\nfPjhhwCAo0ePQq/XIz4+HgBgMpnKXG3ec8891u21bNkSN27csNYPFF99jho1ClOmTMHdd9+NwYMH\nY+zYsRV6f+CBBzBx4kRERUXh448/RkhICDw9PTFixAhERkbixx9/xMCBA7Fo0SKoVDf3cR+z2Wxz\nvr2eAwMDrf9+6KGHsGfPHgwbNgy7d+/GCy+8UGF7Li4ueO211/DCCy8gISEBp06dQmRkJAYOHIj1\n69dXWD4rKwuzZ8/GggUL0K9fP+Tn5+PUqVO4ceMGNmzYAADIz8/H2bNncd9999XqGJC8GOTUaLVt\n2xZLlixBZGQk7r//fut0RVEgSn1FgMlkKrNe6VvxLi4uVW6/9JO/EAIajQZms7nCk2lKSgpat26N\ngwcPolmzZpVuS1TylQVCCBQVFdmsISAgAN9//z1CQkLKTH/jjTfg5+dnc7sAKrztUNmLDKA4PEtY\nLBaoVKpKX0CU3nbptwBKH3OLxYKFCxdab1Pn5eXBYDBYl9XpdJWuV9ratWtx7tw5xMfH46233sK+\nffuwefPmMsvcdttt6N69O44ePYoPPvgACxcuBACEhITgwIEDiI+Px4kTJ7Bp0ybExcXBz8+v0t4B\noE+fPvj666/Ro0cPAMW3tlu1aoVff/0VJpMJ/v7+SEpKqnJc2eu59LgYO3Ys1q1bh5MnTyI/Px/9\n+vWrUM++ffvg7e2Ne+65B+Hh4QgPD8fcuXMRGhpa4QOBBQUFmDNnDsaPH48xY8ZY6xFCIC4uDm5u\nbgCKw770saemg59ap0bt3nvvRXBwMP71r39Zp3l7e1uvSLOysmr9Ce+SK8yrV68iPj4eAwcOxIAB\nA3D8+HFcuHABAPDFF18gPDy8zJN2ZUrWu3z5MgBY3yO+6667bK736KOPYu/evfjqq6+s044dO4bt\n27eja9eutd5ueYcOHYJer4fFYsGePXsQEhKC9u3bw8XFBZ999hkAIDU1FQcOHMCgQYNsbmvIkCF4\n7733YDQaYbFYEB0djXXr1tmtQa1Wo6ioCFlZWRg2bBhatGiBmTNnIiIiAr/++mul60yaNAlvvfUW\nCgsL0bdvXwDAs88+i//+978YPXo0YmJi4OHhgZSUFJv7XrBgAd555x188cUXAIB3330XEyZMwPPP\nP4+IiAjodDr4+Pjg/PnzMBgMKCoqwpEjR2rVs5ubG8LDw7Fw4ULrXZ/yVCoV1q5di2vXrlmn/f77\n77jtttvQvHlz67SioiJERESga9eueOKJJ6zTPTw8EBAQgH/+858AgJycHEydOhWHDh2yeRzIOfGK\nnBq9RYsW4dtvv7X+PH36dDz33HMICwtDu3btEBQUVKvtGgwGjB8/HiaTCYsWLbJ+Qn7ZsmVYsGCB\n9Sp98+bNVV6Jl+jUqRNiYmLw9NNPw2w2w9XVFW+++ab1tndV7rjjDrz55ptYv3491qxZA4vFAh8f\nH2zevBn+/v4AUKvtlteqVSvMnj0b2dnZ6NevH+bMmQMXFxf84x//wIoVKxAbGwuz2YynnnoKAwYM\nQEJCQpXbevLJJ7FmzRqMHz8eZrMZ3bp1q9avBo4YMQLTpk3DP/7xD8ydOxczZ86Eq6sr1Go1VqxY\nUek6oaGhWLp0KWbPnl1m/y+99BJ2794NtVqN4cOHIygoCKmpqXj88cexdetW6wcaS3Tr1g3btm3D\nhg0bsHLlSqhUKri7u8PHxwc//PADrl69isGDB6Nfv36499574evri/79+1tfYNS05wkTJmDPnj1l\n7iSVn19QUIDZs2fDaDRCURT87W9/w7Zt28rcPfn0009x9OhR9OjRA/fff7/1jsHWrVuxdu1aLF++\nHGPHjoXRaMSYMWMQHh5u93Eg56OIyu57EZHTKPkE9OLFixu6lEbp22+/hZ+fH3x9fetke0IIvPXW\nW7hy5QqWLl1aJ9sksoVX5ETUpJXcsq8r99xzj/WuCpEj8IqciIhIYvywGxERkcQY5ERERBJjkBMR\nEUlMyg+7pafrbc739m6G7Ox8B1XTcJpCn+zRObBH59AUegQaZ5++vlX/yqlTXpFrNGr7CzmBptAn\ne3QO7NE5NIUeAfn6dMogJyIiaioY5ERERBJjkBMREUmMQU5ERCQxBjkREZHEGOREREQSY5ATERFJ\njEFO0jCYzEjLzofBZC7zbyKqXyXnW6GxqKFLoUrU6192++GHH7B27Vps374dly5dQlRUFBRFQefO\nnRETEwOVSoU9e/YgLi4OGo0Gc+fORUhISH2WRBIyWyzYfTgJp8+lIyvHAJ1WDUCg0GhBSy8devv7\nYnJoJ6hVfF1KVJfKn3u+3m7o1bElz7dGpt6C/K233sJHH30ENzc3AMCqVasQERGB/v37Y/HixTh0\n6BACAgKwfft2vP/++zAYDJg2bRoGDx4MrVZbX2WRhHYfTsLn3yRbfy40/nUVnpljsM6bNtzf4bUR\nObPy515adgHPt0ao3l5S+fn5ITY21vpzYmIigoKCAADBwcGIj4/Hjz/+iN69e0Or1cLT0xN+fn44\ne/ZsfZVEEio0FuH0uXS7y50+l8Hb7ER1yGAyV3nu8XxrXOrtijwsLAzJyX+9khNCQFEUAIC7uzv0\nej1yc3Ph6fnXH4J3d3dHbm6u3W17ezez+7dwbf2BeWfi7H2mZOQhS2+wu1y2vhBqrQt8W7k7oKq6\n5+yPI8AeZWPr3JP9fKsOmR5Lh337marU+yl5eXnw8vKCh4cH8vLyykwvHexVsfetNL6+nna/Ic0Z\nNIU+vZu7wcdTh8wc22Hu7ekKs9Ek5fFoCo8je5SP2WSu8tyT+Xyrjsb4WDaKbz/r3r07EhISAADH\njh1DYGAgevXqhW+//RYGgwF6vR4XLlyAvz/fd6G/uGo16O3va3e53v6toHOR6xuLiBoznYu6ynOP\n51vj4rAr8sjISERHR2PdunXo0KEDwsLCoFarMX36dEybNg1CCMyfPx86nc5RJZEkJod2AlD8vly2\nvhDaP59ADEYzfLxc0du/lXUZIqo75c+9Vi3++tQ6NR6KEEI0dBE1Ze+WR2O8LVIfmkKfpXs0mMy4\nkWtAc4/iF3sl/5b9yqCpPY7Oypl7LDn3Ov6tJfQ3Chq6nHrXGB9LW7fWHXZFTnSzdC5qtPZuZv25\n9L+JqP6UnHuuWg0aV7wRwL/sRkREJDUGORERkcQY5ERERBJjkBMREUmMQU5ERCQxBjkREZHEGORE\nREQSY5ATERFJjEFOREQkMQY5ERGRxBjkREREEmOQExERSYxBTkREJDEGORERkcQY5ERERBJjkBMR\nEUmMQU5ERCQxBjkREZHEGOREREQSY5ATERFJjEFOREQkMQY5ERGRxBjkREREEmOQExERSYxBTkRE\nJDEGORERkcQY5ERERBJjkBMREUmMQU5ERCQxBjkREZHENI7cmdFoxIsvvojLly/Dw8MDixcvhqIo\niIqKgqIo6Ny5M2JiYqBS8fUFERFRdTg0yPfs2YNmzZphz549+O2337B8+XK4uLggIiIC/fv3x+LF\ni3Ho0CGMGDHCkWURERFJy6GXvklJSQgODgYAdOjQARcuXEBiYiKCgoIAAMHBwYiPj3dkSURERFJz\n6BV5t27dcOTIEQwfPhw//PADUlNT0bJlSyiKAgBwd3eHXq+3ux1v72bQaNQ2l/H19ayTmhu7ptAn\ne3QO7NE5NIUeAbn6dGiQP/DAA7hw4QKmTZuGPn364M4770RaWpp1fl5eHry8vOxuJzs73+Z8X19P\npKfbf0Egu6bQJ3t0DuzROTSFHoHG2aetFxYOvbX+008/YeDAgdi1axdGjRqF22+/Hd27d0dCQgIA\n4NixYwgMDHRkSURERFJz6BX5HXfcgQ0bNuDNN9+Ep6cnXn75ZeTn5yM6Ohrr1q1Dhw4dEBYW5siS\niIiIpObQIPfx8cG7775bYfqOHTscWQYREZHT4C9sExERSYxBTkREJDEGORERkcQY5ERERBJjkBMR\nEUmMQU5ERCQxBjkREZHEGOREREQSY5ATERFJjEFOREQkMQY5ERGRxBjkREREEmOQExERSYxBTkRE\nJDEGORERkcQY5ERERBJjkBMREUmMQU5ERCQxBjkREZHEGOREREQSY5ATERFJjEFOREQkMQY5ERGR\nxBjkREREEmOQExERSYxBTkREJDEGORERkcQY5ERERBJjkBMREUmMQU5ERCQxBjkREZHENI7cmclk\nQlRUFK5cuQKVSoXly5dDo9EgKioKiqKgc+fOiImJgUrF1xdERETV4dAg/+KLL1BUVIS4uDgcP34c\n69evh8lkQkREBPr374/Fixfj0KFDGDFihCPLIiIikpZDL33bt28Ps9kMi8WC3NxcaDQaJCYmIigo\nCAAQHByM+Ph4R5ZEREQkNYdekTdr1gxXrlzBvffei+zsbLz55ps4deoUFEUBALi7u0Ov19vdjrd3\nM2g0apvL+Pp61knNjV1T6JM9Ogf26ByaQo+AXH06NMjfffddDBkyBM8++yxSUlLw8MMPw2QyWefn\n5eXBy8vL7nays/Ntzvf19UR6uv0XBLJrCn2yR+fAHp1DU+gRaJx92nph4dBb615eXvD0LC6mefPm\nKCoqQvfu3ZGQkAAAOHbsGAIDAx1ZEhERkdQcekU+c+ZMLFy4ENOmTYPJZML8+fPRo0cPREdHY926\ndejQoQPCwsIcWRIREZHUHBrk7u7u2LBhQ4XpO3bscGQZREREToO/sE1ERCQxBjkREZHEGOREREQS\nY5ATERFJjEFOREQkMQY5ERGRxBjkREREEmOQExERSYxBTkREJDEGORERkcQY5ERERBJjkBMREUmM\n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\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "image/png": "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\nAAClpaUwGo22eV1dXe0+7mrLly/HiRMnkJaWhrfffhtbtmzBmjVrKs3TpEkTtG/fHrt27UJycjLm\nzp0LAAgJCcG2bduQlpaGvXv34s0338SmTZvQvHlzu9t+rZkzZyIiIgJr166ttk5H+xRQsz5f2aeA\nyz1buXIlWrVqBQAoLi6udLBX3X517XNktVptz48j176mfrVrn4+rlzljxgyMHj0a3333HZKTk7F+\n/XokJyc7XR8AjBkzBlu3bkVhYSEGDRoEd3d3WCwWtGrVqtKNr7m5ufDx8YGLiwtSUlKwd+9e7Nu3\nD2PGjMGbb76JLl261Gh9VDt49zvdlIceegjBwcF4//33bWPe3t62M9Xz58/f8J3iV848c3JykJaW\nhl69eqFnz57Ys2cPMjMzAQDffvsthg8fXim07LnyuDNnzgCA7TXlBx54wOHjJk2ahI8//hjfffed\nbSw1NRWJiYlo27btDS/3WikpKTAYDLBarUhKSkJISAhatmwJFxcXbN++HcDlf2y3bduG3r17O1xW\nUFAQPvzwQ5hMJlitVsTGxmLFihVOa9BqtaioqMD58+fRr18/NGjQAE899RQiIyNx/Phxu4959NFH\n8fbbb+PSpUvo2rUrAODFF1/EV199haFDhyI+Ph4eHh44d+5cjXuh1+vx+uuv45///KftjNnLywtm\nsxmnTp0CALs3NdZEeno6cnJyAAAfffQRgoODAVzu2XvvvQchBEwmE6ZMmYINGzY4Xd6VXl95XFJS\nktPnpybLTE5Otr0TIDExEd27d4dGo0H//v1RVlaGxx57DPHx8cjMzKxyEHHlebzWoEGDkJGRgaSk\nJDz66KMALh+0/vbbb/jhhx8AXL5pNDQ0FHl5eVi+fDneeustDBw4EPPmzUPr1q1x+vTpm9o2uv14\npk43LSYmBvv377f9PmHCBMyaNQuhoaFo2rQpAgMDb2i5RqMRI0eOhNlsRkxMjO1O+5dffhkzZ860\nnWmtWbOm2jOpK1q3bo34+Hi88MILsFgscHNzw9q1a51eTmzRogXWrl2LN954A0uXLoXVaoWPjw/W\nrFmDgIAAALih5V6rYcOGeOaZZ1BUVITu3btj8uTJcHFxwVtvvYVFixYhISEBFosFzz//PHr27In0\n9PRqlzV16lQsXboUI0eOhMViQbt27Wr0dsNBgwZh3LhxeOuttzBlyhQ89dRTcHNzg1arxaJFi+w+\n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\nTkSuQmCC\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "plot_k_func(k_func_proposed)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 19,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 3041.51 | \n",
+ " 124.623 | \n",
+ " 0.0639019 | \n",
+ " 42.2736 | \n",
+ " 0.537434 | \n",
+ " 0.78007 | \n",
+ " 0.7157 | \n",
+ " 0.06437 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 2627 | \n",
+ " 81 | \n",
+ " 0.0318417 | \n",
+ " 35 | \n",
+ " 1 | \n",
+ " 0.76961 | \n",
+ " 0.718447 | \n",
+ " 0.052919 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components alpha train_auroc \\\n",
+ "mean 3041.51 124.623 0.0639019 42.2736 0.537434 0.78007 \n",
+ "median 2627 81 0.0318417 35 1 0.76961 \n",
+ "\n",
+ " test_auroc overfit \n",
+ "mean 0.7157 0.06437 \n",
+ "median 0.718447 0.052919 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by -0.69%\n",
+ "Median testing Auroc improved by -0.79%\n",
+ "Mean overfitting reduced by 0.3%\n",
+ "Median overfitting reduced by -0.7%\n",
+ "Wall time: 52min 43s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k function.\n",
+ "metrics_df = evaluate_classifier(X = X,\n",
+ " y = y,\n",
+ " list_of_queries = query_list,\n",
+ " set_k_range = None,\n",
+ " k_function = k_func,\n",
+ " alpha_range = [10** x for x in range(-3, 1)],\n",
+ " l1_ratio = [0.15])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 20,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 3041.51 | \n",
+ " 124.623 | \n",
+ " 0.0639019 | \n",
+ " 42.2736 | \n",
+ " 119157 | \n",
+ " 0.836994 | \n",
+ " 0.775042 | \n",
+ " 0.0619518 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 2627 | \n",
+ " 81 | \n",
+ " 0.0318417 | \n",
+ " 35 | \n",
+ " 100 | \n",
+ " 0.834954 | \n",
+ " 0.788417 | \n",
+ " 0.0355583 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components alpha train_auroc \\\n",
+ "mean 3041.51 124.623 0.0639019 42.2736 119157 0.836994 \n",
+ "median 2627 81 0.0318417 35 100 0.834954 \n",
+ "\n",
+ " test_auroc overfit \n",
+ "mean 0.775042 0.0619518 \n",
+ "median 0.788417 0.0355583 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 5.25%\n",
+ "Median testing Auroc improved by 6.21%\n",
+ "Mean overfitting reduced by 0.5%\n",
+ "Median overfitting reduced by 1.0%\n",
+ "Wall time: 35min 38s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# k function and alpha and l1_ratio.\n",
+ "metrics_df = evaluate_classifier(X = X,\n",
+ " y = y,\n",
+ " list_of_queries = query_list,\n",
+ " set_k_range = None,\n",
+ " k_function = k_func,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = False)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 21,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " n_comp_status | \n",
+ " alpha | \n",
+ " alpha_status | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " 58944691 | \n",
+ " 4691 | \n",
+ " 20 | \n",
+ " 0.00426348 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1e-05 | \n",
+ " OK | \n",
+ " 0.78652 | \n",
+ " 0.822193 | \n",
+ " -0.0356728 | \n",
+ "
\n",
+ " \n",
+ " 74861460 | \n",
+ " 1460 | \n",
+ " 20 | \n",
+ " 0.0136986 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 0.01 | \n",
+ " OK | \n",
+ " 0.859158 | \n",
+ " 0.753472 | \n",
+ " 0.105686 | \n",
+ "
\n",
+ " \n",
+ " 251283 | \n",
+ " 1283 | \n",
+ " 20 | \n",
+ " 0.0155885 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.859158 | \n",
+ " 0.477273 | \n",
+ " 0.381886 | \n",
+ "
\n",
+ " \n",
+ " 51592405 | \n",
+ " 2405 | \n",
+ " 21 | \n",
+ " 0.00873181 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.780622 | \n",
+ " 0.772013 | \n",
+ " 0.0086099 | \n",
+ "
\n",
+ " \n",
+ " 4763502 | \n",
+ " 502 | \n",
+ " 21 | \n",
+ " 0.0418327 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100000 | \n",
+ " OK | \n",
+ " 0.683211 | \n",
+ " 0.32732 | \n",
+ " 0.355891 | \n",
+ "
\n",
+ " \n",
+ " 56043310 | \n",
+ " 3310 | \n",
+ " 21 | \n",
+ " 0.00634441 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.85255 | \n",
+ " 0.889058 | \n",
+ " -0.0365078 | \n",
+ "
\n",
+ " \n",
+ " 20641064 | \n",
+ " 1064 | \n",
+ " 21 | \n",
+ " 0.0197368 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.74277 | \n",
+ " 0.348086 | \n",
+ " 0.394684 | \n",
+ "
\n",
+ " \n",
+ " 1956951 | \n",
+ " 951 | \n",
+ " 21 | \n",
+ " 0.022082 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.907608 | \n",
+ " 0.828877 | \n",
+ " 0.0787313 | \n",
+ "
\n",
+ " \n",
+ " 74903360 | \n",
+ " 3360 | \n",
+ " 21 | \n",
+ " 0.00625 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10000000 | \n",
+ " OK | \n",
+ " 0.724492 | \n",
+ " 0.796407 | \n",
+ " -0.0719154 | \n",
+ "
\n",
+ " \n",
+ " 59791559 | \n",
+ " 1559 | \n",
+ " 21 | \n",
+ " 0.0134702 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100000 | \n",
+ " OK | \n",
+ " 0.86791 | \n",
+ " 0.895292 | \n",
+ " -0.0273821 | \n",
+ "
\n",
+ " \n",
+ " 47712813 | \n",
+ " 2813 | \n",
+ " 21 | \n",
+ " 0.00746534 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.858776 | \n",
+ " 0.610465 | \n",
+ " 0.248311 | \n",
+ "
\n",
+ " \n",
+ " 46093624 | \n",
+ " 3624 | \n",
+ " 22 | \n",
+ " 0.00607064 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.890894 | \n",
+ " 0.802358 | \n",
+ " 0.0885365 | \n",
+ "
\n",
+ " \n",
+ " 67145174 | \n",
+ " 5174 | \n",
+ " 22 | \n",
+ " 0.00425203 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10000000 | \n",
+ " OK | \n",
+ " 0.79378 | \n",
+ " 0.633366 | \n",
+ " 0.160414 | \n",
+ "
\n",
+ " \n",
+ " 673774 | \n",
+ " 774 | \n",
+ " 22 | \n",
+ " 0.0284238 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.822703 | \n",
+ " 0.816225 | \n",
+ " 0.00647774 | \n",
+ "
\n",
+ " \n",
+ " 40873727 | \n",
+ " 3727 | \n",
+ " 22 | \n",
+ " 0.00590287 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.551374 | \n",
+ " 0.578841 | \n",
+ " -0.0274666 | \n",
+ "
\n",
+ " \n",
+ " 2074011 | \n",
+ " 4011 | \n",
+ " 23 | \n",
+ " 0.00573423 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.823058 | \n",
+ " 0.849624 | \n",
+ " -0.0265659 | \n",
+ "
\n",
+ " \n",
+ " 7157331 | \n",
+ " 331 | \n",
+ " 23 | \n",
+ " 0.0694864 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.787263 | \n",
+ " 0.896774 | \n",
+ " -0.109511 | \n",
+ "
\n",
+ " \n",
+ " 60981740 | \n",
+ " 1740 | \n",
+ " 24 | \n",
+ " 0.0137931 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.905393 | \n",
+ " 0.540525 | \n",
+ " 0.364869 | \n",
+ "
\n",
+ " \n",
+ " 49211918 | \n",
+ " 1918 | \n",
+ " 24 | \n",
+ " 0.012513 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.784888 | \n",
+ " 0.68285 | \n",
+ " 0.102038 | \n",
+ "
\n",
+ " \n",
+ " 37911502 | \n",
+ " 1502 | \n",
+ " 25 | \n",
+ " 0.0166445 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10000000 | \n",
+ " OK | \n",
+ " 0.806097 | \n",
+ " 0.812162 | \n",
+ " -0.00606563 | \n",
+ "
\n",
+ " \n",
+ " 42212708 | \n",
+ " 2708 | \n",
+ " 26 | \n",
+ " 0.00960118 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 0.0001 | \n",
+ " OK | \n",
+ " 0.860673 | \n",
+ " 0.471508 | \n",
+ " 0.389164 | \n",
+ "
\n",
+ " \n",
+ " 5728769 | \n",
+ " 769 | \n",
+ " 26 | \n",
+ " 0.0338101 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.839426 | \n",
+ " 0.959732 | \n",
+ " -0.120306 | \n",
+ "
\n",
+ " \n",
+ " 6751044 | \n",
+ " 1044 | \n",
+ " 26 | \n",
+ " 0.0249042 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100000 | \n",
+ " OK | \n",
+ " 0.830408 | \n",
+ " 0.90098 | \n",
+ " -0.0705721 | \n",
+ "
\n",
+ " \n",
+ " 6721239 | \n",
+ " 1239 | \n",
+ " 27 | \n",
+ " 0.0217918 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.7701 | \n",
+ " 0.552263 | \n",
+ " 0.217837 | \n",
+ "
\n",
+ " \n",
+ " 2381528 | \n",
+ " 1528 | \n",
+ " 31 | \n",
+ " 0.020288 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000000 | \n",
+ " OK | \n",
+ " 0.721437 | \n",
+ " 0.782222 | \n",
+ " -0.0607853 | \n",
+ "
\n",
+ " \n",
+ " 3265502 | \n",
+ " 502 | \n",
+ " 31 | \n",
+ " 0.061753 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.974255 | \n",
+ " 0.912281 | \n",
+ " 0.0619746 | \n",
+ "
\n",
+ " \n",
+ " 48931566 | \n",
+ " 1566 | \n",
+ " 33 | \n",
+ " 0.0210728 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 0.1 | \n",
+ " OK | \n",
+ " 0.87122 | \n",
+ " 0.889251 | \n",
+ " -0.0180311 | \n",
+ "
\n",
+ " \n",
+ " 59251891 | \n",
+ " 1891 | \n",
+ " 37 | \n",
+ " 0.0195664 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 0.0001 | \n",
+ " OK | \n",
+ " 0.621143 | \n",
+ " 0.737711 | \n",
+ " -0.116569 | \n",
+ "
\n",
+ " \n",
+ " 10291371 | \n",
+ " 1371 | \n",
+ " 37 | \n",
+ " 0.0269876 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1 | \n",
+ " OK | \n",
+ " 0.609912 | \n",
+ " 0.436567 | \n",
+ " 0.173345 | \n",
+ "
\n",
+ " \n",
+ " 1630687 | \n",
+ " 687 | \n",
+ " 40 | \n",
+ " 0.0582242 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1000 | \n",
+ " OK | \n",
+ " 0.814857 | \n",
+ " 0.733654 | \n",
+ " 0.0812035 | \n",
+ "
\n",
+ " \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ " ... | \n",
+ "
\n",
+ " \n",
+ " 74281897 | \n",
+ " 1897 | \n",
+ " 123 | \n",
+ " 0.0648392 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 0.0001 | \n",
+ " OK | \n",
+ " 0.981577 | \n",
+ " 0.947606 | \n",
+ " 0.0339709 | \n",
+ "
\n",
+ " \n",
+ " 74283618 | \n",
+ " 3618 | \n",
+ " 125 | \n",
+ " 0.0345495 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 1e-10 | \n",
+ " min | \n",
+ " 0.978894 | \n",
+ " 0.9699 | \n",
+ " 0.0089942 | \n",
+ "
\n",
+ " \n",
+ " 20645727 | \n",
+ " 5727 | \n",
+ " 126 | \n",
+ " 0.022001 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.826403 | \n",
+ " 0.750972 | \n",
+ " 0.075431 | \n",
+ "
\n",
+ " \n",
+ " 10291657 | \n",
+ " 1657 | \n",
+ " 127 | \n",
+ " 0.0766445 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.880702 | \n",
+ " 0.882866 | \n",
+ " -0.00216486 | \n",
+ "
\n",
+ " \n",
+ " 37914907 | \n",
+ " 4907 | \n",
+ " 127 | \n",
+ " 0.0258814 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.773858 | \n",
+ " 0.6986 | \n",
+ " 0.0752586 | \n",
+ "
\n",
+ " \n",
+ " 3845977 | \n",
+ " 977 | \n",
+ " 129 | \n",
+ " 0.132037 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.902039 | \n",
+ " 0.857466 | \n",
+ " 0.0445731 | \n",
+ "
\n",
+ " \n",
+ " 7157214 | \n",
+ " 214 | \n",
+ " 145 | \n",
+ " 0.67757 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.90047 | \n",
+ " 0.684729 | \n",
+ " 0.215741 | \n",
+ "
\n",
+ " \n",
+ " 10293699 | \n",
+ " 3699 | \n",
+ " 180 | \n",
+ " 0.0486618 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.891038 | \n",
+ " 0.898003 | \n",
+ " -0.00696588 | \n",
+ "
\n",
+ " \n",
+ " 6756299 | \n",
+ " 6299 | \n",
+ " 200 | \n",
+ " 0.0317511 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.735716 | \n",
+ " 0.721926 | \n",
+ " 0.0137893 | \n",
+ "
\n",
+ " \n",
+ " 52902178 | \n",
+ " 2178 | \n",
+ " 200 | \n",
+ " 0.0918274 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.826723 | \n",
+ " 0.820013 | \n",
+ " 0.00670988 | \n",
+ "
\n",
+ " \n",
+ " 38453433 | \n",
+ " 3433 | \n",
+ " 204 | \n",
+ " 0.0594232 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.968199 | \n",
+ " 0.971834 | \n",
+ " -0.00363484 | \n",
+ "
\n",
+ " \n",
+ " 57284327 | \n",
+ " 4327 | \n",
+ " 208 | \n",
+ " 0.0480703 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.797122 | \n",
+ " 0.806981 | \n",
+ " -0.00985872 | \n",
+ "
\n",
+ " \n",
+ " 59255055 | \n",
+ " 5055 | \n",
+ " 210 | \n",
+ " 0.041543 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.865271 | \n",
+ " 0.866529 | \n",
+ " -0.00125774 | \n",
+ "
\n",
+ " \n",
+ " 19566525 | \n",
+ " 6525 | \n",
+ " 215 | \n",
+ " 0.0329502 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.860294 | \n",
+ " 0.785022 | \n",
+ " 0.0752716 | \n",
+ "
\n",
+ " \n",
+ " 3241566 | \n",
+ " 1566 | \n",
+ " 218 | \n",
+ " 0.139208 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.940743 | \n",
+ " 0.922054 | \n",
+ " 0.0186889 | \n",
+ "
\n",
+ " \n",
+ " 16306753 | \n",
+ " 6753 | \n",
+ " 221 | \n",
+ " 0.0327262 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.780313 | \n",
+ " 0.734924 | \n",
+ " 0.0453892 | \n",
+ "
\n",
+ " \n",
+ " 47635733 | \n",
+ " 5733 | \n",
+ " 240 | \n",
+ " 0.0418629 | \n",
+ " 30 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.726737 | \n",
+ " 0.685396 | \n",
+ " 0.0413409 | \n",
+ "
\n",
+ " \n",
+ " 10295881 | \n",
+ " 5881 | \n",
+ " 267 | \n",
+ " 0.0454004 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.869302 | \n",
+ " 0.876956 | \n",
+ " -0.00765312 | \n",
+ "
\n",
+ " \n",
+ " 3243430 | \n",
+ " 3430 | \n",
+ " 270 | \n",
+ " 0.0787172 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.852738 | \n",
+ " 0.832952 | \n",
+ " 0.0197858 | \n",
+ "
\n",
+ " \n",
+ " 71571090 | \n",
+ " 1090 | \n",
+ " 318 | \n",
+ " 0.291743 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.906754 | \n",
+ " 0.882407 | \n",
+ " 0.0243474 | \n",
+ "
\n",
+ " \n",
+ " 6734374 | \n",
+ " 4374 | \n",
+ " 401 | \n",
+ " 0.0916781 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.96001 | \n",
+ " 0.952311 | \n",
+ " 0.00769899 | \n",
+ "
\n",
+ " \n",
+ " 52905130 | \n",
+ " 5130 | \n",
+ " 413 | \n",
+ " 0.0805068 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.832686 | \n",
+ " 0.81409 | \n",
+ " 0.0185963 | \n",
+ "
\n",
+ " \n",
+ " 3246956 | \n",
+ " 6956 | \n",
+ " 414 | \n",
+ " 0.059517 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 100 | \n",
+ " OK | \n",
+ " 0.883453 | \n",
+ " 0.863797 | \n",
+ " 0.0196554 | \n",
+ "
\n",
+ " \n",
+ " 6735286 | \n",
+ " 5286 | \n",
+ " 462 | \n",
+ " 0.0874007 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.95465 | \n",
+ " 0.951121 | \n",
+ " 0.0035288 | \n",
+ "
\n",
+ " \n",
+ " 38455657 | \n",
+ " 5657 | \n",
+ " 467 | \n",
+ " 0.0825526 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.942134 | \n",
+ " 0.948224 | \n",
+ " -0.00608928 | \n",
+ "
\n",
+ " \n",
+ " 38455925 | \n",
+ " 5925 | \n",
+ " 500 | \n",
+ " 0.0843882 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.947522 | \n",
+ " 0.942903 | \n",
+ " 0.00461924 | \n",
+ "
\n",
+ " \n",
+ " 6736820 | \n",
+ " 6820 | \n",
+ " 500 | \n",
+ " 0.0733138 | \n",
+ " 50 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.938321 | \n",
+ " 0.939074 | \n",
+ " -0.00075356 | \n",
+ "
\n",
+ " \n",
+ " 71572135 | \n",
+ " 2135 | \n",
+ " 501 | \n",
+ " 0.23466 | \n",
+ " 100 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.92255 | \n",
+ " 0.925382 | \n",
+ " -0.0028321 | \n",
+ "
\n",
+ " \n",
+ " 52905973 | \n",
+ " 5973 | \n",
+ " 510 | \n",
+ " 0.0853842 | \n",
+ " 100 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.845782 | \n",
+ " 0.808048 | \n",
+ " 0.0377341 | \n",
+ "
\n",
+ " \n",
+ " 71572073 | \n",
+ " 2073 | \n",
+ " 580 | \n",
+ " 0.279788 | \n",
+ " 100 | \n",
+ " min | \n",
+ " 10 | \n",
+ " OK | \n",
+ " 0.910151 | \n",
+ " 0.904567 | \n",
+ " 0.00558366 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
106 rows × 10 columns
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components n_comp_status \\\n",
+ "58944691 4691 20 0.00426348 30 min \n",
+ "74861460 1460 20 0.0136986 30 min \n",
+ "251283 1283 20 0.0155885 30 min \n",
+ "51592405 2405 21 0.00873181 30 min \n",
+ "4763502 502 21 0.0418327 30 min \n",
+ "56043310 3310 21 0.00634441 30 min \n",
+ "20641064 1064 21 0.0197368 30 min \n",
+ "1956951 951 21 0.022082 30 min \n",
+ "74903360 3360 21 0.00625 30 min \n",
+ "59791559 1559 21 0.0134702 30 min \n",
+ "47712813 2813 21 0.00746534 30 min \n",
+ "46093624 3624 22 0.00607064 30 min \n",
+ "67145174 5174 22 0.00425203 30 min \n",
+ "673774 774 22 0.0284238 30 min \n",
+ "40873727 3727 22 0.00590287 30 min \n",
+ "2074011 4011 23 0.00573423 30 min \n",
+ "7157331 331 23 0.0694864 30 min \n",
+ "60981740 1740 24 0.0137931 30 min \n",
+ "49211918 1918 24 0.012513 30 min \n",
+ "37911502 1502 25 0.0166445 30 min \n",
+ "42212708 2708 26 0.00960118 30 min \n",
+ "5728769 769 26 0.0338101 30 min \n",
+ "6751044 1044 26 0.0249042 30 min \n",
+ "6721239 1239 27 0.0217918 30 min \n",
+ "2381528 1528 31 0.020288 30 min \n",
+ "3265502 502 31 0.061753 30 min \n",
+ "48931566 1566 33 0.0210728 30 min \n",
+ "59251891 1891 37 0.0195664 30 min \n",
+ "10291371 1371 37 0.0269876 30 min \n",
+ "1630687 687 40 0.0582242 30 min \n",
+ "... ... ... ... ... ... \n",
+ "74281897 1897 123 0.0648392 30 min \n",
+ "74283618 3618 125 0.0345495 30 min \n",
+ "20645727 5727 126 0.022001 30 min \n",
+ "10291657 1657 127 0.0766445 30 min \n",
+ "37914907 4907 127 0.0258814 30 min \n",
+ "3845977 977 129 0.132037 30 min \n",
+ "7157214 214 145 0.67757 30 min \n",
+ "10293699 3699 180 0.0486618 30 min \n",
+ "6756299 6299 200 0.0317511 30 min \n",
+ "52902178 2178 200 0.0918274 30 min \n",
+ "38453433 3433 204 0.0594232 30 min \n",
+ "57284327 4327 208 0.0480703 30 min \n",
+ "59255055 5055 210 0.041543 30 min \n",
+ "19566525 6525 215 0.0329502 30 min \n",
+ "3241566 1566 218 0.139208 30 min \n",
+ "16306753 6753 221 0.0327262 30 min \n",
+ "47635733 5733 240 0.0418629 30 min \n",
+ "10295881 5881 267 0.0454004 50 min \n",
+ "3243430 3430 270 0.0787172 50 min \n",
+ "71571090 1090 318 0.291743 50 min \n",
+ "6734374 4374 401 0.0916781 50 min \n",
+ "52905130 5130 413 0.0805068 50 min \n",
+ "3246956 6956 414 0.059517 50 min \n",
+ "6735286 5286 462 0.0874007 50 min \n",
+ "38455657 5657 467 0.0825526 50 min \n",
+ "38455925 5925 500 0.0843882 50 min \n",
+ "6736820 6820 500 0.0733138 50 min \n",
+ "71572135 2135 501 0.23466 100 min \n",
+ "52905973 5973 510 0.0853842 100 min \n",
+ "71572073 2073 580 0.279788 100 min \n",
+ "\n",
+ " alpha alpha_status train_auroc test_auroc overfit \n",
+ "58944691 1e-05 OK 0.78652 0.822193 -0.0356728 \n",
+ "74861460 0.01 OK 0.859158 0.753472 0.105686 \n",
+ "251283 1000 OK 0.859158 0.477273 0.381886 \n",
+ "51592405 1000 OK 0.780622 0.772013 0.0086099 \n",
+ "4763502 100000 OK 0.683211 0.32732 0.355891 \n",
+ "56043310 1000 OK 0.85255 0.889058 -0.0365078 \n",
+ "20641064 1000 OK 0.74277 0.348086 0.394684 \n",
+ "1956951 100 OK 0.907608 0.828877 0.0787313 \n",
+ "74903360 10000000 OK 0.724492 0.796407 -0.0719154 \n",
+ "59791559 100000 OK 0.86791 0.895292 -0.0273821 \n",
+ "47712813 100 OK 0.858776 0.610465 0.248311 \n",
+ "46093624 100 OK 0.890894 0.802358 0.0885365 \n",
+ "67145174 10000000 OK 0.79378 0.633366 0.160414 \n",
+ "673774 1000 OK 0.822703 0.816225 0.00647774 \n",
+ "40873727 0.1 OK 0.551374 0.578841 -0.0274666 \n",
+ "2074011 1000 OK 0.823058 0.849624 -0.0265659 \n",
+ "7157331 1000 OK 0.787263 0.896774 -0.109511 \n",
+ "60981740 100 OK 0.905393 0.540525 0.364869 \n",
+ "49211918 1000000 OK 0.784888 0.68285 0.102038 \n",
+ "37911502 10000000 OK 0.806097 0.812162 -0.00606563 \n",
+ "42212708 0.0001 OK 0.860673 0.471508 0.389164 \n",
+ "5728769 1000000 OK 0.839426 0.959732 -0.120306 \n",
+ "6751044 100000 OK 0.830408 0.90098 -0.0705721 \n",
+ "6721239 1000000 OK 0.7701 0.552263 0.217837 \n",
+ "2381528 1000000 OK 0.721437 0.782222 -0.0607853 \n",
+ "3265502 10 OK 0.974255 0.912281 0.0619746 \n",
+ "48931566 0.1 OK 0.87122 0.889251 -0.0180311 \n",
+ "59251891 0.0001 OK 0.621143 0.737711 -0.116569 \n",
+ "10291371 1 OK 0.609912 0.436567 0.173345 \n",
+ "1630687 1000 OK 0.814857 0.733654 0.0812035 \n",
+ "... ... ... ... ... ... \n",
+ "74281897 0.0001 OK 0.981577 0.947606 0.0339709 \n",
+ "74283618 1e-10 min 0.978894 0.9699 0.0089942 \n",
+ "20645727 100 OK 0.826403 0.750972 0.075431 \n",
+ "10291657 100 OK 0.880702 0.882866 -0.00216486 \n",
+ "37914907 100 OK 0.773858 0.6986 0.0752586 \n",
+ "3845977 10 OK 0.902039 0.857466 0.0445731 \n",
+ "7157214 100 OK 0.90047 0.684729 0.215741 \n",
+ "10293699 100 OK 0.891038 0.898003 -0.00696588 \n",
+ "6756299 100 OK 0.735716 0.721926 0.0137893 \n",
+ "52902178 10 OK 0.826723 0.820013 0.00670988 \n",
+ "38453433 10 OK 0.968199 0.971834 -0.00363484 \n",
+ "57284327 10 OK 0.797122 0.806981 -0.00985872 \n",
+ "59255055 10 OK 0.865271 0.866529 -0.00125774 \n",
+ "19566525 10 OK 0.860294 0.785022 0.0752716 \n",
+ "3241566 10 OK 0.940743 0.922054 0.0186889 \n",
+ "16306753 10 OK 0.780313 0.734924 0.0453892 \n",
+ "47635733 100 OK 0.726737 0.685396 0.0413409 \n",
+ "10295881 10 OK 0.869302 0.876956 -0.00765312 \n",
+ "3243430 100 OK 0.852738 0.832952 0.0197858 \n",
+ "71571090 100 OK 0.906754 0.882407 0.0243474 \n",
+ "6734374 10 OK 0.96001 0.952311 0.00769899 \n",
+ "52905130 10 OK 0.832686 0.81409 0.0185963 \n",
+ "3246956 100 OK 0.883453 0.863797 0.0196554 \n",
+ "6735286 10 OK 0.95465 0.951121 0.0035288 \n",
+ "38455657 10 OK 0.942134 0.948224 -0.00608928 \n",
+ "38455925 10 OK 0.947522 0.942903 0.00461924 \n",
+ "6736820 10 OK 0.938321 0.939074 -0.00075356 \n",
+ "71572135 10 OK 0.92255 0.925382 -0.0028321 \n",
+ "52905973 10 OK 0.845782 0.808048 0.0377341 \n",
+ "71572073 10 OK 0.910151 0.904567 0.00558366 \n",
+ "\n",
+ "[106 rows x 10 columns]"
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ "\n",
+ "
\n",
+ " \n",
+ " \n",
+ " | \n",
+ " num_samples | \n",
+ " num_positive | \n",
+ " balance | \n",
+ " n_components | \n",
+ " alpha | \n",
+ " train_auroc | \n",
+ " test_auroc | \n",
+ " overfit | \n",
+ "
\n",
+ " \n",
+ " \n",
+ " \n",
+ " mean | \n",
+ " 3041.51 | \n",
+ " 124.623 | \n",
+ " 0.0639019 | \n",
+ " 33.8679 | \n",
+ " 1.26733e+06 | \n",
+ " 0.831054 | \n",
+ " 0.776023 | \n",
+ " 0.0550313 | \n",
+ "
\n",
+ " \n",
+ " median | \n",
+ " 2627 | \n",
+ " 81 | \n",
+ " 0.0318417 | \n",
+ " 30 | \n",
+ " 100 | \n",
+ " 0.830408 | \n",
+ " 0.785022 | \n",
+ " 0.0243272 | \n",
+ "
\n",
+ " \n",
+ "
\n",
+ "
"
+ ],
+ "text/plain": [
+ " num_samples num_positive balance n_components alpha \\\n",
+ "mean 3041.51 124.623 0.0639019 33.8679 1.26733e+06 \n",
+ "median 2627 81 0.0318417 30 100 \n",
+ "\n",
+ " train_auroc test_auroc overfit \n",
+ "mean 0.831054 0.776023 0.0550313 \n",
+ "median 0.830408 0.785022 0.0243272 "
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ },
+ {
+ "name": "stdout",
+ "output_type": "stream",
+ "text": [
+ "Mean testing Auroc improved by 5.35%\n",
+ "Median testing Auroc improved by 5.87%\n",
+ "Mean overfitting reduced by 1.2%\n",
+ "Median overfitting reduced by 2.1%\n",
+ "Wall time: 33min 54s\n"
+ ]
+ }
+ ],
+ "source": [
+ "%%time\n",
+ "# proposed simpler k function and alpha and l1_ratio.\n",
+ "metrics_df = evaluate_classifier(X = X,\n",
+ " y = y,\n",
+ " list_of_queries = query_list,\n",
+ " set_k_range = None,\n",
+ " k_function = k_func_proposed,\n",
+ " alpha_range = [10** x for x in range(-10, 10)],\n",
+ " l1_ratio = [0])\n",
+ "display_stats(metrics_df, metrics_df_current_setup, verbose = True)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 22,
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "image/png": "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\n4xfyDR8+HBMnTsT27dshl8sxb948AMCSJUvQuHFjdOnSBQMHDkR6ejqEEBg7diyCgoLcEhvbxRIR\nUU3C1rqVUNPbxZbHw2r2MT+OMUf2MT+OMUf2sbWui7FdLBER1QQeP6dPRERE7sGiT0REJBEs+kRE\nRBLBok9ERCQRLPpEREQSwaJPREQkESz6REREEsGiT0REJBEs+kRERBLBok9ERCQRLPpEREQSwaJP\nREQkESz6REREEsGiT0REJBEs+kRERBLBok9ERCQRLPpEREQSwaJPREQkESz6REREEsGiT0REJBEs\n+kRERBLBok9ERCQRLPpEREQSwaJPREQkESz6REREEsGiT0REJBEs+kRERBLBok9ERCQR/p4OYPHi\nxfj5558BAIWFhcjLy8POnTst3pOZmYkDBw4gNDQUALBo0SIolUq3x0pEROTLPF70hw8fjuHDhwMA\nnnvuOUycOLHCe44dO4aPPvoI4eHh7g6PiIioxvCaw/vff/89ateujfbt21tMN5lMOH/+PKZPn47+\n/ftj5cqVHoqQiIjIt8mEEMJdK1uxYgU+++wzi2lz587FI488guTkZCxYsABNmjSxGFer1fj8888x\nePBgGI1GDBo0CHPnzsV9991nd10GgxH+/nKnbwMREZGvcuvh/ZSUFKSkpFSYnp2djdq1a1co+AAQ\nEhKCQYMGISQkBADQtm1bHD9+3GHRz8/XWJ0eGalEbq6qGtFLA/NjH/PjGHNkH/PjGHNkn638REY6\nvtbNKw7v79q1Cx07drQ6du7cOaSlpcFoNEKv1+PAgQN48MEH3RwhERGR7/P4hXwAcPbsWTzxxBMW\n05YsWYLGjRujS5cuSEhIQL9+/RAQEICEhAS0aNHCQ5ESERH5Lree03cnW4eGeNjIPubHPubHMebI\nPubHMebIPp8/vE9ERESux6JPREQkESz6REREEsGiT0REJBEs+kRERBLBok9ERCQRLPpEREQSwaJP\nREQkESz6REREEsGiT0REJBEs+kRERBLBok9ERCQRLPpEREQSwaJPREQkESz6REREEsGiT0REJBEs\n+kRERBLBok9ERCQRLPpEREQSwaJPREQkESz6REREEsGiT0REJBEs+kRERBLBok9ERCQRLPpEREQS\nwaJPREQkESz6REREEsGiT0REJBEs+kRERBLBoi8xWr0R1/I10OqNPr0OIiKqOn9PrHTLli347rvv\n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\nsWHDBrRp0wavvfYa1q1bh8TEREyfPt18rruMXC6HwWCosI569eqhfv36WLx4MXr37g0AaNu2Ldat\nWwrH864AAAH2SURBVIeioiIYDAaMGjUKmzdvtpjviy++QFZWFp566inMmDEDN27cQEFBAc6dO4cX\nX3wRsbGx2Llzp8MvNrfasWMHVCoVtFotNm7caD46AABKpRJ33323uejv3LkT//nPf2AwGNCtWzeE\nhYXhueeeQ0JCAv78888qrZfI1binT+RkZYf5hw4dCgBo0aIFYmNj0bNnTzRs2BCtWrWq8jLPnTuH\nhIQEhIaGmi84mzp1KqZPn474+HgApV25HF15//rrr2PmzJnIyspCQEAAsrKyKhxtuFVQUBDS09Oh\nVqvx3HPPoXnz5mjSpIk5Jr1ej969e+PJJ5/EQw89hPHjx2PNmjWQy+WYMWOGxbKaNWsGlUpl0bq4\nTEJCAt566y20adMGQOkh9uPHj6Nfv34wGo3o0KEDEhMTLebp06cPxo0bh/j4ePj7+2P06NGoW7cu\nUlJS0LNnTygUCjz22GMoKSmBRqNxnOi/3XHHHRg2bBjy8/ORkJCADh06mNuals/jRx99hICAALz1\n1lsICAjAmDFjMHjwYAQHB6N27dpWL+wk8iR22SMim7KysgAAL7zwgocjcZ/Vq1dj79695i9XRDUJ\nD+8TERFJBPf0iYiIJIJ7+kRERBLBok9ERCQRLPpEREQSwaJPREQkESz6REREEsGiT0REJBH/H1ob\nkleBefdtAAAAAElFTkSuQmCC\n",
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "num_pos_plot = metrics_df['num_positive'].tolist()\n",
+ "alpha_plot = metrics_df['alpha'].tolist()\n",
+ "alpha_log10_plot = [math.log(a,10) for a in alpha_plot]\n",
+ "plt.scatter(num_pos_plot, alpha_log10_plot)\n",
+ "plt.title('Number of Positives vs. alpha')\n",
+ "plt.ylabel('Log10 of alpha')\n",
+ "plt.xlabel('Number of positive samples')\n",
+ "plt.show()\n"
+ ]
+ }
+ ],
+ "metadata": {
+ "kernelspec": {
+ "display_name": "Python 3",
+ "language": "python",
+ "name": "python3"
+ },
+ "language_info": {
+ "codemirror_mode": {
+ "name": "ipython",
+ "version": 3
+ },
+ "file_extension": ".py",
+ "mimetype": "text/x-python",
+ "name": "python",
+ "nbconvert_exporter": "python",
+ "pygments_lexer": "ipython3",
+ "version": "3.5.3"
+ }
+ },
+ "nbformat": 4,
+ "nbformat_minor": 2
+}
diff --git a/explore/number-of-components/number_of_pca_components_(subset_by_disease).py b/explore/number-of-components/number_of_pca_components_(subset_by_disease).py
new file mode 100644
index 0000000..8cd7f20
--- /dev/null
+++ b/explore/number-of-components/number_of_pca_components_(subset_by_disease).py
@@ -0,0 +1,533 @@
+
+# coding: utf-8
+
+# # Explore how many PCA Components to Keep and Hyperparameter Tuning
+# # (Queries with subset of the diseases)
+
+# __Purpose__
+#
+# Address issue #106 (https://github.com/cognoma/machine-learning/issues/106). Evaluate queries that don't inlcude all the samples but rather subset the samples by disease(s).
+#
+# __Assumptions/Notes:__
+#
+# This notebook differs from the current classifier in a number of ways including:
+# 1. In this notebook, PCA is performed on the entire training set prior to cross-validation rather than performed on each individual cross-validation split. This is done for simplicity and to save time and memory.
+# 2. In this notebook, the covariates data is not used (for now at least).
+#
+#
+# __To Do:__
+#
+# 1. Some additional evaluation and... select a final setup.
+# 2. _We could also try to add the covariates data into this evaluation and see how that changes things but I'm not planning on doing that at this point._
+
+# ## Outline:
+# 1. Imports, constants and load the data
+# 2. Build the querry set
+# * List of genes
+# * Summary stats for each gene-disease combo
+# * Generate a set of queries
+# 3. Evaluate queries with a subset of diseases and varying number of positives
+# - a. Define some helper functions
+# - b. See how the parameters are related using the current setup
+# - c. Evaluate how changing some of the parameters effects performance
+# - d. See if we can use a function to automatically select the number of components
+
+# ## 1. Imports, constants and load the data
+
+# In[1]:
+
+
+import os
+import time
+import random
+import math
+
+from sklearn.decomposition import PCA
+from sklearn.linear_model import SGDClassifier
+from sklearn.metrics import roc_auc_score, roc_curve
+from sklearn.model_selection import train_test_split, StratifiedKFold
+from dask_searchcv import GridSearchCV
+from sklearn.pipeline import Pipeline, FeatureUnion
+from sklearn.preprocessing import StandardScaler, FunctionTransformer
+import matplotlib.pyplot as plt
+import numpy as np
+import pandas as pd
+import seaborn as sns
+from sklearn.feature_selection import SelectKBest
+
+
+# In[2]:
+
+
+RANDOMSEED = 0
+
+
+# In[3]:
+
+
+get_ipython().run_cell_magic('time', '', "# Load the data\ntry: \n path = os.path.join('download', 'expression-matrix.pkl')\n X = pd.read_pickle(path)\nexcept:\n path = os.path.join('download', 'expression-matrix.tsv.bz2')\n X = pd.read_table(path, index_col=0)\n\ntry:\n path = os.path.join('download', 'mutation-matrix.pkl')\n y = pd.read_pickle(path)\nexcept:\n path = os.path.join('download', 'mutation-matrix.tsv.bz2')\n y = pd.read_table(path, index_col=0)\n \npath = os.path.join('download', 'covariates.tsv')\ncovariates = pd.read_table(path,index_col=0)")
+
+
+# ## 2. Build the query set
+
+# In[4]:
+
+
+# List of genes to iterate over (from brankaj's notebook:
+# https://github.com/cognoma/machine-learning/blob/master/explore/Classifier_results-different_genes.ipynb)
+genes_LungCancer = {
+ '207': 'AKT1',
+ '238': 'ALK',
+ '673': 'BRAF',
+ '4921':'DDR2',
+ '1956':'EGFR',
+ '2064':'ERBB2',
+ '3845':'KRAS',
+ '5604':'MAP2K1',
+ '4893':'NRAS',
+ '5290':'PIK3CA',
+ '5728':'PTEN',
+ '5979':'RET',
+ # '6016':'RIT1', (removed because too few positives)
+ '6098':'ROS1',
+}
+
+genes_TumorSuppressors = {
+ '324': 'APC',
+ '672': 'BRCA1',
+ '675': 'BRCA2',
+ '1029':'CDKN2A',
+ '1630':'DCC',
+ '4089':'SMAD4',
+ '4087':'SMAD2',
+ '4221':'MEN1',
+ '4763':'NF1',
+ '4771':'NF2',
+ '7157':'TP53',
+ '5728':'PTEN',
+ '5925':'RB1',
+ '7428':'VHL',
+ '7486':'WRN',
+ '7490':'WT1',
+}
+
+genes_Oncogenes = {
+ #'5155':'PDGFB', #growth factor (removed because too few positives)
+ '5159':'PDGFRB', #growth factor
+ '3791':'KDR', #receptor tyrosine kinases
+ '25':'ABL1', #Cytoplasmic tyrosine kinases
+ '6714':'SRC', #Cytoplasmic tyrosine kinases
+ '5894':'RAF1',#cytoplasmic serine kinases
+ '3265':'HRAS',#regulatory GTPases
+ '4609':'MYC',#Transcription factors
+ #'2353':'FOS',#Transcription factors (removed because too few positives)
+
+}
+
+list_of_genes = (list(genes_LungCancer.keys()) + list(genes_TumorSuppressors.keys()) +
+ list(genes_Oncogenes.keys()))
+
+
+# Create a dictionary of {gene:
+# {disease:
+# {total: #, positive: #, negative: #}, ...
+
+# In[5]:
+
+
+get_ipython().run_cell_magic('time', '', "disease_list_acronyms = [col for col in covariates.columns if col.startswith('acronym_')]\ndisease_list = [disease.strip('acronym_') for disease in disease_list_acronyms]\ngene_dict = {}\nfor gene in list_of_genes:\n # Subset by gene.\n y_gene = y[gene] \n gene_dict[gene] = dict.fromkeys(disease_list)\n for disease in disease_list:\n # Subset by disease.\n disease_cols = [col for col in disease_list_acronyms if col.endswith(disease)]\n has_disease = covariates[disease_cols].max(axis=1) > 0\n disease_cols = covariates[has_disease]\n y_gene_disease = y_gene[y_gene.index.isin(disease_cols.index)]\n # Get query stats.\n stats = {}\n stats['total'] = y_gene_disease.shape[0]\n stats['positive'] = y_gene_disease.sum()\n stats['negative'] = stats['total'] - stats['positive']\n gene_dict[gene][disease] = stats")
+
+
+# In[6]:
+
+
+'''Randomly iterate through gene/disease(s) combinations to create a list
+of queries that we can use for analysis. Something like:
+[ [gene, [disease1, disease2, etc], {total: #, negative: #, positive: #}], ]
+
+Try to provide general coverage of the
+different possibilities of class balance and total sample size while using
+the following constraints:
+1. All queries should have at least 20 positives.
+2. Only use one gene per query (for simplicity).
+'''
+
+def generate_queries(randomseed = 0, positive_bound = 20):
+ random.seed(randomseed)
+ queries = []
+ keys_gene = list(gene_dict.keys())
+ random.shuffle(keys_gene)
+ for gene in keys_gene:
+ keys_disease = list(gene_dict[gene].keys())
+ random.shuffle(keys_disease)
+ total_total, total_positives, total_negatives = 0, 0, 0
+ diseases = []
+ for disease in keys_disease:
+ if total_positives < positive_bound:
+ total_total += gene_dict[gene][disease]['total']
+ total_positives += gene_dict[gene][disease]['positive']
+ diseases.append(disease)
+
+ total_negatives = total_total - total_positives
+ num_diseases = len(diseases)
+ query = [gene, diseases, {'total': total_total, 'positive': total_positives, 'negative': total_negatives}]
+ if query[2]['positive'] >= positive_bound:
+ queries.append(query)
+ return(queries)
+
+query_list1 = generate_queries(randomseed = 0, positive_bound = 20)
+query_list2 = generate_queries(randomseed = 1, positive_bound = 60)
+query_list3 = generate_queries(randomseed = 2, positive_bound = 100)
+query_list4 = generate_queries(randomseed = 3, positive_bound = 200)
+query_list5 = generate_queries(randomseed = 4, positive_bound = 400)
+query_list6 = generate_queries(randomseed = 5, positive_bound = 500)
+query_list = query_list1 + query_list2 + query_list3 + query_list4 + query_list5 + query_list6
+print('There are ' + str(len(query_list)) + ' queries in the list.')
+
+
+# In[7]:
+
+
+# Visuallize our query set to make sure it's not too skewed
+number_of_diseases =[]
+for query in query_list:
+ number_of_diseases.append(len(query[1]))
+number_of_diseases.sort()
+plt.plot(number_of_diseases)
+plt.ylabel('number of diseases')
+plt.title('Diseases')
+plt.show()
+
+number_of_samples =[]
+for query in query_list:
+ number_of_samples.append(query[2]['total'])
+number_of_samples.sort()
+plt.plot(number_of_samples)
+plt.title('Samples')
+plt.ylabel('number of samples')
+plt.show()
+
+number_of_positives =[]
+for query in query_list:
+ number_of_positives.append(query[2]['positive'])
+number_of_positives.sort()
+plt.plot(number_of_positives)
+plt.title('Positives')
+plt.ylabel('number of positives')
+plt.show()
+
+
+# ## 3. Evaluate queries with different subsets of diseases and varying number of positives
+
+# ### 3.a. Define some helper functions
+
+# In[8]:
+
+
+def variance_scorer(x, y):
+ """
+ Get the variance for each column of X.
+
+ Because principal components have decreasing variance
+ (i.e. PC4 has less variance than PC3 which has less variance
+ than PC2 etc.), we can use this function in SelectKBest to select
+ only the top X number of principal components.
+
+ """
+ scores = [np.var(column) for column in x.T]
+ return scores, np.array([np.NaN]*len(scores))
+
+
+# In[9]:
+
+
+def evaluate_classifier(X,
+ y,
+ list_of_queries,
+ set_k_range, k_function,
+ alpha_range,
+ l1_ratio):
+
+ ''' Run a classifier setup on a set of queries.
+
+ Loop through each query; train and test the classifier using the
+ hyperparameters input as parameters; populate the metrics dictionary
+ with some metrics of which parameters were selected and how well
+ the classifier did for that query.
+ '''
+
+ # A dictionary to hold the performance metrics.
+ metrics_dict = {}
+
+ # Loop through each query; train and test the classifer; populate the metrics dictionary.
+ for query in list_of_queries:
+ num_samples = query[2]['total']
+ num_positives = query[2]['positive']
+
+ # Subset by gene.
+ y_query = y[query[0]]
+ # Subset by diseases.
+ disease_cols = [col for col in covariates.columns if col.endswith(tuple(query[1]))]
+ has_disease = covariates[disease_cols].max(axis=1) > 0
+ covariates_query = covariates[has_disease]
+ X_query = X[X.index.isin(covariates_query.index)]
+ y_query = y_query[y_query.index.isin(covariates_query.index)]
+
+ # Test Train split
+ test_size = 0.2
+ X_train, X_test, y_train, y_test = train_test_split(X_query, y_query, stratify=y_query, test_size=test_size, random_state=RANDOMSEED)
+ # PCA.
+ scaler = StandardScaler()
+ if query[2]['total']*(1-test_size)*(1-(1/3)) > 350:
+ n_comp = 350
+ else:
+ n_comp = int(query[2]['total']*(1-test_size) - 1)
+ pca = PCA(n_components = n_comp, random_state = RANDOMSEED)
+ scaler.fit(X_train)
+ X_train_scaled = scaler.transform(X_train)
+ pca.fit(X_train_scaled)
+ X_train = pca.transform(X_train_scaled)
+ X_test_scaled = scaler.transform(X_test)
+ X_test = pca.transform(X_test_scaled)
+
+ if set_k_range:
+ k_range = set_k_range
+ else:
+ k_range = k_function(num_samples=num_samples,
+ num_positives=num_positives,
+ )
+ # Parameter Sweep for Hyperparameters
+ param_grid = {
+ 'select__k': k_range,
+ 'classify__loss': ['log'],
+ 'classify__penalty': ['elasticnet'],
+ 'classify__alpha': alpha_range,
+ 'classify__l1_ratio': l1_ratio,
+ }
+ pipeline = Pipeline(steps=[
+ ('select', SelectKBest(variance_scorer)),
+ ('classify', SGDClassifier(random_state=RANDOMSEED, class_weight='balanced'))
+ ])
+ cv_pipeline = GridSearchCV(estimator=pipeline,
+ param_grid=param_grid,
+ n_jobs=1,
+ scoring='roc_auc')
+ cv_pipeline.fit(X=X_train, y=y_train)
+ y_pred_train = cv_pipeline.decision_function(X_train)
+ y_pred_test = cv_pipeline.decision_function(X_test)
+ # Get ROC info.
+ def get_threshold_metrics(y_true, y_pred):
+ roc_columns = ['fpr', 'tpr', 'threshold']
+ roc_items = zip(roc_columns, roc_curve(y_true, y_pred))
+ roc_df = pd.DataFrame.from_items(roc_items)
+ auroc = roc_auc_score(y_true, y_pred)
+ return {'auroc': auroc, 'roc_df': roc_df}
+ metrics_train = get_threshold_metrics(y_train, y_pred_train)
+ metrics_test = get_threshold_metrics(y_test, y_pred_test)
+
+ # Populate the metrics dictionary.
+ # Get metrics for the classifier.
+ overfit = metrics_train['auroc'] - metrics_test['auroc']
+ # Understand how the parameter grid worked... any params at the edge?
+ if cv_pipeline.best_params_['select__k'] == min(param_grid['select__k']):
+ n_comp_status = 'min'
+ elif cv_pipeline.best_params_['select__k'] == max(param_grid['select__k']):
+ n_comp_status = 'max'
+ else:
+ n_comp_status = 'OK'
+ if cv_pipeline.best_params_['classify__alpha'] == min(param_grid['classify__alpha']):
+ alpha_status = 'min'
+ elif cv_pipeline.best_params_['classify__alpha'] == max(param_grid['classify__alpha']):
+ alpha_status = 'max'
+ else:
+ alpha_status = 'OK'
+ metrics = {'num_samples': num_samples,
+ 'num_positive': num_positives,
+ 'balance': num_positives/num_samples,
+ 'train_auroc': metrics_train['auroc'],
+ 'test_auroc': metrics_test['auroc'],
+ 'n_components': cv_pipeline.best_params_['select__k'],
+ 'alpha': cv_pipeline.best_params_['classify__alpha'],
+ 'overfit': overfit,
+ 'n_comp_status': n_comp_status,
+ 'alpha_status': alpha_status
+ }
+ # Add the metrics to the dictonary.
+ metrics_dict[query[0]+str(query[2]['total'])] = metrics
+ # Change the metrics dict into a formatted pandas dataframe.
+ metrics_df = pd.DataFrame(metrics_dict)
+ metrics_df = metrics_df.T
+ metrics_df.sort_values(by='num_positive', ascending=True, inplace=True)
+ metrics_df = metrics_df[['num_samples', 'num_positive', 'balance', 'n_components','n_comp_status', 'alpha', 'alpha_status','train_auroc', 'test_auroc', 'overfit']]
+
+ return(metrics_df)
+
+
+# In[10]:
+
+
+def display_stats(metrics_df, metrics_df_tocompare = None, verbose = True):
+ if verbose:
+ display(metrics_df)
+ # Summary for metrics_df
+ metrics_df.loc['mean'] = metrics_df.mean()
+ metrics_df.loc['median'] = metrics_df.median()
+ metrics_df_summary = metrics_df.loc[['mean', 'median']]
+ metrics_df_summary = metrics_df_summary[['num_samples', 'num_positive', 'balance', 'n_components', 'alpha', 'train_auroc', 'test_auroc','overfit']]
+ display(metrics_df_summary)
+ if metrics_df_tocompare is not None:
+ # Summary for metrics_df_tocompare
+ metrics_df_tocompare.loc['mean'] = metrics_df_tocompare.mean()
+ metrics_df_tocompare.loc['median'] = metrics_df_tocompare.median()
+ metrics_df_to_compare_summary = metrics_df_tocompare.loc[['mean', 'median']]
+ # Evaluate the improvement
+ mean_testing_auroc_improvement = metrics_df_summary['test_auroc']['mean'] - metrics_df_to_compare_summary['test_auroc']['mean']
+ median_testing_auroc_improvement = metrics_df_summary['test_auroc']['median'] - metrics_df_to_compare_summary['test_auroc']['median']
+ mean_overfit_reduction = metrics_df_to_compare_summary['overfit']['mean'] - metrics_df_summary['overfit']['mean']
+ median_overfit_reduction = metrics_df_to_compare_summary['overfit']['median'] - metrics_df_summary['overfit']['median']
+ print('Mean testing Auroc improved by {:.2f}%'.format(mean_testing_auroc_improvement*100))
+ print('Median testing Auroc improved by {:.2f}%'.format(median_testing_auroc_improvement*100))
+ print('Mean overfitting reduced by {:.1f}%'.format(mean_overfit_reduction*100))
+ print('Median overfitting reduced by {:.1f}%'.format(median_overfit_reduction*100))
+
+
+# ### 3.b. See how the parameters are related using the current setup
+
+# In[11]:
+
+
+get_ipython().run_cell_magic('time', '', 'metrics_df_current_setup = evaluate_classifier(X = X,\n y = y,\n list_of_queries = query_list,\n set_k_range = [20, 40],\n k_function = None,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df_current_setup, metrics_df_tocompare = None)')
+
+
+# In[12]:
+
+
+# Show how some of these metrics/parameters might be related
+metrics_df_for_correlations = metrics_df_current_setup[['num_samples', 'num_positive', 'balance', 'n_components', 'alpha', 'train_auroc', 'test_auroc', 'overfit']]
+plt.figure(figsize=(16,16))
+plt.title('Correlations', y=1.05, size=15)
+sns.heatmap(metrics_df_for_correlations.astype(float).corr(),linewidths=0.1,vmax=1.0, square=True, annot=True)
+sns.plt.show()
+
+
+# ### 3.c. Evaluate how changing some of the parameters effects performance
+#
+# - When a larger range of alpha and an L1_ratio of 0 were used for the queries with all diseases there was a large performance gain (~6%-8%)... will there be a similar performance gain with these queries?
+
+# In[13]:
+
+
+get_ipython().run_cell_magic('time', '', '# alpha and L1_ratio.\nmetrics_df = evaluate_classifier(X = X,\n y = y,\n list_of_queries = query_list,\n set_k_range = [10, 20],\n k_function = None,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = True)')
+
+
+# ## 4.d. Use a function to select k (number of PCA components)
+# - You can't us n_components (which the select_K is realy just a proxy for in this notebook) larger than the smallest total query size * the test train split ratio * 1-(1/cv) (for example if there is a query that has 100 total samples and you do a 80%/20% split than the training set only has 80 samples in it and if you do 3 fold CV each training fold will only have 80*0.66 (54) samples, so you couldn't do PCA with anymore than 54 components).
+# - There is a risk of overfitting if you use too many components for more unballanced queries
+# - It requires less components to capture a reasonable amount of variance for queries with less samples
+# - We haven't seen much of a clear coorelation with the two hueristics above; understanding them quantitatively has been difficult
+
+# In[14]:
+
+
+def k_func(num_samples, num_positives):
+ ''' Decide the number of PCA components based on a heuristic of total samples and class balance.
+ '''
+ # If there are more positives than negatives, set num_positives equal to the number of negatives
+ num_positives = min(num_positives, num_samples - num_positives)
+ # Rule of thumb based on number of positives
+ k = 5 * math.sqrt(num_positives)
+ # Adjust slightly for total number of samples
+ k = k * ((num_samples / 7000)**(1./6.))
+ k = [int(k)]
+ return(k)
+
+
+# In[15]:
+
+
+def k_func_proposed(num_samples, num_positives):
+ ''' Simpler function proposed for use.
+ '''
+ # If there are more positives than negatives, set num_positives equal to the number of negatives
+ num_positives = min(num_positives, num_samples - num_positives)
+ # Rule of thumb based on number of positives
+ if num_positives > 500:
+ k = 100
+ elif num_positives > 250:
+ k = 50
+ else:
+ k = 30
+ k = [int(k)]
+ return(k)
+
+
+# What do the k_funcs look like?
+
+# In[16]:
+
+
+def plot_k_func(k_func):
+ X_plot = [] # number of samples
+ Y_plot = [] # number of positives
+ Z_plot = [] # k (number of components in PCA)
+ for query in query_list:
+ X_plot.append(query[2]['total'])
+ Y_plot.append(query[2]['positive'])
+ Z_plot.append(k_func(query[2]['total'], query[2]['positive']))
+
+
+ plt.scatter(X_plot, Z_plot)
+ plt.title('Number of Components vs. Query Size')
+ plt.ylabel('K')
+ plt.xlabel('Total Number of Samples')
+ plt.show()
+
+ plt.scatter(Y_plot, Z_plot)
+ plt.title('Number of Components vs. Number of Positives')
+ plt.ylabel('K')
+ plt.xlabel('Number of Positives')
+ plt.show()
+
+
+# In[17]:
+
+
+plot_k_func(k_func)
+
+
+# In[18]:
+
+
+plot_k_func(k_func_proposed)
+
+
+# In[19]:
+
+
+get_ipython().run_cell_magic('time', '', '# k function.\nmetrics_df = evaluate_classifier(X = X,\n y = y,\n list_of_queries = query_list,\n set_k_range = None,\n k_function = k_func,\n alpha_range = [10** x for x in range(-3, 1)],\n l1_ratio = [0.15])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[20]:
+
+
+get_ipython().run_cell_magic('time', '', '# k function and alpha and l1_ratio.\nmetrics_df = evaluate_classifier(X = X,\n y = y,\n list_of_queries = query_list,\n set_k_range = None,\n k_function = k_func,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = False)')
+
+
+# In[21]:
+
+
+get_ipython().run_cell_magic('time', '', '# proposed simpler k function and alpha and l1_ratio.\nmetrics_df = evaluate_classifier(X = X,\n y = y,\n list_of_queries = query_list,\n set_k_range = None,\n k_function = k_func_proposed,\n alpha_range = [10** x for x in range(-10, 10)],\n l1_ratio = [0])\ndisplay_stats(metrics_df, metrics_df_current_setup, verbose = True)')
+
+
+# In[22]:
+
+
+num_pos_plot = metrics_df['num_positive'].tolist()
+alpha_plot = metrics_df['alpha'].tolist()
+alpha_log10_plot = [math.log(a,10) for a in alpha_plot]
+plt.scatter(num_pos_plot, alpha_log10_plot)
+plt.title('Number of Positives vs. alpha')
+plt.ylabel('Log10 of alpha')
+plt.xlabel('Number of positive samples')
+plt.show()
+