# -*- coding: utf-8 -*-
"""Categorical_Feature_Selection_Cramer's_V_Test.ipynb

Automatically generated by Colaboratory.

Original file is located at
    https://colab.research.google.com/drive/1N0DCQodKyTeoEC5KRqiUHMv34t1aDJ2M

#Imports and Load Data
"""

import pandas as pd
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
sns.set()
import warnings
warnings.simplefilter(action='ignore')

churn_master_df = pd.read_csv('https://raw.githubusercontent.com/srivatsan88/YouTubeLI/master/dataset/churn_data_st.csv')

churn_df = churn_master_df.copy()

churn_df.head()

"""# Exploring"""

churn_df.corr() # Does not calculate for string data / categorical data

churn_df['Contract'].value_counts()

sns.set(style="darkgrid")
sns.set_palette("hls", 3)
fig, ax = plt.subplots()

ax = sns.countplot(x="Contract", hue="Churn", data=churn_df)

for p in ax.patches:
    height = p.get_height()
    ax.text(p.get_x() + p.get_width()/2., height + 3, '{:1.2f}'.format(height/churn_df.shape[0]),
            ha="center")

"""# Null Hypothesis: - 

- The two categorical Features have no correlation.

# Alternate Hypothesis: -

- The two features have strong correlation.

# Chi-Squared Statistic

- Proves that relationship is significant

$ \chi^2 = sum((observed - Expected) ^ 2 / Expected)$

# Cramer's V Test

$ V = sqrt(\chi ^ 2 / (n * min(C, R) - 1))$

- It is an extension of Chi-Squared Test.

- Used to perform analysis of categorical variables.

- Determines the strength of relation between the two categorical variables.

- It uses the input as Chi-Squared Test statistic.

- It will determine how strong is the relationship between variables.
"""

pd.crosstab(index=churn_df['Contract'], columns=churn_df['Churn'], margins=True)

contract_churn_ct = pd.crosstab(index=churn_df['Contract'], columns=churn_df['Churn'])

contract_churn_ct

print(contract_churn_ct.iloc[0].values)
print(contract_churn_ct.iloc[1].values)
print(contract_churn_ct.iloc[2].values)

from scipy import stats

(chi2, p, dof, _) = stats.chi2_contingency([contract_churn_ct.iloc[0].values, contract_churn_ct.iloc[1].values, contract_churn_ct.iloc[2].values])

print("chi2 = ", chi2)
print("p-value = ",p)
print("Degree of freedom = ",dof)

"""Degree of freedom = Total Categories - 1

p - value < 0.05.
Hence there is a significant relationship between these two variables
"""

# There no builtin function sadly
# Here minimum of C, R column , row is column = 2 
# 2 - 1 = 1. 
import numpy as np

print(np.sqrt(chi2 / churn_df.shape[0]))

# The value will always be between 0 to 1.
# Here it is 0.41  Strength of the relationship is pretty strong.
# Check real world application !!! Do not think only variable.

"""# Applying same to Paperless Billing"""

churn_df['PaperlessBilling'].value_counts()

sns.set(style="darkgrid")
sns.set_palette("hls", 3)
fig, ax = plt.subplots()

ax = sns.countplot(x="PaperlessBilling", hue="Churn", data=churn_df)

for p in ax.patches:
    height = p.get_height()
    ax.text(p.get_x() + p.get_width()/2., height + 3, '{:1.2f}'.format(height/churn_df.shape[0]),
            ha="center")

pb_churn_ct = pd.crosstab(index=churn_df['PaperlessBilling'], columns=churn_df['Churn'])

pb_churn_ct

(chi2, p, dof, _) = stats.chi2_contingency([pb_churn_ct.iloc[0].values, pb_churn_ct.iloc[1].values])

print("Chi 2: ",chi2)
print("P-value: ",p)
print("Degree of freedom ",dof)

# Running Cramer's V formula again
# Again Min of row, columns = columns = 2.
# 2 - 1 = 1
# Hence it reduces to 
print(np.sqrt(chi2/churn_df.shape[0]))

"""# Repeating this for gender"""

churn_df['gender'].value_counts()

sns.set(style="darkgrid")
sns.set_palette("hls", 3)
fig, ax = plt.subplots()

ax = sns.countplot(x="gender", hue="Churn", data=churn_df)

for p in ax.patches:
    height = p.get_height()
    ax.text(p.get_x() + p.get_width()/2., height + 3, '{:1.2f}'.format(height/churn_df.shape[0]),
            ha="center")

gn_churn_ct = pd.crosstab(index=churn_df['gender'], columns=churn_df['Churn'])

gn_churn_ct

(chi2, p, dof, _) = stats.chi2_contingency([gn_churn_ct.iloc[0].values, gn_churn_ct.iloc[1].values])

print("Chi 2: ",chi2)
print("P-value: ",p)
print("Degree of freedom ",dof)

"""- Wait. Here p-value > 0.05
- So this feature shouldn't be selected by $ \chi ^ 2 $ squared test itself

- We reject the alternate hypothesis. Null hypothesis is valid.
"""

# Running Cramer's V formula again
# Again Min of row, columns = columns = 2.
# 2 - 1 = 1
# Hence it reduces to 
print(np.sqrt(chi2/churn_df.shape[0]))

"""- Anyways Cramer is dependent on $\chi^2 $ test so it too will not give any significance"""