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

🫀 심혈관질환 데이터 분석 06. 패턴분석 데이터 전처리

nyamin9 2023. 1. 31. 13:06

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

 

 


 

🩸 저번 글에서는 상관관계 분석을 통해 각 attribute들 사이의 관계를 찾아보았습니다. 하지만 상관관계 분석이 수치형 변수와 수치형 변수 간의 관계만을 알아보는 데 사용한다는 것을 몰라서 약간 잘못된 방법을 사용했다는 것이 지금도 너무 아쉽네요😥.

 

🩸 이번 글부터 다음 몇가지 글까지는 패턴분석을 통해 attribute 사이의 관계를 알아볼 예정입니다.

 

 


🫀 1. support / confidence / lift 이론적 배경

 

 

🩸 Support

 

▪ 지지도

 

 x와 y를 동시에 포함하는 비율

 

 신뢰도(Confidence)를 지지하는 척도

 

 confidence에 의한 규칙이 지지받기 위해서는 support 값이 높아야 함.

 

 

🩸 Confidence

 

신뢰도

 

 x를 포함하는 거래 내역 중, y가 포함된 비율

 

 규칙의 신뢰도에 대한 척도

 

 P(Y|X)

 

 

🩸 Lift

 

신뢰도가 0.9일 때 p(Y)가 0.9면 x,y가 서로 독립이 되기 때문에 x는 y를 설명하는 데에 아무런 도움을 줄수 없음

 

따라서 규칙이 진짜 의미가 있는지 확인하기 위한 척도가 필요함

 

 P(Y|X) / P(Y)

 

  ▪ Lift = 1 : x와 y는 아무 관계가 없음. 독립.

 

  ▪ Lift > 1 : x가 y의 발생 증가를 예측하는 데에 도움이 됨. (양의 상관관계).

 

  ▪ Lift < 1 : x가 y의 발생 감소를 예측하는 데에 도움이 됨. (음의 상관관계).

 

 


🫀 2. Preprocessing

 

 

🩸 저희가 가지고 있는 데이터는 범주형 자료와 수치형 자료가 이것저것 섞여있습니다. 다만 패턴 분석을 통해 규칙을 찾기 위해서는 데이터가 트랜잭션 데이터, 즉 Boolean 형태로 구성된 데이터여만 합니다. 따라서 저희는 각 attribute들을 일정한 기준을 가지고 모두 범주화 한 뒤, 최종적으로 이렇게 범주화된 데이터를 Boolean 표현형으로 바꿔 트랜잭션 데이터를 구할 것입니다.

 

 

 

🩸 Support, Confidence 계산을 위해 데이터를 transaction table 형태로 변경

 

 pre_tran  : 각 attribute의 binary 값을 category 형태로 바꾼 dataframe

 

 transaction  : mlxtend 메소드의 transform 함수를 사용하여 boolean dataframe

 

 

 

🩸 Support ,Confidence 계산

 

 mlxtend.frequent_patterns 모듈의  apriori, association_rules 함수 

 

 apriori( )  : itemsets 간의 Support를 계산하여 dataframe으로 반환 - 설정한 min_support를 만족하는 경우만 반환

 

 association_rules( )  함수의  metric, min_threshold  옵션 : 설정한 metric이 min_threshold 이상인 경우만 반환

 

 

 

🩸 찾고자 하는 것은 cardio에 영향을 미치는 attribute이기에 cardio를 consequents로 하는 경우를 살펴봅니다.

 

 confidence, Lift, support 순서로 우선순위를 설정

 

 min_confidence = 0.6 & Lift > 1 & min_support = 0.01

 

 support를 낮게 설정한 이유는

confidence와 Lift를 만족할 때 antecedents의 support가 너무 작아 전체적인 support가 낮게 나오는 경우를 고려한 것입니다.

 

 


🫀 3. Code

 

🩸 범주형 데이터 생성

# BMI attribute를 위한 categorize 함수 생성
# BMI < 18.5 : 저체중
# 18.5 =< BMI < 25 : 정상
# 25 =< BMI < 30 : 과체중
# 30 =< BMI < 39.9 : 비만
# 39.9 =< BMI  : 고도비만S

def bmi(x):
    if x < 18.5:
        x = 'LOW'
    elif (x >= 18.5) & (x<25):
        x = 'NORMAL'
    elif (x >= 25) & (x < 30):
        x = 'OVER'
    elif (x >= 30) & (x < 39.9):
        x = 'OBESITY'
    else:
        x = 'HIGH_OBESITY'
    return x
# cardio 데이터 범주화
pre_tran = cardio.copy()


# gender : 1 2
pre_tran = pre_tran.replace({'gender':1},'Women')
pre_tran = pre_tran.replace({'gender':2},'Men')


