pbj0812의 코딩 일기

[수학] python을 통한 범주형 피처 처리(클래스, 이진법, 원핫인코딩) 본문

Science/수학

[수학] python을 통한 범주형 피처 처리(클래스, 이진법, 원핫인코딩)

pbj0812 2020. 10. 31. 20:31

0. 목표

 - python을 통한 범주형 피처 처리(클래스, 이진법, 원핫인코딩)

1. 실습

 1) library 호출

import pandas as pd
import copy

 2) 데이터 생성

data = ['A', 'B', 'AB', 'O']

 3) 클래스 ID 모듈

def class_id(inp):
    result = []
    for i in range(len(inp)):
        result.append(i + 1)
    return result

  - 확인

print(class_id(data))

# 결과
[1, 2, 3, 4]

 4) 이진법 표현

  (1) 최대 몫 구하기

   - 인풋을 넣으면 결과값으로 해당 인풋을 2로 나눌 수 있는 최대의 몫 도출

def from_ten_int2(inp):
    i = 0
    while 2 ** i <= inp:
        i += 1
    if i > 0:
        i -= 1
    else:
        pass
    return i

   - 확인

a = from_ten_int2(3)
print(a)

# 결과
1

  (2) 몫, 나머지 구하기

def from_ten_int(inp):
    result = []
    while inp >= 2:
        tmp = from_ten_int2(inp)
        inp = inp - (2 ** tmp)
        result.append(tmp)
    result2 = inp
    return result, result2

   - 확인

a, b = from_ten_int(3)
print(a, b)

# 결과
[1] 1

  (3) 2진법으로 나타내기

   - 반복문을 통하여 해당 자리의 숫자가 몫의 리스트에 포함되어 있으면 1, 아니면 0 삽입

   - 뒤집은 다음 마지막 자리의 수는 나머지로 채움

def ten2int(inp1, inp2):
    result = []
    if len(inp1) >= 1:
        for i in range(inp1[0] + 1):
            if i in inp1:
                result.append(1)
            else:
                result.append(0)
        result.reverse()
        result[-1] = inp2
    else:
        result.append(inp2)
    return result

   - 확인

a = ten2int([1], 1)
print(a)

# 결과
[1, 1]

  (4) 리스트 형태로 받기

   - 첫 번째 리스트 결과는 2진법 결과, 두 번째 리스트는 리스트의 길이 반환

def binary_id(inp):
    result = []
    len_result = []
    for i in inp:
        tmp1, tmp2 = from_ten_int(i)
        tmp_result = ten2int(tmp1, tmp2)
        result.append(tmp_result)
        len_result.append(len(tmp_result))
    return result, len_result

  - 확인

aa, bb = binary_id(class_id(data))
print(aa)
print(bb)

#결과
[[1], [1, 0], [1, 1], [1, 0, 0]]
[1, 2, 2, 3]

  (5) 자릿수 채우기

   - 리스트 길이를 통하여 최대 길이 값보다 작을 경우 차이만큼 0 리스트를 앞에 붙임

def matrix_arrange(inp1, inp2):
    result = []
    max_len = max(inp2)
    for i in range(len(inp1)):
        dif_num = max_len - inp2[i]
        if dif_num == 0:
            result.append(inp1[i])
        else:
            zero_list = []
            for j in range(dif_num):
                zero_list.append(0)
            result.append(zero_list + inp1[i])
    return result

   - 확인

aaa = matrix_arrange(aa, bb)
print(aaa)

# 결과
[[0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0]]

  (6) 최종

def final_binary_id(inp):
    tmp1, tmp2 = binary_id(inp)
    result = matrix_arrange(tmp1, tmp2)
    return result

   - 확인

aaaa = final_binary_id(class_id(data))
print(aaaa)

# 결과
[[0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0]]

 5) 원핫인코딩

  - 클래스의 최대 값 만큼 0 리스트를 만든 뒤 클래스의 위치에 1로 변환

def one_hot(inp):
    max_len = max(inp)
    zero_list = []
    result = []
    for i in range(max_len):
        zero_list.append(0)
    for i in inp:
        tmp_list = copy.deepcopy(zero_list)
        tmp_list[i-1] = 1
        result.append(tmp_list)
    return result

  - 확인

aaaaa = one_hot(class_id(data))
print(aaaaa)

# 결과
[[1, 0, 0, 0], [0, 1, 0, 0], [0, 0, 1, 0], [0, 0, 0, 1]]

 6) 최종

def final(inp):
    # 클래스 ID 분류
    result_class_id = class_id(inp)
    # 이진법 표현
    result_binary = final_binary_id(result_class_id)
    # 원핫인코딩
    result_one_hot = one_hot(result_class_id)
    result = pd.DataFrame({'원본' : inp, '클래스 ID' : result_class_id, '이진법' : result_binary, '원핫인코딩' : result_one_hot})
    return result

  - 확인

final(data)

2. 참고

 - 데이터 과학자와 데이터 엔지니어를 위한 인터뷰 문답집(Hulu 데이터 과학팀)

Comments