<jupyter_start><jupyter_text>predicting the heart-disease using machine-learning  1 problem defintion> given clinical data of a petient try to predict a binary prediction whether they have heart-disease or not  2 data> the data set here we use is UCI machine learning repository > link http://archive.ics.uci.edu/ml/datasets/Heart+Disease> https://www.kaggle.com/ronitf/heart-disease-uci  3. evaluation> if we get 95% of whether the person have heart disease or not during the proof of concept we persue our project  4. features> **create data dictionary****information about our featureas*** ageage in years* sex(1 = male; 0 = female)* cpchest pain type* trestbpsresting blood pressure (in mm Hg on admission to the hospital)* cholserum cholestoral in mg/dl* fbs(fasting blood sugar > 120 mg/dl) (1 = true; 0 = false)* restecgresting electrocardiographic results* thalachmaximum heart rate achieved* exangexercise induced angina (1 = yes; 0 = no)* oldpeakST depression induced by exercise relative to rest* lopethe slope of the peak exercise ST segment* canumber of major vessels (0-3) colored by flourosopy* thal3 = normal; 6 = fixed defect; 7 = reversable defect* target1 or 0<jupyter_code># preparing the tools
#import pandas, numpy, matplotlib,
 


import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline
# import model 
from sklearn.linear_model import LogisticRegression
from sklearn.neighbors import KNeighborsClassifier
from sklearn.ensemble import RandomForestClassifier

# import model evaluation
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.model_selection import RandomizedSearchCV, GridSearchCV
from sklearn.metrics import confusion_matrix, classification_report
from sklearn.metrics import precision_score, recall_score, f1_score
from sklearn.metrics import roc_curve<jupyter_output>C:\anaconda3\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
  import pandas.util.testing as tm<jupyter_text>load data<jupyter_code>data = pd.read_csv("heart-disease.csv")
# data.isna().sum() no missing data<jupyter_output><empty_output><jupyter_text>data exploration or EDA* what question are you going to solve* what kind of data do you have and how to work with it* is there a nissing data how u fix that if you have * how can you add,change or remove features to get the best output<jupyter_code>#df["target"].value_counts()
#df["target"].value_counts().plot(kind="bar", color = ["red","green"]);
#df.info()
#df.describe()<jupyter_output><empty_output><jupyter_text>heart disease frequency according to sex<jupyter_code>#data["sex"].value_counts()    below also the same
data.sex.value_counts()
pd.crosstab(data.target,data.sex).plot(kind="bar",
                                   figsize=(10,6),
                                   color = ["salmon", "lightblue"]);
plt.title("heart disease men vs womens")
plt.xlabel("0 = no-disease, 1 = disease")
plt.ylabel("amount")
plt.legend(["female", "men"])
plt.xticks(rotation=0);
                                    
data.head()<jupyter_output><empty_output><jupyter_text>age vs max. heart rate for heart-disease<jupyter_code># lets plot
plt.figure(figsize = (10,6))
# positive plot
plt.scatter(data.age[data.target == 1],
           data.thalach[data.target == 1],
           color = "salmon")
# negative plot
plt.scatter(data.age[data.target == 0],
           data.thalach[data.target == 0]);
plt.title("age vs max. heart rate for heart-disease")
plt.xlabel("age")
plt.ylabel("max. heart rate (thalach)")
plt.legend(["positive", "negative"]);
#pd.crosstab(data.target, data.sex)
# let see the distribution of the age

#data.age.plot(kind = "hist"); # or
data.age.plot.hist(color = "salmon");<jupyter_output><empty_output><jupyter_text>chest pain<jupyter_code>pd.crosstab(data.cp, data.target)

pd.crosstab(data.cp, data.target).plot(kind = "bar",
                                      figsize = (10,6),
                                      color = ("lightblue","salmon"));
plt.title("chest pain type in heart disease")
plt.xlabel("chest pain type")
plt.ylabel("amount")
plt.legend(["no - disease", "have dsease"])
plt.xticks(rotation = 0);<jupyter_output><empty_output><jupyter_text>make a correlation matrix<jupyter_code>data.corr()
# lets visualize it 
# using seaborn heatmap

corr_max = data.corr()

fig, ax = plt.subplots(figsize = (15,10))
ax = sns.heatmap(corr_max,
              annot = True,
               linewidth = 0.5,
              fmt = ".2f",
              cmap = "YlGnBu")
# to correct bottom and top cut
bottom, top = ax.get_ylim()
ax.set_ylim(bottom + 0.5, top - 0.5);<jupyter_output><empty_output><jupyter_text>5. Modeling<jupyter_code># lets see our data
data.head()
# split data in to x and y
x = data.drop("target", axis = 1)
y = data["target"]
 # split data in to train and test set
# random seed for randomness of result
np.random.seed(42)
x_train, x_test, y_train, y_test = train_test_split(x, y, test_size = 0.2)

