# 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
"""
# Stroke Prediction Dataset
"""
"""
# Context

    According to the World Health Organization (WHO) stroke is the 2nd leading cause of death globally, responsible for approximately 11% of total deaths. This dataset is used to predict whether a patient is likely to get stroke based on the input parameters like gender, age, various diseases, and smoking status. Each row in the data provides relavant information about the patient.

"""
"""
# Attribute information
"""
"""
1. id :unique identifier

2. gender: "Male", "Female" or "Other"

3. age: age of the patient

4. hypertension: 0 if the patient doesn't have hypertension, 1 if the patient has hypertension

5. heart_disease: 0 if the patient doesn't have any heart diseases, 1 if the patient has a heart disease

6. ever_married: "No" or "Yes"

7. work_type: "children", "Govt_jov", "Never_worked", "Private" or "Self-employed"

8. Residence_type: "Rural" or "Urban"

9. avg_glucose_level: average glucose level in blood

10. bmi: body mass index

11. smoking_status: "formerly smoked", "never smoked", "smokes" or "Unknown"*

12. stroke: 1 if the patient had a stroke or 0 if not


"""
"""
## importing the libraries
"""
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import plotly.express as px
from xgboost import XGBClassifier
from sklearn.preprocessing import LabelEncoder
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from imblearn.over_sampling import SMOTE
import warnings
warnings.filterwarnings("ignore")

from plotly.offline import plot, iplot, init_notebook_mode
import plotly.graph_objs as go
init_notebook_mode(connected=True)
df = pd.read_csv("/kaggle/input/stroke-prediction-dataset/healthcare-dataset-stroke-data.csv")
df.drop('id',axis=1,inplace=True)
df.head()
df.shape
print(f'We have {df.shape[0]} instance with the {df.shape[1]-1} features and 1 output variable')
df.info()
"""
<ul>
  <li>As we can see , in our dataset we have both Numarical as we as categorical variables</li>
  <li>"Stroke" is our target variable</li>
  <li>In target variable 1 is for positive cases(has stroke),0 for negative case(doesn't have stroke)</li>
    <li>We have to encode categorical variables into numerical variable.</li>
    <li>In dataset in "bmi" column we have null values</li>
</ul>
"""
"""
# EDA
"""
y = df.stroke
print(y.value_counts())
print(f'Percentage of patient had a stroke: {round(y.value_counts(normalize=True)[1]*100,2)} % --> ({y.value_counts()[1]} patient)\nPercentage of patient did not have a stroke: {round(y.value_counts(normalize=True)[0]*100,2)} % --> ({y.value_counts()[0]} patient)')

"""
<ul>
    <li>Almost 95% of the instance of our target variable is 'No stroke',that is 4861 patients does not have a stroke</li>
    <li>5% of instance of out target variable is "Stroke",that is 249 patients have Stroke.</li>
    <li>This is imbalance data</li>
"""
px.histogram(df, x="stroke", title='Stroke', width=400, height=400)
# missing values
df.isnull().sum()
"""
<ul>
    <li>In "bmi" column we have 201 datapoints missing
"""
"""
<ul style="list-style-type:square;">
  <li>Let's separate numarical and categorical features </li>
</ul>

"""
categorical = ['gender', 'hypertension', 'heart_disease', 'ever_married',
'work_type', 'Residence_type', 'smoking_status']

