About the Dataset

The data was collected and made available by “National Institute of Diabetes and Digestive and Kidney Diseases” as part of the Pima Indians Diabetes Database. Several constraints were placed on the selection of these instances from a larger database. In particular, all patients here belong to the Pima Indian heritage (subgroup of Native Americans), and are females of ages 21 and above.

The columns of the dataset are as follows:

  1. Pregnencies
  2. Glucose
  3. BloodPressure
  4. Skin Thickness
  5. Insulin
  6. BMI
  7. DiabetesPedigreeFunction
  8. Age
  9. Outcome

You can download the dataset from here: https://www.kaggle.com/kandij/diabetes-dataset

In this exercise, we will do hyper parameter tuning using Ridge and Lasso Regression. Before performing Ridge regression, we will perform Linear Regression to see the mean squared error which will give us an idea about the best fit line.

In this case the Outcome column will be out dependent variable.

In [66]:
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
In [67]:
df = pd.read_csv("diabetes2.csv")
In [68]:
df.head()
Out[68]:
Pregnancies Glucose BloodPressure SkinThickness Insulin BMI DiabetesPedigreeFunction Age Outcome
0 6 148 72 35 0 33.6 0.627 50 1
1 1 85 66 29 0 26.6 0.351 31 0
2 8 183 64 0 0 23.3 0.672 32 1
3 1 89 66 23 94 28.1 0.167 21 0
4 0 137 40 35 168 43.1 2.288 33 1
In [69]:
df.shape
Out[69]:
(768, 9)

Shuffling the dataset to avoid any ordering issues

In [70]:
from sklearn.utils import shuffle
df_shuffle = shuffle(df)
In [71]:
df_shuffle.head()
Out[71]:
Pregnancies Glucose BloodPressure SkinThickness Insulin BMI DiabetesPedigreeFunction Age Outcome
27 1 97 66 15 140 23.2 0.487 22 0
427 1 181 64 30 180 34.1 0.328 38 1
600 1 108 88 19 0 27.1 0.400 24 0
726 1 116 78 29 180 36.1 0.496 25 0
167 4 120 68 0 0 29.6 0.709 34 0

Selecting the Dependent feature as Outcome and the rest as the independent feature

In [72]:
DV = 'Outcome'
y = df_shuffle[DV]
X = df_shuffle.drop(DV, axis = 1)
In [73]:
X.head()
Out[73]:
Pregnancies Glucose BloodPressure SkinThickness Insulin BMI DiabetesPedigreeFunction Age
27 1 97 66 15 140 23.2 0.487 22
427 1 181 64 30 180 34.1 0.328 38
600 1 108 88 19 0 27.1 0.400 24
726 1 116 78 29 180 36.1 0.496 25
167 4 120 68 0 0 29.6 0.709 34
In [74]:
y.head()
Out[74]:
27     0
427    1
600    0
726    0
167    0
Name: Outcome, dtype: int64

Linear Regression

Our goal is to calculate the difference between the actual dependent feature(y) and the predicted feature(ŷ). To calculate this we are using the cross_val_score and the parameter scoring='neg_mean_squared_error' will give us the difference for that.

We generally use a scorer object with the scoring parameter in the cross_val_score function. All scorer objects follow the convention that higher return values are better than lower return values.

  1. Thus metrics which measure the distance between the model and the data, like metrics.mean_squared_error, are available as neg_mean_squared_error which return the negated value of the metric.

In the below figure you could see the difference between the actual dependent feature(y) and the predicted feature(ŷ) is shown in the red arrow

In [103]:
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import GridSearchCV, cross_val_score

model = LinearRegression()
negMSE = cross_val_score(model,X,y, scoring='neg_mean_squared_error',cv=5)
mean_negMSE = np.mean(negMSE)
print("Negative Mean squared Error: ",mean_negMSE)
Negative Mean squared Error:  -0.16121424537905413

The above value for the Mean squared error looks pretty close to zero, which means our Linear Regression model has performed well. However let's if we could make our model better by hyper tuning it using Ridge Regression.

Ridge Regression

Here in Ridege Regression we have taken the alpha(λ-parameter) value as a bunch of possible random values. We are doing GridSearch to find the best parameters which will work for the Ridge Regressor.

Here also the value for the scoring parameter will be neg_mean_squared_error which measures the distance between the model and the data.

