ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [3월 1주차-3/7(2)]텍스트 전처리3-정수 인코딩, 패딩
    Why Not SW CAMP 5기/수업 기록 2025. 3. 7. 12:10

    ✅텍스트 전처리

    • 토큰화(tokenization)
    • 정제(cleaning) and 정규화(normalization)
    • 어간 추출 and 표제어 추출
    • 불용어(stopword) 제거
    • 정규 표현식(regular expression)
    • 정수 인코딩(integer encoding)
    • 패딩(padding)
    • 원 핫 인코딩(one-hot encoding)
    • 데이터의 분리(splitting data)

     

    정수 인코딩 (Integer Encoding) 및 패딩 (Padding) 완벽 가이드

    자연어 처리를 수행할 때, 텍스트 데이터를 수치화하는 과정이 필요합니다. 정수 인코딩(Integer Encoding)은 텍스트 데이터를 숫자로 변환하는 방법 중 하나로, 단어에 정수를 부여하는 방식입니다. 또한, 패딩(Padding)은 다양한 길이의 문장을 동일한 길이로 맞춰주는 과정입니다. 이 글에서는 정수 인코딩과 패딩을 수행하는 다양한 방법을 설명합니다.


    1. 정수 인코딩이란?

    정수 인코딩은 단어를 빈도수 순으로 정렬한 후, 빈도수가 높은 단어부터 차례대로 낮은 숫자를 부여하는 방식입니다. 이를 통해 텍스트 데이터를 수치화할 수 있습니다.

    정제 작업과 정규화 작업을 병행하며 단어 토큰화를 수행하는 과정:

    1. 단어를 소문자로 변환
    2. 단어의 개수를 통일
    3. 불용어(stopwords)와 단어 길이가 2 이하인 경우 제외
    4. 텍스트를 수치화

    2. 정수 인코딩 구현하기

    (1) 데이터 준비 및 전처리

    먼저 필요한 라이브러리를 불러오고 데이터를 준비합니다.

    import nltk
    nltk.download('punkt')
    nltk.download('stopwords')
    
    from nltk.tokenize import sent_tokenize, word_tokenize
    from nltk.corpus import stopwords
    
    
    raw_text = """A barber is a person. a barber is good person.
                a barber is huge person. he Knew A Secret!
                The Secret He Kept is huge secret. Huge secret.
                His barber kept his word. a barber kept his word.
                His barber kept his secret.
                But keeping and keeping such a huge secret to himself was driving the barber crazy.
                the barber went up a huge mountain."""
                
    sentences = sent_tokenize(raw_text)

     

    단어 토큰화 및 정제 작업 수행:

    preprocessed_sentences = []  # 전처리된 문장 리스트
    
    stop_words = set(stopwords.words('english'))
    
    for sentence in sentences:
        tokenized_sentence = word_tokenize(sentence)
        result = []
        
        for word in tokenized_sentence:
            word = word.lower()
            if word not in stop_words and len(word) > 2:
                result.append(word)
        
        preprocessed_sentences.append(result)

     

    전처리된 문장

    [['barber', 'person'],
     ['barber', 'good', 'person'],
     ['barber', 'huge', 'person'],
     ['knew', 'secret'],
     ['secret', 'kept', 'huge', 'secret'],
     ['huge', 'secret'],
     ['barber', 'kept', 'word'],
     ['barber', 'kept', 'word'],
     ['barber', 'kept', 'secret'],
     ['keeping', 'keeping', 'huge', 'secret', 'driving', 'barber', 'crazy'],
     ['barber', 'went', 'huge', 'mountain']]
    

    3. 정수 인코딩 방법

    (1) Counter() 사용하기

    Counter()를 사용하여 단어 빈도수를 계산한 후, 상위 5개의 단어를 선정합니다.

    from collections import Counter
    
    all_words_list = sum(preprocessed_sentences, [])
    vocab = Counter(all_words_list)
    
    # 상위 5개 단어 선택
    vocab = vocab.most_common(5)
    print(vocab)
    

    출력 결과:

    [('barber', 8), ('secret', 6), ('huge', 5), ('kept', 4), ('person', 3)]
    

    각 단어에 정수 인덱스 부여:

    word_to_index = {word: i+1 for i, (word, _) in enumerate(vocab)}
    word_to_index['OOV'] = len(word_to_index) + 1  # Out-Of-Vocabulary 처리
    

    결과:

    {'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5, 'OOV': 6}
    

    (2) FreqDist 사용하기

    NLTK의 FreqDist를 사용하여 단어 빈도수를 계산할 수도 있습니다.

    from nltk import FreqDist
    import numpy as np
    
    vocab = FreqDist(np.hstack(preprocessed_sentences))
    

    상위 5개 단어 추출 및 정수 인코딩:

    vocab = vocab.most_common(5)
    word_to_index = {word[0]: index + 1 for index, word in enumerate(vocab)}
    word_to_index['OOV'] = len(word_to_index) + 1
    

    (3) 텍스트 정수 변환

    단어를 사전에 정의된 word_to_index를 사용하여 정수로 변환합니다.

    encoded_sentences = []
    
    for sentence in preprocessed_sentences:
        encoded_sentence = []
        
        for word in sentence:
            try:
                encoded_sentence.append(word_to_index[word])
            except KeyError: 
                encoded_sentence.append(word_to_index['OOV'])
                
        encoded_sentences.append(encoded_sentence)

    출력

    [[1, 5],
     [1, 6, 5],
     [1, 3, 5],
     [6, 2],
     [2, 4, 3, 2],
     [3, 2],
     [1, 4, 6],
     [1, 4, 6],
     [1, 4, 2],
     [6, 6, 3, 2, 6, 1, 6],
     [1, 6, 3, 6]]
    

    (4) Keras를 사용한 정수 인코딩

    Keras의 Tokenizer를 사용하여 단어를 정수로 변환할 수도 있습니다.

    from tensorflow.keras.preprocessing.text import Tokenizer
    
    tokenizer = Tokenizer(num_words = 6)
    tokenizer.fit_on_texts(preprocessed_sentences)
    
    print(tokenizer.word_index)

    출력 결과:

    {'barber': 1, 'secret': 2, 'huge': 3, 'kept': 4, 'person': 5, 'word': 6, 'keeping': 7, 'good': 8, 'knew': 9, 'driving': 10, 'crazy': 11, 'went': 12, 'mountain': 13}
    

    텍스트를 정수로 변환:

    print(tokenizer.texts_to_sequences(preprocessed_sentences))
    

    출력 예시:

    [[1, 5], [1, 5], [1, 3, 5], [2], [2, 4, 3, 2], [3, 2], [1, 4], [1, 4], [1, 4, 2], [3, 2, 1], [1, 3]]

    4. 패딩 (Padding) 적용하기

    다양한 길이의 문장을 동일한 길이로 맞추기 위해 패딩을 적용합니다.

    (1) 수동 패딩 적용

    import numpy as np
    from tensorflow.keras.preprocessing.text import Tokenizer
    
    tokenizer = Tokenizer()
    # 빈도수를 기준으로 단어 집합 생성
    tokenizer.fit_on_texts(preprocessed_sentences)
    encoded = tokenizer.texts_to_sequences(preprocessed_sentences)
    
    max_len = max(len(item) for item in encoded)
    
    for sentence in encoded:
        while len(sentence) < max_len:
            sentence.append(0)
    
    padded_np = np.array(encoded)

    출력 예시:

    array([[ 1,  5,  0,  0,  0,  0,  0],
           [ 1,  8,  5,  0,  0,  0,  0],
           [ 1,  3,  5,  0,  0,  0,  0],
           [ 9,  2,  0,  0,  0,  0,  0],
           [ 2,  4,  3,  2,  0,  0,  0],
           [ 3,  2,  0,  0,  0,  0,  0],
           [ 1,  4,  6,  0,  0,  0,  0],
           [ 1,  4,  6,  0,  0,  0,  0],
           [ 1,  4,  2,  0,  0,  0,  0],
           [ 7,  7,  3,  2, 10,  1, 11],
           [ 1, 12,  3, 13,  0,  0,  0]])

    (2) pad_sequences() 사용

    from tensorflow.keras.preprocessing.sequence import pad_sequences
    
    tokenizer = Tokenizer()
    tokenizer.fit_on_texts(preprocessed_sentences)
    encoded = tokenizer.texts_to_sequences(preprocessed_sentences)
    
    padded = pad_sequences(encoded, padding='post', maxlen=5, truncating='post')
    # padding 미설정 시 0이 앞에 채워짐
    # truncating 미설정 시 maxlen에 맞게 앞 데이터(여기서는 7,7)가 지워짐

    출력 예시:

    array([[ 1,  5,  0,  0,  0],
           [ 1,  8,  5,  0,  0],
           [ 1,  3,  5,  0,  0],
           [ 9,  2,  0,  0,  0],
           [ 2,  4,  3,  2,  0],
           [ 3,  2,  0,  0,  0],
           [ 1,  4,  6,  0,  0],
           [ 1,  4,  6,  0,  0],
           [ 1,  4,  2,  0,  0],
           [ 7,  7,  3,  2, 10],
           [ 1, 12,  3, 13,  0]])

    (3) 임의의 숫자로 패딩

    last_value = len(tokenizer.word_index) + 1
    
    padded = pad_sequences(encoded, padding='post', value = last_value)

    출력 예시:

    '''
    array([[ 1,  5, 14, 14, 14, 14, 14],
           [ 1,  8,  5, 14, 14, 14, 14],
           [ 1,  3,  5, 14, 14, 14, 14],
           [ 9,  2, 14, 14, 14, 14, 14],
           [ 2,  4,  3,  2, 14, 14, 14],
           [ 3,  2, 14, 14, 14, 14, 14],
           [ 1,  4,  6, 14, 14, 14, 14],
           [ 1,  4,  6, 14, 14, 14, 14],
           [ 1,  4,  2, 14, 14, 14, 14],
           [ 7,  7,  3,  2, 10,  1, 11],
           [ 1, 12,  3, 13, 14, 14, 14]])
    '''

    패딩을 통해 문장 길이를 맞추면 모델이 데이터를 효과적으로 학습할 수 있습니다.

     


    5. 마무리

    정수 인코딩과 패딩은 자연어 처리에서 필수적인 과정입니다. 다양한 방법을 활용하여 데이터에 적합한 방식을 선택하세요!

     

Designed by Tistory.