numerical = ['age','avg_glucose_level', 'bmi']
"""
 <h2>Let's work on Numerical Features</h2>
"""
df[numerical].describe()
"""
As we can see :-
<ul>
  <li>Slightly left skew on the 'age' (mean: 43.22 & median: 45)
</li>
  <li>Slightly right skew on the 'bmi' (mean: 28.89 & median: 28.10)
</li>
  <li>And right skew distribution on the 'avg_glucose_level' (mean: 106.14 & median: 91.88)

</li>
</ul>
"""
#skewness
df[numerical].skew()
"""
<ul>
    <li>Based on the result, age has slight left skew, other two features have right tail, positively skewed shape distribution.</li>
"""
df[numerical].hist(figsize=(8,6));
"""

<h2>Let's work on Categorical Features</h2>
"""
fig = px.histogram(df, x="gender", title='Gender', width=400, height=400)
fig.show()
"""
<ul>
    <li>We have 2994 female and 2115 male and 1 other gender people</li>
"""
"""
<h4>Hypertension</h4>
"""
fig = px.histogram(df, x="hypertension", title='hypertension', width=400, height=400)
fig.show()
"""
<ul>
    <li>we have 4612 patients who don't have hypertension</li>
    <li> and 498 patients who have hypertension</li>
    </ul>
"""
print (f'{round(df["hypertension"].value_counts(normalize=True)*100,2)}')
"""
<h4>Heart Disease</h4>
"""
print (f'{round(df["heart_disease"].value_counts(normalize=True)*100,2)}')
fig = px.histogram(df, x="heart_disease", title='Heart disease', width=400, height=400)
fig.show()
"""
<ul>
    <li>We have 276 patients with heart disease which is 5.4% of the sample.</li>
"""
"""
<h4>Married</h4>
"""
print (f'{round(df["ever_married"].value_counts(normalize=True)*100,2)}')
fig = px.histogram(df, x="ever_married", title='Ever married', width=400, height=400)
fig.show()
"""
<li>3353 people have been married and 1757 people are not married before.</li>
"""
print (f'{round(df["work_type"].value_counts(normalize=True)*100,2)}')
fig = px.histogram(df, x="work_type", title='Work type', width=400, height=400)
fig.show()
"""
<li>2925 people work in the private sector.</li>
<li>819 people are self-employed</li>
<li>657 people work at the government job.</li>
"""
"""
<h4>Smoking</h4>
"""
print (f'{round(df["smoking_status"].value_counts(normalize=True)*100,2)}')
fig = px.histogram(df, x="smoking_status", title='smoking_status', width=400, height=400)
fig.update_layout(xaxis={'categoryorder':'total descending'})
fig.show()
"""
<li>1892 people are 'never smoked'</li>
<li>789 people are 'smoke'</li>

"""
"""
# Bivariate Analysis
"""

print (f'A person with hypertension has a probability of {round(df[df["hypertension"]==1]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person without hypertension has a probability of  {round(df[df["hypertension"]==0]["stroke"].mean()*100,2)} % get a stroke')
fig = px.histogram(df, x="hypertension", color="stroke",width=400, height=400)
fig.show()
"""
<li>As we have seen, stroke probability for those who has hypertension are quite different than for those who don't.</li>
<li>%13.2 and %3.9 respectively</li>
<li>It means that person with hypertension are almost 3.3 time more likely to get stroke than the ones who don't have hypertension.</li>
"""
"""
<h4>Gender & Stroke</h4>
"""

print (f'A female person has a probability of {round(df[df["gender"]=="Female"]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A male person has a probability of {round(df[df["gender"]=="Male"]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person from  the other category of gender has a probability of {round(df[df["gender"]=="Other"]["stroke"].mean()*100,2)} % get a stroke')

fig = px.histogram(df, x="gender", color="stroke",width=400, height=400)
fig.show()
"""
<li>Male compare to female are more likelyto get stroke, but difference between female and male is very small.</li>
"""
"""
<h4>Heart Disease & Stroke</h4>
"""
print (f'A person with heart disease has a probability of {round(df[df["heart_disease"]==1]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person without heart disease has a probability of {round(df[df["heart_disease"]==0]["stroke"].mean()*100,2)} % get a stroke')

fig = px.histogram(df, x="heart_disease", color="stroke",width=400, height=400)
fig.show()
"""
<Li>As we have seen, stroke probability for those who has heart disease are quite different than for those who don't.</li>
<li>17.03% and 4.18% respectively</li>
<li>It means that person with heart diease are 4.07 times more likely to get stroke than the ones who don't have heart disease.</li>
"""
"""
<h4>Married & Stroke</h4>
"""

print (f'A person married (or married before) has a probability of {round(df[df["ever_married"]=="Yes"]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person never married has a probability of {round(df[df["ever_married"]=="No"]["stroke"].mean()*100,2)} % get a stroke')

