pbj0812의 코딩 일기

[통계학] ID3 구현을 통한 변수 선택 본문

Science/통계학

[통계학] ID3 구현을 통한 변수 선택

pbj0812 2020. 3. 9. 02:40

0. 목표

 - 타이타닉 데이터 셋에서 ID3 알고리즘을 통해 우선적으로 분류되어야 할 변수 선택

1. 수식

 - Gain(A) = Info(D) - Info A(D)

  => A의 정보 소득 = 전체 데이터(D)의 정보량 - 속성 A로 분류시 정보량

  => 우선적으로 분류되어야 할 변수는 최종 결과값(A의 정보 소득)이 가장 큰 값

2. 준비물

 1) kaggle 타이타닉 데이터 셋 다운로드(링크에서 titanic 검색)

 2) 데이터 전처리

import pandas as pd

data = pd.read_csv('E:/수료증/인프런/밑바닥부터시작하는머신러닝/train.csv')

data2 = data[['Pclass', 'Sex', 'Survived']]

  - Pclass : 승선권 클래스(1, 2, 3)

  - Sex : 성별(male, female)

  - Survived : 생존여부(1 : 생존, 0 : 사망) => Y 값

3. 시나리오 설계

 1) Pclass 기준

  (1) Pclass = 1, Survived = 0

  (2) Pclass = 1, Survived = 1

  (3) Pclass = 2, Survived = 0

  (4) Pclass = 2, Survived = 1

  (5) Pclass = 3, Survived = 0

  (6) Pclass = 3, Survived = 1

 2) Sex 기준

  (1) Sex = male, Survived = 1

  (2) Sex = male, Survived = 0

  (3) Sex = female, Survived = 1

  (4) Sex = female, Survived = 0

4. 구현 (2. 2) 에 이어서)

 1) 데이터 길이 확인

  - 결과 : 891

data_length = len(data)
print(data_length)

 2) 생존 값 추출

  - 결과 : [0, 1]

selection = list(set(data['Survived']))
print(selection)

 3) 전체 엔트로피 계산

  - 결과 : 0.9607079018756469

result = []
for i in selection:
    survive_i = len(data[data['Survived']==i])/data_length
    result.append(-survive_i * log2(survive_i))

total_entropy = sum(result)
print(total_entropy)

 4) 변수별 엔트로피 계산

  - 함수의 입력값으로는 데이터셋, 변수, y값

  - selection 에는 변수별 하위 분류값(male or female, 1 or 2 or 3)들을 저장하고, selection2 에는 정답의 분류값(0, 1)을 저장

  - 첫 번째 for 에서는 속성별 분류, 두 번째 for 에서는 생존 분류를 하여 각 계산 값들을 result에 저장

def id3(dataset, attribute, y):
    result = []
    dataset_len = len(dataset)
    selection = list(set(dataset[attribute]))
    selection2 = list(set(dataset[y]))
    # 분류(male or female / 1 or 2 or 3)
    for i in selection:
        data = dataset[dataset[attribute] == i]
        data_len = len(data)
        # 생존 분류(0 or 1)
        for j in selection2:
            data2 = data[data[y] == j]
            data2_len = len(data2)
            result.append((data_len/dataset_len) * (-data2_len/data_len * log2(data2_len/data_len)))
    
    print(result)
    entropy = sum(result)
    
    return entropy

 5) 실행

  (1) Sex

   - 결과 :

[0.17770643145518203, 0.11256033982862157, 0.1586592427396773, 0.29412178119155175]

   - 합계 : 0.7430477952150327

final = id3(data2, 'Sex', 'Survived')

  (2) Pclass

   - 결과 : [0.12866077730874131, 0.10187402231670659, 0.10055439286798974, 0.10551493382505135, 0.16717888888089577, 0.2730938413802505]

   - 합계 : 0.8768768565796353

 6) 최종 결과값(전체 엔트로피 - 속성별 엔트로피)

  1) Sex

   - 0.2176601066606142

  2) Pclass

   - 0.0838310452960116

total_entropy - final

5. 결과

 - Sex의 결과값이 Pclass의 결과값보다 높으므로 Sex로 우선 분류를 하면 Pclass로 분류를 한 결과보다 좋은 결과를 얻을 가능성이 높음

6. 참고

 - 밑바닥부터 시작하는 머신러닝(최성철 교수님)

Comments