ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 1-2. 한국어 띄어쓰기 구현 - CRFSuite
    카테고리 없음 2019. 3. 29. 15:27

    Python-CRFSuite

    CRFSuite : 주변의 레이블들을 보고 해당 아이템이 어떤 레이블인지 판단하는 통계적 모델링 기법이다.

    CRF를 이용한 한국어 자동 띄어쓰기(심광섭)와 theeluwin님의 블로그를 참고하여 진행하였다.

     

    구현한 내용이 위의 블로그와 동일한데 논문에서 사용한 방법대로 feature set을 늘려 구현하였다.

    이 포스팅에서는 위의 블로그에 없는, 추가 구현한 내용만 작성하도록 하겠다.

     

    feature 생성 부분이 간단하게 앞 뒤의 한 음절만 보는 방식(아래의 feature set중 맨 위)이었는데,

    아래 처럼 다양한 feature를 보고 계산하도록 추가하였다.(성능 90% -> 90중후반으로 상승)

    논문 표 4. 상태 자질

    def one_index2feature(sent, i, offset):
        word, tag = sent[i + offset]
        if offset < 0:
            sign = ''
        else:
            sign = '+'
        return '{}{}:word={}'.format(sign, offset, word)
    
    
    def one_feature_set(sent, i, pre, post):
        length = len(sent)
        feature = ['bias', one_index2feature(sent, i, 0)]
        for p in range(pre, 0, -1):
            if i > p - 1:
                feature.append(one_index2feature(sent, i, -p))
        if i <= 0:
            feature.append('bos')
        for p in range(post, 0, -1):
            if i < length - p:
                feature.append(one_index2feature(sent, i, p))
        if i >= length:
            feature.append('eos')
    
        return feature
    
    
    def two_index2feature(sent, i, offset):
        word1, tag1 = sent[i + offset]
        word2, tag2 = sent[i + offset + 1]
        if offset < 0:
            sign = ''
        else:
            sign = '+'
        return '{}{}:word={}'.format(sign, offset, word1 + word2)
    
    
    def two_feature_set(sent, i, pre, post):
        length = len(sent)
        feature = ['bias', two_index2feature(sent, i, 0)]
        for p in range(pre, 0, -1):
            if i > p - 1:
                feature.append(two_index2feature(sent, i, -p))
        if i <= 0:
            feature.append('bos')
        for p in range(post, 0, -1):
            if i < length - p:
                feature.append(two_index2feature(sent, i, p))
        if i >= length:
            feature.append('eos')
    
        return feature
    
    
    def three_feature_set(sent, i, pre, post):
        length = len(sent)
        feature = ['bias', three_index2feature(sent, i, 0)]
        for p in range(pre, 0, -1):
            if i > p - 1:
                feature.append(two_index2feature(sent, i, -p))
        if i <= 0:
            feature.append('bos')
        for p in range(post, 0, -1):
            if i < length - p:
                feature.append(two_index2feature(sent, i, p))
        if i >= length:
            feature.append('eos')
    
        return feature
    
    
    def three_index2feature(sent, i, offset):
        word1, tag1 = sent[i + offset]
        word2, tag2 = sent[i + offset + 1]
        word3, tag3 = sent[i + offset + 2]
        if offset < 0:
            sign = ''
        else:
            sign = '+'
        return '{}{}:word={}'.format(sign, offset, word1 + word2 + word3)
    
    
    def word2features(sent):
        features = []
        for i in range(len(sent)):
            features.append(one_feature_set(sent, i, 2, 2))
            if i < len(sent) - 1:
                features.append(two_feature_set(sent, i, 2, 0))
            if i < len(sent) - 2:
                features.append(three_feature_set(sent, i, 2, 0))
    
        return features

    one, two, three는 각각 feature로 보는 음절의 개수를 뜻한다.
    위의 코드를 돌려보면 feature가 B, I ,BB, BI, BBI, III 등 총 14개?가 나온다.

    댓글

Designed by Tistory.