fig = px.histogram(df, x="ever_married", color="stroke",width=400, height=400)
fig.show()
"""
<li>person is married(or married before) are 5.7 times more likely to get stroke than the ones who don't have marriage history.</li>
"""
"""
<h4>Smoking & Stroke</h4>
"""
print (f'A formerly smoked person has a probability of {round(df[df["smoking_status"]=="formerly smoked"]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person never smoked has a probability of {round(df[df["smoking_status"]=="never smoked"]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person smokes has a probability of {round(df[df["smoking_status"]=="smokes"]["stroke"].mean()*100,2)} % get a stroke')

print()

print (f'A person whom smoking history is not known,has a probability of {round(df[df["smoking_status"]=="Unknown"]["stroke"].mean()*100,2)} % get a stroke')

print()


fig = px.histogram(df, x="smoking_status", color="stroke",width=600, height=600)
fig.show()
"""
<li>There are differeneces based on the smoking habits.</li>
<li>A formerly smoked person has a probability to get stroke 1.66 times more than person never smoked.</li>
<li>A person smokes has a a probability to get stroke 1.11 times more than person never smoked.</li>
<li>It is smal difference between who smokes and who does not smoke in regard to probability of getting stroke.</li>
"""
"""
# Correlation matrix & Scatter Plot
"""
df[numerical].corr()
"""
<li>There is very small positive correlaation between numerical features</li>
"""
"""
<h4>Age & BMI</h4>
"""
fig = px.scatter(df,x="age",y="bmi",title="Age & BMI",color="stroke")
fig.show()
"""
<li>From this view , we can say that the patient having age more than 40 and bmi between 15-60 are likely to have stroke.</li>
"""
"""
## Label Encoder
"""
enc = LabelEncoder()
gender=enc.fit_transform(df['gender'])
smoking_status=enc.fit_transform(df['smoking_status'])
work_type=enc.fit_transform(df['work_type'])
Residence_type=enc.fit_transform(df['Residence_type'])
ever_married=enc.fit_transform(df['ever_married'])
df['ever_married']=ever_married
df['Residence_type']=Residence_type
df['smoking_status']=smoking_status
df['gender']=gender
df['work_type']=work_type
df.head()
#lets fill the missing values in "bmi" column
df['bmi'] = df['bmi'].fillna(df['bmi'].mean())
df.isnull().sum()
#lets make age column int
df['age']=df['age'].astype('int')
df.info()
"""
# Splitting the data into training and testing
"""
X = df.drop('stroke',axis=1)
y = df["stroke"]
X_train,X_test,y_train,y_test=train_test_split(X,y,test_size=0.3,random_state=123)
"""
## Standard scalar 
"""
sc = StandardScaler()
X_train = sc.fit_transform(X_train)
X_test = sc.transform(X_test)
"""
# Handeling imbalance data
"""
"""
<h4> We will be using SMOTE technique to handle the imbalance data</h4>
"""

print("Before OverSampling, counts of label '1': {}".format(sum(y_train==1)))
print("Before OverSampling, counts of label '0': {} \n".format(sum(y_train==0)))

sm = SMOTE(random_state=2)
X_train_res, y_train_res = sm.fit_resample(X_train, y_train.ravel())

print('After OverSampling, the shape of train_X: {}'.format(X_train_res.shape))
print('After OverSampling, the shape of train_y: {} \n'.format(y_train_res.shape))

print("After OverSampling, counts of label '1': {}".format(sum(y_train_res==1)))
print("After OverSampling, counts of label '0': {}".format(sum(y_train_res==0)))
"""
<h4>Data is now balanced ;) </h4>
"""
"""
# Modeling
"""
xgb_model = XGBClassifier()
xgb_model.fit(X_train_res, y_train_res)
print('Training Score: {}'.format(xgb_model.score(X_train_res, y_train_res)))

print('Test Score: {}'.format(xgb_model.score(X_test, y_test)))
"""
## Thanks for reading!! Please upvote if you like it ;)
"""