2337 lines (2336 with data), 172.9 kB
{
"cells": [
{
"cell_type": "markdown",
"metadata": {
"hide": true
},
"source": [
"import sklearn\n",
"import os\n",
"import seaborn as sns\n",
"import pandas as pd\n",
"import numpy as np\n",
"import matplotlib.pyplot as plt\n",
"# ^^^ pyforest auto-imports - don't write above this line\n",
"# Clinical Deterioration Prediction Model - Logistic Regression\n",
"$$\n",
"\\renewcommand{\\like}{{\\cal L}}\n",
"\\renewcommand{\\loglike}{{\\ell}}\n",
"\\renewcommand{\\err}{{\\cal E}}\n",
"\\renewcommand{\\dat}{{\\cal D}}\n",
"\\renewcommand{\\hyp}{{\\cal H}}\n",
"\\renewcommand{\\Ex}[2]{E_{#1}[#2]}\n",
"\\renewcommand{\\x}{{\\mathbf x}}\n",
"\\renewcommand{\\v}[1]{{\\mathbf #1}}\n",
"$$"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Data\n",
"\n",
"The final dataset used for the inferential statistics project includes unique ICU admission of 46,234 patients’ demographic (age), vital (blood pressure, heart rate, body temperature, and Glasgow Comma Scale), underlying conditions (HIV, metastatic cancer, and hematologic malignancy), admission type (scheduled surgical, medical, or unscheduled surgical), renal (urinary output, and Blood Urea Nitrogen), and others (serum bicarbonate level, sodium level, potassium level, and bilirubin level) data. This dataset is build based on the commonly used mortality prediction tool, Simplified Acute Physiology Score II (SAPSII)."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/plain": [
"'C:\\\\Users\\\\abebu\\\\Dropbox\\\\Data Science\\\\Projects\\\\Capstone Project 1\\\\Potential Projects\\\\9. MIMIC\\\\Machine Learning\\\\Clinical-Deterioration-Prediction-Model--Logistic-Regression'"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"os.getcwd()"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"os.chdir(\"C://Users/abebu/Google Drive/mimic-iii-clinical-database-1.4\")"
]
},
{
"cell_type": "code",
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os\\nimport pandas as pd'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"text/html": [
"<div>\n",
"<style scoped>\n",
" .dataframe tbody tr th:only-of-type {\n",
" vertical-align: middle;\n",
" }\n",
"\n",
" .dataframe tbody tr th {\n",
" vertical-align: top;\n",
" }\n",
"\n",
" .dataframe thead th {\n",
" text-align: right;\n",
" }\n",
"</style>\n",
"<table border=\"1\" class=\"dataframe\">\n",
" <thead>\n",
" <tr style=\"text-align: right;\">\n",
" <th></th>\n",
" <th>SUBJECT_ID</th>\n",
" <th>HADM_ID</th>\n",
" <th>ICUSTAY_ID</th>\n",
" <th>los</th>\n",
" <th>hdeath</th>\n",
" <th>death</th>\n",
" <th>admission</th>\n",
" <th>ud</th>\n",
" <th>bun</th>\n",
" <th>Bicarbonate</th>\n",
" <th>...</th>\n",
" <th>Sodium</th>\n",
" <th>Temp</th>\n",
" <th>Bilirubin</th>\n",
" <th>WBC</th>\n",
" <th>hr</th>\n",
" <th>gcs</th>\n",
" <th>bp</th>\n",
" <th>AGE</th>\n",
" <th>UO</th>\n",
" <th>saps2</th>\n",
" </tr>\n",
" </thead>\n",
" <tbody>\n",
" <tr>\n",
" <td>0</td>\n",
" <td>268</td>\n",
" <td>110404</td>\n",
" <td>280836</td>\n",
" <td>3.2490</td>\n",
" <td>1</td>\n",
" <td>1</td>\n",
" <td>8</td>\n",
" <td>0.0</td>\n",
" <td>6.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>11.0</td>\n",
" <td>26.0</td>\n",
" <td>13.0</td>\n",
" <td>12.0</td>\n",
" <td>0.0</td>\n",
" <td>82.0</td>\n",
" </tr>\n",
" <tr>\n",
" <td>1</td>\n",
" <td>269</td>\n",
" <td>106296</td>\n",
" <td>206613</td>\n",
" <td>3.2788</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>8</td>\n",
" <td>17.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>5.0</td>\n",
" <td>7.0</td>\n",
" <td>0.0</td>\n",
" <td>37.0</td>\n",
" </tr>\n",
" <tr>\n",
" <td>2</td>\n",
" <td>270</td>\n",
" <td>188028</td>\n",
" <td>220345</td>\n",
" <td>2.8939</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>11.0</td>\n",
" <td>0.0</td>\n",
" <td>13.0</td>\n",
" <td>18.0</td>\n",
" <td>0.0</td>\n",
" <td>45.0</td>\n",
" </tr>\n",
" <tr>\n",
" <td>3</td>\n",
" <td>271</td>\n",
" <td>173727</td>\n",
" <td>249196</td>\n",
" <td>2.0600</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>8</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>7.0</td>\n",
" <td>0.0</td>\n",
" <td>24.0</td>\n",
" </tr>\n",
" <tr>\n",
" <td>4</td>\n",
" <td>272</td>\n",
" <td>164716</td>\n",
" <td>210407</td>\n",
" <td>1.6202</td>\n",
" <td>0</td>\n",
" <td>0</td>\n",
" <td>8</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>...</td>\n",
" <td>0.0</td>\n",
" <td>3.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>0.0</td>\n",
" <td>5.0</td>\n",
" <td>12.0</td>\n",
" <td>0.0</td>\n",
" <td>28.0</td>\n",
" </tr>\n",
" </tbody>\n",
"</table>\n",
"<p>5 rows × 22 columns</p>\n",
"</div>"
],
"text/plain": [
" SUBJECT_ID HADM_ID ICUSTAY_ID los hdeath death admission ud \\\n",
"0 268 110404 280836 3.2490 1 1 8 0.0 \n",
"1 269 106296 206613 3.2788 0 0 8 17.0 \n",
"2 270 188028 220345 2.8939 0 0 0 0.0 \n",
"3 271 173727 249196 2.0600 0 0 8 0.0 \n",
"4 272 164716 210407 1.6202 0 0 8 0.0 \n",
"\n",
" bun Bicarbonate ... Sodium Temp Bilirubin WBC hr gcs bp \\\n",
"0 6.0 0.0 ... 0.0 0.0 0.0 0.0 11.0 26.0 13.0 \n",
"1 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 5.0 \n",
"2 0.0 0.0 ... 0.0 3.0 0.0 0.0 11.0 0.0 13.0 \n",
"3 0.0 0.0 ... 0.0 3.0 0.0 0.0 0.0 0.0 0.0 \n",
"4 0.0 0.0 ... 0.0 3.0 0.0 0.0 0.0 0.0 5.0 \n",
"\n",
" AGE UO saps2 \n",
"0 12.0 0.0 82.0 \n",
"1 7.0 0.0 37.0 \n",
"2 18.0 0.0 45.0 \n",
"3 7.0 0.0 24.0 \n",
"4 12.0 0.0 28.0 \n",
"\n",
"[5 rows x 22 columns]"
]
},
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"saps = pd.read_csv(\"saps_ts.csv\", header=0, index_col=0)\n",
"saps.head()"
]
},
{
"cell_type": "code",
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os\\nimport pandas as pd'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"saps = pd.get_dummies(saps, columns=['Potassium', 'Sodium',\n",
" 'WBC', 'hr', 'bp']) "
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {},
"outputs": [],
"source": [
"saps.to_csv('saps_ts.csv')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"First, run logistics regression using saps2 (the sum of all features) as explantory variable and death at ICU (hdeath - hospital death) as target variable. "
]
},
{
"cell_type": "code",
"execution_count": 12,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dimensions of y before reshaping: (61117,)\n",
"Dimensions of X before reshaping: (61117,)\n",
"Dimensions of y after reshaping: (61117,)\n",
"Dimensions of X after reshaping: (61117, 1)\n"
]
}
],
"source": [
"# Create arrays for features and target variable\n",
"y = saps['hdeath'].values\n",
"X = saps['saps2'].values\n",
"\n",
"# Print the dimensions of X and y before reshaping\n",
"print(\"Dimensions of y before reshaping: {}\".format(y.shape))\n",
"print(\"Dimensions of X before reshaping: {}\".format(X.shape))\n",
"\n",
"# Reshape X and y\n",
"#y = y.reshape(-1, 1)\n",
"X = X.reshape(-1, 1)\n",
"\n",
"# Print the dimensions of X and y after reshaping\n",
"print(\"Dimensions of y after reshaping: {}\".format(y.shape))\n",
"print(\"Dimensions of X after reshaping: {}\".format(X.shape))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"\n",
"* Split the data into a training and test (hold-out) set\n",
"* Train on the training set, and test for accuracy on the testing set"
]
},
{
"cell_type": "code",
"execution_count": 13,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training Accuracy: 0.9077164735912037\n",
"Testing Accuracy: 0.9036649214659686\n"
]
}
],
"source": [
"from sklearn.model_selection import train_test_split\n",
"from sklearn.linear_model import LogisticRegression\n",
"from sklearn.metrics import accuracy_score\n",
"\n",
"# Split the data into a training and test set.\n",
"Xlr, Xtestlr, ylr, ytestlr = train_test_split(X, y,random_state=5)\n",
"\n",
"clf = LogisticRegression(solver='lbfgs')\n",
"# Fit the model on the trainng data.\n",
"clf.fit(Xlr, ylr)\n",
"\n",
"# Print the accuracy\n",
"print('Training Accuracy: {}'.format((accuracy_score(clf.predict(Xlr), ylr))))\n",
"print('Testing Accuracy: {}'.format((accuracy_score(clf.predict(Xtestlr), ytestlr))))\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Hyperparameter Tuning "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The model has some hyperparameters we can tune for hopefully better performance. In Logistic Regression, the most important parameter to tune is the *regularization parameter* `C`. Note that the regularization parameter is not always part of the logistic regression model. The regularization parameter is used to control for unlikely high regression coefficients, and in other cases can be used when data is sparse, as a method of feature selection. We may not need this for our model but worth checking. \n"
]
},
{
"cell_type": "code",
"execution_count": 14,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import KFold\n",
"from sklearn.metrics import accuracy_score\n",
"\n",
"def cv_score(clf, x, y, score_func=accuracy_score):\n",
" result = 0\n",
" nfold = 5\n",
" for train, test in KFold(nfold).split(x): # split data into train/test groups, 5 times\n",
" clf.fit(x[train], y[train]) # fit\n",
" result += score_func(clf.predict(x[test]), y[test]) # evaluate score function on held-out data\n",
" return result / nfold # average"
]
},
{
"cell_type": "code",
"execution_count": 15,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.9079345258458951\n"
]
}
],
"source": [
"clf = LogisticRegression(solver='lbfgs')\n",
"score = cv_score(clf, Xlr, ylr)\n",
"print(score)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Using the `cv_score` function (5-fold cross validation) for a basic logistic regression model without regularization,the score on the held-out data (test data) is `0.908`, `91%`. "
]
},
{
"cell_type": "code",
"execution_count": 16,
"metadata": {
"scrolled": true
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"score: 0.9079345258458951, C:0.01\n",
"score: 0.9079345258458951, C:0.1\n",
"score: 0.9079345258458951, C:1\n",
"score: 0.9079345258458951, C:10\n",
"score: 0.9079345258458951, C:100\n",
"\n",
"The Maximum score with training data is 0.9079345258458951 for a C value of 0.01.\n"
]
}
],
"source": [
"#the grid of parameters to search over\n",
"Cs = [0.01, 0.1, 1, 10, 100]\n",
"max_score = 0\n",
"for c in Cs:\n",
" clf=LogisticRegression(solver='lbfgs', C=c)\n",
" score = cv_score(clf, Xlr, ylr)\n",
" print(f'score: {score}, C:{c}')\n",
" if score > max_score:\n",
" max_score = score\n",
" max_C = c\n",
"print(f'\\nThe Maximum score with training data is {max_score} for a C value of {max_C}.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Based on the training set the best model parameter is 0.9079345258458951 for a C value of 0.01."
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The accuracy with the test data is 0.9036649214659686.\n"
]
}
],
"source": [
"clf =LogisticRegression(solver='lbfgs', C=max_C)\n",
"# Fit the model on teh training data\n",
"clf.fit(Xlr, ylr)\n",
"# Print the accuracy from the test data\n",
"print(f'The accuracy with the test data is {accuracy_score(clf.predict(Xtestlr), ytestlr)} for a C value of {max_C}.')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Running the model with C=0.01 gives as the same accuracy results on the test data as the deafult. This is not always the case hence important to experment with the hyperparameters that works best with new data. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Grid Search"
]
},
{
"cell_type": "code",
"execution_count": 18,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Best score on training data: 0.9080219037022492 using {'C': 0.1, 'penalty': 'l2', 'solver': 'liblinear'}\n"
]
}
],
"source": [
"from sklearn.model_selection import GridSearchCV\n",
"\n",
"model = LogisticRegression(max_iter=1000)\n",
"\n",
"# define parameter values\n",
"solvers = ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga']\n",
"penalty = ['none', 'l1', 'l2', 'elasticnet']\n",
"c_values = [100, 10, 1.0, 0.1, 0.01]\n",
"\n",
"# define grid search\n",
"grid = dict(solver=solvers,penalty=penalty,C=c_values)\n",
"grid_search = GridSearchCV(estimator=model, param_grid=grid, n_jobs=-1, cv=5, scoring='accuracy', error_score=0)\n",
"grid_result = grid_search.fit(Xlr, ylr)\n",
"\n",
"# summarize results\n",
"print(f\"Best score on training data: {grid_result.best_score_} using {grid_result.best_params_}\")"
]
},
{
"cell_type": "code",
"execution_count": 19,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Score on test data: 0.9044502617801047\n"
]
}
],
"source": [
"print(f'Score on test data: {accuracy_score(grid_result.predict(Xtestlr), ytestlr)}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It gives a diffrent best value of C - this time 0.1. The GridSearchCV performs slightly better on test data (0.9036 vs 0.9044), almost the same. "
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's first set some code up for classification that we will need for further discussion on the math. We first set up a function `cv_optimize` which takes a classifier `clf`, a grid of hyperparameters (such as a complexity parameter or regularization parameter) implemented as a dictionary `parameters`, a training set (as a samples x features array) `Xtrain`, and a set of labels `ytrain`. The code takes the traning set, splits it into `n_folds` parts, sets up `n_folds` folds, and carries out a cross-validation by splitting the training set into a training and validation section for each foldfor us. It prints the best value of the parameters, and retuens the best classifier to us."
]
},
{
"cell_type": "code",
"execution_count": 20,
"metadata": {},
"outputs": [],
"source": [
"def cv_optimize(clf, parameters, Xtrain, ytrain, n_folds=5):\n",
" gs = sklearn.model_selection.GridSearchCV(clf, param_grid=parameters, cv=n_folds)\n",
" gs.fit(Xtrain, ytrain)\n",
" print(\"BEST PARAMS\", gs.best_params_)\n",
" best = gs.best_estimator_\n",
" return best"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We then use this best classifier to fit the entire training set. This is done inside the `do_classify` function which takes a dataframe `indf` as input. It takes the columns in the list `featurenames` as the features used to train the classifier. The column `targetname` sets the target. The classification is done by setting those samples for which `targetname` has value `target1val` to the value 1, and all others to 0. We split the dataframe into 80% training and 20% testing by default, standardizing the dataset if desired. (Standardizing a data set involves scaling the data so that it has 0 mean and is described in units of its standard deviation. We then train the model on the training set using cross-validation. Having obtained the best classifier using `cv_optimize`, we retrain on the entire training set and calculate the training and testing accuracy, which we print. We return the split data and the trained classifier."
]
},
{
"cell_type": "code",
"execution_count": 21,
"metadata": {
"hide": true
},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"def do_classify(clf, parameters, indf, featurenames, targetname, target1val, standardize=False, train_size=0.8):\n",
" subdf=indf[featurenames]\n",
" if standardize:\n",
" subdfstd=(subdf - subdf.mean())/subdf.std()\n",
" else:\n",
" subdfstd=subdf\n",
" X=subdfstd.values\n",
" y=(indf[targetname].values==target1val)*1\n",
" Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, train_size=train_size)\n",
" clf = cv_optimize(clf, parameters, Xtrain, ytrain)\n",
" clf=clf.fit(Xtrain, ytrain)\n",
" training_accuracy = clf.score(Xtrain, ytrain)\n",
" test_accuracy = clf.score(Xtest, ytest)\n",
" print(\"Accuracy on training data: {:0.2f}\".format(training_accuracy))\n",
" print(\"Accuracy on test data: {:0.2f}\".format(test_accuracy))\n",
" return clf, Xtrain, ytrain, Xtest, ytest"
]
},
{
"cell_type": "code",
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os\\nimport sklearn\\nimport matplotlib.pyplot as plt\\nimport pandas as pd'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"BEST PARAMS {'C': 0.01}\n",
"Accuracy on training data: 0.91\n",
"Accuracy on test data: 0.90\n"
]
}
],
"source": [
"clf_l, Xtrain_l, ytrain_l, Xtest_l, ytest_l = do_classify(LogisticRegression(solver='lbfgs'), \n",
" {\"C\": [0.01, 0.1, 1, 10, 100]}, \n",
" saps, ['saps2'], 'hdeath',1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Standardize"
]
},
{
"cell_type": "code",
"execution_count": 100,
"metadata": {
"hide": true
},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"def do_classify(clf, parameters, indf, featurenames, targetname, target1val, standardize=True, train_size=0.8):\n",
" subdf=indf[featurenames]\n",
" if standardize:\n",
" subdfstd=(subdf - subdf.mean())/subdf.std()\n",
" else:\n",
" subdfstd=subdf\n",
" X=subdfstd.values\n",
" y=(indf[targetname].values==target1val)*1\n",
" Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, train_size=train_size)\n",
" clf = cv_optimize(clf, parameters, Xtrain, ytrain)\n",
" clf=clf.fit(Xtrain, ytrain)\n",
" training_accuracy = clf.score(Xtrain, ytrain)\n",
" test_accuracy = clf.score(Xtest, ytest)\n",
" print(\"Accuracy on training data: {:0.2f}\".format(training_accuracy))\n",
" print(\"Accuracy on test data: {:0.2f}\".format(test_accuracy))\n",
" return clf, Xtrain, ytrain, Xtest, ytest"
]
},
{
"cell_type": "code",
"execution_count": 101,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport seaborn as sns\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"BEST PARAMS {'C': 0.01}\n",
"Accuracy on training data: 0.91\n",
"Accuracy on test data: 0.91\n"
]
}
],
"source": [
"clf_l, Xtrain_l, ytrain_l, Xtest_l, ytest_l = do_classify(LogisticRegression(solver='lbfgs'), \n",
" {\"C\": [0.01, 0.1, 1, 10, 100]}, \n",
" saps, ['saps2'], 'hdeath',1)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### ROC Curve\n",
"`Plotting an ROC curve - receiver operating characteristic `"
]
},
{
"cell_type": "code",
"execution_count": 24,
"metadata": {},
"outputs": [],
"source": [
"def make_roc(name, clf, ytest, xtest, ax=None, labe=5, proba=True, skip=0):\n",
" initial=False\n",
" if not ax:\n",
" ax=plt.gca()\n",
" initial=True\n",
" if proba:\n",
" fpr, tpr, thresholds=roc_curve(ytest, clf.predict_proba(xtest)[:,1])\n",
" else:\n",
" fpr, tpr, thresholds=roc_curve(ytest, clf.decision_function(xtest))\n",
" roc_auc = auc(fpr, tpr)\n",
" if skip:\n",
" l=fpr.shape[0]\n",
" ax.plot(fpr[0:l:skip], tpr[0:l:skip], 'o-', alpha=0.8, label='ROC curve for %s (area = %0.2f)' % (name, roc_auc))\n",
" else:\n",
" ax.plot(fpr, tpr, '.-', alpha=0.8, label='ROC curve for %s (area = %0.2f)' % (name, roc_auc))\n",
" label_kwargs = {}\n",
" label_kwargs['bbox'] = dict(\n",
" boxstyle='round,pad=0.1', alpha=0.1,\n",
" )\n",
" for k in range(0, fpr.shape[0],labe):\n",
" #from https://gist.github.com/podshumok/c1d1c9394335d86255b8\n",
" threshold = str(np.round(thresholds[k], 2))\n",
" ax.annotate(threshold, (fpr[k], tpr[k]), **label_kwargs)\n",
" if initial:\n",
" ax.plot([0, 1], [0, 1], 'k--')\n",
" ax.set_xlim([0.0, 1.0])\n",
" ax.set_ylim([0.0, 1.05])\n",
" ax.set_xlabel('False Positive Rate')\n",
" ax.set_ylabel('True Positive Rate')\n",
" ax.set_title('ROC')\n",
" ax.legend(loc=\"lower right\")\n",
" return ax"
]
},
{
"cell_type": "code",
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os\\nimport sklearn\\nimport matplotlib.pyplot as plt\\nimport pandas as pd'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import os\\nimport sklearn\\nimport matplotlib.pyplot as plt\\nimport pandas as pd'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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Nm2ibdu2NG3alLZt27Jv375s34ucWrVqFYMHDwZg8ODBrFy58op9jDEkJyeTkpLChQsXcDqdlC9fHnD//syePZspU6Zccsytt97K6dOnOXHixE3HeC1eNybNxxhqlCtOmrVsiDrDqDy4RnJyMoGBgVSpUoWwsDAWLFhAt27d8uBKIiKe9491UUT9ej7b7V/uiSU5JRVfhw8XO4xSXWlM+M8OOtfP+n+Ua5QtziM57OlwuVx8+eWXPPzww4A7qWjWrNkl+9SsWZPz589z7tw5du7cydixY6953unTpxMaGspPP/0EkG13V2b79+9n9erVOBwO0tLSWLFiBUOHDuX777+nWrVqlC9fngEDBvDUU0/Rrl07jhw5Qrdu3dizZ88l54mMjKRnz55s27YNICPZ6dChA1OnTuUvf/kLc+bMAdytWplbb7IyYsQIBg0axODBg1m8eDGjRo1i5cqVPPnkkzz55JP079+fhQsXZnnswoULefLJJxk4cCApKSm4XC5mzZrFzp07M+I7fPhwxv6LFi3i0KFD/Pjjj/j6+nLmzJkrzvntt99e0j06YsQIpk6dCsAf//hHPvzwQ+65554rXl927129evVYt24dvr6+rF69mkmTJmUk1RclJCRwxx13ZPka33nnHRo0aHDJcydPnqRChQoAVKhQgdjYK/+nok2bNnTq1IkKFSpgrWXEiBHUr18fgGeffZaxY8dmudbpbbfdxrfffsv999+fZTy5xeuSNHAnagG+Prk+aeDQoUNMnDiR48ePs3btWm655RY2bNiQq9cQEfE2v11Ixd9x6aBoh4/htws3132VlJREREQEhw8fplmzZnTp0gW4dILW5a5ncPbq1atZtmxZxuNSpUpd85jf//73GeOM+/Xrx7Rp0xg6dCjLli2jX79+GefdvXt3xjHnzp0jISGBkJCQLM8ZHx9PXFwcHTp0ANytOr///e8ztl8879Vs2LCBDz74AHAnQRMmTMh4/mIL0YABA7Icm9emTRtmzpxJdHQ0ffr0oXbt2le91urVqxk+fDi+vu4UoXTp0lfsc/z4ccqVK5fx+Ouvv+aFF14gMTGRM2fO0LBhw4wkLfPry+69i4+PZ/DgwRw4cABjDE6n84prhoSEZCSVueXgwYPs2bOH6OhoALp06cK6desoUaIEBw8e5KWXXrokgb0oLCyMmJiYXI0lK16X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\n",
"text/plain": [
"<Figure size 720x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"from sklearn.metrics import roc_curve, auc\n",
"plt.figure(figsize=(10,6))\n",
"ax=make_roc(\"logistic\", clf_l, ytest_l, Xtest_l, labe=200, skip=2)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Cross Validation Score\n",
"\n",
"we should evaluate the performance of an algorithm rigorously by using resampling approaches (e.g. 100 times 5-fold cross-validation) to get some measurement of the variability in the performance of the algorithm. Maybe on a particular hold-out set, two algorithms have very similar performance but the variability of their estimates is massively different. That has serious implication on when we deploy our model in the future or use it to draw conclusion about future performance."
]
},
{
"cell_type": "code",
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"AUC scores computed using 5-fold cross-validation: [0.84631633 0.81585015 0.85512388 0.85891427 0.84046901]\n"
]
}
],
"source": [
"# Import necessary modules\n",
"from sklearn.model_selection import cross_val_score\n",
"\n",
"# Compute cross-validated AUC scores: cv_auc\n",
"cv_auc = cross_val_score(clf_l, Xtest_l, ytest_l.ravel(), cv=5, scoring='roc_auc')\n",
"\n",
"# Print list of AUC scores\n",
"print(\"AUC scores computed using 5-fold cross-validation: {}\".format(cv_auc))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Run class_weight "
]
},
{
"cell_type": "code",
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"['SUBJECT_ID',\n",
" 'HADM_ID',\n",
" 'ICUSTAY_ID',\n",
" 'los',\n",
" 'hdeath',\n",
" 'death',\n",
" 'admission',\n",
" 'ud',\n",
" 'bun',\n",
" 'Bicarbonate',\n",
" 'ventilation',\n",
" 'Temp',\n",
" 'Bilirubin',\n",
" 'gcs',\n",
" 'AGE',\n",
" 'UO',\n",
" 'saps2',\n",
" 'Potassium_0.0',\n",
" 'Potassium_3.0',\n",
" 'Sodium_0.0',\n",
" 'Sodium_1.0',\n",
" 'Sodium_5.0',\n",
" 'WBC_0.0',\n",
" 'WBC_3.0',\n",
" 'hr_0.0',\n",
" 'hr_2.0',\n",
" 'hr_4.0',\n",
" 'hr_7.0',\n",
" 'hr_11.0',\n",
" 'bp_0.0',\n",
" 'bp_2.0',\n",
" 'bp_5.0',\n",
" 'bp_13.0']"
]
},
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"list(saps.columns)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Dimensions of y before reshaping: (61117,)\n",
"Dimensions of X before reshaping: (61117, 26)\n",
"Dimensions of y after reshaping: (61117, 1)\n",
"Dimensions of X after reshaping: (61117, 26)\n"
]
}
],
"source": [
"# Create arrays for features and target variable\n",
"y = saps['hdeath'].values\n",
"X = saps[['admission',\n",
" 'ud',\n",
" 'bun',\n",
" 'Bicarbonate',\n",
" 'ventilation',\n",
" 'Temp',\n",
" 'Bilirubin',\n",
" 'gcs',\n",
" 'AGE',\n",
" 'UO',\n",
" 'Potassium_0.0',\n",
" 'Potassium_3.0',\n",
" 'Sodium_0.0',\n",
" 'Sodium_1.0',\n",
" 'Sodium_5.0',\n",
" 'WBC_0.0',\n",
" 'WBC_3.0',\n",
" 'hr_0.0',\n",
" 'hr_2.0',\n",
" 'hr_4.0',\n",
" 'hr_7.0',\n",
" 'hr_11.0',\n",
" 'bp_0.0',\n",
" 'bp_2.0',\n",
" 'bp_5.0',\n",
" 'bp_13.0']].values\n",
"# Print the dimensions of X and y before reshaping\n",
"print(\"Dimensions of y before reshaping: {}\".format(y.shape))\n",
"print(\"Dimensions of X before reshaping: {}\".format(X.shape))\n",
"\n",
"# Reshape X and y\n",
"y = y.reshape(-1, 1)\n",
"#X = X.reshape(-1, 1)\n",
"\n",
"# Print the dimensions of X and y after reshaping\n",
"print(\"Dimensions of y after reshaping: {}\".format(y.shape))\n",
"print(\"Dimensions of X after reshaping: {}\".format(X.shape))\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Training Accuracy: 0.9216135436437812\n",
"Testing Accuracy: 0.918913612565445\n"
]
}
],
"source": [
"# Split the data into a training and test set.\n",
"Xlr, Xtestlr, ylr, ytestlr = train_test_split(X, y.ravel(),random_state=5)\n",
"\n",
"clf = LogisticRegression(solver='lbfgs', max_iter=1000)\n",
"# Fit the model on the trainng data.\n",
"clf.fit(Xlr, ylr)\n",
"\n",
"# Print the accuracy\n",
"print('Training Accuracy: {}'.format((accuracy_score(clf.predict(Xlr), ylr))))\n",
"print('Testing Accuracy: {}'.format((accuracy_score(clf.predict(Xtestlr), ytestlr))))\n"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
"def cv_score(clf, x, y, score_func=accuracy_score):\n",
" result = 0\n",
" nfold = 5\n",
" for train, test in KFold(nfold).split(x): # split data into train/test groups, 5 times\n",
" clf.fit(x[train], y[train]) # fit\n",
" result += score_func(clf.predict(x[test]), y[test]) # evaluate score function on held-out data\n",
" return result / nfold # average"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[1],\n",
" [0],\n",
" [0],\n",
" ...,\n",
" [0],\n",
" [0],\n",
" [0]], dtype=int64)"
]
},
"execution_count": 66,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"y"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"<class 'pandas.core.frame.DataFrame'>\n",
"Int64Index: 61117 entries, 0 to 61116\n",
"Data columns (total 33 columns):\n",
"SUBJECT_ID 61117 non-null int64\n",
"HADM_ID 61117 non-null int64\n",
"ICUSTAY_ID 61117 non-null int64\n",
"los 61117 non-null float64\n",
"hdeath 61117 non-null int64\n",
"death 61117 non-null int64\n",
"admission 61117 non-null int64\n",
"ud 61117 non-null float64\n",
"bun 61117 non-null float64\n",
"Bicarbonate 61117 non-null float64\n",
"ventilation 61117 non-null float64\n",
"Temp 61117 non-null float64\n",
"Bilirubin 61117 non-null float64\n",
"gcs 61117 non-null float64\n",
"AGE 61117 non-null float64\n",
"UO 61117 non-null float64\n",
"saps2 61117 non-null float64\n",
"Potassium_0.0 61117 non-null int64\n",
"Potassium_3.0 61117 non-null int64\n",
"Sodium_0.0 61117 non-null int64\n",
"Sodium_1.0 61117 non-null int64\n",
"Sodium_5.0 61117 non-null int64\n",
"WBC_0.0 61117 non-null int64\n",
"WBC_3.0 61117 non-null int64\n",
"hr_0.0 61117 non-null int64\n",
"hr_2.0 61117 non-null int64\n",
"hr_4.0 61117 non-null int64\n",
"hr_7.0 61117 non-null int64\n",
"hr_11.0 61117 non-null int64\n",
"bp_0.0 61117 non-null int64\n",
"bp_2.0 61117 non-null int64\n",
"bp_5.0 61117 non-null int64\n",
"bp_13.0 61117 non-null int64\n",
"dtypes: float64(11), int64(22)\n",
"memory usage: 15.9 MB\n"
]
}
],
"source": [
"saps.info()"
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
}
],
"source": [
"saps['Potassium_0.0'] = saps['Potassium_0.0'].astype(np.int64)\n",
"saps['Potassium_3.0'] = saps['Potassium_3.0'].astype(np.int64)\n",
"saps['Sodium_0.0'] = saps['Sodium_0.0'].astype(np.int64)\n",
"saps['Sodium_1.0'] = saps['Sodium_1.0'].astype(np.int64)\n",
"saps['Sodium_5.0'] = saps['Sodium_5.0'].astype(np.int64)\n",
"saps['WBC_0.0'] = saps['WBC_0.0'].astype(np.int64)\n",
"saps['WBC_3.0'] = saps['WBC_3.0'].astype(np.int64)\n",
"saps['hr_0.0'] = saps['hr_0.0'].astype(np.int64)\n",
"saps['hr_2.0'] = saps['hr_2.0'].astype(np.int64)\n",
"saps['hr_4.0'] = saps['hr_4.0'].astype(np.int64)\n",
"saps['hr_7.0'] = saps['hr_7.0'].astype(np.int64)\n",
"saps['hr_11.0'] = saps['hr_11.0'].astype(np.int64)\n",
"saps['bp_0.0'] = saps['bp_0.0'].astype(np.int64)\n",
"saps['bp_2.0'] = saps['bp_2.0'].astype(np.int64)\n",
"saps['bp_5.0'] = saps['bp_5.0'].astype(np.int64)\n",
"saps['bp_13.0'] = saps['bp_13.0'].astype(np.int64)"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0.9214825696009912\n"
]
}
],
"source": [
"score = cv_score(clf, Xlr, ylr)\n",
"print(score)"
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"score: 0.921002639409019, C:0.01\n",
"score: 0.9214171293342783, C:0.1\n",
"score: 0.9214825696009912, C:1\n",
"score: 0.9215043846097171, C:10\n",
"score: 0.9215262019981758, C:100\n",
"\n",
"The Maximum score with training data is 0.9215262019981758 for a C value of 100.\n"
]
}
],
"source": [
"#the grid of parameters to search over\n",
"Cs = [0.01, 0.1, 1, 10, 100]\n",
"max_score = 0\n",
"for c in Cs:\n",
" clf=LogisticRegression(solver='lbfgs', max_iter=1000, C=c)\n",
" score = cv_score(clf, Xlr, ylr)\n",
" print(f'score: {score}, C:{c}')\n",
" if score > max_score:\n",
" max_score = score\n",
" max_C = c\n",
"print(f'\\nThe Maximum score with training data is {max_score} for a C value of {max_C}.')"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"The accuracy with the test data is 0.919044502617801.\n"
]
}
],
"source": [
"clf =LogisticRegression(solver='lbfgs', max_iter=1000, C=max_C)\n",
"# Fit the model on teh training data\n",
"clf.fit(Xlr, ylr)\n",
"# Print the accuracy from the test data\n",
"print(f'The accuracy with the test data is {accuracy_score(clf.predict(Xtestlr), ytestlr)}.')"
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Best score on training data: 0.9215480943342714 using {'C': 0.1, 'penalty': 'l1', 'solver': 'liblinear'}\n"
]
}
],
"source": [
"model = LogisticRegression(max_iter=1000)\n",
"\n",
"# define parameter values\n",
"solvers = ['newton-cg', 'lbfgs', 'liblinear', 'sag', 'saga']\n",
"penalty = ['none', 'l1', 'l2', 'elasticnet']\n",
"c_values = [100, 10, 1.0, 0.1, 0.01]\n",
"\n",
"# define grid search\n",
"grid = dict(solver=solvers,penalty=penalty,C=c_values)\n",
"grid_search = GridSearchCV(estimator=model, param_grid=grid, n_jobs=-1, cv=5, scoring='accuracy', error_score=0)\n",
"grid_result = grid_search.fit(Xlr, ylr)\n",
"\n",
"# summarize results\n",
"print(f\"Best score on training data: {grid_result.best_score_} using {grid_result.best_params_}\")"
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Score on test data: 0.918782722513089\n"
]
}
],
"source": [
"print(f'Score on test data: {accuracy_score(grid_result.predict(Xtestlr), ytestlr)}')"
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [],
"source": [
"def cv_optimize(clf, parameters, Xtrain, ytrain, n_folds=5):\n",
" gs = sklearn.model_selection.GridSearchCV(clf, param_grid=parameters, cv=n_folds)\n",
" gs.fit(Xtrain, ytrain)\n",
" print(\"BEST PARAMS\", gs.best_params_)\n",
" best = gs.best_estimator_\n",
" return best"
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [],
"source": [
"from sklearn.model_selection import train_test_split\n",
"\n",
"def do_classify(clf, parameters, indf, featurenames, targetname, target1val, standardize=False, train_size=0.8):\n",
" subdf=indf[featurenames]\n",
" if standardize:\n",
" subdfstd=(subdf - subdf.mean())/subdf.std()\n",
" else:\n",
" subdfstd=subdf\n",
" X=subdfstd.values\n",
" y=(indf[targetname].values==target1val)*1\n",
" Xtrain, Xtest, ytrain, ytest = train_test_split(X, y, train_size=train_size)\n",
" clf = cv_optimize(clf, parameters, Xtrain, ytrain)\n",
" clf=clf.fit(Xtrain, ytrain)\n",
" training_accuracy = clf.score(Xtrain, ytrain)\n",
" test_accuracy = clf.score(Xtest, ytest)\n",
" print(\"Accuracy on training data: {:0.2f}\".format(training_accuracy))\n",
" print(\"Accuracy on test data: {:0.2f}\".format(test_accuracy))\n",
" return clf, Xtrain, ytrain, Xtest, ytest"
]
},
{
"cell_type": "code",
"execution_count": 80,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"BEST PARAMS {'C': 10}\n",
"Accuracy on training data: 0.92\n",
"Accuracy on test data: 0.92\n"
]
}
],
"source": [
"clf_l, Xtrain_l, ytrain_l, Xtest_l, ytest_l = do_classify(LogisticRegression(solver='lbfgs', max_iter=2000), \n",
" {\"C\": [0.01, 0.1, 1, 10, 100]}, \n",
" saps, ['admission',\n",
" 'ud',\n",
" 'bun',\n",
" 'Bicarbonate',\n",
" 'ventilation',\n",
" 'Temp',\n",
" 'Bilirubin',\n",
" 'gcs',\n",
" 'AGE',\n",
" 'UO',\n",
" 'Potassium_0.0',\n",
" 'Potassium_3.0',\n",
" 'Sodium_0.0',\n",
" 'Sodium_1.0',\n",
" 'Sodium_5.0',\n",
" 'WBC_0.0',\n",
" 'WBC_3.0',\n",
" 'hr_0.0',\n",
" 'hr_2.0',\n",
" 'hr_4.0',\n",
" 'hr_7.0',\n",
" 'hr_11.0',\n",
" 'bp_0.0',\n",
" 'bp_2.0',\n",
" 'bp_5.0',\n",
" 'bp_13.0'], 'hdeath',1)"
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [],
"source": [
"def make_roc(name, clf, ytest, xtest, ax=None, labe=5, proba=True, skip=0):\n",
" initial=False\n",
" if not ax:\n",
" ax=plt.gca()\n",
" initial=True\n",
" if proba:\n",
" fpr, tpr, thresholds=roc_curve(ytest, clf.predict_proba(xtest)[:,1])\n",
" else:\n",
" fpr, tpr, thresholds=roc_curve(ytest, clf.decision_function(xtest))\n",
" roc_auc = auc(fpr, tpr)\n",
" if skip:\n",
" l=fpr.shape[0]\n",
" ax.plot(fpr[0:l:skip], tpr[0:l:skip], 'o-', alpha=0.8, label='ROC curve for %s (area = %0.2f)' % (name, roc_auc))\n",
" else:\n",
" ax.plot(fpr, tpr, '.-', alpha=0.8, label='ROC curve for %s (area = %0.2f)' % (name, roc_auc))\n",
" label_kwargs = {}\n",
" label_kwargs['bbox'] = dict(\n",
" boxstyle='round,pad=0.1', alpha=0.1,\n",
" )\n",
" for k in range(0, fpr.shape[0],labe):\n",
" #from https://gist.github.com/podshumok/c1d1c9394335d86255b8\n",
" threshold = str(np.round(thresholds[k], 2))\n",
" ax.annotate(threshold, (fpr[k], tpr[k]), **label_kwargs)\n",
" if initial:\n",
" ax.plot([0, 1], [0, 1], 'k--')\n",
" ax.set_xlim([0.0, 1.0])\n",
" ax.set_ylim([0.0, 1.05])\n",
" ax.set_xlabel('False Positive Rate')\n",
" ax.set_ylabel('True Positive Rate')\n",
" ax.set_title('ROC')\n",
" ax.legend(loc=\"lower right\")\n",
" return ax"
]
},
{
"cell_type": "code",
"execution_count": 81,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 720x432 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"plt.figure(figsize=(10,6))\n",
"ax=make_roc(\"logistic\", clf_l, ytest_l, Xtest_l, labe=200, skip=2)"
]
},
{
"cell_type": "code",
"execution_count": 79,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"AUC scores computed using 5-fold cross-validation: [0.86265553 0.88734978 0.86138377 0.87400611 0.85694651]\n"
]
}
],
"source": [
"# Compute cross-validated AUC scores: cv_auc\n",
"cv_auc = cross_val_score(clf_l, Xtest_l, ytest_l.ravel(), cv=5, scoring='roc_auc')\n",
"\n",
"# Print list of AUC scores\n",
"print(\"AUC scores computed using 5-fold cross-validation: {}\".format(cv_auc))"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"#standard scaling \n",
"# xgboost\n",
"#\n",
"\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Weighted Logistic Regression for Imbalanced Dataset"
]
},
{
"cell_type": "code",
"execution_count": 90,
"metadata": {},
"outputs": [
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"application/javascript": [
"\n",
" if (window._pyforest_update_imports_cell) { window._pyforest_update_imports_cell('import sklearn\\nimport os\\nimport pandas as pd\\nimport numpy as np\\nimport matplotlib.pyplot as plt'); }\n",
" "
],
"text/plain": [
"<IPython.core.display.Javascript object>"
]
},
"metadata": {},
"output_type": "display_data"
},
{
"data": {
"image/png": "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\n",
"text/plain": [
"<Figure size 432x288 with 1 Axes>"
]
},
"metadata": {
"needs_background": "light"
},
"output_type": "display_data"
}
],
"source": [
"survived=saps.saps2.loc[saps.hdeath==0]\n",
"deceased=saps.saps2.loc[saps.hdeath==1]\n",
"\n",
"_ = plt.hist(survived, bins=30, alpha=0.5, label='ICU Patients Survived')\n",
"_ = plt.hist(deceased, bins=30, alpha=0.5, label='ICU Patients Deceased')\n",
"_ = plt.xlabel('SAPSII Total Score')\n",
"_ = plt.ylabel('Frequency')\n",
"_ = plt.legend()"
]
},
{
"cell_type": "code",
"execution_count": 95,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[[13384 199]\n",
" [ 1038 659]]\n",
" precision recall f1-score support\n",
"\n",
" 0 0.93 0.99 0.96 13583\n",
" 1 0.77 0.39 0.52 1697\n",
"\n",
" accuracy 0.92 15280\n",
" macro avg 0.85 0.69 0.74 15280\n",
"weighted avg 0.91 0.92 0.91 15280\n",
"\n"
]
}
],
"source": [
"# Generate the confusion matrix and classification report\n",
"# Import necessary modules\n",
"from sklearn.metrics import classification_report\n",
"from sklearn.metrics import confusion_matrix\n",
"ypred = clf.predict(Xtestlr)\n",
"# Generate the confusion matrix and classification report\n",
"print(confusion_matrix(ytestlr, ypred))\n",
"print(classification_report(ytestlr, ypred))"
]
},
{
"cell_type": "code",
"execution_count": 98,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Accuracy Score: 0.9013089005235602\n",
"[[13567 16]\n",
" [ 1492 205]]\n",
" precision recall f1-score support\n",
"\n",
" 0 0.90 1.00 0.95 13583\n",
" 1 0.93 0.12 0.21 1697\n",
"\n",
" accuracy 0.90 15280\n",
" macro avg 0.91 0.56 0.58 15280\n",
"weighted avg 0.90 0.90 0.87 15280\n",
"\n",
"Area Under Curve: 0.5598117356217265\n",
"Recall score: 0.12080141426045964\n"
]
}
],
"source": [
"from sklearn.metrics import roc_auc_score, recall_score\n",
"\n",
"# define class weights (11%, 89%)\n",
"w = {0:89, 1:11}\n",
"\n",
"# define model\n",
"clf2 = LogisticRegression(solver='lbfgs', max_iter=1000, class_weight=w)\n",
"# fit\n",
"clf2.fit(Xlr,ylr)\n",
"# test\n",
"ypred = clf2.predict(Xtestlr)\n",
"# performance\n",
"print(f'Accuracy Score: {accuracy_score(ytestlr,ypred)}')\n",
"print(confusion_matrix(ytestlr, ypred))\n",
"print(classification_report(ytestlr, ypred))\n",
"print(f'Area Under Curve: {roc_auc_score(ytestlr, ypred)}')\n",
"print(f'Recall score: {recall_score(ytestlr,ypred)}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### XGBoost \n",
"\n",
"XGBoost Python api provides a method to assess the incremental performance by the incremental number of trees. It uses two arguments: “eval_set” — usually Train and Test sets — and the associated “eval_metric” to measure your error on these evaluation sets."
]
},
{
"cell_type": "code",
"execution_count": 87,
"metadata": {},
"outputs": [],
"source": [
"from xgboost import XGBClassifier\n",
"model = XGBClassifier(silent=False, \n",
" scale_pos_weight=1,\n",
" learning_rate=0.01, \n",
" colsample_bytree = 0.4,\n",
" subsample = 0.8,\n",
" objective='binary:logistic', \n",
" n_estimators=100, \n",
" reg_alpha = 0.3,\n",
" max_depth=3, \n",
" gamma=1)"
]
},
{
"cell_type": "code",
"execution_count": 89,
"metadata": {
"scrolled": false
},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[0]\tvalidation_0-auc:0.805756\tvalidation_0-error:0.083622\tvalidation_1-auc:0.809636\tvalidation_1-error:0.087631\n",
"[1]\tvalidation_0-auc:0.806417\tvalidation_0-error:0.083535\tvalidation_1-auc:0.806968\tvalidation_1-error:0.087696\n",
"[2]\tvalidation_0-auc:0.833609\tvalidation_0-error:0.083535\tvalidation_1-auc:0.83371\tvalidation_1-error:0.087565\n",
"[3]\tvalidation_0-auc:0.847123\tvalidation_0-error:0.082968\tvalidation_1-auc:0.848982\tvalidation_1-error:0.086976\n",
"[4]\tvalidation_0-auc:0.841802\tvalidation_0-error:0.082968\tvalidation_1-auc:0.842443\tvalidation_1-error:0.086322\n",
"[5]\tvalidation_0-auc:0.843148\tvalidation_0-error:0.082902\tvalidation_1-auc:0.844063\tvalidation_1-error:0.086846\n",
"[6]\tvalidation_0-auc:0.85287\tvalidation_0-error:0.083535\tvalidation_1-auc:0.854493\tvalidation_1-error:0.087696\n",
"[7]\tvalidation_0-auc:0.852881\tvalidation_0-error:0.083557\tvalidation_1-auc:0.85407\tvalidation_1-error:0.087107\n",
"[8]\tvalidation_0-auc:0.854487\tvalidation_0-error:0.08347\tvalidation_1-auc:0.854802\tvalidation_1-error:0.087631\n",
"[9]\tvalidation_0-auc:0.855782\tvalidation_0-error:0.083208\tvalidation_1-auc:0.855388\tvalidation_1-error:0.087173\n",
"[10]\tvalidation_0-auc:0.859383\tvalidation_0-error:0.083797\tvalidation_1-auc:0.858915\tvalidation_1-error:0.087696\n",
"[11]\tvalidation_0-auc:0.858277\tvalidation_0-error:0.083841\tvalidation_1-auc:0.857677\tvalidation_1-error:0.087827\n",
"[12]\tvalidation_0-auc:0.85842\tvalidation_0-error:0.084604\tvalidation_1-auc:0.858429\tvalidation_1-error:0.088416\n",
"[13]\tvalidation_0-auc:0.857983\tvalidation_0-error:0.086219\tvalidation_1-auc:0.858302\tvalidation_1-error:0.090118\n",
"[14]\tvalidation_0-auc:0.859352\tvalidation_0-error:0.085215\tvalidation_1-auc:0.860531\tvalidation_1-error:0.089332\n",
"[15]\tvalidation_0-auc:0.860412\tvalidation_0-error:0.083797\tvalidation_1-auc:0.861723\tvalidation_1-error:0.087893\n",
"[16]\tvalidation_0-auc:0.862379\tvalidation_0-error:0.083971\tvalidation_1-auc:0.862877\tvalidation_1-error:0.087893\n",
"[17]\tvalidation_0-auc:0.862198\tvalidation_0-error:0.083688\tvalidation_1-auc:0.862819\tvalidation_1-error:0.087696\n",
"[18]\tvalidation_0-auc:0.86192\tvalidation_0-error:0.083601\tvalidation_1-auc:0.862644\tvalidation_1-error:0.087631\n",
"[19]\tvalidation_0-auc:0.861278\tvalidation_0-error:0.083666\tvalidation_1-auc:0.861946\tvalidation_1-error:0.087696\n",
"[20]\tvalidation_0-auc:0.862406\tvalidation_0-error:0.083688\tvalidation_1-auc:0.862919\tvalidation_1-error:0.087696\n",
"[21]\tvalidation_0-auc:0.865696\tvalidation_0-error:0.084342\tvalidation_1-auc:0.866523\tvalidation_1-error:0.089005\n",
"[22]\tvalidation_0-auc:0.865447\tvalidation_0-error:0.085019\tvalidation_1-auc:0.866014\tvalidation_1-error:0.089202\n",
"[23]\tvalidation_0-auc:0.86629\tvalidation_0-error:0.084713\tvalidation_1-auc:0.866522\tvalidation_1-error:0.089005\n",
"[24]\tvalidation_0-auc:0.86573\tvalidation_0-error:0.084321\tvalidation_1-auc:0.865647\tvalidation_1-error:0.088743\n",
"[25]\tvalidation_0-auc:0.866428\tvalidation_0-error:0.084691\tvalidation_1-auc:0.86653\tvalidation_1-error:0.089005\n",
"[26]\tvalidation_0-auc:0.866293\tvalidation_0-error:0.084495\tvalidation_1-auc:0.866744\tvalidation_1-error:0.088809\n",
"[27]\tvalidation_0-auc:0.86664\tvalidation_0-error:0.084626\tvalidation_1-auc:0.866838\tvalidation_1-error:0.089071\n",
"[28]\tvalidation_0-auc:0.866418\tvalidation_0-error:0.08443\tvalidation_1-auc:0.866702\tvalidation_1-error:0.088809\n",
"[29]\tvalidation_0-auc:0.865961\tvalidation_0-error:0.084648\tvalidation_1-auc:0.866056\tvalidation_1-error:0.089136\n",
"[30]\tvalidation_0-auc:0.867179\tvalidation_0-error:0.084408\tvalidation_1-auc:0.867253\tvalidation_1-error:0.088678\n",
"[31]\tvalidation_0-auc:0.867052\tvalidation_0-error:0.084626\tvalidation_1-auc:0.867089\tvalidation_1-error:0.088874\n",
"[32]\tvalidation_0-auc:0.867114\tvalidation_0-error:0.084757\tvalidation_1-auc:0.867105\tvalidation_1-error:0.089005\n",
"[33]\tvalidation_0-auc:0.867554\tvalidation_0-error:0.084866\tvalidation_1-auc:0.867242\tvalidation_1-error:0.089071\n",
"[34]\tvalidation_0-auc:0.867817\tvalidation_0-error:0.085084\tvalidation_1-auc:0.86753\tvalidation_1-error:0.089136\n",
"[35]\tvalidation_0-auc:0.86776\tvalidation_0-error:0.085237\tvalidation_1-auc:0.867284\tvalidation_1-error:0.089136\n",
"[36]\tvalidation_0-auc:0.867917\tvalidation_0-error:0.08539\tvalidation_1-auc:0.867914\tvalidation_1-error:0.089136\n",
"[37]\tvalidation_0-auc:0.868079\tvalidation_0-error:0.085324\tvalidation_1-auc:0.868238\tvalidation_1-error:0.089071\n",
"[38]\tvalidation_0-auc:0.867856\tvalidation_0-error:0.085608\tvalidation_1-auc:0.86799\tvalidation_1-error:0.089529\n",
"[39]\tvalidation_0-auc:0.867798\tvalidation_0-error:0.085651\tvalidation_1-auc:0.86819\tvalidation_1-error:0.089529\n",
"[40]\tvalidation_0-auc:0.868403\tvalidation_0-error:0.085564\tvalidation_1-auc:0.868699\tvalidation_1-error:0.089463\n",
"[41]\tvalidation_0-auc:0.86849\tvalidation_0-error:0.085215\tvalidation_1-auc:0.868739\tvalidation_1-error:0.089136\n",
"[42]\tvalidation_0-auc:0.868427\tvalidation_0-error:0.085542\tvalidation_1-auc:0.868531\tvalidation_1-error:0.089529\n",
"[43]\tvalidation_0-auc:0.86876\tvalidation_0-error:0.085542\tvalidation_1-auc:0.86891\tvalidation_1-error:0.089463\n",
"[44]\tvalidation_0-auc:0.869809\tvalidation_0-error:0.085608\tvalidation_1-auc:0.870056\tvalidation_1-error:0.089463\n",
"[45]\tvalidation_0-auc:0.869507\tvalidation_0-error:0.085499\tvalidation_1-auc:0.869661\tvalidation_1-error:0.089463\n",
"[46]\tvalidation_0-auc:0.869391\tvalidation_0-error:0.085608\tvalidation_1-auc:0.869682\tvalidation_1-error:0.08966\n",
"[47]\tvalidation_0-auc:0.869438\tvalidation_0-error:0.08576\tvalidation_1-auc:0.869752\tvalidation_1-error:0.089594\n",
"[48]\tvalidation_0-auc:0.869761\tvalidation_0-error:0.085848\tvalidation_1-auc:0.870027\tvalidation_1-error:0.089725\n",
"[49]\tvalidation_0-auc:0.870033\tvalidation_0-error:0.08552\tvalidation_1-auc:0.870413\tvalidation_1-error:0.089463\n",
"[50]\tvalidation_0-auc:0.870215\tvalidation_0-error:0.085651\tvalidation_1-auc:0.870418\tvalidation_1-error:0.089529\n",
"[51]\tvalidation_0-auc:0.869963\tvalidation_0-error:0.085433\tvalidation_1-auc:0.870094\tvalidation_1-error:0.089332\n",
"[52]\tvalidation_0-auc:0.870333\tvalidation_0-error:0.085084\tvalidation_1-auc:0.870355\tvalidation_1-error:0.08894\n",
"[53]\tvalidation_0-auc:0.870283\tvalidation_0-error:0.085128\tvalidation_1-auc:0.870476\tvalidation_1-error:0.08894\n",
"[54]\tvalidation_0-auc:0.870032\tvalidation_0-error:0.085433\tvalidation_1-auc:0.870275\tvalidation_1-error:0.089398\n",
"[55]\tvalidation_0-auc:0.870189\tvalidation_0-error:0.085455\tvalidation_1-auc:0.870531\tvalidation_1-error:0.089463\n",
"[56]\tvalidation_0-auc:0.869892\tvalidation_0-error:0.085608\tvalidation_1-auc:0.870177\tvalidation_1-error:0.089529\n",
"[57]\tvalidation_0-auc:0.869509\tvalidation_0-error:0.085739\tvalidation_1-auc:0.86973\tvalidation_1-error:0.089594\n",
"[58]\tvalidation_0-auc:0.869183\tvalidation_0-error:0.085979\tvalidation_1-auc:0.869321\tvalidation_1-error:0.089529\n",
"[59]\tvalidation_0-auc:0.869056\tvalidation_0-error:0.085564\tvalidation_1-auc:0.869175\tvalidation_1-error:0.089398\n",
"[60]\tvalidation_0-auc:0.86907\tvalidation_0-error:0.085564\tvalidation_1-auc:0.869009\tvalidation_1-error:0.089398\n",
"[61]\tvalidation_0-auc:0.868867\tvalidation_0-error:0.08576\tvalidation_1-auc:0.868804\tvalidation_1-error:0.089529\n",
"[62]\tvalidation_0-auc:0.868679\tvalidation_0-error:0.085957\tvalidation_1-auc:0.86868\tvalidation_1-error:0.089594\n",
"[63]\tvalidation_0-auc:0.868765\tvalidation_0-error:0.086371\tvalidation_1-auc:0.868526\tvalidation_1-error:0.089856\n",
"[64]\tvalidation_0-auc:0.868661\tvalidation_0-error:0.085717\tvalidation_1-auc:0.868409\tvalidation_1-error:0.089529\n",
"[65]\tvalidation_0-auc:0.86865\tvalidation_0-error:0.085957\tvalidation_1-auc:0.868427\tvalidation_1-error:0.089529\n",
"[66]\tvalidation_0-auc:0.868777\tvalidation_0-error:0.08552\tvalidation_1-auc:0.868408\tvalidation_1-error:0.089398\n",
"[67]\tvalidation_0-auc:0.86935\tvalidation_0-error:0.085717\tvalidation_1-auc:0.868996\tvalidation_1-error:0.089529\n",
"[68]\tvalidation_0-auc:0.869549\tvalidation_0-error:0.086262\tvalidation_1-auc:0.868994\tvalidation_1-error:0.089921\n",
"[69]\tvalidation_0-auc:0.870164\tvalidation_0-error:0.086502\tvalidation_1-auc:0.86985\tvalidation_1-error:0.089921\n",
"[70]\tvalidation_0-auc:0.870224\tvalidation_0-error:0.085957\tvalidation_1-auc:0.869928\tvalidation_1-error:0.089594\n",
"[71]\tvalidation_0-auc:0.869967\tvalidation_0-error:0.085957\tvalidation_1-auc:0.869716\tvalidation_1-error:0.089594\n",
"[72]\tvalidation_0-auc:0.869862\tvalidation_0-error:0.086349\tvalidation_1-auc:0.869547\tvalidation_1-error:0.089921\n"
]
},
{
"name": "stdout",
"output_type": "stream",
"text": [
"[73]\tvalidation_0-auc:0.870112\tvalidation_0-error:0.086437\tvalidation_1-auc:0.869796\tvalidation_1-error:0.089921\n",
"[74]\tvalidation_0-auc:0.870304\tvalidation_0-error:0.086524\tvalidation_1-auc:0.869977\tvalidation_1-error:0.089856\n",
"[75]\tvalidation_0-auc:0.870106\tvalidation_0-error:0.086349\tvalidation_1-auc:0.869769\tvalidation_1-error:0.089921\n",
"[76]\tvalidation_0-auc:0.870013\tvalidation_0-error:0.085979\tvalidation_1-auc:0.869659\tvalidation_1-error:0.089529\n",
"[77]\tvalidation_0-auc:0.869817\tvalidation_0-error:0.086306\tvalidation_1-auc:0.869416\tvalidation_1-error:0.089921\n",
"[78]\tvalidation_0-auc:0.869962\tvalidation_0-error:0.085695\tvalidation_1-auc:0.869603\tvalidation_1-error:0.089398\n",
"[79]\tvalidation_0-auc:0.870129\tvalidation_0-error:0.085455\tvalidation_1-auc:0.869848\tvalidation_1-error:0.089202\n",
"[80]\tvalidation_0-auc:0.869945\tvalidation_0-error:0.085477\tvalidation_1-auc:0.869671\tvalidation_1-error:0.089267\n",
"[81]\tvalidation_0-auc:0.870049\tvalidation_0-error:0.085586\tvalidation_1-auc:0.869803\tvalidation_1-error:0.089398\n",
"[82]\tvalidation_0-auc:0.870052\tvalidation_0-error:0.085717\tvalidation_1-auc:0.869887\tvalidation_1-error:0.089463\n",
"[83]\tvalidation_0-auc:0.87035\tvalidation_0-error:0.08576\tvalidation_1-auc:0.870185\tvalidation_1-error:0.089529\n",
"[84]\tvalidation_0-auc:0.870545\tvalidation_0-error:0.086066\tvalidation_1-auc:0.870365\tvalidation_1-error:0.089594\n",
"[85]\tvalidation_0-auc:0.870496\tvalidation_0-error:0.085673\tvalidation_1-auc:0.870276\tvalidation_1-error:0.089398\n",
"[86]\tvalidation_0-auc:0.870563\tvalidation_0-error:0.085542\tvalidation_1-auc:0.870213\tvalidation_1-error:0.089332\n",
"[87]\tvalidation_0-auc:0.870483\tvalidation_0-error:0.085957\tvalidation_1-auc:0.870176\tvalidation_1-error:0.089463\n",
"[88]\tvalidation_0-auc:0.870437\tvalidation_0-error:0.08624\tvalidation_1-auc:0.870178\tvalidation_1-error:0.08966\n",
"[89]\tvalidation_0-auc:0.871024\tvalidation_0-error:0.086371\tvalidation_1-auc:0.870727\tvalidation_1-error:0.089725\n",
"[90]\tvalidation_0-auc:0.871107\tvalidation_0-error:0.085935\tvalidation_1-auc:0.870856\tvalidation_1-error:0.089267\n",
"[91]\tvalidation_0-auc:0.871102\tvalidation_0-error:0.086175\tvalidation_1-auc:0.870947\tvalidation_1-error:0.089529\n",
"[92]\tvalidation_0-auc:0.871265\tvalidation_0-error:0.08552\tvalidation_1-auc:0.871157\tvalidation_1-error:0.089202\n",
"[93]\tvalidation_0-auc:0.871577\tvalidation_0-error:0.085848\tvalidation_1-auc:0.871507\tvalidation_1-error:0.089267\n",
"[94]\tvalidation_0-auc:0.871623\tvalidation_0-error:0.085499\tvalidation_1-auc:0.871392\tvalidation_1-error:0.089202\n",
"[95]\tvalidation_0-auc:0.871802\tvalidation_0-error:0.085673\tvalidation_1-auc:0.87163\tvalidation_1-error:0.089202\n",
"[96]\tvalidation_0-auc:0.871816\tvalidation_0-error:0.085324\tvalidation_1-auc:0.871624\tvalidation_1-error:0.089136\n",
"[97]\tvalidation_0-auc:0.871802\tvalidation_0-error:0.085411\tvalidation_1-auc:0.87166\tvalidation_1-error:0.089136\n",
"[98]\tvalidation_0-auc:0.871747\tvalidation_0-error:0.085411\tvalidation_1-auc:0.871759\tvalidation_1-error:0.089136\n",
"[99]\tvalidation_0-auc:0.871832\tvalidation_0-error:0.085433\tvalidation_1-auc:0.871987\tvalidation_1-error:0.089136\n",
"Wall time: 3.24 s\n"
]
},
{
"data": {
"text/plain": [
"XGBClassifier(base_score=0.5, booster='gbtree', colsample_bylevel=1,\n",
" colsample_bynode=1, colsample_bytree=0.4, gamma=1,\n",
" learning_rate=0.01, max_delta_step=0, max_depth=3,\n",
" min_child_weight=1, missing=None, n_estimators=100, n_jobs=1,\n",
" nthread=None, objective='binary:logistic', random_state=0,\n",
" reg_alpha=0.3, reg_lambda=1, scale_pos_weight=1, seed=None,\n",
" silent=False, subsample=0.8, verbosity=1)"
]
},
"execution_count": 89,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"\n",
"eval_set = [(Xlr, ylr), (Xtestlr, ytestlr)]\n",
"eval_metric = [\"auc\", \"error\"]\n",
"%time model.fit(Xlr, ylr, eval_metric=eval_metric, eval_set=eval_set, verbose=True)\n",
"\n"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"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.7.4"
}
},
"nbformat": 4,
"nbformat_minor": 1
}