모바일은 화면을 돌려 가로화면으로 보시는 게 읽으시기 편할 수 있습니다. 돌려서 보시는 걸 추천드릴게요!!
🩸 저번 글에 이어 여러 가지 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, 즉 주성분 분석을 통해 데이터를 분석하겠습니다.
'🐍 파이썬 데이터 분석 프로젝트 > 🫀 심혈관질환 데이터 분석' 카테고리의 다른 글
🫀 심혈관질환 데이터 분석 11. plotly 차트보드 (0) | 2023.02.02 |
---|---|
🫀 심혈관질환 데이터 분석 10. 주성분분석 (0) | 2023.02.02 |
🫀 심혈관질환 데이터 분석 08. 카이제곱검정 (0) | 2023.02.01 |
🫀 심혈관질환 데이터 분석 07. 패턴분석 (0) | 2023.01.31 |
🫀 심혈관질환 데이터 분석 06. 패턴분석 데이터 전처리 (0) | 2023.01.31 |