# This Python 3 environment comes with many helpful analytics libraries installed
# It is defined by the kaggle/python Docker image: https://github.com/kaggle/docker-python
# For example, here's several helpful packages to load

import numpy as np # linear algebra
import pandas as pd # data processing, CSV file I/O (e.g. pd.read_csv)

# Input data files are available in the read-only "../input/" directory
# For example, running this (by clicking run or pressing Shift+Enter) will list all files under the input directory

import os
for dirname, _, filenames in os.walk('/kaggle/input'):
    for filename in filenames:
        print(os.path.join(dirname, filename))

# You can write up to 20GB to the current directory (/kaggle/working/) that gets preserved as output when you create a version using "Save & Run All" 
# You can also write temporary files to /kaggle/temp/, but they won't be saved outside of the current session
import seaborn as sns
import matplotlib.pyplot as plt
%matplotlib inline
df = pd.read_csv('/kaggle/input/heart-failure-prediction/heart.csv')
"""
# DATA EXPLORATION
"""
df.info()
df.describe()
df.head()
"""
# DATA VISUALISATION
"""
sns.pairplot(df,hue='HeartDisease', palette= 'coolwarm')
sns.heatmap(df.corr(),annot=True)
##MaxHR & Oldpeak are most correlated to HeartDisease
##Age
plt.figure(figsize=(20,7))
sns.countplot(data=df,x='Age')
##Sex
plt.figure(figsize=(20,7))
sns.countplot(data=df,x='Sex', hue= 'HeartDisease')
##ChestPainType
plt.figure(figsize=(20,7))
sns.countplot(data=df,x='Sex', hue= 'ChestPainType')
##RestingBP
plt.figure(figsize=(30,10))
sns.countplot(data=df,x='RestingBP',hue='HeartDisease')
##FastingBS
plt.figure(figsize=(30,10))
sns.countplot(data=df,x='FastingBS',hue='HeartDisease')
##RestingECG
plt.figure(figsize=(30,10))
sns.countplot(data=df,x='RestingECG',hue='HeartDisease')
##MaxHR
fig, ax = plt.subplots(figsize=(30, 10))
sns.countplot(data=df,x='MaxHR',hue='HeartDisease', ax=ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
plt.show()
##ExerciseAngina
sns.countplot(data=df,x='ExerciseAngina',hue='HeartDisease')
##Oldpeak
fig, ax = plt.subplots(figsize=(20, 10))
sns.countplot(data=df,x='Oldpeak',hue='HeartDisease', ax=ax)
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
plt.show()
##ST_Slope
sns.countplot(data=df,x='ST_Slope',hue='HeartDisease')
##HeartDisease
sns.countplot(data=df,x='HeartDisease')
df.isnull().sum()
##no missing values
"""
# PREPROCESSING
"""
"""
**Categorical Feature**
"""
cat_feats = ['Sex','ChestPainType','RestingECG','ExerciseAngina','ST_Slope']
##transforming categorical features using dummy variables
dummy_data = pd.get_dummies(data=df,columns=cat_feats,drop_first=True)
dummy_data.info()
dummy_data.head()
"""
**Feature Scaling**
"""
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
scaler.fit(dummy_data.drop('HeartDisease',axis=1))
scaled_features = scaler.transform(dummy_data.drop('HeartDisease',axis=1))
##getting columns names without the column HeartDisease
df_names = dummy_data.drop(dummy_data.filter(regex='HeartDisease').columns, axis=1).columns
df_names
df_final = pd.DataFrame(scaled_features,columns=df_names)
df_final.head()
"""
# **Feature Selection**
"""
from sklearn.model_selection import train_test_split
X = df_final
y = df['HeartDisease']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=101)
"""
# Predicting Heart Disease Using KNN
"""
from sklearn.neighbors import KNeighborsClassifier
knn = KNeighborsClassifier(n_neighbors=1)
knn.fit(X_train,y_train)
pred = knn.predict(X_test)
from sklearn import metrics
from sklearn.metrics import classification_report,confusion_matrix,accuracy_score
print(confusion_matrix(y_test,pred))
print(classification_report(y_test,pred))
pred!= y_test
"""
**Choosing a K Value using the elbow method** 
"""
"""
Create a for loop that trains various KNN models with different k values, then keep track of the error_rate for each of these models with a list.
"""
error_rate = []

for i in range (1,40):
        
        knn = KNeighborsClassifier(n_neighbors=i)
        knn.fit(X_train,y_train)
        pred_i = knn.predict(X_test)
        error_rate.append(np.mean(pred_i != y_test))
plt.figure(figsize=(10,6))
plt.plot(range(1,40),error_rate,color='blue', linestyle='dashed', marker='o',
         markerfacecolor='red', markersize=10)
plt.title('Error Rate vs. K Value')
plt.xlabel('K')
plt.ylabel('Error Rate')
"""
**Retrain with new K value**
"""
# NOW WITH K=14
knn = KNeighborsClassifier(n_neighbors=14)

knn.fit(X_train,y_train)
pred = knn.predict(X_test)

print('WITH K=14')
print('\n')
print(confusion_matrix(y_test,pred))
print('\n')
print(classification_report(y_test,pred))
"""
# Predicting Heart Disease using a Decision Tree Model
"""
from sklearn.tree import DecisionTreeClassifier
dtree = DecisionTreeClassifier()
dtree.fit(X_train,y_train)
pred_tree = dtree.predict(X_test)
print(classification_report(y_test,pred_tree))
print(confusion_matrix(y_test,pred_tree))
"""
# Predicting Heart Disease using Random Forest Classifier
"""
from sklearn.ensemble import RandomForestClassifier
rfc = RandomForestClassifier(n_estimators=600)
rfc.fit(X_train,y_train)
pred_forest = rfc.predict(X_test)
print(classification_report(y_test,pred_forest))
print(confusion_matrix(y_test,pred_forest))
"""
# Predicting Heart Disease using Logistic Regression
"""
from sklearn.linear_model import LogisticRegression
logmodel = LogisticRegression()
logmodel.fit(X_train,y_train)
pred_log = logmodel.predict(X_test)
print(classification_report(y_test,pred_log))
print(confusion_matrix(y_test,pred_log))
"""
KNN and Random Forest Classifier have the highest accuracy of 86%
"""