The formula for Ridge Regression is:

In [104]:
from sklearn.linear_model import Ridge

RidgeRegression = Ridge()
hyperParameters = {'alpha':[1e-15,1e-10,1e-8,1e-3,1e-2,1,5,10,20,30,35,40,45,50,55,100]}
ridgeRegressor = GridSearchCV(RidgeRegression, hyperParameters, scoring='neg_mean_squared_error', cv=5)
ridgeRegressor.fit(X,y)
Out[104]:
GridSearchCV(cv=5, error_score='raise-deprecating',
             estimator=Ridge(alpha=1.0, copy_X=True, fit_intercept=True,
                             max_iter=None, normalize=False, random_state=None,
                             solver='auto', tol=0.001),
             iid='warn', n_jobs=None,
             param_grid={'alpha': [1e-15, 1e-10, 1e-08, 0.001, 0.01, 1, 5, 10,
                                   20, 30, 35, 40, 45, 50, 55, 100]},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring='neg_mean_squared_error', verbose=0)
In [105]:
print("Best value for lambda : ",ridgeRegressor.best_params_)
print("Best score for cost function: ", ridgeRegressor.best_score_)
Best value for lambda :  {'alpha': 20}
Best score for cost function:  -0.16115569805145077

Lasso Regression

For Lasso Regressor, we follow the same process as Ridge Regressor, the only difference is we are taking the magnitude of slope here instead of square of slope as in case of Ridge Regressor.

The formula for Lasso Regression is :

In [83]:
from sklearn.linear_model import Lasso
from sklearn.model_selection import GridSearchCV
LassoRegression = Lasso()
hyperParameters = {'alpha':[1e-15,1e-10,1e-8,1e-3,1e-2,1,5,10,20,30,35,40,45,50,55,100]}
LassoRegressor = GridSearchCV(LassoRegression, hyperParameters, scoring='neg_mean_squared_error', cv=5)
LassoRegressor.fit(X,y)
C:\Users\tkhan050\AppData\Local\Continuum\anaconda3\lib\site-packages\sklearn\linear_model\coordinate_descent.py:475: ConvergenceWarning: Objective did not converge. You might want to increase the number of iterations. Duality gap: 2.4922689077000655, tolerance: 0.014130081300813009
  positive)
Out[83]:
GridSearchCV(cv=5, error_score='raise-deprecating',
             estimator=Lasso(alpha=1.0, copy_X=True, fit_intercept=True,
                             max_iter=1000, normalize=False, positive=False,
                             precompute=False, random_state=None,
                             selection='cyclic', tol=0.0001, warm_start=False),
             iid='warn', n_jobs=None,
             param_grid={'alpha': [1e-15, 1e-10, 1e-08, 0.001, 0.01, 1, 5, 10,
                                   20, 30, 35, 40, 45, 50, 55, 100]},
             pre_dispatch='2*n_jobs', refit=True, return_train_score=False,
             scoring='neg_mean_squared_error', verbose=0)
In [84]:
print("Best value for lambda : ",LassoRegressor.best_params_)
print("Best score for cost function: ", LassoRegressor.best_score_)
Best value for lambda :  {'alpha': 0.001}
Best score for cost function:  -0.16122710328737014

There is not a huge difference between the scores of Ridge and lasso in this case. But there are cases where there is significant difference between these 2.

We will split the dependent(y) features and the independent(X) features and then pass the test independent set to predict the dependent value

In [106]:
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X,y, test_size = 0.33, random_state = 10)

Predicting the y_test values by passing the test independent features to both ridge and lasso regressor to see which one performs better.

In [107]:
predict_ridge = ridgeRegressor.predict(X_test)
predict_lasso = LassoRegressor.predict(X_test)

We will plot a distance plot to show the probability distribution function for the difference between the actual(y) dependent feature and the predicted(ŷ) dependent feature through ridge regressor

In [118]:
import seaborn as sns

sns.distplot(y_test-predict_ridge)
Out[118]:
<matplotlib.axes._subplots.AxesSubplot at 0x2028fa2e748>

We will plot a distance plot to show the probability distribution function for the difference between the actual(y) dependent feature and the predicted(ŷ) dependent feature through Lasso regressor

In [117]:
sns.distplot(y_test-predict_lasso)
Out[117]:
<matplotlib.axes._subplots.AxesSubplot at 0x20290371588>