text: # -*- coding: utf-8 -*-
  """Demo171_RandomImputation_Titanic.ipynb
  
  
  ## Imputation
  
  - Replacing missing data with statistical estimates of the missing values is called imputation 
  
  - Imputation completes a dataset and removes missing values 
  
  - Replace by mean if the variable has a Normal distribution 
  
  - Replace by median if the variable has a Skewed distribution 
  
  - Iterative imputation computes the missing value using all the other values in the dataset
  
  - **Random sampling takes a random value from available observations and uses that value to fill the NA**
  
  
  
  ### When to use it?
  
  - When data are missing completely at random (MCAR) 
  
  ### Pros
  
  - Easy
  - Completes the dataset and does not loose much information
  - Preserves variable variance 
  
  ### Cons
  
  - Change of covariance wrt other variables 
  - Random in nature 
  
  
  ### Key Takeaway
  
  - We usually create a new variable for the missing data to capture the relations where data is not MCAR 
  
  - So imputation handles the MCAR ascpect, whereas the new variable captures all the other statistical relations
  """
  
  import pandas as pd
  import matplotlib.pyplot as plt
  import seaborn as sns
  import numpy as np
  
  from google.colab import drive
  drive.mount('/content/gdrive')
  data = pd.read_csv("gdrive/My Drive/Colab Notebooks/FeatureEngineering/train.csv")
  
  """## Titanic"""
  
  data = data[['Age', 'Fare','Survived']]
  data.head()
  
  data.isnull().mean()
  
  from sklearn.model_selection import train_test_split
  X_train, X_test, y_train, y_test = train_test_split(data[['Age', 'Fare']], data['Survived'], test_size=0.2)
  X_train.shape, X_test.shape
  
  def impute(df, column, dft):
      df_temp = df.copy()
      df_temp[column] = df_temp[column].apply(lambda x: np.random.choice(dft[column].dropna().values) if np.isnan(x) else x)
      return df_temp
  
  sns.distplot(X_train['Age'])
  
  X_train_0 = impute(X_train, 'Age', X_train)
  X_test_0 = impute(X_test, 'Age', X_train)
  
  X_train_0.shape
  
  type(X_train_0)
  
  X_train_0 = X_train_0.values
  
  type(X_train_0)
  
  X_test_0 = X_test_0.values
  
  fig, ax = plt.subplots(1,2, figsize=(10,10))
  sns.distplot(X_train['Age'], ax = ax[0], color='blue')
  sns.distplot(X_train_0[:,0], ax = ax[1], color='red')
  
  from sklearn.impute import SimpleImputer
  obj = SimpleImputer(missing_values = np.nan, strategy= 'mean')
  X_train_mean = obj.fit_transform(X_train)
  X_test_mean = obj.transform(X_test)
  
  fig, ax = plt.subplots(1,2, figsize=(10,10))
  sns.distplot(X_train['Age'], ax = ax[0], color='blue')
  sns.distplot(X_train_mean[:,0], ax = ax[1], color='red')
  
  from sklearn.impute import SimpleImputer
  obj = SimpleImputer(missing_values = np.nan, strategy= 'median')
  X_train_median = obj.fit_transform(X_train)
  X_test_median = obj.transform(X_test)
  
  fig, ax = plt.subplots(1,2, figsize=(10,10))
  sns.distplot(X_train['Age'], ax = ax[0], color='blue')
  sns.distplot(X_train_median[:,0], ax = ax[1], color='red')
  
  from sklearn.impute import SimpleImputer
  obj = SimpleImputer(missing_values = np.nan, strategy= 'most_frequent')
  X_train_mode = obj.fit_transform(X_train)
  X_test_mode = obj.transform(X_test)
  
  fig, ax = plt.subplots(1,2, figsize=(10,10))
  sns.distplot(X_train['Age'], ax = ax[0], color='blue')
  sns.distplot(X_train_mode[:,0], ax = ax[1], color='red')
  
  print('Std original: ', X_train['Age'].std())
  print('Std 0: ', X_train_0[:,0].std())
  print('Std mean: ', X_train_mean[:,0].std())
  print('Std median: ', X_train_median[:,0].std())
  print('Std mode: ', X_train_mode[:,0].std())
  
  """### Model performance"""
  
  from sklearn.metrics import accuracy_score
  
  from sklearn.linear_model import LogisticRegression
  classifier = LogisticRegression()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.linear_model import RidgeClassifierCV
  classifier = RidgeClassifierCV()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.linear_model import RidgeClassifierCV
  classifier = RidgeClassifierCV()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.svm import SVC
  classifier = SVC()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.neural_network import MLPClassifier
  classifier = MLPClassifier()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.svm import LinearSVC
  classifier = LinearSVC()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.ensemble import RandomForestClassifier
  classifier = RandomForestClassifier()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.tree import DecisionTreeClassifier
  classifier = DecisionTreeClassifier()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.ensemble import GradientBoostingClassifier
  classifier = GradientBoostingClassifier()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.linear_model import SGDClassifier
  classifier = SGDClassifier()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.linear_model import Perceptron
  classifier = Perceptron()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.naive_bayes import GaussianNB
  classifier = GaussianNB()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  from sklearn.neighbors import KNeighborsClassifier
  classifier = KNeighborsClassifier()
  classifier.fit(X_train_0,y_train)
  y_pred = classifier.predict(X_test_0)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mean,y_train)
  y_pred = classifier.predict(X_test_mean)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_median,y_train)
  y_pred = classifier.predict(X_test_median)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  classifier.fit(X_train_mode,y_train)
  y_pred = classifier.predict(X_test_mode)
  y_pred = np.round(y_pred).flatten()
  print(accuracy_score(y_test, y_pred))
  
  