<jupyter_start><jupyter_text>Análise de Dados de Pacientes de Doenças Cardíacas- Fonte: *Heart Disease Data Set* - Kaggle (https://www.kaggle.com/ronitf/heart-disease-uci)- Objetivo: Explorar as conexões entre doenças cardíacas e outras condições e características dos pacientes.> Este notebook depende do *dataset* mantido pelo usuário *ronit* na plataforma kaggle. Baixe o dataset no site indicado acima (requer *login*) e o desempacote na mesma pasta que este notebook.  Importando as bibliotecas e acessando os dados<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.decomposition import PCA
from sklearn.preprocessing import (
    OneHotEncoder,
    scale
)

data = pd.read_csv('heart.csv')
data.head()<jupyter_output><empty_output><jupyter_text>Segundo informações fornecidas pelo mantenedor do dataset, as colunas referem-se a:- age: idade em anos;- sex: sexo.     - 0: feminino    - 1: masculino- cp: tipo de dor no peito.    - 0: angina típica    - 1: angina atípica    - 2: dor não anginosa    - 3: assintomático- trestbps: pressão sanguínea em repouso. Em mmHg.- chol: colesterol sérico em mg/dl.- fbs: nível de açucar no sangue.    - 0: menor que 120 mg/dl    - 1: maior que 120 mg/dl- restecg: resultados eletrocardiográficos em repouso.    - 0: normal    - 1: tendo anormalidade da onda ST-T (inversões da onda T e/ou elevação ou depressão ST > 0,05 mV)    - 2: mostrando hipertrofia ventricular esquerda provável ou definitiva pelos critérios Estes.- thalach: frequência cardíaca máxima alcançada.- exang: presença de angina induzida por exercício.    - 0: não    - 1: sim- oldpeak: depressão de ST induzida por exercício em relação ao repouso.- slope: inclinação do segmento ST no pico do esforço.    - 0: subida    - 1: plano    - 2: descida- ca: número de vasos principais (0-3) coloridos por fluorosopia.- thal: resultado do teste de estresse.    - 3: normal    - 6: defeito fixo    - 7: defeito reversível- target: presença/ausência de condição cardíaca.    - 0: ausência    - 1: presença  Análise Univariada<jupyter_code>data.shape
data.info()
data.describe()<jupyter_output><empty_output><jupyter_text>Observações iniciais:- O *dataset* não apresenta dados faltantes.- Segundo o dicionário apresentado (e observação dos dados), variáveis categóricas estão representadas de forma numérica.- O *dataset* se encontra ligeiramente desbalanceado (o número de pacientes com condições cardíacas é um pouco maior que o de pacientes que não apresentam estas condições).- A faixa de idade dos pacientes é entre 29 e 77 anos, sendo que a maioria (75%) possui idade superior a 47 anos.- A maioria dos pacientes são do sexo masculino.- A maioria dos pacientes (cerca de 75%) não apresenta pressão alta em repouso (igual ou acima de 140mmHg, segundo heart.org).- A maioria dos pacientes (acima de 75%) apresenta colesterol alto (acima de 200mg/dl, segundo medlineplus.gov).- O nível de açucar no sangue da maioria dos pacientes se encontra abaixo de 120mg/dl.- A maioria dos pacientes não apresentou angina no teste de estresse.<jupyter_code># Seaborn configurations
fig_dims = (10, 6)

sns.set_theme(
    palette='hot',
    style='whitegrid',
    font_scale=1.2,
    rc={'figure.figsize':fig_dims}
)
# Age
age_plt = sns.histplot(
    data=data,
    x='age',
    kde=True,
    binwidth=1
)
age_plt.set(title='Patient Age Distribution', xlabel='Age')
plt.show()

plt.title("Age Boxplot")
plt.boxplot(data['age'], labels=[''])
plt.show()

print('Patients Age Descriptive Statistics\n')
print(data['age'].describe())<jupyter_output><empty_output><jupyter_text>O gráfico da distribuição das idades dos pacientes, acima, demonstra que a maioria dos pacientes encontra-se, aproximadamente, entre 50 e 65 anos (esta observação é compatível com o observado nos quartis da variável, em que 50% dos pacientes encontram-se entre 47 e 61 anos).<jupyter_code># Gender
aux = data.copy()
aux.loc[aux['sex'] == 0, 'sex'] = 'Female'
aux.loc[aux['sex'] == 1, 'sex'] = 'Male'

gender_plt = sns.histplot(
    data=aux,
    x='sex',
    hue='sex',
    palette=['b','r'],
    legend=False,
    shrink=.7
)
gender_plt.set(title='Patient Gender Count', xlabel='Gender')
plt.show()<jupyter_output><empty_output><jupyter_text>O número de pacientes homens é mais que o dobro do número de pacientes mulheres.<jupyter_code># Chest Pain
aux = data.copy()
aux.loc[aux['cp'] == 0, 'cp'] = 'Typical Angina'
aux.loc[aux['cp'] == 1, 'cp'] = 'Atypical Angina'
aux.loc[aux['cp'] == 2, 'cp'] = 'Non-anginal Pain'
aux.loc[aux['cp'] == 3, 'cp'] = 'Asymptomatic'

chest_pain_plt = sns.histplot(
    data=aux,
    x='cp',
    hue='cp',
    legend=False
)
chest_pain_plt.set(title='Types of Chest Pain Count', xlabel='Chest Pain Type')
chest_pain_plt.invert_xaxis()
plt.show()

print('Types Of Chest Pain Percents\n')
print((aux['cp'].value_counts()/len(aux['cp']))*100)<jupyter_output><empty_output><jupyter_text>Aproximadamente metade (47%) dos pacientes apresentou angina típica. \Mais de um quarto dos pacientes (28.7%) apresentou dor não anginosa. \16.5% apresentou angina atípica e apenas 7.6% se apresentou assintomático.<jupyter_code># Blood Pressure
blood_pressure_plt = sns.kdeplot(
    data=data['trestbps'],
    shade=True
)
blood_pressure_plt.set(title='Blood Pressure Distribution', xlabel='Blood Pressure')
plt.show()

plt.title("Blood Pressure Boxplot")
plt.boxplot(data['trestbps'], labels=[''])
plt.show()

print('Blood Pressure Descriptive Statistics\n')
print(data['trestbps'].describe())<jupyter_output><empty_output><jupyter_text>A maioria dos pacientes não apresenta pressão alta em repouso (acima de 140mmHg, segundo heart.org). \A variável apresenta alguns *outliers* no extremo superior (aprox. acima de 170mmHg). Neste caso é importante manter os *outliers*, dado a hipótese de que, quanto mais alta a pressão sanguínea, maior o risco de doenças cardíacas. Os *outliers*, portanto, permitem observar os "casos extremos" de pressão alta e sua relação com a ocorrência de condições cardíacas.<jupyter_code># Cholesterol
cholesterol_plt = sns.kdeplot(
    data=data['chol'],
    shade=True
)
cholesterol_plt.set(title='Serum Cholesterol Distribution', xlabel='Cholesterol')
plt.show()

plt.title("Serum Cholesterol Boxplot")
plt.boxplot(data['chol'], labels=[''])
plt.show()

print('Serum Cholesterol Descriptive Statistics\n')
print(data['chol'].describe())<jupyter_output><empty_output><jupyter_text>A distribuição do colesterol sérico é semelhante à da pressão sanguínea, o que faz sentido, dado a hipótese de que colesterol alto resulta em aumento da pressão. \A grande maioria (acima de 75%) dos pacientes apresenta colesterol alto (acima de 200mg/dl, segundo medlineplus.gov), com alguns casos extremos (*outliers*) apresentando colesterol sérico acima de 400mg/dl. \Semelhante ao caso da pressão sanguínea, é interessante manter os *outliers* do colesterol sérico de modo a observar a influência de níveis extremos na ocorrência de doênças cardíacas.<jupyter_code># Blood Sugar
aux = data.copy()
aux.loc[aux['fbs'] == 0, 'fbs'] = 'Under 120mg/dl'
aux.loc[aux['fbs'] == 1, 'fbs'] = 'Over 120mg/dl'

blood_sugar_plt = sns.histplot(
    data=aux,
    x='fbs',
    hue='fbs',
    legend=False,
    shrink=.7
)
blood_sugar_plt.set(title='Blood Sugar Levels', xlabel='')
blood_sugar_plt.invert_xaxis()
plt.show()

print('Blood Sugar Levels Percents\n')
print((aux['fbs'].value_counts()/len(aux['fbs']))*100)<jupyter_output><empty_output><jupyter_text>Cerca de 15% dos pacientes apresentaram nível alto de açucar no sangue. (o valor limite, 120mg/dl, foi apresentado no dicionário do data set).<jupyter_code># Electrocardiographic Results
aux = data.copy()
aux.loc[aux['restecg'] == 0, 'restecg'] = 'Normal'
aux.loc[aux['restecg'] == 1, 'restecg'] = 'ST-T Wave Abnormality'
aux.loc[aux['restecg'] == 2, 'restecg'] = 'Left Ventricular Hypertrophy'

ecg_plt = sns.histplot(
    data=aux,
    x='restecg',
    hue='restecg',
    legend=False,
    shrink=.9
)
ecg_plt.set(title='Resting Eletrocardiographic Results', xlabel='')
plt.show()

print('ECG Results Percents\n')
print((aux['restecg'].value_counts()/len(aux['restecg']))*100)<jupyter_output><empty_output><jupyter_text>Poucos pacientes (menos de 1.5%) apresentaram, nos resultados eletrocardiográficos, hipertrofia ventricular esquerda provável ou definitiva pelos critérios Estes. \Entre os pacientes restantes, aproximadamente metade apresentou anormalidade da onda ST-T.<jupyter_code># Heart Rate
heart_rate_plt = sns.kdeplot(
    data=data['thalach'],
    shade=True
)
heart_rate_plt.set(title='Maximum Heart Rate Distribution', xlabel='Heart Rate')
plt.show()

plt.title("Maximum Heart Rate Boxplot")
plt.boxplot(data['thalach'], labels=[''])
plt.show()

print('Heart Rate Descriptive Statistics\n')
print(data['thalach'].describe())<jupyter_output><empty_output><jupyter_text>A maioria dos pacientes apresentou frequência cardíaca máxima, no teste de estresse, entre 130 e 175, de acordo com o gráfico de distribuição. \A variável apresenta um *outlier* no extremo inferior. A remoção deste *outlier* fica sujeita a análises e resultados futuros já que pode, ou não, os afetar significantemente. Ele não aparenta ser erro no registro, portanto, de imediato, a recomendação é mantê-lo.<jupyter_code># Exercise Induced Angina
aux = data.copy()
aux.loc[aux['exang'] == 0, 'exang'] = 'No'
aux.loc[aux['exang'] == 1, 'exang'] = 'Yes'

exercise_angina_plt = sns.histplot(
    data=aux,
    x='exang',
    hue='exang',
    legend=False,
    shrink=.7
)
exercise_angina_plt.set(title='Exercise Induced Angina', xlabel='')
exercise_angina_plt.invert_xaxis()
plt.show()

print('Presence of Exercise Induced Angina Percents\n')
print((aux['exang'].value_counts()/len(aux['exang']))*100)<jupyter_output><empty_output><jupyter_text>Cerca de um terço (32.6%) dos pacientes apresentaram angina durante o exercício.<jupyter_code># ST Depression Induced By Exercise Relative To Rest
st_depression_plt = sns.kdeplot(
    data=data['oldpeak'],
    shade=True
)
st_depression_plt.set(title='ST Depression Induced By Exercise Relative To Rest Distribution', xlabel='')
plt.show()

plt.title("ST Depression Induced By Exercise Relative To Rest Boxplot")
plt.boxplot(data['oldpeak'], labels=[''])
plt.show()

print('ST Depression Descriptive Statistics\n')
print(data['oldpeak'].describe())<jupyter_output><empty_output><jupyter_text>Segundo publicações (obtidas na *National Library of Medicine* - https://pubmed.ncbi.nlm.nih.gov), um alto valor nesta variável é uma manifestação comum de isquemia miocárdica. \A variável possui alguns *outliers* no extremo superior. Dado a correlação afirmada nos estudos entre valores altos nesta variável e doenças cardíacas, mantém-se os *outliers*.<jupyter_code># Slope of the Peak Exercise ST Segment
aux = data.copy()
aux.loc[aux['slope'] == 0, 'slope'] = 'Upsloping'
aux.loc[aux['slope'] == 1, 'slope'] = 'Flat'
aux.loc[aux['slope'] == 2, 'slope'] = 'Downsloping'

slope_plt = sns.histplot(
    data=aux,
    x='slope',
    hue='slope',
    legend=False,
    shrink=.9
)
slope_plt.set(title='Slope of the Peak Exercise ST Segment', xlabel='')
plt.show()

print('Slope Percents\n')
print((aux['slope'].value_counts()/len(aux['slope']))*100)<jupyter_output><empty_output><jupyter_text>Variável representa a morfologia do segmento ST no pico do esforço. A análise da morfologia do segmento ST é usada para identificar possíveis condições cardíacas. \Na amostra, a maioria dos pacientes (46.9%) apresenta morfologia de descida (downsloping).<jupyter_code># Major Vessels Colored by Fluoroscopy
contrast_agent_plt = sns.histplot(
    data=data,
    x='ca',
    hue='ca',
    legend=False,
    binwidth=1
)
contrast_agent_plt.set(title='Major Vessels Colored by Fluoroscopy', xlabel='Number of Major Vessels')
contrast_agent_plt.set_xticks([0.5, 1.5, 2.5, 3.5])
contrast_agent_plt.set_xticklabels(['0', '1', '2', '3'])
plt.show()

print('Number Of Major Vessels Colored By Fluoroscopy Percents\n')
print((data['ca'].value_counts()/len(data['ca']))*100)<jupyter_output><empty_output><jupyter_text>Para a grande maioria dos pacientes (57.8%) o exame de fluoroscopia não coloriu nenhum dos principais vasos sanguíneos.<jupyter_code># Thallium Stress Test Results
data['thal'].value_counts()<jupyter_output><empty_output><jupyter_text>A variável *thal*, referente ao resultado no teste de estresse, não se comporta como divulgado no dicionário do *data set*. Sem uma referência para compreender e fazer sentido dos valores apresentados, a recomendação é a remoção da variável.<jupyter_code># Target (Presence of Heart Disease)
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'

gender_plt = sns.histplot(
    data=aux,
    x='target',
    hue='target',
    palette=['r','b'],
    legend=False,
    shrink=.7
)
gender_plt.set(title='Heart Disease Presence', xlabel='')
plt.show()

print('Heart Disease Presence Percents\n')
print((aux['target'].value_counts()/len(aux['target']))*100)<jupyter_output><empty_output><jupyter_text>O *data set* apresenta um pouco mais da metade (54.5%) de pacientes que possuem doenças cardíacas.  Pré-processamento dos dados e *Feature Engineering*  Remoção de variávelA variável *thal* não se comporta como esperado (segundo as informações providas pelo mantenedor do *data set*). Sendo inviável inferir significado aos valores apresentados na variável, dado a falta de informações, não faz sentido mantê-la no *data set*.<jupyter_code>data = data.drop('thal', axis=1)<jupyter_output><empty_output><jupyter_text>*One-Hot Encoding*<jupyter_code># Change numerical categories to their respective names (most of the binary categories were left unchanged)
data.loc[data['sex'] == 0, 'sex'] = 'female'
data.loc[data['sex'] == 1, 'sex'] = 'male'

data.loc[data['cp'] == 0, 'cp'] = 'typical_angina'
data.loc[data['cp'] == 1, 'cp'] = 'atypical_angina'
data.loc[data['cp'] == 2, 'cp'] = 'non-anginal'
data.loc[data['cp'] == 3, 'cp'] = 'asymptomatic'

data.loc[data['restecg'] == 0, 'restecg'] = 'normal'
data.loc[data['restecg'] == 1, 'restecg'] = 'ST-T_abnormality'
data.loc[data['restecg'] == 2, 'restecg'] = 'left_vent_hypertrophy'

data.loc[data['slope'] == 0, 'slope'] = 'upsloping'
data.loc[data['slope'] == 1, 'slope'] = 'flat'
data.loc[data['slope'] == 2, 'slope'] = 'downsloping'

# One hot encoding each variable
cat_to_encode = [
    'sex',
    'cp',
    'restecg',
    'slope'
]

one_hot_encoder = OneHotEncoder(sparse=False, dtype=np.int)

for category in cat_to_encode:
    cat_encoded = one_hot_encoder.fit_transform(data[[category]])
    columns_encoded = category + '-' + one_hot_encoder.categories_[0]
    
    data = pd.concat([data, pd.DataFrame(cat_encoded, columns=columns_encoded)], axis=1)
    
    data = data.drop(category, axis=1)

data.columns<jupyter_output><empty_output><jupyter_text>Redução de Dimensionalidade<jupyter_code># Pearson Correlation
correlation_matrix = data.corr(method="pearson")

cor_plt = sns.heatmap(
    data=correlation_matrix[['target']], 
    center=True, 
    annot=True, 
    cmap="RdYlBu"
)
cor_plt.set(title='Pearson Correlation of target')
plt.show()<jupyter_output><empty_output><jupyter_text>Nenhuma variável possui correlação linear particularmente forte (>= 0.6 ou <= -0.6) com a presença de doenças cardíacas. \A maior correlação apresentada foi uma correlação linear negativa entre a presença de doenças cardíacas e dores no peito do tipo angina típica (correlação de Pearson de -0.52).  Análise de Componentes Principais<jupyter_code>scaled_data = scale(data)

pca = PCA()
pca.fit(scaled_data)
pca_data = pca.transform(scaled_data)

per_var = np.round(pca.explained_variance_ratio_*100, decimals=2)
labels = ['PC' + str(i) for i in range(1, len(per_var)+1)]

scree_plt = sns.barplot(
    x=per_var,
    y=labels,
    color='r'
)
scree_plt.set(
    title='Scree Plot',
    xlabel='Percent of Explained Variance',
    ylabel='Principal Component'
)
plt.show()
important_vars = []
for i in range(8):
    loading_scores = pd.Series(pca.components_[i-1], index=data.columns)
    sorted_loading_scores = loading_scores.abs().sort_values(ascending=False)
    top_5_var = sorted_loading_scores[:5].index.values

    for var in top_5_var:
        if var not in important_vars:
            important_vars.append(var)
important_vars<jupyter_output><empty_output><jupyter_text>Portanto, a partir do estudo dos componentes principais, pode-se determinar as principais variáveis que descrevem os dados.Aliado à observação das correlações de Pearson relacionadas à variável *target*, pode-se selecionar as variáveis que, associadas a esta, possuem potencial de prover maiores informações que expliquem a ocorrência de doenças cardíacas.Foram selecionadas as seguintes variáveis:- age- sex- cp- restecg- thalach- exang- oldpeak- slope- ca  Análise Multivariada<jupyter_code># Age x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'

age_target_plt = sns.kdeplot(
    data=aux,
    x='age',
    shade=True,
    hue='target'
)
sns.kdeplot(
    data=aux,
    x='age',
    shade=False
)
age_target_plt.set(
    title='Age Distribution per Heart Health',
    xlabel='Age'
)

plt.show()

print('Age Descriptive Statistics For Patients With Heart Conditions\n')
print(data.loc[data['target'] == 1, 'age'].describe())<jupyter_output><empty_output><jupyter_text>Entre os pacientes que apresentaram problemas cardíacos, a maioria encontra-se aproximadamente entre 40 e 65 anos (a partir da observação da distribuição, corroborado pelos quartis).Pacientes mais novos que 55 anos, no *dataset*, se apresentaram, mais frequentemente, com presença de problemas cardíacos do que ausência. Uma possível explicação para tal é que pacientes desta faixa etária não fazem exames de *checkup* com a mesma frequência que os mais velhos e, portanto, quando investigam a saúde do coração é porque já apresentam sintomas e dificuldades.<jupyter_code># Age x Gender
aux = data.copy()
aux.loc[aux['sex-male'] == 1, 'sex'] = 'Male'
aux.loc[aux['sex-female'] == 1, 'sex'] = 'Female'

age_target_plt = sns.kdeplot(
    data=aux,
    x='age',
    shade=True,
    hue='sex'
)
sns.kdeplot(
    data=aux,
    x='age',
    shade=False
)
age_target_plt.set(
    title='Age/Gender Distribution',
    xlabel='Age'
)

plt.show()

print('Age Descriptive Statistics For Male Patients\n')
print(data.loc[data['sex-male'] == 1, 'age'].describe())
print('\nAge Descriptive Statistics For Female Patients\n')
print(data.loc[data['sex-female'] == 1, 'age'].describe())<jupyter_output><empty_output><jupyter_text>Existe pouca diferença (exceto na quantidade de pacientes) entre homens e mulheres no *dataset*.50% dos pacientes homens se encontram entre 47 e 59 anos. O paciente homem mais novo possuia 29 anos. O mais velho 77.50% das pacientes mulheres se encontram entre 49 e 63 anos. A paciente mulher mais nova possuia 34 anos. A mais velha 76.As médias e medianas estão bem próximas também, sendo médias 53.8 (homens) e 55.7 (mulheres), e medianas 54 (homens) e 57 (mulheres).Em todas estatísticas, mulheres apresentaram idade um pouco superior a dos pacientes homens presentes no *dataset*.<jupyter_code># Age x Gender for Patients with Heart Conditions
aux = data.copy()
aux = aux[aux['target'] == 1]
aux.loc[aux['sex-male'] == 1, 'sex'] = 'Male'
aux.loc[aux['sex-female'] == 1, 'sex'] = 'Female'

age_target_plt = sns.kdeplot(
    data=aux,
    x='age',
    shade=True,
    hue='sex'
)
sns.kdeplot(
    data=aux,
    x='age',
    shade=False
)
age_target_plt.set(
    title='Age/Gender Distribution For Patients With Heart Conditions',
    xlabel='Age'
)

plt.show()

print('Age Descriptive Statistics For Male Patients With Heart Conditions\n')
print(aux.loc[aux['sex-male'] == 1, 'age'].describe())
print('\nAge Descriptive Statistics For Female Patients With Heart Conditions\n')
print(aux.loc[aux['sex-female'] == 1, 'age'].describe())

plt.title("Age/Gender Boxplots For Patients With Heart Conditions")
plt.boxplot(
    [aux.loc[aux['sex-male'] == 1, 'age'],
    aux.loc[aux['sex-female'] == 1, 'age']], 
    labels=['Male', 'Female']
)
plt.show()<jupyter_output><empty_output><jupyter_text>A idade de mulheres que apresentaram condições cardíacas possuem uma variância maior que a de homens (105.4 e 75.4, respectivamente).De modo geral, homens apresentaram problemas cardíacos mais cedo, sendo que 75% o fizeram com idade menor ou igual a 57 anos e o paciente homem mais novo que apresentou condições cardíacas possuia 29 anos. O paciente homem mais velho que apresentou problemas possuia 70 anos.Entre mulheres, 75% das que apresentaram problemas cardíacos possuiam idade inferior ou igual a 63 anos, com a mulher mais nova a apresentar problemas possuindo 34 anos. A mais velha possuia 76 anos.<jupyter_code># Gender x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'
aux.loc[aux['sex-male'] == 1, 'sex'] = 'Male'
aux.loc[aux['sex-female'] == 1, 'sex'] = 'Female'

gender_plt = sns.histplot(
    data=aux,
    x='sex',
    hue='target',
    multiple='fill',
    palette=['r','b'],
    shrink=.6
)
gender_plt.set(title='Heart Disease Per Gender', xlabel='', ylabel='')
plt.show()

print('Male Heart Health Percents\n')
print((aux.loc[aux['sex-male'] == 1, 'target'].value_counts()/len(data[data['sex-male'] == 1]))*100)
print('\nFemale Heart Health Percents\n')
print((aux.loc[aux['sex-female'] == 1, 'target'].value_counts()/len(data[data['sex-female'] == 1]))*100)<jupyter_output><empty_output><jupyter_text>O percentual de mulheres que apresentaram problemas cardíacos é consideravelmente maior que o de pacientes homens (75% para mulheres, 45% para homens).<jupyter_code># Chest Pain Type x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'
aux.loc[aux['cp-typical_angina'] == 1, 'cp'] = 'Typical Angina'
aux.loc[aux['cp-atypical_angina'] == 1, 'cp'] = 'Atypical Angina'
aux.loc[aux['cp-non-anginal'] == 1, 'cp'] = 'Non-Anginal Pain'
aux.loc[aux['cp-asymptomatic'] == 1, 'cp'] = 'Asymptomatic'


gender_plt = sns.histplot(
    data=aux,
    x='cp',
    hue='target',
    multiple='fill',
    palette=['r','b'],
    shrink=.6
)
gender_plt.set(title='Heart Disease Per Chest Pain Type', xlabel='', ylabel='')
plt.show()

print('Heart Health Percents Of Patients With Typical Angina Pain\n')
print((aux.loc[aux['cp-typical_angina'] == 1, 'target'].value_counts()/len(data[data['cp-typical_angina'] == 1]))*100)
print('\nHeart Health Percents Of Patients With Atypical Angina Pain\n')
print((aux.loc[aux['cp-atypical_angina'] == 1, 'target'].value_counts()/len(data[data['cp-atypical_angina'] == 1]))*100)
print('\nHeart Health Percents Of Patients With Non-Anginal Pain\n')
print((aux.loc[aux['cp-non-anginal'] == 1, 'target'].value_counts()/len(data[data['cp-non-anginal'] == 1]))*100)
print('\nHeart Health Percents Of Asymptomatic Patients\n')
print((aux.loc[aux['cp-asymptomatic'] == 1, 'target'].value_counts()/len(data[data['cp-asymptomatic'] == 1]))*100)<jupyter_output><empty_output><jupyter_text>A grande maioria (73%) dos paciente que apresentaram dor anginal típica não apresentaram doenças cardíacas.Dos pacientes que apresentaram dor anginal atípica ou dor não anginal a grande maioria (82% e 79%, respectivamente) apresentou doenças cardíacas.Similarmente, a maioria (69.6%) dos pacientes assintomáticos apresentaram condições cardíacas.<jupyter_code># Resting ECG Results x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'
aux.loc[aux['restecg-normal'] == 1, 'restecg'] = 'Normal'
aux.loc[aux['restecg-ST-T_abnormality'] == 1, 'restecg'] = 'ST-T Wave Abnormality'
aux.loc[aux['restecg-left_vent_hypertrophy'] == 1, 'restecg'] = 'Left Ventricular Hypertrophy'


gender_plt = sns.histplot(
    data=aux,
    x='restecg',
    hue='target',
    multiple='fill',
    palette=['r','b'],
    shrink=.6
)
gender_plt.set(title='Heart Disease Per ECG Results', xlabel='', ylabel='')
plt.show()

print('Heart Health Percents Of Patients With Normal ECG Results\n')
print((aux.loc[aux['restecg-normal'] == 1, 'target'].value_counts()/len(data[data['restecg-normal'] == 1]))*100)
print('\nHeart Health Percents Of Patients With ST-T Wave Abnormality\n')
print((aux.loc[aux['restecg-ST-T_abnormality'] == 1, 'target'].value_counts()/len(data[data['restecg-ST-T_abnormality'] == 1]))*100)
print('\nHeart Health Percents Of Patients With Left Ventricular Hypertrophy\n')
print((aux.loc[aux['restecg-left_vent_hypertrophy'] == 1, 'target'].value_counts()/len(data[data['restecg-left_vent_hypertrophy'] == 1]))*100)<jupyter_output><empty_output><jupyter_text>63% dos pacientes que apresentaram anormalidades na onda ST-T no resultado do ECG apresentaram problemas cardíacos.3/4 dos pacientes com hipertrofia no ventrículo esquerdo apresentaram problemas cardíacos.<jupyter_code># Heart Rate x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'

age_target_plt = sns.kdeplot(
    data=aux,
    x='thalach',
    shade=True,
    hue='target'
)
sns.kdeplot(
    data=aux,
    x='thalach',
    shade=False
)
age_target_plt.set(
    title='Heart Rate Distribution per Heart Health',
    xlabel='Heart Rate'
)

plt.show()

print('Heart Rate Descriptive Statistics For Patients With Heart Conditions\n')
print(data.loc[data['target'] == 1, 'thalach'].describe())<jupyter_output><empty_output><jupyter_text>Os pacientes com ritmos cardíacos mais altos (acima de 150) possuem uma chance consideravelmente maior de possuirem problemas cardíacos.<jupyter_code># Exercise Induced Angina x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'
aux.loc[aux['exang'] == 0, 'exang'] = 'No'
aux.loc[aux['exang'] == 1, 'exang'] = 'Yes'

gender_plt = sns.histplot(
    data=aux,
    x='exang',
    hue='target',
    multiple='fill',
    palette=['r','b'],
    shrink=.6
)
gender_plt.set(title='Heart Disease Per Occurrence Of Exercise Induced Angina', xlabel='Exercise Induced Angina', ylabel='')
plt.show()

print('Heart Health Percents For Patients That Didn\'t Present Exercise Induced Angina\n')
print((aux.loc[aux['exang'] == 'No', 'target'].value_counts()/len(aux[aux['exang'] == 'No']))*100)
print('\nHeart Health Percents For Patients That Did Present Exercise Induced Angina\n')
print((aux.loc[aux['exang'] == 'Yes', 'target'].value_counts()/len(aux[aux['exang'] == 'Yes']))*100)<jupyter_output><empty_output><jupyter_text>Pacientes que não apresentaram angina durante o teste de estresse possuem maior chance de possuirem problemas cardíacos.<jupyter_code># ST Depression Induced By Exercise Relative To Rest x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'

age_target_plt = sns.kdeplot(
    data=aux,
    x='oldpeak',
    shade=True,
    hue='target'
)
sns.kdeplot(
    data=aux,
    x='oldpeak',
    shade=False
)
age_target_plt.set(
    title='ST Depression Induced By Exercise Relative To Rest Distribution per Heart Health',
    xlabel=''
)

plt.show()<jupyter_output><empty_output><jupyter_text>Ao contrário do indicado por pesquisa bibliográfica, a grande maioria dos pacientes com problemas cardíacos no *dataset* apresentaram valores baixos na depressão da onda ST induzida por exercício, em relação ao repouso.<jupyter_code># Major Vessels Colored By Fluoroscopy x Heart Condition
aux = data.copy()
aux.loc[aux['target'] == 0, 'target'] = 'Healthy Heart'
aux.loc[aux['target'] == 1, 'target'] = 'Heart Condition'

age_target_plt = sns.kdeplot(
    data=aux,
    x='ca',
    shade=True,
    hue='target'
)
sns.kdeplot(
    data=aux,
    x='ca',
    shade=False
)
age_target_plt.set(
    title='Number of Major Vessels Colored By Fluroscopy Distribution per Heart Health',
    xlabel=''
)

plt.show()<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.13604315025029964, 'fraction_numerical': 0.013748854262144821, 'mean_word_length': 5.360313901345291, 'pattern_counts': {'":': 0, '<': 122, '<?xml version=': 0, '>': 124, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '30', 'dir': 'jupyter-structured-clean-dedup', 'id': '611199', 'license': 'MIT', 'n_tokens_mistral': 10852, 'n_tokens_neox': 10057, 'n_words': 2738, 'path': 'EDA/Análise de Dados de Pacientes de Doenças Cardíacas/heart_disease_analysis.ipynb', 'repo_name': 'rfmf/ds_portfolio', 'size': '28366'}