text_plain_output_1.png
from scipy import stats

import matplotlib.pyplot as plt

import numpy as np

import pandas as pd

import seaborn as sns

csv_path = '/kaggle/input/heart-failure-prediction/heart.csv'
hrz = pd.read_csv(csv_path)

target = ['HeartDisease']
num_attribs = ['Age', 'RestingBP', 'Cholesterol', 'MaxHR', 'Oldpeak']
cat_nom_attribs = ['ChestPainType', 'RestingECG', 'ST_Slope']
cat_bin_attribs = ['Sex', 'FastingBS', 'ExerciseAngina']
cat_attribs = cat_nom_attribs + cat_bin_attribs

attribs = num_attribs + target

ncol = 3
nrow = int(np.ceil(len(num_attribs)/ncol))

fig, axs = plt.subplots(nrow, ncol, figsize=(10, 5), facecolor=None)   

i = 1
for col in num_attribs:
    plt.subplot(nrow, ncol, i)
    ax = sns.histplot(data=hrz, x=col, hue=target[0], multiple="stack", palette='colorblind') #kdeplot 
    ax.set_xlabel(col, fontsize=12)
    ax.set_ylabel("count", fontsize=12)
    sns.despine(right=True)
    sns.despine(offset=0, trim=False)
    i+=1

fig.delaxes(axs[nrow-1, ncol-1])
plt.suptitle('Distribution of Numerical Features', fontsize = 14);
plt.tight_layout()    

ncol = 3
nrow = int(np.ceil(len(num_attribs)/ncol))

f, axes = plt.subplots(nrow, ncol, figsize=(8,6))

for name, ax in zip(num_attribs, axes.flatten()):
    sns.boxplot(y=name, x= "HeartDisease", data=hrz, orient='v', ax=ax)

f.delaxes(axes[nrow-1, ncol-1])
plt.suptitle('Box-and-whisker plot', fontsize = 14);
plt.tight_layout()    

grid = sns.FacetGrid(hrz, col='ST_Slope', height=3.0, aspect=1.2)
grid.map(sns.pointplot, 'ChestPainType', 'HeartDisease', 'Sex', hue_order=['M', 'F'], order=['ASY', 'ATA', 'NAP', 'TA'], palette='colorblind')
grid.add_legend()
grid = sns.FacetGrid(hrz, col='ExerciseAngina', height=3.0, aspect=1.2)
grid.map(sns.pointplot, 'ChestPainType', 'HeartDisease', 'Sex', hue_order=['M', 'F'], order=['ASY', 'ATA', 'NAP', 'TA'], palette='colorblind')
grid.add_legend()

grid = sns.FacetGrid(hrz, col='ExerciseAngina', height=3.0, aspect=1.2)
grid.map(sns.pointplot, 'RestingECG', 'HeartDisease', 'Sex', hue_order=['M', 'F'], order=['Normal', 'LVH', 'ST'], palette='colorblind')
grid.add_legend()

def cramers_v(x, y):
    confusion_matrix = pd.crosstab(x, y)
    chi2 = stats.chi2_contingency(confusion_matrix)[0]
    n = confusion_matrix.sum().sum()
    phi2 = chi2 / n
    r, k = confusion_matrix.shape
    phi2corr = max(0, phi2 - (k - 1) * (r - 1) / (n - 1))
    rcorr = r - (r - 1) ** 2 / (n - 1)
    kcorr = k - (k - 1) ** 2 / (n - 1)
    return np.sqrt(phi2corr / min(kcorr - 1, rcorr - 1))
hrz_ = hrz[cat_attribs + target]
rows = []
for x in hrz_:
    col = []
    for y in hrz_:
        col.append(cramers_v(hrz_[x], hrz_[y]))
    rows.append(col)
cramers_results = np.array(rows)
df = pd.DataFrame(cramers_results, columns=hrz_.columns, index=hrz_.columns)
mask = np.triu(np.ones_like(df, dtype=bool))
fig, ax = plt.subplots(figsize=(8, 6), facecolor=None)
sns.heatmap(df, cmap=sns.color_palette('husl', as_cmap=True), vmin=0, vmax=1.0, center=0, annot=True, fmt='.2f', square=True, linewidths=0.01, cbar_kws={'shrink': 0.8})
ax.set_title("Association between categorical variables (Cramer's V)", fontsize=14)