CoolFace
Apppublic

deepthiaj/Electro_oneAPI

sourceHugging Faceupdated 3y agoView on Hugging Face
3likes
xgb1.md313 linesDownload Raw Back to root
1import streamlit as st2import pandas as pd 3import pickle4import xgboost as xgb5import numpy as np6import sklearn 7from sklearn.metrics import confusion_matrix, classification_report8import seaborn as sns9import matplotlib.pyplot as plt10# from streamlit_pandas_profiling import st_profile_report11# from st_aggrid import AgGrid12from io import StringIO13from scipy import signal14import ecg_plot15import daal4py as d4p16 17st.title("Automated Diagnosis of Heart Disease from Electro-Cardiogram")18st.write('This is a prototype for checking heart health condition. The performance of the model has been achieved using XGboost ML algorithm.')19st.write('Please select the data and the model from the dropdown menu on the left panel to see the working of this prototype.')20 21st.divider()22 23enc_dat = pd.read_csv("PTB_ECGencoded_dat.csv")24 25# Split the dataset into features (X) and target (y)26X = enc_dat.iloc[:, :-1].values  # Features (all columns except the last one)27y = enc_dat.iloc[:, -1].values   # Target (last column "diagnosis")28# Map the existing class labels to the expected class values29class_mapping = {0: 0, 1: 1, 3: 2, 4: 3, 6: 4, 7: 5}30mapped_labels = np.array([class_mapping[label] for label in y])31 32# Define the model parameters33model_params = {34    'objective': 'multi:softmax',35#     'num_class': 10,36    'num_class': 6,  # Adjust the number of classes accordingly37    'random_state': 4238}39 40# Create and train the XGBoost model41xgb_model = xgb.XGBClassifier(**model_params)42# xgb_model.fit(X, y)43xgb_model.fit(X, mapped_labels)44 45 46 47 48daal_model = d4p.get_gbt_model_from_xgboost(xgb_model.get_booster())49 50 51 52 53 54 55 56# # Train an XGBoost model57# params = {58#     'objective': 'multi:softmax',59#     'num_class': 10,60#     'random_state': 4261# }62 63# xgb_model = xgb.XGBClassifier(**params)64# xgb_model.fit(X, y)65 66 67# test_data = pd.read_csv("PTB_ECGencoded_dat.csv")68# X_test = test_data.iloc[:, :-1].values69# y_test = test_data.iloc[:, -1].values70# # Map the existing class labels to the expected class values71# class_mapping = {0: 0, 1: 1, 3: 2, 4: 3, 6: 4, 7: 5}72# mapped_labels = np.array([class_mapping[label] for label in y_])73# Choose a test data point74# ecg_test_data = X_test[0]  75 76 77 78 79    80st.subheader("Performance evaluation of the Automated Diagnosis Model")81 82 83if st.button('ECG analysis of Patient001'):84    # patient001_signal_analysis()   to visualize data analysis of single patient upon a button click85    st.write('give plots and heart rate analysis. Please upload ECG signal data in specified format below for analysis')86    # refer PTB website for format87    # call preprocessing module88    # call ecg_analysis()89 90st.divider()91    # # Evaluate the model on the entire dataset92y_pred = xgb_model.predict(X)93accuracy = np.sum(y_pred == mapped_labels) / len(mapped_labels)  # Calculate accuracy94    # print(f"Accuracy: {accuracy}")95acc = (accuracy / 1) * 10096st.write("The accuracy of the diagnosis report is: ", acc, "%")97 98 99# Make a faster prediction with oneDAL100daal_prediction = d4p.gbt_classification_prediction(nClasses = n_classes).compute(X_test, daal_model).prediction101 102# # List all results that you need by placing '|' between them103# predict_algo = d4p.104#  gbt_classification_prediction(nClasses = n_classes,105#  resultsToEvaluate = "computeClassLabels|computeClassProbabilities")106# daal_prediction = predict_algo.compute(X_test, model)107# # Get probabilities:108# probabilities = daal_prediction.probabilities109# # Get labels:110# labels = daal_prediction.prediction111    112st.divider()113    114    # # Evaluate the model on the entire dataset115    # y_pred = loaded_model.predict(X)116    117    # # Calculate evaluation metrics118classification_metrics = classification_report(mapped_labels, y_pred, output_dict=True)119st.caption(":blue[Classification Metrics]")120# classification_metrics = [classification_metrics]121# cm = classification_metrics.insert(0,'metrics')122st.table(classification_metrics)123# st.json(classification_metrics)124st.write("1: Myocardial infarction, 2: Bundle branch block, 3: Dysrhythmia , 4: Valvular heart disease, 5: Myocarditis")125 126st.divider()127    # # Calculate confusion matrix128confusion_mat = confusion_matrix(mapped_labels, y_pred)129# st.write("Confusion matrix:")130    131    # # Plot confusion matrix132plt.figure(figsize=(10, 8))133htmap = sns.heatmap(confusion_mat, annot=True, fmt="d", cmap="Blues")134plt.title("Confusion Matrix")135plt.xlabel("Predicted Class")136plt.ylabel("True Class")137plt.show()138htmap = htmap.figure139st.pyplot(htmap)140    141 142st.divider()143    # Format signal info & preprocessing module for generating X[0] to diagnose from an external input data & give a dropbox to enter a single patient ecg data in .dat and .hea format144 145 146 147 148 149 150patient_enc_data = {"Patient001":X[0],"Patient002":X[100],"Patient003":X[200],"Patient004":X[50],"Patient005":X[40],"Patient006":X[30],"Patient007":X[20],"Patient008":X[10],"Patient009":X[60],"Patient010":X[110],"Patient011":X[120],"Patient012":X[130],"Patient013":X[140],"Patient014":X[150],"Patient015":X[160],"Patient016":X[170],"Patient017":X[180],"Patient018":X[190],"Patient019":X[210],"Patient020":X[220],"Patient021":X[21],"Patient022":X[22],"Patient023":X[23],"Patient024":X[24],"Patient025":X[25],"Patient026":X[26],"Patient027":X[27],"Patient028":X[28],"Patient029":X[29],"Patient030":X[31],"Patient031":X[41],"Patient032":X[42],"Patient033":X[43],"Patient034":X[44],"Patient035":X[45],"Patient036":X[46],"Patient037":X[47],"Patient038":X[48],"Patient039":X[49],"Patient040":X[51],"Patient41":X[61],"Patient042":X[62],"Patient043":X[63],"Patient044":X[64],"Patient045":X[65],"Patient046":X[66],"Patient047":X[67],"Patient048":X[68],"Patient049":X[69],"Patient050":X[71], }151patient_ecg_sel = st.selectbox( "Select a ECG of a patient from the list", list(patient_enc_data.keys()))152 153 154 155 156def ecg_analysis(ecg_test_data):157    158    # Classify the test data point159    predicted_class = xgb_model.predict(np.array([ecg_test_data]))160    161    162    st.subheader("Diagnosis Report")163    # Define the mapping of diagnosis labels to numerical values164    # diagnosis_mapping = {165    #     "Myocardial infarction": 1,166    #     "Cardiomyopathy/Heart failure": 2,167    #     "Bundle branch block": 3,168    #     "Dysrhythmia": 4,169    #     "Myocardial hypertrophy": 5,170    #     "Valvular heart disease": 6,171    #     "Myocarditis": 7,172    #     "Miscellaneous": 8,173    #     "Healthy controls": 9174    # }175    176    if predicted_class[0] == 0:177        st.write("Sorry, We cannot give your diagnosis report at the moment. Kindly consult a doctor in person.")178    elif predicted_class[0] == 1:179        st.write("You are diagnosed with Myocardial infarction.")180        st.write("Kindly consult a doctor to take the necessary treatment.")181    elif predicted_class[0] == 2:182        st.write("You are diagnosed with Bundle branch block.")183        st.write("Kindly consult a doctor to take the necessary treatment.")184    elif predicted_class[0] == 3:185        st.write("You are diagnosed with Dysrhythmia.")186        st.write("Kindly take consult a doctor to the necessary treatment.")187    elif predicted_class[0] == 4:188        st.write("You are diagnosed with Valvular heart disease.") 189        st.write("Kindly consult a doctor to take the necessary treatment.")190    elif predicted_class[0] == 5:191        st.write("You are diagnosed with Myocarditis.")  192        st.write("Kindly consult a doctor to take the necessary treatment.")193    else:194        st.write("Sorry, We cannot give your diagnosis report at the moment. Kindly consult a doctor in person.")195    196 197 198if st.button("Analyze Raw ECG"):199#     # if new_data:200#         # new_patient_data_preprocessing()201#     # else:202         ecg_train_dat = pd.read_csv("PTB_ECGdata.csv")203#         # AgGrid(ecg_train_dat)204#         # pr = ecg_train_dat.profile_report()205#         # st_profile_report(pr)206#         # st.write('To be updated!')207#         # Count the occurrences of each unique value in the "diagnosis" column208         diagnosis_counts = ecg_train_dat["diagnosis"].value_counts()209        210#         # Create a bar plot211#         plot0 = plt.bar(diagnosis_counts.index, diagnosis_counts)212        213#         # Rotate x-axis labels for better readability214#         plt.xticks(rotation=65)215        216#         # Add labels and title217#         plt.xlabel("Diagnosis")218#         plt.ylabel("Count")219#         plt.title("Distribution of Diagnosis")220        221#         # Adjust layout to prevent overlapping of labels222#         plt.tight_layout()223        224#         # Display the chart225#         plt.show()226#         st.pyplot(plot0)227         st.bar_chart(diagnosis_counts)228    229def new_patient_data_preprocessing(new_data):230    231    # code to preprocess .dat and .hea files from PTB ecg database, check one from ptb xl as external new data & convert it into .csv & encode to pass it as an argument to call ecg_analysis function232    st.write('')233 234 235def single_patient_signal_analysis(csv_path):236    df = pd.read_csv(csv_path)237#    print(df.keys(), df.shape)238 239    # ecg_plot.plot(df, sample_rate = 500, title='ECG')240    #ecg_plot.save_as_png('ecg','ecg_plots/')241    242    # Plot ECG waveform243    plt.figure(figsize=(12, 4))244    p0 = plt.plot(df["i"])245    plt.title("ECG Waveform")246    plt.xlabel("Sample Number")247    plt.ylabel("Amplitude (mV)")248    plt.show()249    #p0=p0.figure250    #st.pyplot(p0)251    #st.write(p0)252    253    # Calculate and plot PSD of ECG waveform254    f, Pxx = signal.welch(df["i"], fs=360, nperseg=1024)255    plt.figure(figsize=(12, 4))256    p1=plt.plot(f, Pxx)257    plt.title("Power Spectral Density (PSD) of ECG Waveform")258    plt.xlabel("Frequency (Hz)")259    plt.ylabel("PSD")260    plt.show()261    #p1 =p1.figure262    #st.pyplot(p1)263    264    # Calculate heart rate (HR)265    qrs_peaks, _ = signal.find_peaks(df["i"], height=0.5)266    duration = len(df) / 360  # total duration of recording in seconds267    hr = len(qrs_peaks) / duration268    st.write("Heart Rate:", hr, "bpm")269    st.write("The patient has been diagnosed with ",df.loc[0]["diagnosis"])270    271    # Calculate mean and standard deviation of RR interval272    rr_intervals = [qrs_peaks[i] - qrs_peaks[i-1] for i in range(1, len(qrs_peaks))]273    mean_rr = sum(rr_intervals) / len(rr_intervals) / 360  # convert to seconds274    std_rr = (sum((rr - mean_rr*360)**2 for rr in rr_intervals) / (len(rr_intervals) - 1) / 360)**0.5  # convert to seconds275    st.write("Mean RR Interval:",nmean_rr, "s")276    st.write("Standard Deviation of RR Interval:",nstd_rr ,"s")277    278    # Calculate mean and standard deviation of QRS amplitude279    mean_qrs_amp = df.loc[qrs_peaks, "i"].mean()280    std_qrs_amp = df.loc[qrs_peaks, "i"].std()281    st.write("Mean QRS Amplitude:", mean_qrs_amp, "mV")282    st.write("Standard Deviation of QRS Amplitude:", std_qrs_amp, "mV" )283 284 285 286    287# st.write("")288# uploaded_file = st.file_uploader("Upload ECG file")289# if uploaded_file is not None:290 291#     # Can be used wherever a "file-like" object is accepted:292#     dataframe = pd.read_csv(uploaded_file)293#     st.write(dataframe)294 295if st.button("Check Heart health"):296    ecg_test_data = patient_enc_data[patient_ecg_sel]297    st.write("Diagnosis report of", patient_ecg_sel)298    # st_profile_report(ecg_test_data)299    ecg_analysis(ecg_test_data)300else:301    st.write("Diagnosis report of Patient001")302    ecg_test_data = X[0]      303    ecg_analysis(ecg_test_data)304    305    306 307 308if st.button('Signal Analysis of Single Patient ECG'):309    single_patient_signal_analysis("s0010_re.csv")310 311 312 313