원핫 인코딩(One-Hot Encoding) 개념과 구현해보기

    사람과 컴퓨터는 데이터를 바라보는 형태가 다르다

     

    인간과 컴퓨터는 데이터를 바라보는 형태가 다르다 사람은 어떤 물체를 보더라도 숫자로 인식하지는 않지만 컴퓨터에게 인공지능을 구현시키기 위해서는 컴퓨터가 알아먹기 쉽게 숫자값으로 변환을 해줘야 된다.

     

    예를 들어 내가 지금 여기서 열심히 포스팅을 하고 있는 내용을 컴퓨터에게 이해 시키려면 단어들을 숫자 형태로 정리해서 컴퓨터에게 입력시켜줘야 한다는 것이다. 

     

    원핫 인코딩(One-Hot Encoding)은 사람이 매우 쉽게 이해할 수 있는 데이터를 컴퓨터에게 주입시키기 위한 가장 기본적인 방법이다.

     

    원핫인코딩 개념

     

    원핫(One-Hot) 인코딩이라는 말처럼 이 기술은 데이터를 수많은 0과 한개의 1의 값으로 데이터를 구별하는 인코딩이다. 예를 들어, 글자가 적힌 종이를 0부터 9까지의 숫자값으로 분류를 하는 작업을 한다면 숫자값들은 다음과 같은 값들로 이루어질 수 있을 것이다.

     

    [1,0,0,0...0]
    [0,1,0,0...0]
    [0,0,1,0...0]
    ...

     

    이와같이 0으로 이루어진 벡터에 단 한개의 1의 값으로 해당 데이터의 값을 구별하는 것이 원핫 인코딩이다.

    원핫 인코딩은 매우 기초적이면서도 아주 흔히 사용되는 기법으로 딥러닝 뿐만 아니라 데이터 마이닝, 자연어 처리 등 아직도 많은 분야에서 사용되고 있는 기법이다.

     

    파이썬(Python)으로 원핫 인코딩 구현하기

     

    인공지능 포스팅을 케라스와 텐서플로우를 베이스로 하기 때문에 구현하는 방식도 케라스를 활용하여 설명해보고자 한다.

     

    import tensorflow as tf
    from tensorflow.keras.preprocessing.text import Tokenizer
    
    str = "저는 몬스터 에너지를 좋아합니다. 그 중 몬스터 파이프라인 펀치는 너무 맛나요"

    "저는 몬스터 에너지를 좋아합니다. 그 중 몬스터 파이프라인 펀치는 너무 맛나요"라는 문장을 str 변수에 담는다

     

    tokenizer = Tokenizer()
    tokenizer.fit_on_texts([str])
    print(tokenizer.word_index)
    {'몬스터': 1, '저는': 2, '에너지를': 3, '좋아합니다': 4, 
    '그': 5, '중': 6, '파이프라인': 7, '펀치는': 8, '너무': 9, '맛나요': 10}

    Tokenizer의 fit_on_texts 메소드에 str 문장을 넣으면, 공백을 기준으로 데이터를 분리하여 tokenizing을 하는 작업을 수행한다.  토크나이징 작업이 완료되었다면, tokenizer.word_index를 print하여 결과를 확인해보면 어떤 단어가 어떤 값으로 index 되었는지 알 수 있다.

     

     

    이번에는 단어간 인덱스 결과를 기준으로 다시 문장의 값을 인코딩해보도록 한다.

    encoded = tokenizer.texts_to_sequences([str])[0]
    print(encoded)
    [2, 1, 3, 4, 5, 6, 1, 7, 8, 9, 10]

    이미 tokenizer에는 단어별 인덱스값들이 저장된 상태이며, texts_to_sequences에 문장을 넣으면 문장의 내용을 인덱스 배열로 리턴하게 된다.

     

    이제 위 데이터를 one-hot encoding 하는 작업을 수행하면 된다. 원핫인코딩은 사실 별도의 메소드를 만들어도 짧은 라인으로 구현을 할 수 있기 때문에 직업 배열값을 받아서 구현해도 상관이 없지만 keras에서 제공해주는 메소드가 있으니 제공해주는 함수를 사용해보도록 한다.

     

    onehot = tf.keras.utils.to_categorical(encoded)
    print(onehot)
    [[0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0.]
     [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1.]]

    케라스에서 to_categorical 함수에 배열값을 전달하면 원핫 인코딩을 하기 때문에 매우 쉽게 구현할 수 있다. [2,1,3,4...] 값을 encoding 하면 위와 같은 모양의 벡터값으로 리턴을 한다.

     

    만약에 데이터의 범위를 직접 지정하고 싶은 상황이 올 수 있다. 예를 들어, 현재 데이터가 부족하여 5개밖에 없는데 10개까지 늘려야 할 경우 미리 범위를 크게 지정하여 추후 데이터가 새로 들어와도 개발을 하는데 문제가 발생하지 않도록 할 수 있다.

     

    onehot = tf.keras.utils.to_categorical(encoded, 20)
    print(onehot)

    위 코드는 20이라고 범위를 늘린것이다. 

    [[0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.]
     [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 0. 0. 0. 0. 0. 0. 0. 0. 0.]]

    값을 지정하여 넣을 경우 위와 같이 나머지 값은 0이 추가되면서 데이터를 생성한다.

    댓글

    Designed by JB FACTORY