# cholesterol : 1 2 3
pre_tran = pre_tran.replace({'cholesterol':1},'Normal_cho')
pre_tran = pre_tran.replace({'cholesterol':2},'Above_Normal_cho')
pre_tran = pre_tran.replace({'cholesterol':3},'Well_Above_Normal_cho')


# gluc : 1 2 3
pre_tran = pre_tran.replace({'gluc':1},'Normal_gluc')
pre_tran = pre_tran.replace({'gluc':2},'Above_Normal_gluc')
pre_tran = pre_tran.replace({'gluc':3},'Well_Above_Normal_gluc')


# smoke : 0 1
pre_tran = pre_tran.replace({'smoke':0},'No_Smoke')
pre_tran = pre_tran.replace({'smoke':1},'Smoke')


# alco : 0 1
pre_tran = pre_tran.replace({'alco':0},'No_Alcohol')
pre_tran = pre_tran.replace({'alco':1},'Alcohol')


# active : 0 1
pre_tran = pre_tran.replace({'active':0},'No_Active')
pre_tran = pre_tran.replace({'active':1},'Active')


# cardio : 0 1, target
pre_tran = pre_tran.replace({'cardio':0},'No_cardio')
pre_tran = pre_tran.replace({'cardio':1},'Cardio')


# ap_hi가 140이상이면 HBP_SYS(고혈압), 그 외에는 NBP_SYS(정상)
# ap_lork 90 이상이면 HBP_DIAS(고혈압), 그 외에는 NBP_DIAS(정상)
pre_tran["ap_hi"] = np.where(pre_tran["ap_hi"] >=140, 'HBP_SYS', 'NBP_SYS')
pre_tran["ap_lo"] = np.where(pre_tran["ap_lo"] >=90, 'HBP_DIAS', 'NBP_DIAS')


# age : 연령대로 분류
pre_tran.loc[pre_tran['age'] // 10 == 3, 'age'] = 30
pre_tran.loc[pre_tran['age'] // 10 == 4, 'age'] = 40
pre_tran.loc[pre_tran['age'] // 10 == 5, 'age'] = 50
pre_tran.loc[pre_tran['age'] // 10 == 6, 'age'] = 60


# BMI : 앞서 생성한 BMI 함수 사용
pre_tran['BMI'] = pre_tran['BMI'].apply(bmi)

print('row : ', len(pre_tran))
print('columns : ', len(pre_tran.columns))
pre_tran.head()
>>

row :  64500
columns :  11

 

위와 같은 과정을 거치면 우리가 가지고 있는 데이터가 모두 범주형으로 변합니다. 페턴분석을 위해, 이제는 이 범주형 데이터를 트랜잭션 데이터로 만들어주면 됩니다.

 

 


🩸 트랜잭션 데이터 생성

 

# transaction table 생성
# mlxtend.preprocessing 모듈의 TransactionEncoder 임포트
from mlxtend.preprocessing import TransactionEncoder


# transaction 데이터 생성
# 범주형 데이터를 mlxtend 메소드의 transform 함수에 넣기 위해 list형태로 변환 : trans_data
trans_data = np.array(pre_tran)
trans_data = np.array(trans_data.tolist())


# transform() 함수로 trans_data가 one-hot encoding 된 형태의 boolean list를 te_ary로 받음
# te_ary를 데이터프레임 형태로 변환하여 transaction data 생성 
# transaction : attribute의 각 category에 대한 value를 column으로 받음
te = TransactionEncoder()
te_ary = te.fit(trans_data).transform(trans_data)
transaction = pd.DataFrame(te_ary, columns=te.columns_)
transaction

 

 

어엇 사진이 잘 안보입니다,,,😥 한번에 최대한 많은 attribute를 보여드리고 싶어서 캡처를 저렇게 떴는데 아쉽네요. 혹시 더 자세히 보고 싶으신 분들은 사진을 한번만 더 클릭해주시면 좋을 것 같습니다!!

 


 

🩸 드디어 원하는 형태의 트랜잭션 데이터를 만들었습니다. 이제부터는 이렇게 만들어진 데이터프레임에 대한 패턴을 분석해서 같이 나오는 친구들이 무엇이 있는지, 그 수치는 어떠한지에 대해서 분석하면 됩니다.

 

🩸 데이터에서 상관관계를 뽑아 사용하는 것 역시 중요하지만, 이를 위해 전처리 단계를 진행하는 동안 데이터 분석에 대한 좀 더 넓은 시야를 가지게 되었던 것 같습니다. 수업시간에 배운 이론만을 바탕으로 정말 많은 삽질을 하면서 배운 방법들이기 때문에, 아마 두고두고 생각나지 않을까 싶습니다😀😀.

 

🩸 다음 글에서는 트랜잭션 데이터에서 support, confidence, lift를 구하고 시각화하는 부분을 다루겠습니다.