# put model in dictionary

models = {"logistic regression": LogisticRegression(),
        "KNN": KNeighborsClassifier(),
        "Random Forest": RandomForestClassifier()}

# create a function to score and fit
def fit_and_score(models, x_train, x_test, y_train, y_test):
    """
    fit and evaluate given machine learning model
    """
    # set random seed
    np.random.seed(42)
    # make a dictionary to store a score
    model_score = {}
    #loop through models
    
    for name,model in models.items():
        #fit the model
        model.fit(x_train, y_train)
        #evaluate the model and append its value to model score
        model_score[name] = model.score(x_test, y_test)
        
    return model_score
model_score = fit_and_score(models=models,
                            x_train = x_train,
                            x_test = x_test,
                            y_train = y_train,
                            y_test = y_test)
model_score<jupyter_output><empty_output><jupyter_text>model comparsion<jupyter_code># lets visualize that
model_comparsion = pd.DataFrame(model_score,index=["accuracy"])
model_comparsion.T.plot(kind = "bar");
plt.xticks(rotation = 0)
#this is the baseline model result so it can be tune up to better result by adjusting hyperparameters  
# model.get_params()<jupyter_output><empty_output><jupyter_text>**lets look at the following*** hyperparameter tunning* feature importance* confusion matrix* cross_validation* precision* recall* f1 score* classification report* roc curve* area under the curve (AUC) HYPERPARAMETER TUNING **using by hand for KNN**<jupyter_code># lets tunn KNN
# create storing list 
train_score = []
test_score = []
knn = KNeighborsClassifier()

# tunning parameter is nighbors
neighbors = range(1,21)

for i in neighbors:
    # set parameters
    knn.set_params(n_neighbors  = i)
    knn.fit(x_train,y_train)
    # update the list for stor the score
    train_score.append(knn.score(x_train, y_train))
    test_score.append(knn.score(x_test, y_test))

#test_score
# lets visualize it
plt.plot(neighbors,train_score, label = "train score")
plt.plot(neighbors, test_score, label = "test score")
plt.xticks(np.arange(1,21,1))
plt.xlabel("number of neighbors")
plt.ylabel("model accuracy score")
plt.legend()


print(f"the maximum accuracy of KNN score on test data is : {max(test_score)*100:.2f}%")
clf = LogisticRegression()
clf.get_params()<jupyter_output><empty_output><jupyter_text>hyperparameter tuning with randomizedsearchCV **logestic regression**<jupyter_code># create hyperparameter grid for logistic regression
#clf = LogisticRegression()
#clf.get_params()


log_reg_grid = {"C":np.logspace(-4, 4,20),
               "solver": ["liblinear"]}

#create hyperparameter for random forest
rf_grid = {"n_estimators": np.arange(10,1000,50),
          "max_depth": [None, 3, 5, 10],
           "min_samples_split": np.arange(2,20,2),
           "min_samples_leaf": np.arange(1,20,2)
          }
# tuning logistic regression
np.random.seed(42)
# model using randomizedsearchcv
clf_lgr = RandomizedSearchCV(estimator=LogisticRegression(),
                             param_distributions=log_reg_grid,
                            n_iter=20,
                            cv = 5,
                            verbose=True)
# fit to new model
clf_lgr.fit(x_train, y_train)
clf_lgr.best_params_
clf_lgr.score(x_test, y_test)<jupyter_output><empty_output><jupyter_text>**tuning random forest**<jupyter_code>np.random.seed(42)
clf2 = RandomForestClassifier()
clf_rf = RandomizedSearchCV(estimator=clf2,
                             param_distributions=rf_grid,
                            n_iter=20,
                            cv = 5,
                            verbose=True)
# fit to the model
clf_rf.fit(x_train, y_train)
# the best hyperparameters
clf_rf.best_params_
# evaluation
clf_rf.score(x_test, y_test)<jupyter_output><empty_output><jupyter_text>hyperparameter tuning with GridSearchCV<jupyter_code># create hyperparameter

# for logisticregression
log_grid = {"C":np.logspace(-4, 4,30),
               "solver": ["liblinear"]}

# model using new gridsearchcv

clf_gsc = GridSearchCV(LogisticRegression(),
                      param_grid=log_grid,
                      cv = 5,
                      verbose=True)
clf_gsc.fit(x_train, y_train)
# evaluaion
clf_gsc.score(x_test, y_test)
# check the best hyperparameters
clf_gsc.best_params_<jupyter_output><empty_output><jupyter_text>**evaluation and accuracy of tunned models** * ROC curve* confusion matrix* classification report* precision score* recall score* F1 - score<jupyter_code># lets get y_preds (the predictin)
y_preds = clf_gsc.predict(x_test)
y_preds
# compare with y_test
# ROC is the ratio of true positive rate vs false positive rate
# import roc

