TF-IDF를 구현해 보았습니다.

9231 단어 Python3mecabtf-idf
최근 TF-IDF에 대한 코드를 Python으로 작성했으므로 그에 대해 나름대로 정리해 둡니다. 해석이 다른 곳 등 있으면 지적하십시오.
소스 코드는 여기 : Github

TF-IDF란?



wikipedia에서 인용 htps : // 그럼.ぃきぺぢ아. rg / uki / Tf-df

tf-idf는 문서에 포함된 단어의 중요도를 평가하는 방법 중 하나이며, 주로 정보 검색이나 주제 분석 등의 분야에서 사용되고 있다. tf-idf는 tf(영: Term Frequency, 단어의 출현 빈도)와 idf(영: Inverse Document Frequency, 역문서 빈도)의 2개의 지표에 기초하여 계산된다.

문서 중에서 단어의 중요도를 나타내는 것으로, 그 문서의 특징 등을 알고 싶을 때 사용합니다. TF값과 IDF값을 곱한 값이 TF-IDF값이 됩니다.

TF (Term Frequency 단어의 출현 빈도)



제목에 있는 거리입니다. 문서를 단어별로 분해하여 TF 값을 찾으려는 단어의 출현 빈도를 찾습니다. 단어의 출현 빈도가 높은 쪽이 중요도가 높기 때문에, 이 값은 커집니다.
TF = \frac{特定の単語の出現数}{文書の全単語数}

IDF (Inverse Document Frequency 역 문서 빈도)



IDF 값을 찾으려는 단어의 문서 빈도의 역수에 로그를 취하여 값을 구합니다. 그러나, 단지 로그를 취한 경우라면 IDF값이 0이 되어 버리는 일이 있기 때문에, 이번은 로그 취한 값에 1을 더했습니다.
많은 문서에 등장하는 단어는 특징이 없는 단어라고 할 수 있으므로 IDF 값은 작아집니다. 반대로 적은 문서에서만 사용되는 단어는 특징이 있는 단어라고 할 수 있으므로 IDF 값은 커집니다.
IDF = \log \frac{全文書数}{単語が出現した文書数} + 1

TF 값과 IDF 값을 곱한 값이 TF-IDF 값이 되므로 문서에서 단어의 출현 빈도가 높고, 많은 문서에서는 사용되지 않는 단어일수록 그 문서에서의 단어의 TF-IDF 값은 커지고, 그 문서의 특징을 나타내는 단어라고 할 수 있습니다.

구현해 보았다.



이번은 푸른 하늘 문고 에서 13 작품을 가져와 그것을 사용하여 구현했다. 코드도 붙입니다만, 전체는 Github 쪽에 있으므로, 일부를 발췌합니다.

형태소 분석



TF-IDF 값을 구하려면 먼저 단어별로 분해해야 합니다. 이번에는 단어 중 명사를 대상으로했습니다. 형태소 분석에는 MeCab을 사용했습니다. 또한 일부 스톱워드를 설정했습니다.
로컬에 있는 데이터를 읽어, 그 문서를 형태소 해석해 단어 마다의 출현 횟수를 카운트 해, 그 Counter(dict)를 돌려줍니다.

main.py
def get_word_counter(filename):
    filepath = './TF-IDF/text_data/'+filename
    with codecs.open(filepath, 'r', encoding='shift-jis') as fp:
        word_counter = Counter()
        text = fp.read()
        text_lines = text.split('\n')
        for text_line in text_lines:
            node = tagger.parseToNode(text_line)
            while node:
                word_type = node.feature.split(',')[0]
                if (word_type == '名詞') and (len(node.surface) != 0) \
                        and (not(node.surface in stop_word_list)):
                    word_counter[node.surface] += 1
                node = node.next
    return word_counter

TF 값



이전에 찾은 단어의 출현 빈도를 사용하여 문서의 각 단어에 대해 TF 값을 계산합니다.
(key, value)=(단어, TF값)인 dict를 반환합니다.

main.py
def get_tf_dict(word_counter):
    tf_dict = {}
    word_total = sum(word_counter.values())
    for word, count in word_counter.items():
        tf_dict[word] = count/word_total
    return tf_dict

IDF 값



각 문서에 대해 단어의 출현 빈도를 기록하는 dict를 사용하여 IDF 값을 계산합니다.
(key, value)=(단어, IDF값)이 되어 있는dict를 돌려줍니다.

main.py
def get_idf_dict(file_word_counter, targetname):
    word_list = file_word_counter[targetname].keys()
    filename_list = file_word_counter.keys()
    idf_dict = {}
    for word in word_list:
        word_count = 0
        for filename in filename_list:
            if word in file_word_counter[filename].keys():
                word_count += 1
        idf_dict[word] = log(len(filename_list)/word_count)+1
    return idf_dict


실행 결과



13작품을 이용하여 작품마다 TF-IDF값이 높은 10단어를 출력했습니다. 그 일부를 붙여 둡니다. 작품을 상징하는 단어가 높은 값을 취하고 있음을 알 수 있습니다. 어쩌면 좋은 느낌으로 구현할 수 있었던 것이 아닐까요.


요약



TF-IDF에 대해 배운 것을 나름대로 정리했습니다. 파이썬으로 좋은 느낌으로 구현이 가능했기 때문에 좋았다고 생각합니다. 그러나 고유 명사나 복합 명사 등은 사용자 사전을 정의하지 않기 때문에 단어 구분이 부자연스러운 곳이 있는 것이 과제군요.
scikit-learn을 사용해도 계산은 할 수 있는 것 같기 때문에 그것도 시도해 볼까라고 생각합니다.

좋은 웹페이지 즐겨찾기