🐍 파이썬 데이터 분석 프로젝트/🫀 심혈관질환 데이터 분석

🫀 심혈관질환 데이터 분석 09. Kulczynski

nyamin9 2023. 2. 1. 13:26

모바일은 화면을 돌려 가로화면으로 보시는 게 읽으시기 편할 수 있습니다. 돌려서 보시는 걸 추천드릴게요!!

 

 


 

🩸 저번 글에 이어 여러 가지 Null invariant measure들을 통해 attribute 간의 관계를 알아보도록 하겠습니다.

 


🫀 1. Null Invariant Measure 데이터프레임 생성

 

📌 chi-square, p-value 계산

 

# chi-square 계산(transaction dataframe 기준 : 각 attribute의 category)
# scipy.stats의 chi2_contingency를 통해서 contingency table 생성.
# contingency table을 바탕으로 chi-square와 p-value 계산.

chi_list = pd.DataFrame()

from scipy.stats import chi2_contingency

for i in range(len(transaction.columns)):
    f=transaction.columns[i]
    contigency = pd.crosstab(transaction[f],transaction['Cardio'])
    chi, p, dof, expected = chi2_contingency(contigency)
    chi_list = chi_list.append((pd.DataFrame({'chi' :chi, 'p-value':p}, 
               index = [transaction.columns[i]+" & cardio"])))

 

 

📌 support 계산

 

# support 계산 함수

## transaction data와 item을 parameter로 받음

## item이 list 형태면 그대로 반환하며, 아니면 list 형태로 바꿔 items_list로 반환
## sum()연산

## transaction data에서 item_list의 attribute를 받아 column기준 sum 연산 수행. 

## a : 위에서 수행한 sum 연산결과가 items_list의 길이와 같은 row의 개수 
## 즉 해당하는 items_list의 요소를 모두 가지고 있는 row의 개수

## 이를 전체 transaction 수(변수 b)로 나눠 해당 item 집합이 발생한 확률을 구함.

def support(transaction, item): 
    items_list = item if isinstance(item,list) else list(item)
    a = np.sum(transaction.loc[:,items_list].sum(axis=1)==len(items_list)) 
    b = transaction.loc[:,items_list].shape[0]
    return a/b

 

 

📌 Jaccard, Kulczynski, IR 계산

# 위에서 만든 support 함수를 사용해 집합 X, 집합 Y, 교집합의 support를 구해 metric 공식에 대입.
# 얻은 결과값을 dataframe형태로 변환

Null_inv = pd.DataFrame()

for i in range(len(transaction.columns)):
    rslt01 = support(transaction, [transaction.columns[i]])
    rslt02 = support(transaction, ['Cardio'])
    rslt03 = support(transaction, (transaction.columns[i],'Cardio'))
    
    jacc = rslt03 / (rslt01+rslt02-rslt03)
    kulc = (0.5)*((rslt03/rslt01) + (rslt03/rslt02)) 
    ir = abs((rslt01 - rslt02)) / (rslt01+rslt02-rslt03)

    Null_inv = Null_inv.append((pd.DataFrame
    	                       ({'Jaccard' :jacc, 'kulczynski' :kulc, 'IR' : ir}, 
                                 index = [transaction.columns[i]+" & cardio"])))

 

 

📌 데이터프레임 생성

# chi-square와 p-value, jaccard, kulczynski, IR을 하나의 데이터프레임으로 통합 - Null_inv
Null_inv = pd.merge(Null_inv, chi_list, how = 'outer', left_index=True, right_index=True)
Null_inv = Null_inv.drop(['Cardio & cardio', 'No_cardio & cardio'], axis = 0)

# kulczynski를 기준으로 큰 순서부터 나열
Null_inv = Null_inv.sort_values('kulczynski', ascending = False)
Null_inv

 

 

이렇게 해서 최종 값들을 모두 구했는데, 숫자도 너무 복잡하고 그 크기를 비교하기도 힘들어 보입니다. 따라서 이 중에서 가장 데이터를 잘 표현하기로 알려진 kulczynski와 IR을 시각화해서 attribute 간의 패턴을 분석할 생각입니다.

 

 


🫀 2. 시각화

 

# 시각화를 위한 plotly library 임포트
import plotly.graph_objects as go
import plotly.offline as pyo
pyo.init_notebook_mode()

# Transaction Data의 Attribute-Cardio 별 Kulczynski / IR 값 시각화
fig = go.Figure()
fig.add_trace(
    go.Scatter(
    x = Null_inv.index, y = Null_inv['IR'], mode = 'markers+lines+text', name = 'IR'))

fig.add_trace(
    go.Scatter(
    x = Null_inv.index, y = Null_inv['kulczynski'], mode = 'markers+lines+text', name = 'Kulczynski'))

fig.update_layout(
    {
        'title' : {'text':'Attribute-Cardio 별 Kulczynski / IR 값', 'font':{'size' : 25}},
        'template' : 'plotly_white'
    })

fig.add_hline(y=0.5, line_dash="dot",
              line_color = "#ff0000",
              annotation_text="Kulczynski = 0.5", 
              annotation_position="bottom right",
              annotation_font_size=17,
              annotation_font_color="black"
             )

fig.show()

 

 


🫀 3. Null-Invariant Measures 결과

 

🩸 kulczynski, IR, chi-square 값으로 몇가지 유추가 가능합니다.

 

▪ (1) 30 & cardio : kulczynski = 0.109444, IR = 0.980692, chi-square = 111.024261

 

  - 둘의 관계는 negative하며, 두 집합의 분포가 imbalanced 합니다.

 

 (2) HBP_SYS & cardio : kulczynski = 0.640039, IR = 0.431196, chi-square = 10586.494635

 

  - 둘의 관계는 positive하고, 두 집합의 분포 역시 어느정도 고릅니다.

 

 

 

🩸kulczynski의 결과가 0.5를 기준으로 나뉘고, 그에 따른 IR로부터 몇가지 결과를 얻을 수 있습니다.

 

 IR값이 feature가 가지는 수준에 대해 다양하게 나오기에, 집합 간 분포가 고르지 않은 경우가 많습니다.

 

즉, 각 feature에 대한 분포의 영향(e.x. BMI 에서는 HIGH_OBESITY 가 굉장히 많은 부분을 차지)을 배제할 수 없습니다.

 

  - 이에 kulczynski와 IR 값만으로 정확한 attribute를 선택하는 것은 어려움이 있다고 생각하였습니다.

 

 

 

 그럼에도 kulczynski와 IR 값으로 선택한 attribute는 다음과 같습니다.

 

  ▪  ap_hi, ap_lo, gluc, gender, active, age, cholesterol 

 

 

또한 추세에 비해 작은 chi-square값을 가지는 attribute를 제외하면 남은 attribute는 아래와 같습니다.

 

  ▪  age, ap_hi, ap_lo, cholesterol, gluc, active, BMI 

 

 


🩸 이렇게 해서 Null-invariant measure를 통해 데이터의 패턴을 파악해 보았습니다. 사실 이 값들의 크기를 통해 관계를 파악하는 데에는 절대적인 기준치가 존재하지 않기에 데이터의 attribute들 사이의 값들을 상대평가하고 p-value를 통해 통계적으로 유의한 패턴을 분석하였습니다. 아무래도 상대적인 값들을 통해 그 관계를 비교하였기에 아주 정확한 패턴이라고 말하기는 어렵겠지만, 일단은 이렇게 나온 값들과 관계를 가지고 프로젝트를 진행할 예정입니다🙂.

 

🩸 다음 글에서는 PCA, 즉 주성분 분석을 통해 데이터를 분석하겠습니다.