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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsn_comp_statusalphaalpha_statustrain_auroctest_aurocoverfit
67143450min0.01OK0.6895020.5641290.125373
46093750min0.01OK0.7444210.4431820.301239
2073850min0.01OK0.6280190.3958910.232128
58944250min1max0.758810.6729840.0858264
408748100max0.01OK0.7571180.7330310.0240868
560455100max0.1OK0.9071560.5084060.39875
42215750min0.01OK0.7265850.6060660.12052
74905850min0.01OK0.7298140.5650930.164721
477179100max0.01OK0.8717290.7672710.104459
2580100max0.001min0.7299040.540430.189474
492185100max1max0.6508320.4876450.163187
515991100max0.1OK0.7671250.6284150.138711
748610450min0.1OK0.6558990.5610930.0948058
3265112100max1max0.7962640.869321-0.0730568
5979117100max0.001min0.6995250.5484480.151076
4893117100max0.1OK0.8432350.7827020.0605324
7428135100max0.001min0.9720910.9663440.00574742
672136100max1max0.6139240.62016-0.00623589
23813850min0.001min0.6589070.5407390.118167
2064153100max0.1OK0.8279510.73130.0966513
379116950min1max0.7007550.626160.0745953
4089185100max1max0.8538770.892832-0.0389552
6098188100max1max0.7747830.7423510.0324319
195623150min1max0.8205510.7604290.0601219
1630235100max1max0.7344920.6732220.0612695
675237100max1max0.6204360.645226-0.0247902
592526350min1max0.8207830.7600050.0607777
102927450min1max0.8138530.825692-0.0118388
5728279100max1max0.7556460.7169680.0386786
4763316100max1max0.7043670.708792-0.00442577
32442350min1max0.8519760.841820.0101554
673500100max1max0.9170880.927095-0.0100076
384552750min0.1OK0.9282410.9153070.012934
5290853100max1max0.8021650.7991110.00305423
71572587100max1max0.8939140.880260.0136536
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657800.5335430.772050.6927980.0792519
median1371000.7667710.7629680.7007950.0610236
\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\nyr6VK1cqISFBPXv2VHx8vG7evKm7775bTz/9tF3vdcdicvbs2fr444919epVrVq1yro+IoLzrAAA\nAFxVzZo1tW7dOkVGRmrXrl2qUKGC9bWuXbuqa9eM05y++eYbHTt2zO5CUvqHYrJTp07q1KmTpkyZ\nol69etn9JgAAAMg9TZo00ebNm9W+fXtZLBaNGjVKS5Ys0fXr1xUVFfXPvyAHbJrm7ty5s5YvXy6T\nyWRd17Ilj2ADAAD5k+Fv7tfpKoxGo0aMyHpe5+1mlv9NR/IPNhWTL774oooXL67Q0IzHi3G7CwAA\nAEg2FpMWi+Vf39ASAAAgz3DxzmRusulSpIoVK2r37t0ymUzWHwAAAMCmzuTPP/+stWvXWpcNBoPW\nrFnjsFAAAABwDzYVk4sXL5YkJSQkqEiRIpwzCQAA8jcXv89kbrKpmNy2bZuGDx+utLQ0Pf744ypZ\nsqTatm3r6GwAAABwcTaV1RMnTtSsWbMUFBSkXr16ae7cuY7OBQAA4LIMHh5O/3EVNhWTRqPROr1d\nsGBB+fr6OjoXAAAA3IBNxWR4eLjGjRunq1evatq0aSpZsqSjcwEAAMAN2FRMDh8+XCVLllStWrXk\n4+Ojt99+29G5AAAAXJfRw/k/LsKmC3A8PDz0v//9T+XKlZMk7d69W/fdd59DgwEAAMD12VRM9unT\nRwkJCQoNDZXFYpHBYKCYBAAA+ZcLdQadzaZi8vLly4qNjXV0FgAAALgZm86ZLFu2rC5cuODoLAAA\nAHAzNnUmd+zYoUaNGqlo0aLWp99s2rTJocEAAABclYEn4FjZVEx+9913js4BAAAAN2RTWX3w4EG1\nbt1aDRo0UMuWLbV//35H5wIAAIAbsKkzGRMTo5EjR6pSpUo6cOCAhg8fzgU5AAAg/+JqbiubJ/wr\nVaokSapcubI8PW2qQQEAAJDH2VQVGo1GrVu3TrVr19a2bdvk5eXl6FwAAACui86klU2dyVGjRmnh\nwoXq2LGjFi1axOMUAQAAIMnGzmSpUqXUq1cvxcXFqVy5cipVqpSjcwEAAMAN2FRMTpgwQVu3blW1\natX05Zdf6tFHH9Xzzz/v6GwAAAAuiftMZrKpmNy4caMWLFggo9GotLQ0RUVFUUwCAADAtmKyRIkS\nSklJkb+/v8xms4KCghydCwAAwHVxAY6VTcXkxYsX1bRpU1WqVElHjhxRgQIF1L59e0nifpMAAAD5\nmE3F5KRJkxydAwAAAG7IpmLy8uXLWrZsmW7dumVdN2zYMEdlAgAAcG1Mc1vZVEwOHDhQPXr0UEBA\ngKPzAAAAwI3YVEyWLl1aTz/9tKOzAAAAuAWDB53JP9hUTDZt2lT9+vVTRESEdV2fPn0cFgoAAADu\nwaZicvbs2XrssceY5gYAAEAWNhWTRYoUUc+ePR2dBQAAwD3wBBwrm4rJokWLKjo6Wvfcc48MBoMk\nKSoqyqHBAAAA4PpsvgBHki5duuTQMAAAAG6BWwNZ2dSj7dOnj6pUqaKCBQuqUqVKXHwDAAAASZLB\nYrFY/mmjcePG6cSJE6pZs6Z++eUXhYWFaeDAgbmRDwAAwOWYtnzt7Ajyqtva2REk2TjNvW3bNusz\nuJ955hm1a9fO5je4uWq6fclgE+/HuivtxG5nx8jTPEpXVy9DGWfHyNOmWI5Lkm5eT3FukDzO28dX\nKXNjnB0jT/Pt8KYip/zo7Bh52vJe9ZwdQZJkYJrbyqZpbrPZrPT0dEmSxWKxXoQDAACA/M2mzmRk\nZKQ6dOig6tWr69dff1VkZKSjcwEAAMAN2FRMduvWTQ0aNNCxY8fUunVrVaxY0dG5AAAAXBf3mbSy\naSTmz5+vhQsX6vHHH9c777yjb7/91tG5AAAA4AZs6kzOnTtXX331lSRp6tSp6ty5s1q2bOnQYAAA\nAK6KC3Ay2dSZNBqN8vTMqDsLFCjABTgAAACQZGNn8pFHHlHHjh1VrVo17du3T40bN3Z0LgAAALgB\nm4rJF198UY0aNVJcXJxatmypSpUqSZJ2796t6tWrOzQgAACAy2Ga28rmS5EqV66syMhIayEpZTwZ\nBwAAAPmXTZ3Jv2PDkxgBAADyHm4NZPWvRoILcQAAAPI3ymoAAADYjWluAACAHDJ4cAHOH2wqJr/9\n9ltNnTpVJpNJFotFBoNBa9as0RNPPOHofAAAAHBhNhWTn3zyiaZMmaLQ0NAs69u1a+eQUAAAAC6N\nWwNZ2VRMhoWFqXTp0o7OAgAAADdjUzHp7e2t559/XpUrV7Zewd2/f3+HBgMAAIDrs6mYbNiwoaNz\nAAAAuA+mua1sKiZbtWrl6BwAAABwQ//q1kAAAAD5kYEn4FgxEgAAALAbxSQAAADsxjQ3AABATnEB\njhWdSQAAANiNziQAAEBOGejH/YGRAAAAgN0oJgEAAGA3prkBAAByimluK0YCAAAAdqOYBAAAgN2Y\n5gYAAMghC9PcVowEAAAA7EZnEgAAIKfoTFoxEgAAALAbxSQAAADsxjQ3AABAThkMzk7gMuhMAgAA\nwG50JgEAAHLKSD/uD4wEAAAA7JZvOpMb9h7V+0s2yGQ2q0LJ4hrW8XH5FSqYZZu563do/qadMhgM\nCgsqougOTRXo76ukG7c0bM4KxV24IovFoifur6JuTR5w0pG4rvVbd2jCZ3NkSk1VhbKlFdO/l/x8\nfbJtZ7FYNGTsRypXJkzd2j5pXT938XdasHKtbt0y6Z7yZRXTv7e8vArk5iHkGc/MGKuzew/q+3Gf\nODuKy9qwcaPenzxZJlOqKpQvr2FDo+Xn52fTNmlpaRo7brx+3LJFaWlmde3SVe3atpEkHT16TCNi\nYnTj+nXJYNArL/dV/Xr1rL/TZDKp78uvqE3r1mrS5NFcPWZXtfHQaU1evVOpaekqH1JE0U/WlZ+3\n1223XXfgpKIX/qiNg9vnckr3dF94UT37QLgKeBgVdzlFE384qhupadm2e75uGTW4O1BJt8ySpDNX\nb2jM6kPyK+ipPg/erbuDfHUzNU3fH7yoJXvP5/ZhwMXli87klaTrip69QuO6P6XFb/VQqaDCmrR4\nfZZt9p88r5lrf9bM/p31zeBuCg8uqg+XbZIkfbhso0KK+Oubwd00+7Uu+mrTTu2OO+OMQ3FZV64m\nasjYjzQx+lUt/2ySwkKLa/z0Odm2O3rytLq9PkIrN2zJsv77TVs1e9FKTR/zlhZ/Mk63TCZ98c2y\n3IqfZ5SoFKH/WzNHtdo1d3YUl3blSoKihw7TuPfGavG3C1XqrlKa9P5km7dZ8PXXOnnypL7+ar7m\nzJql2XPmaM/evZKkUaNHq+VTT2r+vFgNHzZUrw98Q2Zzxj/Qu3fvVueuz2jnrl25e8AuLCHlpoZ9\n+6PGRjXUwr5PqVRRf01evfO22568nKgJq3Yo3WLJ5ZTuKcDbU/0aldPIVQfVM3anzife0nN1St92\n28oh/npn9SH1XbBbfRfs1pjVhyRJPeuV0Y3UNPWat1P9F+5R7fCiuj+8aG4ehsuyGIxO/3EVrpPE\ngbb8Fqcq4SVUungxSVK7BjW0/Jf9svzpC+me8BJaHN1D/oUK6laqWRevJqmITyFJ0sDWj6h/y0aS\npEuJKTKZ0+TnXTD7G+Vjm7fvVpWKESpTKlSS1L7FY1q6dmOWMZYyuo+tmjbS4w/VzbJ+0ffr9Wyb\nFioS4Cej0aihL/fUk48+lGv584qHX+qqLTO+0vb5FOJ3suWnLaryv/+pdOlwSVK7tm21fMWKLJ/X\nO22zdu06PfXUk/L09FRAQIAeb/qYli1bLklKS09TYmKSJOl6Soq8vDI7bHPmxqrPSy+qapUquXWo\nLm/L0bP6X6kghQcGSJLa1q6gFXvisn133DCZ9eY3m/Rq01rOiOmWaoYV0aGLyTp77aYkadn+82pU\nLijbdp5GgyKCfPV09ZL6oE11DXmsooL9Mj635YL9tPZwvNItkjndom0nElQ/IjBXjwOuL19Mc59P\nSFJIUX/rckgRfyXfNCnlpinLVHcBDw+t3X1Yw+euVAFPD73YvIEkyWAwyNPDoEFfLNXqXQfVuFp5\nlQkpluvH4crOx19WieDML5iQ4EAlX7+hlOs3skx1v9mnuyTpp517sux//Mw5Xb56TT0Hj9TFywmq\nVaWSXn2+c+6Ez0Ni+w6VJFV6pL6Tk7i28+cvKCQkxLocUry4kpOTlZKSYp3qvtM25y9cUIksr4Xo\n0OHDkqTBb7yhHi/00qzZs3XlyhW9M2a0PD0zvmrfGTNakvTFFzMdfozu4sK16woJyPyOKB7go+Rb\nqUq5lZplqnvk0p/0dK0KKh9CV8xWwb4FdSn5lnX5UvIt+Rb0VKECHlmmugN9vbT77DV9vvWEzly7\nqdbVSyr68Urqu+BXHbyQpMblg7X/fJIKGA2qf3egzOnpzjgc1+NCnUFns2kk1qxZo27duqlr167q\n0qWLnnjiCUfn+k/99S/cPxiN2e8R1bh6ea0f01e9m9VX74++Unp65r6jn2mh9WP66tr1m5q64keH\n5XVH6Zbbf7kYbbzazWxO05YdezR+SD/N/2CMriUla9Lnsf9lRMDK8nefVw8Pm7ZJv80/ph5GD926\ndUuvv/GGRgwfpu+/W6kZ0z9VTMxInT/POWZ/5++mrD3+9P08/+eD8jAa1bJmudyKlSf83W0Q/zrm\nF5JuaejyAzrzewfz691nFRrgrRD/gvp0y3FJ0uQ21fXW45W08/RVmdM4zQBZ2fQv/cSJE9W3b1+F\nhoaqVatWqlixoqNz/adKFAvQpcQU6/LFa0kK8PGWT8HMv3pPxidox9HT1uWWdavq3JVEJd64qc0H\n4nTxWsa0lU9BLzWrVVkHTl/IvQNwA6HBQYq/ctW6fOHSFQX4+8qnkLdN+xcPLKpH6t0nP18feRXw\n1BOPPKRd+w85Ki7yuRIlSujSpUvW5YsXLyogIEA+hQrZtE1oiRKK//Nr8RcVElJcR44c1c0bN9Xw\noYxTNKpVq6aIiAjt2bM3F47KPZUo7KtLyTesyxeTrivA20uF/nTx3ZJdR7X/zCW1/3ip+s5eq1vm\nNLX/eKniE687I7JL61w7TJPbVNfkNtXVtHKIivpk/jsX5FtQSTdTdcuc9Y+hMsV81Lh88F9+k0Hm\ndIt8vDw0/acTenH+Lg1Zul/pFuls4s1cOBK4E5uKyeLFi6tGjRqSpKeffloXLrhXIVW3Uhn9evys\nTly8Ikn6atMuPVw161+4l64la+Dni5WQnPHltHzbfpULDVIR30JateM3TVnxoywWi0ypZq3aeVD3\nlw/P9eNwZfVrVdevBw7r+JlzkqR5S79X47r32bz/Yw/W0Xcbf9LNWyZZLBat+fFnVa0Y4ai4yOfq\n1q2rX/fs0YkTJyVJXy34Wg8/3NDmbR5++GF9u2iRzGazEpOStPK779To4UYKCw9TcnKydu3aLUk6\ndeqUjsXFqVIl9/oDPDfVjQjVntOXdPJyoiTp618OqWGlsCzbfNkzUl+99KRie7fQ5E6NVdDTQ7G9\nWyg4IPvdIvK7Wb+csl5E0/+bPaoU4qeShTP+qI+8J0Q/HU/Ito/FIr3QoKxC/DNO+2r+vxI6fiVF\nl1NMirynhLrcl/H/o0ihAnq8cnH9cPhStt+RLxmMzv9xETadM1mgQAFt27ZNZrNZGzduVEJC9g+j\nKwv099WITs302vRFSk1L011BRTSyS3PtO3lOw+d8p/lvPKua5cLU47G66v5+rDyNRgUX9tOEHq0k\nSa+2aqSYeavUevQMGSQ1qlZenR6u7dyDcjGBRQsr5rXe6vf2eKWmmhVWMkSjB/TR3kNH9db4KVo4\n5b077t/hiaa6lpSsNi8NVHp6uu4pV1av9+yaS+mR3wQWK6YRw4bptQEDlGpO1V133aWRb7+tffv2\na/iIEZo/L/Zvt5Gkdm3b6PTpU2ob1V7m1FS1adNatWtnXBgyfvw4vfvee7plMsnT01NvvTlEYWFh\nd4qTrxXzK6RhT9XTgPkbMr6fi/rr7Vb1tf/MZY1YvEWxvVs4O6LbunYzVRN+OKLBTSrK08Og84k3\nNXbtEUlS+WBfvdywnPou2K0TCdc1ZdMxDW1WWUaDdDnFpHd+v5p7/s7Teq1xeX3U7l4ZJM3+5ZQO\nxyc78ajgigyWvzuh8E8uXLigY8eOKTg4WJMmTVKzZs0UGRlp0xvcXDX9X4fE3/N+rLvSTux2dow8\nzaN0dfUylHF2jDxtiuW4JOnm9ZQ7b4h/xdvHVylzY5wdI0/z7fCmIqdwTr0jLe9V7583ygXmc4ed\nHUGeoeWdHUGSjZ3JoKAgXbx4UQkJCerSpYsMPNwcAAAAsrGYfPnll5WYmKjg4IwTdA0Gg+67z/bz\n4QAAAJA32VRMJiQkaM6c7E8zAQAAyI9c6Qk0zmbTSJQsWVLnzp1zdBYAAAC4mTt2Jhs0yHgCjMlk\n0sqVK1W4cGHr+ZKbNm1yfDoAAABXRGfS6o7FJAUjAAAA7sSmsnrHjh166qmn1KBBAz399NM6cOCA\no3MBAADADdh0AU5MTIzGjRuncuXK6dChQ4qOjlZsLM9NBgAA+RS3SbSyqTPp7++vcuUyHj9YoUIF\neXvb9rxlAAAA5G02dSYDAwM1ZMgQ1alTR/v27VN6errmzZsnSYqKinJoQAAAALgum4rJu+++W5J0\n4sQJ+fn56f7771d8fLxDgwEAALgsrua2umMxGRcXJ0lq3rx5ttfKli3rmEQAAABwG3csJqOjoyUp\n27O4U1NTNXfuXMelAgAAcGE8ASfTHYvJL7/8UpI0d+5cff7550pNTc3YydOm2XEAAADkcTaV1XPm\nzNGXX36phg0bavTo0SpfvryjcwEAAMAN2FRMFi9eXMWLF1dKSooeeOABJSYmOjoXAACA6zIanf/j\nImy+z+Tq1atlMBgUGxurq1evOjoXAAAA3IBNxWRMTIxKliyp/v376/jx43rzzTcdnQsAAMB1GYzO\n/3ERNl1J4+fnp3vuuUeS9MYbbzg0EAAAANyH65S1AAAAcDvc4wcAACCnXGia2dkYCQAAANiNziQA\nAEBO0Zm0YiQAAABgN4pJAAAA2I1pbgAAgByyMM1txUgAAADAbnQmAQAAcorOpBUjAQAAALtRTAIA\nAMBuTHMDAADklMHg7AQug84kAAAA7EZnEgAAIKe4AMeKkQAAAIDdKCYBAABgN6a5AQAAcogn4GRi\nJAAAAGA3ikkAAIA8Jj09XdHR0YqKilKXLl104sSJLK+vXbtWrVu3VlRUlObPn/+v3otpbgAAgJxy\n8Wnu1atXy2Qyad68edq1a5fGjBmjjz/+WJKUmpqq0aNHa8GCBSpUqJA6dOigxo0bKygoyK73cngx\n6f1Yd0e/Rb7nUbq6syPkeVMsx50dIV/w9vF1doQ8z7fDm86OkOct71XP2REAbd++XQ8++KAk6d57\n79XevXutrx09elTh4eEqXLiwJKlWrVratm2bmjVrZtd7ObyYvLn8Y0e/Rb7mHdlbaXE7nB0jT/Mo\nW1M3r6c4O0ae9kcR2ctQxqk58ropluP6vnItZ8fI05oc2K795xOdHSNPu6dEgLMjSJIsLv4EnOTk\nZPn5+VmXPTw8ZDab5enpqeTkZPn7+1tf8/X1VXJyst3v5do9WgAAAOSYn5+fUlIyGyHp6eny9PS8\n7WspKSlZisucopgEAADIY2rWrKkNGzZIknbt2qUKFSpYX4uIiNCJEyd09epVmUwm/fLLL6pRo4bd\n78UFOAAAADlksTg7wZ01adJEmzdvVvv27WWxWDRq1CgtWbJE169fV1RUlN544w11795dFotFrVu3\nVkhIiN3vRTEJAACQxxiNRo0YMSLLuoiICOt/N27cWI0bN/5P3otiEgAAIIfSXb01mYs4ZxIAAAB2\no5gEAACA3ZjmBgAAyCEmuTPRmQQAAIDd6EwCAADkUDqtSSs6kwAAALAbxSQAAADsxjQ3AABADlm4\nz6QVnUkAAADYjc4kAABADnEBTiY6kwAAALAbxSQAAADsxjQ3AABADjHLnYnOJAAAAOxGMQkAAAC7\nMc0NAACQQ1zNnYnOJAAAAOxGZxIAACCHeAJOJjqTAAAAsBvFJAAAAOzGNDcAAEAOpTs7gAuhMwkA\nAAC70ZkEAADIIa6/yURnEgAAAHajmAQAAIDdmOYGAADIIZ6Ak4nOJAAAAOxGZxIAACCHeAJOJjqT\nAAAAsBvFJAAAAOzGNDcAAEAO8QScTHQmAQAAYDc6kwAAADnE9TeZ6EwCAADAbvmmM7lhX5zeX7ZZ\nJnOaKpQM0rD2j8rPu2CWbeZu3KX5m3+VwWBQWFBhRbd7VIH+Plm26ffZEgUX9tPg1o1yM75bWL91\nhybMiJUp1awKZcMV06+n/Hx9sm1nsVg0ZNwUlSsTpm5tWkiS/i9mgk6cvWDd5sz5i7qvamV9OHxA\nruV3JRs2btT7kyfLZEpVhfLlNWxotPz8/GzaJi0tTWPHjdePW7YoLc2srl26ql3bNpKko0ePaURM\njG5cvy4ZDHrl5b6qX6+e9XeaTCb1ffkVtWndWk2aPJqrx+yOnvn/9u47PIpy7eP4d9MhhZBKIAkl\ngCCcKEVFEURBRVBBpCsgiopHLEiR3qsCokiXjlQpcmiHpiAiSlGp0nsgDQIkpO++f3DcGJOwyb4m\nu4+OYG0AACAASURBVAu/z3XtZWbm2dl7xmH23vuZZ2bOOKIOHWPz+Jm2DsXhBDzxOBW7d8PJzZXE\nYyc5PGAYmUlJ5uUhzZpSttMr5mkXby/cg4P54cnnSIu/yhM/biE1Osa8/OzsBVxZu6FIt8ER7P1p\nJwtnTCY9PY2yFSrR7eMBFPf0yrWtyWRi0pihhJePoHnbDgB8MuhjLl+6YG4TczmKag/UpN/oCUUS\nvziGe6IyeTXxFoOWbGJ856as6deJMv4+fL72x2xtjlyIZv53+5j/QRtWftyB8ABfJm/Yla3NnK17\n+fV0VFGG7jCuJtyg/4TpTBzYnfWzJhAWEsSEOYtztDt1/hKv9xnBxh92Z5s/cUB3Vk0Zw6opYxj2\nwZt4e3kyoNvrRRW+Xbl69RqDBg9h/KfjWLN6FWVCy/D5F5Py3eabFSs4f/48K5YvY9HChXy9aBEH\nDx0CYNTo0TRv9iLLli5h6JDB9P64DxkZGQD8/vvvvNqxE7/+9lvRbrADKlUlgg+3LqJW66a2DsUh\nuZb0pdrIwRz4oBe7mrzMrYsXqdTjvWxtLn+7jt0t2rO7RXt+bt2R1Lh4/hgxlrT4qxQvV5b0GzfM\ny3e3aK9EMhfXE64xacwweg8fy+SFKyhVugwLpn+Za9sLZ88wqPu/+fG7Ldnm9x42ls9mLeKzWYv4\nd8/+eHp581b33kURvt0zmkw2f9mLeyKZ/OnYeaqHBVM2sCQAretGsn7fH9luOHp/WDBr+r+GdzF3\nUtMziLmeiK9nMfPyX05c4Mc/ztLysX8VefyO4Mf9B6heuQLlyoQA0Lbp06zd9mOOm7ou/s8mXnq6\nAY3r1cl1PWnpGfQdP5W+b3ckJNC/0OO2Rz/t/onq1apRtmw4AK1btWL9hg3Z9uWd2mzb9h3Nmr2I\ni4sLPj4+NH72GdatWw9ApjGTGzduAnArKQk3NzfzOhctXkK3d//Nv6pXL6pNdVgN3u3IT3OWs2/Z\nOluH4pD86z7K9UNHuHXudsXr4uJvKPX8c3m2L9elE2nxV7m0bCUAvjUiMWUaqTV3OnVWL6HCv98E\np3vi66xAftuzm0pV7qd06O3zRONmL7Njy8Zcb7a9YfVyGj73AnWfzL1HIj09nS9GD+X1bh8REFSq\nUOMWx2PxX19aWhpHjx4FYMuWLaSnpxd6UP+0K9duEuzrbZ4OLuFNYkoaSalp2dq5Ojuz7eBJnhn6\nFftOX6LZw/cDEHM9kU9WbWf0q8/h7GQo0tgdxZXYeEr9JfkLDvQj8VYySbeSs7Ub8G5nXmxUL8/1\nrPzvdwT5laRR3YcKLVZ7d+VKNMHBwebp4KAgEhMTSfpLF+Cd2lyJjqZUtmXBRMfcvoSgX58+zJ4z\nh6efbcxbXd+hf7++uLjcvtpl7JjR1K+X9/8bybLkvcH8vHCVrcNwWB6lgkm9fMU8nRodg6u3F86e\nnjnauvr6Uva1Vzk2erx5nsHFhau7fmb/m93Y26EL/nXrEP5qmyKJ3ZHExUTjH5R1LvAPDOJWUhLJ\nt5JytH3rw940eLZJnuvauu5b/AICqFNfl3j9yWQHL3thMZns2bMnR44cAeDMmTP06dOn0IP6p+X1\nyCMnQ87Nf+pfFdk+oivvPFuHd6atIi0jg4/nb6DXS08QWCLniU5uy6vc7uRcsGrBvFXr6drupX8i\nJIdlMuV+9zInZ+d8tTEacy5zdnImNTWV3n36MGzoEDb/dyNzZn3FiBEjuXLlSi5rEilEefwoNxkz\nc8wr0/olYrdtJ+VS1iVGl5av4tioTzGlp5NxM5Fzc78mqJGSnL8zGfM4Lzs55zr/TtYsX0yrDm/8\nf0OSu5TFATjR0dG8/PLLALz55pt06NCh0IP6p5Uq6c3B81lfmDHXE/Ep7k5xd1fzvPOxCcTdTKJm\nhTIANH+kGiOWb+Pw+RguXb3O+NXbAYi7eQuj0URaegZD2j5dtBtix0IC/Tnwx0nzdHTcVXy8PCnu\n4ZHvdRw5eYbMTCMPRVYtjBAdRqlSpTh48JB5OiYmBh8fH4oXK5avNiGlShEbF5e1LDaG4OAgTp48\nRUpyCk/Urw9AZGQkERERHDx4iFKl1G0lRSfl8hVKRGZdTuEeHEh6wnWMySk52pZ67hmOjfo027yQ\nF5tw84/jJB7/3znHYMD4v2t/73WLZk1jz64dACQnJRFeoaJ5WXxcLF7ePnj85VySH6ePH8OYmUG1\nB2v+o7HK3cNi2chgMHDmzBkAzp8/n2vVw949el9ZDpy9wrnYawAs33WABtUjsrWJu5HEx/M3cC3x\ndrfs+n1/UDHEnxoVSrNpcBeW9XqVZb1epdVj/+KZGpWVSP5N3VqRHPjjBGcvXQZg6botPPVo7QKt\nY+/BozzyQDUMhnv7UoJHH32UAwcPcu7ceQCWf7OCBg2eyHebBg0asPrbb8nIyODGzZts/O9/ebLB\nk4SFh5GYmMhvv/0OwIULFzh95gxVqtxXhFsnAvE/7qbEA/+ieNkwAELbtCRm2/Yc7Vx8vCkeHkbC\nrweyzfesFEHEe++AkxNO7u6EvdKa6A2biyR2e9f+ja7mATNjps7h+JFDRF28fZ7475oVPFy3foHX\nefj3ffyr5kP3/Ln574wm27/shcXKZN++fenevTtxcXEEBQUxdOjQoojrH+XvXZxh7Z6m59x1pGdk\nEhrgy8j2z3L4fDRDl25mWa9XqRlRhjeffog3Jn+Di5OBwBJefPb6C7YO3WH4+5ZgxEdd6T5iIukZ\nGYSFBDO61785dPwUAyfOZNWUMRbXce7SFcoEBxRBtPbN38+PYUOG0LNXL9Iz0gkNDWXk8OEcPnyE\nocOGsWzpkjzbALRu1ZKLFy/Qqk1bMtLTadnyZWrXrgXAhAnj+eTTT0lNS8PFxYWBA/oTFhZmy82V\ne1D61Wsc6T+UyImfYHB1JfnCRQ71GYRPtarcP3wgu1u0B6B4eBipsXGY/lZ1PD15JlUG9ObRb5fi\n5OpC9MYtXFqua1j/zrekH+/1GcSng/qQnp5OqTKhfNBvCAAn/zjC5E9H8NmsRRbXE3XxAkGlQgo5\nWnFkBlNeFxT+xbVr17hw4QKhoaH4+fkV6ANS1k+1OjixzKPJO2Se2W/rMO5qzuVrkpLLBevyz/Eo\nfvt65K6GcjaN4243zXSWzVVr2TqMu9rTR/dx5MoNW4dxV7u/lI+tQwDgZOxNW4dAxUBvy42KgMXK\n5Pr16/n888+pWLEix48fp1u3bjRr1qwoYhMRERGxS3Z0m0ebs5hMzps3j5UrV+Lp6UliYiKdOnVS\nMikiIiIiQD6SSYPBgOf/7v3l5eWFu7u7hXeIiIiI3N2MdnWnR9uymEyGhYUxZswYateuzd69ewkP\nDy+KuERERETEAVi8NdDIkSMJCwtj165dhIWFMfx/I0ZFRERERCxWJrt27crs2bOLIhYRERERh6AB\nOFksJpM+Pj5s3bqVcuXK4eR0u5BZvnz5Qg9MREREROyfxWQyPj6euXPnmqcNBgPz588vzJhERERE\n7Jo9PYHG1iwmkwsWLCiKOERERETEAVlMJp966qlsz+P09vZm9erVhRqUiIiIiDgGi8nkxo0bATCZ\nTBw6dMg8LSIiInKv0gCcLBZvDeTm5oabmxvu7u7UqlWLI0eOFEVcIiIiIuIALFYmx48fb+7mjomJ\nMY/oFhEREblX6Qk4WSwmkxUqVDD/XaVKFerVq1eoAYmIiIiI47BYZnzhhRcoV64coaGhBAQEsH37\n9qKIS0REREQcgMXKZLdu3UhPTycmJobMzEyCgoJ4/vnniyI2EREREbukAThZLFYmr127xqxZs4iM\njGTlypWkpqYWRVwiIiIi4gAsViY9PDwASE5OxsPDI9s9J0VERETuRUaVJs0sViafeeYZJk+eTJUq\nVWjdujVubm5FEZeIiIiIOACLlclXXnkFk8mEwWDgiSeeoGzZsgBs2bKFRo0aFXqAIiIiImK/8nXT\nyD+7tu+77z5zt/f8+fMLLyoRERERO5ZptP3LXlh9B3KTrhUQERERuedZ7ObOiwbiiIiIyL1KA3Cy\n6NmIIiIiImI1dXOLiIiIiNWs7ubu3LnzPxmHiIiIiMPIVFHNzGIyOW3aNL766ivzKG6AnTt38tRT\nTxVqYCIiIiJi/ywmk+vXr+eHH36gWLFiRRGPiIiIiDgQi8lkaGhotqqkiIiIyL1Oo7mzWEwm09PT\neeGFF6hcuTJw+5ZA48ePL/TARERERMT+WUwm33zzzaKIQ0RERMRh2NMTaGwtz2Tyu+++48knn+TM\nmTM5lj388MOFGpSIiIiIOIY8k8mEhAQAYmNjiywYEREREXEseSaTL730EgDdunUjJiaGjIwMTCYT\nMTExRRaciIiIiD3SAJwsFq+Z7NevH7/99hvJycmkpKQQFhbGsmXLiiI2EREREbFzFh+n+Mcff7Bu\n3Toef/xx1q1bh7u7e1HEJSIiImK3Mk0mm7/shcVksmTJkhgMBm7duoWfn19RxCQiIiIiDsJiMlmt\nWjVmzZpFUFAQ3bt3JyUlpSjiEhEREREHYPGayebNmxMUFISHhwc7duwgMjKyKOISERERsVtG++ll\ntjmDyXTnTvd27dqxePHioopHRERExO5tOWH7Wyc2qhRo6xCAfFQmixcvzqhRoyhfvjxOTrd7xdu0\naZPvD7g5f4jVwYll3h2HkPHrRluHcVdzqdGYpMUjbB3GXc2z3QAANletZeNI7m5PH91HV0M5W4dx\nV5tmOkuld1fZOoy72onJL9k6BAAyVZo0s5hM7tq1ixo1ahAfHw9AampqoQclIiIiIo4hz2Ry+fLl\nfPPNNxQvXpwffvgBAKPRSEZGBj169CiyAEVERETEfuWZTDZr1oxHH32U6dOn07VrVwCcnJzw9/cv\nsuBERERE7JGegJMlz2TSzc2N0NBQhg8fXpTxiIiIiIgDsXjNpIiIiIhkl6nCpJnFm5aLiIiIiORF\nyaSIiIiIWE3d3CIiIiIFpAE4WVSZFBERERGrKZkUEREREaupm1tERESkgPQ4xSyqTIqIiIiI1VSZ\nFBERESkgDcDJosqkiIiIiFhNyaSIiIiIWE3d3CIiIiIFpMcpZlFlUkRERESspsqkiIiISAFpAE4W\nVSZFRERExGpKJkVERETEaurmFhERESkgo56AY6bKpIiIiIhYTZVJERERkQLSrYGyqDIpIiIiIlZT\nMikiIiIiVlM3t4iIiEgB6T6TWVSZFBERERGrqTIpIiIiUkCZqkyaqTIpIiIiIlZTMikiIiIiVlM3\nt4iIiEgB6Qk4WVSZFBERERGrqTIpIiIiUkB6Ak4WVSZFRERExGpKJkVERETEaurmFhERESkgPQEn\niyqTIiIiImI1JZMiIiIi94iUlBTee+892rdvz5tvvsnVq1dzbWc0GunSpQuLFy+2uE4lkyIiIiIF\nlGky2fxljcWLF1O5cmUWLVpE8+bNmTJlSq7tJk6cyI0bN/K1znvmmsmdJy7x5fe/k5ZhpFKQLwOf\nfwQvd9dc235/7CKD1/zE9l6tss2/ciOJznM2s/jN5/At7l4UYTuU7fsPM3HJf0hLz6RyeGmGv90O\nr+Ie2dr854c9zP7PNgwGA8XcXOn72stUjwgH4PE3+xHk52tu+/oLT/H847WLdBsczQ/HLzJpy6+k\nZxqpFOzLoBcfxcvDLde23x09z6BVu/ihX9sijtLxBDzxOBW7d8PJzZXEYyc5PGAYmUlJ5uUhzZpS\nttMr5mkXby/cg4P54cnnSIu/yhM/biE1Osa8/OzsBVxZu6FIt+Fu0WnOOKIOHWPz+Jm2DsUhNagW\nTI9m1XBzceLYpRv0+3o/iSkZ2do0fziM1xtWNE97ebhSqmQx6vXfyLXEVAa3eYCHKwYA8P3haMau\nOlSk2yD/rH379tGlSxcA6tevn2syuXHjRgwGA/Xq1cvXOu+JZPJaUgpD1/7MrE5PE+7nzRfbfuPL\nbb/R57mHcrQ9f/UmE7f+yt9vbL/2wBmm7zhIbGJyEUXtWK7eSGTAtEUsHPoBZUOCGP/1GiYsXsOg\nN1qb25yJimbc12v4ZnRPAkuWYMevh/lgwiy2Th7KmahofDyLs3JsbxtuhWO5lpTCkNW7mPNGY8L9\nffh8834mbfmVvs8/kqPt+fgbfLZpvy4YzwfXkr5UGzmYPa+8zq1zF6jY4z0q9XiPP4aNMbe5/O06\nLn+7DgCDiwu1F8zkzMy5pMVfpXi5sqTfuMHuFu1ttQl3hVJVImg7eTgV6tQg6tAxW4fjkPy83BjT\noRZtxm/nXGwSvZpVo2ezagxZ+nu2dqt/ucDqXy4A4OJkYFH3+szYfJz4m6m0qBNO+SBvmo7cipPB\nwNKeT9C4Rmk2/hpli02yK5kO8ASc5cuXM2/evGzz/P398fb2BsDT05ObN29mW378+HHWrl3LF198\nweTJk/P1OfdEN/fuM1e4P8SfcL/bO69lzYpsOHwO09++WFPSMxj47U90b1Qj2/zYm7fYfvwin7d5\noshidjS7DvxB9YhwyoYEAdD26bqs27kv2z52c3Fh2FttCSxZAoBqFcKJS7hJWkYGvx0/g7OTE68N\nm8RLvccwZcVGMo1Gm2yLo/jpVBTVygQQ7u8DQKvaldlw8EyO4zo5LYMBK3fS49latgjT4fjXfZTr\nh45w69ztL9eLi7+h1PPP5dm+XJdOpMVf5dKylQD41ojElGmk1tzp1Fm9hAr/fhOc7olT7T+qwbsd\n+WnOcvYtW2frUBzW41WDOHjuGudib1fVF/1whhcfCrvje956pjLxiaks2XkWACeDgeLuzri5OOPm\n6oSrsxNp6To3O4pWrVqxdu3abC9vb2+S/tfTkpSUhI+PT7b3rF69mujoaDp16sSqVauYO3cuO3bs\nuOPnFKgymZ6ejqtr7l3D9iz6xi2CfYqbp4N8ipOUmk5SWka2ru6R6/fQokYElYJ8s70/0Ls4n7bM\nX6n3XnU5/hql/LP2W7C/L4nJKSQlp5q7ussE+VMmyB8Ak8nEJwtW8WSt6ri5uJCRaeTRyPvo+Uoz\nUtLSeGfsDLyKedCxSQNbbI5DiL6e87hOTE0nKTU9W1f3yLW7aVGrMpWCS9oiTIfjUSqY1MtXzNOp\n0TG4envh7OmZrasbwNXXl7Kvvcrul7O6vA0uLlzd9TPHP52Is4c7NaZ9TkZiIufnW76IXbIseW8w\nAFUa1rVxJI6rlG9xLl/L6k27kpCMdzFXvDxccnR1A5T0dOP1hhVpPuY787yVu8/xXM0y7BzVGGcn\nAz8ejWHboSs53iuOo2bNmmzfvp3IyEh27NhBrVrZCw29e2f1EE6aNImAgADq169/x3Va/Lm8bNky\nxo4dC8Dbb7/N6tWrrYndpvLq2nM2GMx/L997AhcnA80ejCiqsO4qpjzK/U5OhhzzbqWk8tHEuZy/\nEsewt29fv9eq4WP0e+1l3Fxd8PEsTqemDdi650Chxuzo8jyu/7LPl/1yDGcnJ5rXrJhrW8lFLscs\ngMmYmWNemdYvEbttOymXsrr8Li1fxbFRn2JKTyfjZiLn5n5NUKMnCy1ckbzkVRDPq3u2zePl2Hrg\nMhfjb5nnvdekKlcTU3m0z3rq9d9Iif8lnHJ7P9r6ZY127dpx4sQJ2rVrx9KlS+nWrRsAc+bMYevW\nrVat02JlcvHixSxfvhyA6dOn8+qrr9K8eXOrPsxWSvkU59ClePN07M1kfDzcKOaWtfn/OXCalIxM\n2s/cQLrRSOr//v687RMEehfPbbXyFyEBJTlw8px5OubqdXw8i1PcI/tApai4q7z7yUwiygQzZ1A3\nPNxuV9DW7NjDfWVLc1/ZMgCYTODi7Fx0G+CASpXw5NClOPN0zM1b/zuus6rt//ntFCnpGbSdupb0\nzNvHddupa5n0ylME+ui4zk3K5SuUiKxunnYPDiQ94TrG5JQcbUs99wzHRn2abV7Ii024+cdxEo+f\nvD3DYMCYkbMKJFIYPmhalYaRpYDbA2mORWWNxg329SAhKY3ktJw/jACa1AxlxPLs11M+82Bphi37\nnfRME+mZGaz6+TyNHyzD7K0nC28jpFAVK1aML774Isf8zp0755j33nvv5WudFpNJJycnXFxuN3N1\ndcVgyP1Xuz2rUyGEiVt/5fzVm4T7ebNi/wmeqFwmW5v5rz9r/jsqIZE2Mzaw6M28r5OS7B6LrMKn\nC1dz7nIMZUOCWLrlR56qXT1bm4TEJF4bOonmTzzMv1tm37cnLlxm8y+/M/Gj10nPyGDxf3+g6eO6\nxu9OHo0I4bNN+zgff4Nwfx9W7D3OE1WyXw+14K0m5r+jriXSasp/WPLO80UdqkOJ/3E3lXt3p3jZ\nMG6du0Bom5bEbNueo52LjzfFw8NI+DV7Bd2zUgRBTzfk9w964eTqStgrrbmydmNRhS/3uM/XHeXz\ndUeB2wNw1vVvSNlAT87FJtHu8fJsPXA51/f5FHOlbKAn+09nv+fg4QsJNKlVhp9PxOHiZKDhv0L4\n7Wzu9yW81zjCAJyiYjGZbNiwIe3btycyMpLDhw/z1FNPFUVc/yg/Tw8GPV+Hj1fsJD3TSGhJL4a+\nWIcjUfGMWPeLksZ/gH8Jb0Z0bc+Hn80hIyOTsGB/Rr37KodOnWfQjCWsHNubpZt/5HLcNbbsOciW\nPQfN75094F3+3bIxI+d8Q/NeY8jIzOTZRx6k5VOP2nCL7J+fVzGGNHuMXst2kJ6ZSWhJb4a/VJcj\nl+IZtuYnJY1WSr96jSP9hxI58RMMrq4kX7jIoT6D8KlWlfuHDzSP0i4eHkZqbBymv1UdT0+eSZUB\nvXn026U4uboQvXELl5avssWmyD3uamIafRbuZ1KXR3BzceJ8bBK95u8FoHq4L6NeqcGLo29fH1k2\n0JPYGylk/C1BGrXiIINaRbJxYCOMJhM/HYtlxqbjRb4tYt8Mpr8P/czF0aNHOXPmDBUqVKBKlSoF\n+oCb84dYG5vkg3fHIWT8qqpHYXKp0ZikxSNsHcZdzbPdAAA2V1U1ujA9fXQfXQ3lbB3GXW2a6SyV\n3tWPh8J0YvJLtg4BgE+3276rv9cT9nH9qsXK5JUrV5g6dSonT56kfPny9O3bl9DQ0KKITURERMQu\nqZs7i8XR3AMGDKBZs2YsWbKEl156if79+xdFXCIiIiLiACwmk6mpqTRs2BAfHx8aNWpEZmbuo8BE\nRERE7hW2vi2QPVVGLSaTmZmZHDt2+1FWf/5XRERERATycc3kwIED6devH7GxsQQFBTFihAYiiIiI\niMhtFpPJXbt2sWLFiqKIRURERMQh2FM3s61Z7Obevn27rpMUERERkVxZrExeu3aNevXqERoaisFg\nwGAwsGTJkqKITURERMQuqTKZxWIyOW3atKKIQ0REREQckMVkctWqnHfy79atW6EEIyIiIiKOxWIy\nGRAQAIDJZOLIkSMYjcZCD0pERETEnqmbO4vFZLJt27bZprt06VJowYiIiIiIY7GYTJ45c8b8d2xs\nLFFRUYUakIiIiIi9U2Uyi8VkctCgQea/3d3d+fjjjws1IBERERFxHBaTyQULFmSbTk9PL7RgRERE\nRMSxWEwmlyxZwpw5c8jIyMBkMuHq6sp///vfoohNRERExC6pmzuLxSfgfP311yxYsID69eszevRo\nIiIiiiIuEREREXEAFpPJoKAggoKCSEpK4pFHHuHmzZtFEZeIiIiIOACL3dze3t5s2bLF/BjFhISE\noohLRERExG5lqJvbzGJlcsSIEZQuXZqPPvqIs2fPMmDAAADS0tIKPTgRERERsW8WK5NeXl7cf//9\nAPTp08c8v0uXLsyfP7/wIhMRERGxUxqAk8ViZTIvJpN2ooiIiMi9zupk0mAw/JNxiIiIiIgDstjN\nLSIiIiLZqZs7i7q5RURERMRqFpPJK1euZJs+ffo0ABUrViyciERERETsXKbJZPOXvcizm/v48eNE\nR0czbtw4evXqBUBmZiYTJkzg22+/ZfDgwUUWpIiIiIjYpzyTyRs3brB+/Xri4+NZt24dcHvQTfv2\n7YssOBERERGxb3kmk7Vr16Z27docPnyYatWqAWA0GnFysvoySxEREZG7ggbgZLGYGZ46dYp169ax\natUqHn/8cWbNmlUUcYmIiIiIA7CYTM6fP5/HHnuMNWvW8P333/Pdd98VRVwiIiIidivTaLL5y15Y\nTCbd3d0B8PT0xM3NjYyMjEIPSkREREQcg8VkMjw8nDZt2vDyyy/z5Zdfct999xVFXCIiIiLiACw+\nAWf06NEkJSXh6elJ9erVCQwMLIq4REREROyWPXUz25rFZPLEiRMMHjyYGzdu8OKLL1KpUiWefPLJ\noohNREREROycxW7uESNGMHr0aEqWLEnLli2ZNGlSUcQlIiIiYrcyjUabv+xFvm4aWbZsWQwGA35+\nfnh6ehZ2TCIiIiLiICwmkyVKlGDJkiUkJyezbt06SpQoURRxiYiIiIgDsHjNZOXKlbl06RJ+fn4c\nOnQIPz+/oohLRERExG5pAE6WPJPJ5cuX880333Dq1CkiIiIA2Lt3r+4zKSIiIiJmBpPJlGtqnZaW\nRkxMDNOnT6dr164AODk54e/vj5ubW5EGKSIiImJP2s/fY+sQWNTxIVuHANwhmfynrD0aXZirv+c9\nXzWY3y4l2DqMu9qDZXxpMm2XrcO4q63v+hgAR67csHEkd7f7S/lQ6d1Vtg7jrnZi8kt0NZSzdRh3\ntWmms7YOAYA2c3+xdQgsfe1hW4cA5HM0t4iIiIhIbiwOwBERERGR7DI0AMdMlUkRERERsZqSSRER\nERGxmrq5RURERApI95nMosqkiIiIiFhNlUkRERGRAlJlMosqkyIiIiJiNSWTIiIiImI1dXOLiIiI\nFJC6ubOoMikiIiIiVlNlUkRERKSAVJnMosqkiIiIiFhNyaSIiIiIWE3d3CIiIiIFpG7uLKpMioiI\niIjVVJkUERERKSCTKpNmqkyKiIiIiNWUTIqIiIiI1dTNLSIiIlJARnVzm6kyKSIiIiJWU2VSnBW7\nyQAAHklJREFUREREpIBMJlUm/6TKpIiIiIhYTcmkiIiIiFhN3dwiIiIiBaT7TGZRZVJERERErKZk\nUkRERESspm5uERERkQLSfSazqDIpIiIiIlZTZVJERESkgExGW0dgP1SZFBERERGrKZkUEREREaup\nm1tERESkgPQ4xSyqTIqIiIiI1VSZFBERESkg3RooiyqTIiIiImI1JZMiIiIiYjV1c4uIiIgUkEnd\n3GaqTIqIiIiI1e7ZyuSRvT+xfsF0MtLTCSkXQZtuH+NR3DNHu53rVrBr47cYDAb8S5Wm1b974+1b\n0gYRO4b9u3ey+KuppKelEV6hIl179ae4p1eOdj9s3sCapQsxGAy4u3vw2ns9iLivqnl5XEw0A959\ng0++WohPCd+i3AS791B4SV57JBxXZyfOxCcx8ftTJKdn5mjX5dFyPF7Bn5upGQBcSkhmzJbjeLm7\n0K1eBSoEeJKSnsnmYzH859CVot4Mu7b3p50snDGZ9PQ0ylaoRLePB+R6HMPt24NMGjOU8PIRNG/b\nAYBPBn3M5UsXzG1iLkdR7YGa9Bs9oUjidxQNqgXTo1k13FycOHbpBv2+3k9iSka2Ns0fDuP1hhXN\n014erpQqWYx6/TdyLTGVwW0e4OGKAQB8fziasasOFek23A06zRlH1KFjbB4/09ahOBRVJrPck8lk\n4vUElk4aTbfRkwksHcbaeVNZN386L3f9KFu7CyeP8f3qpfSYOJtinl6smTOZjYu+otW/e9kocvt2\nI+EaUz8ZwbAvZhASGs7XM75k0cwpdPmwd7Z2UefPsXD6JMZMn09J/wB+3f0j4wd/zJQlawDYvmk9\ny+fM4Fp8rC02w675eLjQ/cmK9Fx9kKjrKXR+pCyd65Rlyg+nc7StGuzN2C3HORp9M9v8tx4rR3J6\nJl2X/oqTwcDAxlWIvpHKL+evFdVm2LXrCdeYNGYYoyd/RenQcOZPm8SC6V/y9kd9crS9cPYMMyZ+\nwvEjBwkvH2Ge33vYWPPfJ44e5tPBfXire+8c77+X+Xm5MaZDLdqM38652CR6NatGz2bVGLL092zt\nVv9ygdW/3E7MXZwMLOpenxmbjxN/M5UWdcIpH+RN05FbcTIYWNrzCRrXKM3GX6NssUkOp1SVCNpO\nHk6FOjWIOnTM1uGIA7snu7mP/fYLYRWrEFg6DIDHGjdn/47NOW5AGlbxPvpOXUQxTy/S01K5fjUO\nT+8StgjZIfy+92ci7qtKSGg4AE+/2IKdWzfm2K8ubq683bMfJf1vVxMq3FeVhKvxZKSnczUulj07\nt9NHFZxc1Qzz5XhMIlHXUwBYd+QKT/6vKvNXLk4GIgI8afFAab5s+QD9n7mPQC83ACoGerHtRCxG\nE2QYTew5d426Ef5Fuh327Lc9u6lU5X5K/+84btzsZXZsyXkcA2xYvZyGz71A3Scb5bqu9PR0vhg9\nlNe7fURAUKlCjdvRPF41iIPnrnEuNgmART+c4cWHwu74nreeqUx8YipLdp4FwMlgoLi7M24uzri5\nOuHq7ERauh6YnF8N3u3IT3OWs2/ZOluHIg4uX8nkwYMHs03/8ssvhRJMUUmIi8E3IMg8XSIgkJRb\nSaQm38rR1tnFhYO7f2DYGy05ffh3Hmr4XFGG6lDiY6LxDwo2T/sHBpGclETyraRs7YJKlaZmnceB\n212E86d+Tu3H6uHi6opfQCA9h40ltFyFIo3dUQR6uhOXmGqejktMxdPdhWKuztna+Xu68XvUdeb+\nfI5u3/zOH9E3GdS4CgDHom/yVKVAnJ0MeLg4UbeCP37FXYt0O+xZXC7H8a1cjmOAtz7sTYNnm+S5\nrq3rvsUvIIA69Z8slFgdWSnf4ly+lmyevpKQjHcxV7w8cu8wK+npxusNKzLymwPmeSt3n+P6rXR2\njmrMj6Oe43xsItt0yUa+LXlvMD8vXGXrMByW0WSy+cte3LGbe+/evZw8eZK5c+fSuXNnADIzM1m0\naBFr164tkgALQ17XORiccs+t/1WnHv+qU4/dm/7DjKE96Tt1MU55tL2X5fVoKScn51znpyQnM2Xs\nMOJjo+k39vPCDO2uYTDkPv/vJ5Xom6kMXn/UPL3i9yja1Qol2Nudr346S5dHyzGp5QNcu5XGrxcT\nqBrsXYhRO5a8zg95Hcd3smb5Yv7ds9//N6S7Ul6n0Mw89n+bx8ux9cBlLsZn/eh/r0lVriam8mif\n9bi7OjP17Tq83rAis7eeLIyQRSQPd0wmfXx8iIuLIy0tjdjY29evGQwGevVyvGsGNy6axeFffgQg\nJTmJkLJZla/r8XEU8/LG3aNYtvfEXb7IjWtXqXB/JAAPN2zCN9PGk5x4E08fdXcDLJsznb27fgAg\n+VZStuvGrsbG4untg0exYjneFxd9hbH9e1CmbDkGT5iCm7tHkcXsaF6tHcYj5fwAKO7mzNm/fJkG\neLpzMyWd1IzsXXvl/IpTwd+TbSf+et2pgQyjieJuzszafY7E/w3MaflgGaJupBT6dtizRbOmsWfX\nDgCSk5IIr5A14CM+LhavPI7jOzl9/BjGzAyqPVjzH43VkX3QtCoNI29393t5uHIs6oZ5WbCvBwlJ\naSSn5RxMBtCkZigjlme/nvKZB0szbNnvpGeaSM/MYNXP52n8YBklk1IkNAAnyx2TycqVK1O5cmVa\nt25NUFDQnZravcbt36Bx+zcAuJlwjXEfvEZs1AUCS4fx03+/pfrDj+d4z42r8SycMIyPPpuFl48v\n+3dsplR4eSWSf9G689u07vw2ANevXaVXl/ZcvniekNBwNv9nJbUfq5fjPYk3rjOke1eeePZ5WnXq\nUtQhO5yFey+wcO/tAQglPFyZ0voBSpfwIOp6Ck3uD2b32ZwDZ0wmePvx8hy+coPom6k0rVaKs1eT\niE9Ko9PD4RR3c2bqzjP4FnOlcdUgxm45UdSbZVfav9GV9m90BSDh2lU+7NyOqIvnKR0azn/XrODh\nuvULvM7Dv+/jXzUfwpBXOfke9Pm6o3y+7nbF3M/LjXX9G1I20JNzsUm0e7w8Ww9czvV9PsVcKRvo\nyf7TV7PNP3whgSa1yvDziThcnAw0/FcIv529mus6RKTw3DGZfP/99/niiy9o0aJFjmU7d+4stKAK\nm7dvSdq+14d5nwwiMyMd/1JlaP9BfwAunPyDZV9+Qo+Js6lQ7QEatezA1AEf4OTkjI+fP537jrRx\n9ParREk/3uk1kAlD+pKRkUGp0mV4t89gAE4dO8r0cSP5ZOZCNq1ZSVxMNHt2fs+end+b3z9w3GS8\nSyhRv5PrKel89v1J+j19Hy7OBq7cSGHctttVmEqBnrz/REXe++Z3zl27xbSdpxn8XFWcDBCflMbY\nLccBWPbrRXo+VYkprR/EAHy99wInYhNtuFX2xbekH+/1GcSng/qQnp5OqTKhfNBvCAAn/zjC5E9H\n8NmsRRbXE3XxAkGlQgo5Wsd1NTGNPgv3M6nLI7i5OHE+Nole8/cCUD3cl1Gv1ODF0d8BUDbQk9gb\nKWT8rRI0asVBBrWKZOPARhhNJn46FsuMTceLfFtE7nUGU14XugELFy7k1Vdf5bfffuPBBx+06gPW\nHo22Ojix7Pmqwfx2KcHWYdzVHizjS5Npu2wdxl1tfdfHADhy5YaFlvL/cX8pHyq9qwEXhenE5Jfo\naihn6zDuatNMZ20dAgC1Bm60dQjsG97Y1iEAFiqTCxYsIDQ0lM8++4zevXtnG2Dx+OM5u4VFRERE\n5N5yx2SyV69ebNq0ifj4+Byjt5VMioiIyL3KqAE4ZndMJhs1akSjRo1YvXo1zZs3L6qYRERERMRB\n5Otmid98801hxyEiIiIiDihfz+ZOS0ujefPmlC9f3nyz7vHjxxdqYCIiIiL26g7jl+85+Uome/bs\nWdhxiIiIiIgDylc39/3338+PP/7IqlWrSEhIIDg42PKbREREROSul69ksl+/foSFhXHu3DkCAgLo\n379/YcclIiIiYrdMRtu/7EW+ksmEhARatmyJi4sLNWvWxGi0oy0QEREREZvJ1zWTAKdOnQLgypUr\nODs7F1pAIiIiIvZO95nMkq/K5IABA+jXrx9Hjhzh/fffp0+fPoUdl4iIiIg4gHxVJs+fP8/ixYvN\ntwUSEREREYF8ViZ/+uknmjVrxmeffcaFCxcKOyYRERERu2Yymmz+shf5qkwOHDiQtLQ0tm7dyrBh\nw0hPT2fu3LmFHJqIiIiI2Lt8D8A5cOAAO3fuJD4+nmeffbYwYxIRERGxa/ZUGbS1fCWTTZo0ITg4\nmLp169KjRw/8/PwKOy4RERERcQD5umayW7duREVFsX//ftq0acO3335b2HGJiIiIiAPIV2Vy3rx5\nrFy5Ek9PTxITE+nUqRPNmjUr7NhERERE7JLRpG7uP+WrMmkwGPD09ATAy8sLd3f3Qg1KRERERBxD\nviqTYWFhjBkzhtq1a7N3717Cw8MLOy4RERERu6UBOFnyVZkcPXo0YWFh7Nq1i7CwMIYPH17YcYmI\niIiIA8hXZdLFxYVXXnmlsGMREREREQeT7/tMioiIiMht6ubOoodti4iIiIjVVJkUERERKSCjKpNm\nqkyKiIiIiNWUTIqIiIiI1dTNLSIiIlJAJj0Bx0yVSRERERGxmiqTIiIiIgWkWwNlUTIpIiIico9I\nSUmhV69exMfH4+npydixY/Hz88vWZvbs2axduxaDwUDXrl15+umn77hOdXOLiIiI3CMWL15M5cqV\nWbRoEc2bN2fKlCnZlt+4cYP58+ezZMkSZs+ezahRoyyuU8mkiIiISAEZjSabv6yxb98+6tWrB0D9\n+vX56aefsi0vVqwYpUuXJjk5meTkZAwGg8V1qptbRERE5C60fPly5s2bl22ev78/3t7eAHh6enLz\n5s0c7wsJCaFp06ZkZmby9ttvW/wcJZMiIiIid6FWrVrRqlWrbPO6detGUlISAElJSfj4+GRbvmPH\nDmJiYti6dSsAb7zxBjVr1iQyMjLPz1EyKSIiIlJAJmOmrUOwSs2aNdm+fTuRkZHs2LGDWrVqZVte\nokQJPDw8cHNzw2Aw4O3tzY0bN+64TiWTIiIiIveIdu3a8fHHH9OuXTtcXV0ZP348AHPmzCE8PJyG\nDRuya9cuWrdujZOTEzVr1qRu3bp3XKeSSREREZECctTKZLFixfjiiy9yzO/cubP57/fff5/3338/\n3+vUaG4RERERsZrBpIdLioiIiBRI2dcX2ToEzs1ub+sQAHVzi4iIiBSYo3ZzFwZ1c4uIiIiI1VSZ\nFBERESkgU6Yqk39SZVJERERErKZkUkRERESspm5uERERkQLSAJwsqkyKiIiIiNWUTP4/de/enbS0\nNKKioti2bRsAI0eOJCoqysaRycKFC20dQqHr0KEDp06dynO5pUdg3c1SU1NZvnx5vtquXLmSrVu3\nFnJEd6+C7Os/7dmzhz/++KOQIpJ/wubNm3nmmWeYP38+3bp1A+DYsWPs2bPHxpHZB5Mx0+Yve6Fk\n8v/ps88+w83Njd27d7N//34A+vfvT+nSpW0cmUydOtXWIYgNxcbG5jvBadGiBQ0bNizkiO5eBdnX\nf1qxYgUxMTGFFJH8E7Zt20afPn3o2LEjX375JQCbNm3i5MmTNo5M7I1dXzO5cuVKtm/fTkpKCufP\nn+fNN99k1apVDBkyhIiICBYvXkxcXBwvvfQS3bt3JyQkhIsXL9K0aVNOnDjBkSNHaNCgAR999FGu\n67948SIffPABgYGBREdHU79+fbp3787Fixfp168fmZmZGAwGBgwYQJUqVejbty/nzp0jJSWFjh07\n0rx5c5566inWrl3LjBkzSElJoUaNGsydO5chQ4bQq1cvvvjiC0JDQ9m4cSN79+7lgw8+oH///ly7\ndg2AAQMGcN999xXlbs11v7Zo0SLXtlOmTGHLli1kZmbSrl072rZty+zZs1m3bh0uLi7Url2bXr16\nMWnSJM6dO8e1a9dISEjglVdeYdOmTZw5c4axY8cSEBBQoH39zDPPULNmTc6cOYO/vz+TJk3CaDQy\nePBgzp07h9Fo5MMPP+SRRx7hhRde4OGHH+bYsWMYDAamTJnCwoULuX79OkOGDKFTp0707dsXFxcX\njEYj48ePJyQkpEj3+T8hMTGR/v37c/PmTWJiYmjfPuvJB5MmTeL06dPEx8dz48YNBgwYQO3atUlL\nS6NHjx5ERUXh6+vLF198QXx8PEOGDCE1NZXY2Fg+/PBDGjVqZMMtKxzTpk3j5MmTVKlShccee4xb\nt24xcuRIVq9ezaFDh0hISKBKlSqMHj2aSZMmERAQQIUKFZg5cyaurq5cvHiRJk2a8M477+T5GQsX\nLmTTpk0kJydTsmRJvvzyS9auXcvp06fp2bMnqampPPfcc2zbto0OHTrg5+fH9evXmTFjBv369ePi\nxYtkZmbSuXNnmjRpwu+//86oUaMwGo0EBwczbtw4PDw8inCvWefPff3ll19y/PjxHOe3v587K1as\nyA8//MDhw4epWLFirj++czve27dvT4cOHXL9DnjnnXfw9fWlfv361K1bl+HDh+Ps7Iy7uzvDhw+n\ndOnSuZ7P7jbp6en07ds327E1adIk1q9fj8FgYNiwYTz66KOEh4czYsQIAHx9fRk1ahRHjhxh3Lhx\nuLq60qpVK3bs2MGhQ4coWbIk3bp1Y+XKlaxatQpXV1eqVatGZGSkjbdW7IVdJ5Nw+4Qya9Yszp49\nS9euXQkMDMy13YULF5g9ezYpKSk0bNiQHTt2UKxYMZ588sk8k0mAS5cuMWvWLLy9vWnfvj2HDx9m\n+vTpdOzYkUaNGnH06FH69evH/Pnz2bNnD8uWLQPgxx9/NK/D2dmZt956i9OnT9OwYUPmzp0LQMuW\nLVm9erX5H2HPnj2ZNm0aderUoX379pw9e5a+ffuyePHif26H5dPf92tuyeSRI0fYsWMHy5cvJzMz\nkwkTJnDs2DE2bNjAkiVLcHFx4b333uO7774DwMPDg1mzZjFjxgy2b9/OtGnTWLFiBevWraNTp075\n3tcrV67kwoULzJs3j5CQENq2bcvBgwc5cuQIJUuWZNSoUVy7do1XX32VdevWkZSURNOmTRk4cCA9\nevRgx44dvPPOOyxcuJAhQ4bw9ddfExkZSa9evdi7dy83b950yGTy3LlzNG3alGeeeYbo6Gg6dOhA\ncHCwebmHhwfz58/nxIkT9OjRgzVr1nDr1i26d+9OaGgoHTp04OjRoyQmJtK5c2ceeeQR9u/fz6RJ\nk+7KZLJr164cP36cevXqcf36dQYMGEBiYiI+Pj7MmTMHo9FI06ZNiY6Ozva+qKgo1qxZQ1paGvXq\n1cszmTQajSQkJDB37lycnJx44403OHjw4B1jev7553n66adZuHAhfn5+jBs3jsTERFq0aEGdOnUY\nNGgQEyZMICIiguXLl3Pq1CmqVav2j+2TwvLnvk5OTs5xfps5c2aOc2f16tWpV68eTZo0ybMXJ7fj\n/a8/oP4uNjaWFStW4ObmRosWLRg5ciRVq1Zly5YtjBkzhq5du+Y4n5lMJgwGQ6HsE1tZunRpjmMr\nJCSEvXv38sADD/Dzzz/Tr18/2rdvz6hRo6hYsSLLly/nq6++4rHHHst2ycLPP/9MkyZNqFGjBgDB\nwcG89NJLBAQEKJFEA3D+yu6TySpVqgAQEhJCWlpatmV/fax4WFgY3t7euLm5ERAQgK+vL4DFE0WV\nKlXMbSMjIzlz5gynTp3ioYceAqBq1apcuXIFLy8v+vXrx8CBA0lMTOTFF1+0GPsLL7xA+/btadWq\nFYmJiVSuXJnjx4+ze/duNmzYAMD169fzuSf+WXfar386c+YMkZGRODs74+zsTJ8+fdiwYQMPPPAA\nrq6uANSuXZsTJ04AcP/99wPg7e1NxYoVAShRogSpqanmz8zPvgYoWbKkOeELCQkhNTWV48ePs2/f\nPg4cOABARkYGV69ezfbZf7b9q5YtWzJz5ky6dOmCt7c33bt3/3/tO1sJCAhg3rx5bNq0CS8vLzIy\nMrItr1OnDgCVKlUiLi4OuL3/Q0NDze9PTk4mMDCQqVOn8s0332AwGHKs525Uvnx5ANzd3bl69Sof\nffQRxYsX59atW6Snp2drW7lyZVxcXHBxcbljVdDJyQlXV1fzuq5cuZJjX/71HPXXOE6dOsVjjz0G\ngJeXFxEREVy4cIG4uDgiIiIAaNWq1f9vo20gt/ObNedOsHy8Q/b9GxoaipubGwAxMTFUrVoVgIce\neojx48fnej67G+V2bNWoUYNVq1YRGxvLU089hYuLC6dOnWLo0KHA7WpmuXLlgKxjVKQg7P6ayb8n\ng25ubsTGxgK3K2d5tcuvU6dOkZycTGZmJgcOHKBixYpERESwd+9eAI4ePUpAQAAxMTEcPnyYyZMn\nM2PGDD799NNsJzcnJyeMRmO2dXt7e1O9enVGjx5trvxVqFCB1157jQULFjBx4sR8n1j/afnZXxUq\nVODIkSMYjUbS09Pp3Lkz5cuX58CBA2RkZGAymdizZ4/55GNpnfnd13mtq0KFCjRt2pQFCxYwc+ZM\nGjdufMcfDX9+0WzdupVatWoxb948GjduzFdffWVx2+3R7NmzefDBBxk3bhyNGzfOkagcPnwYuP2F\n/mfFMrf98vnnn9OsWTM+/fRTHnnkkRzruVv89d+kk9PtU92OHTu4fPkyEyZM4KOPPiIlJSXH9uf3\nXPLHH3+wZcsWJk6cyMCBAzEajZhMJtzd3c3nqD//n/x93X897hMTEzl+/DihoaEEBQVx9uxZAGbM\nmMHmzZut2/gi9ue+zu38lte502Aw3PHYy+t4z+s74M//xwBBQUHmwT179uyhXLlyuZ7P8voh7chy\nO7ZatGjB0aNHWbFihflHSvny5Rk7diwLFiygV69eNGjQAMi+H3NjMBhyfNfdq2w9+MaeKqN2X5n8\nu44dOzJ06FBKly5NUFDQ/3t9rq6ufPDBB8TFxdG4cWOqVKlC7969GThwILNnzyYjI4ORI0cSGBhI\nbGwsbdu2xcnJiddffx0Xl6zdV7lyZaZOnZqjS6pVq1Z06dKFUaNGAbe7g/r378+yZctITEw0j5Cz\nR1WrVqVevXq0a9cOo9FIu3btqFKlCs8995x5Xq1atWjUqFG+RmXmd1/npW3btgwYMIBXX32VxMRE\n2rdvf8cTX0REBD179uT999/n448/ZurUqRiNRvr27WvV/rC1J598khEjRrB+/Xq8vb1xdnbO9mV4\n9OhROnXqRHJyMsOHD89zPY0bN+aTTz5hxowZlCpVynx9293G39+f9PR0UlJSzPMiIyOZMmUKr7zy\nCgaDgbCwMKsHgZQtW5ZixYqZr7sLDAwkJiaGBg0asHjxYtq1a0e1atXw9PTM8d7WrVszcOBA2rVr\nR2pqKt26dcPf35+hQ4fSr18/nJycCAwM5LXXXrMqtqL2575OSkpiw4YN2c5veZ07H3jgAcaNG0do\naKi5GvtXeR3v+fkOGDFiBMOHD8dkMuHs7MyoUaMICwvLcT77s5J5N8nt2AoICODZZ59l165dhIeH\nAzBkyBA+/vhjc2I/cuTIfP1bqF69Op988gkRERHm3hARg+luLUvkw8WLF/noo4/M1/JI4dG+Llx/\nDiBp166drUMREbknhLT60tYhcHm5fRSkHK4yaY2lS5eydu3aHPPvNDDnXnKn/fPnhdci96qtW7ea\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657261.1430.3473710.7939460.7056820.0882634
median1371600.10.7871520.7079570.0707356
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.6576400.5384290.8339170.7092580.124658
median1376400.7692140.8527680.7133220.0894777
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.65785.71430.4944570.7761750.69470.0814751
median1371000.2972290.7768170.6875230.0524966
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.65778.57142.692060.77860.702460.0761406
median13710010.7745170.6995820.0584197
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.65794.28573461410.8297570.7637740.0659825
median137100550.8308140.756850.0418654
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657226.2861.680350.7777030.6915620.0861411
median1371600.10.7635510.6698360.0685817
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657347.7140.5379140.8259450.7099640.115981
median1373200.7689570.860.7182750.10949
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657382.2863.14305e+060.8517950.774830.0769651
median137320100.8688350.7587370.0592118
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.6576403.14889e+070.8700030.7718270.0981763
median137640550.8726640.7551830.0634218
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657166.3140.4643710.7532380.6957420.0574961
median1371000.10.7551690.6912460.0582237
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657169.61.45260.7666040.70850.0581044
median137800.10.7610070.7058450.0491028
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsn_comp_statusalphaalpha_statustrain_auroctest_aurocoverfit
67143428max1000OK0.7710980.5740740.197024
46093720OK1000OK0.8162410.5824380.233803
2073828max100OK0.7747280.749570.0251575
58944214OK1000OK0.7410090.7028190.0381898
40874814OK1000OK0.7684370.7429460.0254908
56045580max10OK0.9263280.7031140.223214
42215730OK1000OK0.7222050.5876250.13458
74905820OK1000OK0.7158190.718188-0.00236926
47717980max100OK0.8574190.8188070.0386118
258080max1000000000max0.7041290.706623-0.00249354
49218580max1000OK0.7287360.761327-0.0325916
51599150OK10OK0.8237550.670470.153284
7486104100OK10000000OK0.707260.6593440.0479152
3265112175max10OK0.9605690.9576380.00293089
5979117175max10OK0.8697150.6933560.176359
4893117175max10OK0.8984870.8129420.0855446
7428135175max1e-05OK0.9917250.9833790.00834692
672136175max100OK0.7898820.7259190.0639631
238138175max100OK0.7929410.7164170.0765236
2064153175max100OK0.8251440.7663630.058781
3791169175max100OK0.7876890.739860.047829
4089185175max100OK0.8764710.906917-0.030446
6098188175max1000OK0.7623450.7477480.0145974
1956231250OK10OK0.911480.8531690.0583107
1630235400max100OK0.7900460.7322530.0577937
675237400max10OK0.8378640.703860.134004
5925263400max10OK0.9286830.8720110.0566725
1029274400max10OK0.9250130.8743140.0506987
5728279400max10OK0.9047080.8383170.0663911
4763316250OK10OK0.8136830.7880810.0256023
324423150OK10OK0.9145170.8774110.0371053
673500800max10OK0.961020.9520720.00894727
3845527400OK10OK0.9602360.9468460.0133901
5290853800max10OK0.8770660.8629980.0140685
71572587800max1OK0.9544740.9277140.0267597
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_positiven_componentsalphatrain_auroctest_aurocoverfit
mean256.657223.5432.88574e+070.8397410.7787690.0609711
median1371751000.8315040.7554490.0478721
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsn_comp_statusalphaalpha_statustrain_auroctest_aurocoverfit
589446914691200.0042634840max0.001min0.7829230.744920.0380031
748614601460200.013698620min0.01OK0.8173290.6006940.216634
2512831283200.015588520min0.001min0.8004950.5088930.291602
515924052405210.0087318120min1max0.7612820.7075470.0537348
4763502502210.041832720min0.001min0.7742030.250.524203
560433103310210.0063444120min0.001min0.7651530.6591950.105959
206410641064210.019736820min0.001min0.6846520.3289470.355705
1956951951210.02208240max0.001min0.9095880.8957220.0138656
749033603360210.0062520min0.1OK0.7023810.5935630.108818
597915591559210.013470240max0.001min0.8568150.8425320.0142825
477128132813210.0074653440max0.01OK0.8273750.577370.250005
460936243624220.0060706440max0.01OK0.6404220.4088070.231615
671451745174220.0042520320min0.01OK0.6965950.6302130.0663813
673774774220.028423820min0.01OK0.8439640.8178810.026083
408737273727220.0059028740max1max0.5798370.584569-0.00473223
20740114011230.0057342320min1max0.7918840.918797-0.126913
7157331331230.069486440max0.1OK0.8346880.6838710.150817
609817401740240.013793140max0.01OK0.7135350.4058310.307705
492119181918240.01251340max0.001min0.7260030.77467-0.0486671
379115021502250.016644540max0.001min0.8086370.84527-0.0366335
422127082708260.0096011840max0.01OK0.8567650.4729980.383767
5728769769260.033810140max0.001min0.8869650.92349-0.036525
67510441044260.024904240max0.1OK0.8927690.7607840.131985
67212391239270.021791820min0.001min0.6312970.685597-0.0542992
23815281528310.02028820min1max0.6835420.5511110.132431
3265502502310.06175340max0.1OK0.9725530.8666670.105887
489315661566330.021072820min1max0.8763020.8631920.0131097
592518911891370.019566420min0.1OK0.7496180.6578340.0917835
102913711371370.026987640max0.01OK0.6016260.4397650.161861
1630687687400.058224220min0.01OK0.7716390.6673080.104332
.................................
7428189718971230.064839240max1max0.9824540.9400560.0423975
7428361836181250.034549540max1max0.9846030.9608010.0238016
2064572757271260.02200120min1max0.7750.6885280.0864719
1029165716571270.076644540max1max0.883980.8699670.0140128
3791490749071270.025881440max1max0.7351430.6494460.0856966
38459779771290.13203740max1max0.8777240.8097290.0679958
71572142141450.6775740max0.001min0.8935740.6551720.238401
1029369936991800.048661840max1max0.8958970.8901910.0057065
675629962992000.031751140max0.1OK0.7025080.6110450.0914631
5290217821782000.091827420min0.1OK0.7109830.6798610.0311218
3845343334332040.059423220min1max0.9546420.959903-0.00526127
5728432743272080.048070340max1max0.7378910.771816-0.0339252
5925505550552100.04154340max0.1OK0.8025160.7743870.0281295
1956652565252150.032950240max1max0.8360850.7481850.0879003
324156615662180.13920840max1max0.9256390.8812290.0444103
1630675367532210.032726240max1max0.7131610.6668640.0462971
4763573357332400.041862940max1max0.7017270.6904760.0112513
1029588158812670.045400440max1max0.847650.852951-0.00530103
324343034302700.078717220min0.1OK0.8249330.7918420.0330905
7157109010903180.29174340max1max0.8294660.8266030.00286332
673437443744010.091678120min1max0.9403010.9341820.00611882
5290513051304130.080506840max0.001min0.6423550.660249-0.0178934
324695669564140.05951740max1max0.8761850.8628950.01329
673528652864620.087400740max1max0.9410260.9348160.00620965
3845565756574670.082552640max1max0.9288620.929254-0.000391796
3845592559255000.084388240max1max0.9378970.934470.00342684
673682068205000.073313840max1max0.9162910.919691-0.00340091
7157213521355010.2346640max1max0.8879480.893028-0.00507907
5290597359735100.085384240max1max0.7886510.7594140.0292372
7157207320735800.27978840max1max0.8688970.871555-0.00265732
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsalphatrain_auroctest_aurocoverfit
mean3041.51124.6230.063901932.26420.4849620.7899950.7225180.0674771
median2627810.0318417400.10.7918840.7263220.0456447
\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": "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\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/\n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\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\nXWjVrQ/BpcthTE0lZO40Lpw6BkCFZ2rQrOu7GAwGa3clzzr740G+X/45KcnJFPU4gyMAACAASURB\nVC5egubvDMDlAdf4hy3rObz1KwwGAz4BRWnW4308vAuSnJjIxgWfcOPCWUwmI0Gln+DlN/vi6Oyc\nC73JG/bs28enM2eTlJREmdKlGDVsCB4eHtlqExMby4jRY7l85Somk5H/Nm3KG693BmDXnr0MHTma\nIoUD0n/O4vlzcXfP/Pt6FOzft5c5M2eQnJREydKlGTxsBO5/u87m2jVpWI9C/v7pbTt06sJLjZtw\nLzqaqR9P4vKlSyQmJtLljTdp3PRlq/Utr7r48yF2r1pAakoyhYIep3G3/jg/4Pnix60b+HnbRgwG\nAwX8i/Cft/rh7l2Q9Z+MJir0Znq7qPDbBD9RmVf7j7FmN/Kc/fv2MvsvY3TIQ8ZyVu0a/20sv/b7\nWP7DN19tYPeunUye9qnlO5TH1SpbiF6NyuBkb8f52zGMWn+SuMSUDG1efqooHWs9nn7s4eyAv7cL\n/5m0k7txSQAEeLuwtEcN2s7YR9T9ZKv2Ib/osmgyt06e5fsp83M7FJF0j8zMVkx0JF9On8Abg8Yy\ndPZyfAsX5ZslczK1C71xja8Wz+KdkZMZ+OkiXmrTmQUThgBwZNd3hN28zqDpS/jw08VcOHmMY/t3\nWbkneVdcdBTrZ31E+/dH0Xf6UgoGFOH7L+dlanfz4ln2f7OKt8fOpNfURfgWCWT7yoUA7F63jNTU\nVP43+XN6Tl5AclISe9Z/ae2u5Bl3IyMZNmosUz+awDfrQggsVoxPZs7KdpvPZs8lIMCf9atXsHzp\nYlavXccvx08A8Mvx43Tp+Bohy5elfz2qiVZk5F3GjRrB+I8+ZuW6DRQtFsismdNz1O7qlSt4enmx\nZPmq9K8/XpyOHTmcQv4BLFm+kumz5vDJ5I8ICw21ah/zmvv3otg8bzLN+w6n2+RFFPAvwu5VCzK1\nu335HIc3raHTyE95c9J8ChYuxt41SwBo0Xc4XSfMpeuEufznrfdwcfPgxdd7WbsrecofY3TCRx+z\nat0GipkZyw9q98dYXrp8VfrXH2M5OjqaSePHMvXjSZhMKicq6ObEqJaVGLD8Z1p8spcbkfH0fqlM\npnYbj92i3cz9tJu5n46zDhARm8ikb06nJ1ovP1WUhd2q4+/lYu0u5AuFy5Wk7/blPNOmaW6HIpLJ\nI5Ns/frzEYJLl8O/aBAAtRo35+ju7zP9sXBwdKR9z4F4+/gBEFyqHPei7pKSnIwx1UhSYjwpKcmk\nJCeRkpKMg5OT1fuSV104foRiJcviWyQQgGqNmvHL3u2ZrnGxkmXpO30ZLu4eJCclce/uHdw8vQB4\nrHxl6r7aCTs7O+zs7SnyeCmi7jy6L0oP/nCIiuWfoHhwMABtWrVk85ZvM1zTh7UZ+P579O/TG4A7\nd+6QlJSEh0daQnXs+AkOHz1K246d6fLW2xz96Wcr9y7vOPzDDzxRvgJBwcUBaNmqNVu3bMk0dh/W\n7sTxX7Czs6dn9250ateGhfPnkpqayr3oaA4fPsSbb78NgH9AAPMXf4GXt5d1O5nHXD7xI4VLlMGn\ncNrzxdMNX+HU/szPF4UfL8PbUxbj7OZOSlISsZF3cPXwzNAmNSWZTXM+okGnd/Dy9edR9qAx+l02\nx/J3fxvL/+vejY7t2rDg97EMsP37rfj5FaJX337W7Vge9VxpP07djOZaxH0AQg5do/GTRR96zut1\nSnA3Lom1R64DUMjTmbrlA+i15EeLx5tf1f1fZw4uCuHH1ZtyO5R8z2Qy2dRXXpCtMsITJ05QqVKl\n9OPDhw9TrVo1iwVlCVF3wijo92e5VAG/QiTcjyMh/n6GUkLfgCL4BhQB0gbU+gUzqFitJg6OjlRv\n0Jif9+9k2OstMBpTKfdUNSpVq2n1vuRV0XfC8fb784WOl28hEuPjSIy/n6mU0N7BgdOH9/HVnI+x\nd3CiQduuAJR68tn0NlHhtzm4aS3Nuve3TgfyoNuhoRQO+HPcBvj7ExsXR1xcXHopobk2Dg4ODBo2\ngu+376B+3Rd4rHjai6sC3t683KQxDerV5adjx+jTfwAhy5dl+FmPitDQ2wT8pd+F/P2Ji4vlflxc\nhvKrh7VLTU3l2erV6dmnH4mJibzfpxfu7h5Uqvwkfn5+rFi2jB8O7Cc5OYn2HTsT/Pvv4VEVExGO\nl0+h9GNPn0Ikxd8nKf5+plJCewcHzh3dz7fzp2Lv6EitVl0y3H9817d4FPSlzLO1rBJ7XhYaehv/\nbI7lrNqlpqZS7S9juf/vY7ldh9do2ao1AJu++dp6ncrDCnu7EBqdkH4cdi8BTxdH3J0dMpUSAhRw\nc6RTrcdp/9n+9NvCYxJ5f/mj+2bXv2FlrxEAlGug12SS9zx0Zuvo0aOsXLmSAQMGsGrVKlatWsXy\n5csZPXq0teL715iMxgfebmf34EuQmBDPoknDCf/tJu17DgRgy8pFeHgXYNzSrxm9cB1xsffYsX6l\nxWK2NSZTzq5x+Wq1GLTwK+q36cKSsR9g/Mvv6ObFs3w+rA/V/9Ocss/UsEi8tiCrXX/s7O1z1GbC\nmFHs2fYd9+7dY87naaVa0z6eRIN6dQGo8tRTPFm5Mj8cOvwvRW5bsvqQxr9eQ3PtmrVoyXsDBuLk\n5ISnpyftXuvI7l07SElJ4dbNm7h7uDN34WJGj5/I9KlT+PXM6X+9H7Ykq+cLQxbPF2Wq1qT33LXU\nbNmZ1RMHZXhOP7JlLc83f80icdqa7DwfmGv397Hc/vexLJlltWQ7NYvr2/LZIHadCeVWZLwFoxKR\nvOShM1teXl7ppUfh4eEAGAwGBgwYYJXg/r82ffk5Jw+nvXuUcD+OIsVLpt8XHXEHNw9PnF1cM513\nNzyUeWMGUjioOL3GTcfp980Zjh/cw6tv98XB0TFtpqv+fzi2fxf1W7SzTofyoO0rF/Lr0QMAJMbf\nJyD4zwXAMXfDcXX3xOlv1zjit5vERt2l+BNps6VV6jXm63nTSIiLwc3Tm+P7d7Bx/ic0fbM3T9Zu\naL3O5EFFCgdw4uTJ9OOw8HC8vLxwc3XNVpv9B3+gdKmS+BcqhJubG41fasT3O3ZyLyaGVSFreatr\nlz83eDGZcHB4dPbMmT9nFvv27AYgLi6OEiVLpd8XHh6Gp5cXrq4Zx25A4cKcOnnige22bNpI6TJl\nKFU6bb2G6ffr6Vcobfam6cv/BSAwKJjKTz3F6VMnKfdEeYv2Ma/Zu2YxF348CKQ9XxQK+uvzxR1c\nHvB8EXn7JnHRkQSWrQhA5bovsXXhpyTExeLq6UXolQsYU1MJeqKy9TqSx8z721gumY2xXLhwYU7n\ncCxLmncalOaFJ9KqONydHbgQGpN+n7+XM9H3k0hITn3guS9VKsJHG89YJU4RS8jifTJ5iIc+e5Yp\nU4YyZcrQpk0b/P1trw6+6Wtv0fS1twCIiYpkYq8uhN26jn/RIPZt2UCl6plLTuJi7jF9UC+qN2hM\n4/ZdM9wXWLIMP+/bQZnKVUhNSeHEof08VraCVfqSVzVo9wYN2r0BQGx0JDP7v0nEbzfwLRLI4a3f\nUO7ZzFP6MVERhHwyhnc//hx3L29+2bcN/+DHcPP05uTB3WxeOIMuwz6mWMmy1u5OnlPjuepM/uRT\nrl67RvHgYELWrqPeC7Wz3Wbr99vYvmMnwwZ/SHJyMt99v40a1avj7ubGqpA1PFY8mBcb1OfMr2c5\nceo0Y0YOz41u5opuPd6lW493Abh79y6d2rXm+rWrBAUXZ8PaNdR+oW6mc6o9V4MZn0x9YLtLFy+y\na8d2xn80mZTkZNauXkWjxk0oWqwYZcs9weaN39C6XXvuRkRw4vgvvNb5det1No+o3ep1ard6HYC4\n6EgWfvg2d2/fwKdwIMe2b6TUA2axY6Pu8vXM8XSdMAc3T29O79+BX9BjuP6+zvPameMUr/DUI70r\n7Ns93uXtv4zljn8Zy+vXrqFOFmN5+l/G8l/b/XUsJycns2b1qgw7ET7qZm8/z+zt5wEo6O5ESO9a\nBPu6cS3iPq2qBbPrTNgDz/N0cSDI141frkVaM1wRyWUG00NWj/Xu3Zvp06dTq1bmpGTfvn3ZeoDv\nzj74SSc3nDp6kG+WziU1JQW/wkXp2G8o7p5eXDv/KytmTmLgp4v4bvVSNi9fQNHiJTKc23PMJwCs\nmfcJ1y+ew87OjjJPPkOLN3pin4vv+L1U1p/Vx2/l2uP/3bmffmDr8vmkpqTgE1CUV3sOws3Ti5sX\nz7Jh9sf8b/LnABz+7isOfbcBOzt7PH38eOXNPhQMKMK0Xh1JiIvF6/cNSgCCy1Xklbf65laXaFO5\nKIkxUbn2+Hv37efTz2aRnJxCUGAxxo0awY2btxg5dhwhy5dl2cbb25t7MTGMHT+R8xcvYTAYqF+3\nDu92fxs7OztOnT7DhI8nExd3HwcHewa815dqVavmSh+dPQsAEBFzP1ceH+DAvr3M+WwGyckpFAsM\nZPioMXh5e3Pm9Ckmjh3NkuWrHtouISGeKZMmcerkcVJSUqjf8EW6v9sTg8HA7du/MWXSRG7dvIHR\naKJt+w40f7WV1fvo6+nGwqPXrP64Wbl47BC7Vy0kNSWZgv5FafrOB7h6ePHbpbN8O38qXSfMBeDn\nbd/w0/dfY2dnh0dBX158vRcF/NPW1m5dNB2PAr483yJvlBG+UTWYu7k4jiFtjM7+2xj1/n0sTxg7\nmqV/GcsPapeQEM/kv43lHr+P5T9s+uZrdmzfxpRPMu90aGk+nm48PWSL1R83K7XKpG397mBvx427\n9xm25jj34pMpX8yL4S0q0W5mWoVN+WLeTGj7JM2m7snyZ/08rjH1xm3LE1u//zyuMT0Mj+V2GDli\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsn_comp_statusalphaalpha_statustrain_auroctest_aurocoverfit
589446914691200.0042634820max100OK0.7863020.791176-0.00487428
748614601460200.013698620max100OK0.8876950.6710070.216688
2512831283200.015588520max0.01OK0.8029080.5138340.289074
515924052405210.0087318120max100OK0.8173910.7830190.0343722
4763502502210.041832710min10OK0.7440260.3634020.380624
560433103310210.0063444110min10OK0.8381960.7378420.100354
206410641064210.019736820max1000OK0.7209060.3516750.369231
1956951951210.02208220max100OK0.8917740.8368980.0548758
749033603360210.0062510min0.1OK0.5907460.688623-0.0978768
597915591559210.013470220max1OK0.8079870.863636-0.0556498
477128132813210.0074653420max100OK0.8365690.5670840.269485
460936243624220.0060706420max100OK0.8681980.7780860.0901118
671451745174220.0042520320max1OK0.6506380.6180890.0325484
673774774220.028423820max0.001OK0.838140.7201990.117941
408737273727220.0059028720max0.1OK0.5476810.597709-0.0500282
20740114011230.0057342310min100OK0.8058860.819549-0.0136624
7157331331230.069486420max0.01OK0.6614720.5354840.125989
609817401740240.013793120max1OK0.8263120.2787170.547595
492119181918240.01251320max10000000OK0.7818660.6833770.0984882
379115021502250.016644510min10000OK0.7944120.816216-0.0218047
422127082708260.0096011820max100OK0.8478190.5039110.343908
5728769769260.033810120max1000000OK0.8187430.955705-0.136962
67510441044260.024904210min100000OK0.8237390.876471-0.0527313
67212391239270.021791820max1000000OK0.7618910.5465020.215389
23815281528310.02028810min1000000OK0.701520.782222-0.0807018
3265502502310.06175320max100OK0.9453190.8456140.0997051
489315661566330.021072820max1000OK0.8704040.941368-0.070964
592518911891370.019566420max1e-07OK0.7126860.6562980.0563876
102913711371370.026987620max1OK0.6239210.4600210.1639
1630687687400.058224220max100OK0.8309360.7173080.113628
.................................
7428189718971230.064839220max1e-08OK0.9798220.9424230.0373994
7428361836181250.034549520max0.0001OK0.9792980.9662370.013061
2064572757271260.02200120max100OK0.8204920.753720.0667716
1029165716571270.076644520max10OK0.8903450.8764820.0138631
3791490749071270.025881420max100OK0.7565950.6931660.0634284
38459779771290.13203720max100OK0.8926170.8649320.0276847
71572142141450.6775720max100OK0.8873040.6970440.19026
1029369936991800.048661820max100OK0.8901030.897372-0.00726953
675629962992000.031751120max100OK0.7242010.7122750.0119261
5290217821782000.091827420max100OK0.7793260.787247-0.00792146
3845343334332040.059423220max10OK0.9654540.974062-0.00860808
5728432743272080.048070320max1000OK0.7076350.743816-0.0361817
5925505550552100.04154320max10OK0.8291550.863974-0.034819
1956652565252150.032950220max100OK0.8144160.7486090.0658078
324156615662180.13920820max10OK0.9364780.9201180.0163599
1630675367532210.032726220max10OK0.7632950.7298120.0334832
4763573357332400.041862920max100OK0.7209490.6846190.0363302
1029588158812670.045400420max10OK0.8358550.84862-0.0127648
324343034302700.078717220max10OK0.8502050.8306080.0195972
7157109010903180.29174320max100OK0.9011990.8770290.0241697
673437443744010.091678120max10OK0.9427620.9393710.0033906
5290513051304130.080506820max10OK0.7898440.7762970.0135473
324695669564140.05951720max100OK0.8769640.8631260.0138382
673528652864620.087400720max10OK0.9325090.939418-0.0069097
3845565756574670.082552620max10OK0.9227650.934501-0.0117355
3845592559255000.084388220max10OK0.923940.925659-0.00171889
673682068205000.073313820max10OK0.9027320.912856-0.0101236
7157213521355010.2346620max10OK0.8726610.885535-0.0128737
5290597359735100.085384220max100OK0.7638110.7607140.00309695
7157207320735800.27978820max10OK0.8754550.878503-0.0030482
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsalphatrain_auroctest_aurocoverfit
mean3041.51124.6230.063901918.39621333070.809890.7531680.0567219
median2627810.0318417201000.8144160.7623380.0295182
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsalphatrain_auroctest_aurocoverfit
mean3041.51124.6230.063901942.27360.5374340.780070.71570.06437
median2627810.03184173510.769610.7184470.052919
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsalphatrain_auroctest_aurocoverfit
mean3041.51124.6230.063901942.27361191570.8369940.7750420.0619518
median2627810.0318417351000.8349540.7884170.0355583
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsn_comp_statusalphaalpha_statustrain_auroctest_aurocoverfit
589446914691200.0042634830min1e-05OK0.786520.822193-0.0356728
748614601460200.013698630min0.01OK0.8591580.7534720.105686
2512831283200.015588530min1000OK0.8591580.4772730.381886
515924052405210.0087318130min1000OK0.7806220.7720130.0086099
4763502502210.041832730min100000OK0.6832110.327320.355891
560433103310210.0063444130min1000OK0.852550.889058-0.0365078
206410641064210.019736830min1000OK0.742770.3480860.394684
1956951951210.02208230min100OK0.9076080.8288770.0787313
749033603360210.0062530min10000000OK0.7244920.796407-0.0719154
597915591559210.013470230min100000OK0.867910.895292-0.0273821
477128132813210.0074653430min100OK0.8587760.6104650.248311
460936243624220.0060706430min100OK0.8908940.8023580.0885365
671451745174220.0042520330min10000000OK0.793780.6333660.160414
673774774220.028423830min1000OK0.8227030.8162250.00647774
408737273727220.0059028730min0.1OK0.5513740.578841-0.0274666
20740114011230.0057342330min1000OK0.8230580.849624-0.0265659
7157331331230.069486430min1000OK0.7872630.896774-0.109511
609817401740240.013793130min100OK0.9053930.5405250.364869
492119181918240.01251330min1000000OK0.7848880.682850.102038
379115021502250.016644530min10000000OK0.8060970.812162-0.00606563
422127082708260.0096011830min0.0001OK0.8606730.4715080.389164
5728769769260.033810130min1000000OK0.8394260.959732-0.120306
67510441044260.024904230min100000OK0.8304080.90098-0.0705721
67212391239270.021791830min1000000OK0.77010.5522630.217837
23815281528310.02028830min1000000OK0.7214370.782222-0.0607853
3265502502310.06175330min10OK0.9742550.9122810.0619746
489315661566330.021072830min0.1OK0.871220.889251-0.0180311
592518911891370.019566430min0.0001OK0.6211430.737711-0.116569
102913711371370.026987630min1OK0.6099120.4365670.173345
1630687687400.058224230min1000OK0.8148570.7336540.0812035
.................................
7428189718971230.064839230min0.0001OK0.9815770.9476060.0339709
7428361836181250.034549530min1e-10min0.9788940.96990.0089942
2064572757271260.02200130min100OK0.8264030.7509720.075431
1029165716571270.076644530min100OK0.8807020.882866-0.00216486
3791490749071270.025881430min100OK0.7738580.69860.0752586
38459779771290.13203730min10OK0.9020390.8574660.0445731
71572142141450.6775730min100OK0.900470.6847290.215741
1029369936991800.048661830min100OK0.8910380.898003-0.00696588
675629962992000.031751130min100OK0.7357160.7219260.0137893
5290217821782000.091827430min10OK0.8267230.8200130.00670988
3845343334332040.059423230min10OK0.9681990.971834-0.00363484
5728432743272080.048070330min10OK0.7971220.806981-0.00985872
5925505550552100.04154330min10OK0.8652710.866529-0.00125774
1956652565252150.032950230min10OK0.8602940.7850220.0752716
324156615662180.13920830min10OK0.9407430.9220540.0186889
1630675367532210.032726230min10OK0.7803130.7349240.0453892
4763573357332400.041862930min100OK0.7267370.6853960.0413409
1029588158812670.045400450min10OK0.8693020.876956-0.00765312
324343034302700.078717250min100OK0.8527380.8329520.0197858
7157109010903180.29174350min100OK0.9067540.8824070.0243474
673437443744010.091678150min10OK0.960010.9523110.00769899
5290513051304130.080506850min10OK0.8326860.814090.0185963
324695669564140.05951750min100OK0.8834530.8637970.0196554
673528652864620.087400750min10OK0.954650.9511210.0035288
3845565756574670.082552650min10OK0.9421340.948224-0.00608928
3845592559255000.084388250min10OK0.9475220.9429030.00461924
673682068205000.073313850min10OK0.9383210.939074-0.00075356
7157213521355010.23466100min10OK0.922550.925382-0.0028321
5290597359735100.0853842100min10OK0.8457820.8080480.0377341
7157207320735800.279788100min10OK0.9101510.9045670.00558366
\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", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
num_samplesnum_positivebalancen_componentsalphatrain_auroctest_aurocoverfit
mean3041.51124.6230.063901933.86791.26733e+060.8310540.7760230.0550313
median2627810.0318417301000.8304080.7850220.0243272
\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() +