def plot_roc_cur(fper, tper):  
    plt.plot(fper, tper, color='orange', label='ROC')
    #plt.plot([0, 1], [0, 1], color='darkblue', linestyle='--')
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver Operating Characteristic (ROC) Curve')
    plt.legend()
    plt.show()
    
fper, tper, thresholds = roc_curve(y_test, y_preds) 
plot_roc_cur(fper, tper)
# confussion matrix
print(confusion_matrix(y_test, y_preds))
# using seaborn plot confusion matrix  heatmap

sns.set(font_scale=1.5)

def confu_mat_plot(y_test, y_preds):
    fig, ax = plt.subplots(figsize = (3,3))
    ax = sns.heatmap(confusion_matrix(y_test, y_preds),
                    annot = True,
                    cbar=False)
    plt.xlabel("true label")
    plt.ylabel("predicted label")
    
    
    bottom, top = ax.get_ylim()
    ax.set_ylim(bottom + 0.5, top - 0.5);
confu_mat_plot(y_test, y_preds)


#classification report

print(classification_report(y_test,y_preds))<jupyter_output>precision    recall  f1-score   support

           0       0.89      0.86      0.88        29
           1       0.88      0.91      0.89        32

    accuracy                           0.89        61
   macro avg       0.89      0.88      0.88        61
weighted avg       0.89      0.89      0.89        61<jupyter_text>calculate evaluation materics using  cross_validation<jupyter_code>clf_gsc.best_params_
# create the new classification mode using the best parameters of logisticregression model

clf = LogisticRegression(C = 0.20433597178569418,
                        solver = "liblinear")
clf.fit(x_train, y_train)
clf.score(x_test, y_test)
y_preds = clf.predict(x_test)

# lets use cross_val for accuracy
cr_val_accuracy = cross_val_score(clf,
                                 x,
                                 y,
                                 cv = 5,
                                 scoring="accuracy")
cr_val_accuracy
accuracy = np.mean(cr_val_accuracy)
# crossvalidation on precision
cr_val_precision = cross_val_score(clf,
                                 x,
                                 y,
                                 cv = 5,
                                 scoring="precision")
cr_val_precision
precision = np.mean(cr_val_precision)
# crossvalidation on recall
cr_val_recall = cross_val_score(clf,
                                 x,
                                 y,
                                 cv = 5,
                                 scoring="recall")
cr_val_recall
recall = np.mean(cr_val_recall)
# crossvalidation on F1
cr_val_F1 = cross_val_score(clf,
                                 x,
                                 y,
                                 cv = 5,
                                 scoring="f1")
cr_val_F1
F1 = np.mean(cr_val_F1)
print(f"the accuracy of logistic regression model is: {np.mean(cr_val_accuracy)*100:.2F}%")
print(f"the precision of logistic regression model is: {np.mean(cr_val_precision)*100:.2F}%")
print(f"the recall score of logistic regression model is: {np.mean(cr_val_recall)*100:.2F}%")
print(f"the F1 score of logistic regression model is: {np.mean(cr_val_F1)*100:.2F}%")
#metrics.SCORERS.keys()
# visualization

cv_metics = pd.DataFrame({"accuracy score":np.mean(cr_val_accuracy),
                         "precision score": np.mean(cr_val_precision),
                         "recall score": np.mean(cr_val_recall),
                         "f1 score": np.mean(cr_val_F1)},
                        index=[0])
#cv_metics.plot.bar()
cv_metics.T.plot.bar(title = "cross validation metrics classification",
                    legend = False);
#plt.xticks(rotation=0)<jupyter_output><empty_output><jupyter_text>feature importance<jupyter_code>clf = LogisticRegression(C = 0.20433597178569418,
                        solver = "liblinear")
clf.fit(x_train, y_train);
data.head()
# coefficients
clf.coef_
# mach coeffecient of feature to columns

feature_dict = dict(zip(data.columns, list(clf.coef_[0])))
feature_dict
# lets visualize  it shows the relation between the feature for the target
featue_df = pd.DataFrame(feature_dict,index = [0])
featue_df.T.plot.bar(title = "feature importace",
                legend = False);
pd.crosstab(data["sex"], data["target"])
pd.crosstab(data["cp"],data["target"])<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10570363598002673, 'fraction_numerical': 0.017652436880230677, 'mean_word_length': 3.094442844802764, 'pattern_counts': {'":': 15, '<': 63, '<?xml version=': 0, '>': 70, 'https://': 1, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 17, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '262101', 'license': 'Apache-2.0', 'n_tokens_mistral': 4825, 'n_tokens_neox': 4543, 'n_words': 1140, 'path': 'project_one (heart-disease).ipynb', 'repo_name': 'dawitmamo/ds_and_ML', 'size': '14219'}