인공지능/RNN

자연어처리( doc2vec )

쿠와와 2020. 11. 22. 21:58
import nltk
import random
import collections
import time

# word to vector -> 단어를 숫자로 바꾸겠다. document to vector 다큐먼트를 벡터로 바꿈
# ex 영화 리뷰를 그 안의 단어를 가지고 충분히 학습 후 -> 긍정, 부정을 나눔 => doc to vec


# doc 분석해서 어떤 분류인지 알아내겠다.
def make_vocab(vocab_size=2000):        # 사실 2천개는 너무 적음 만개는 해야함
    # nltk.download('movie_reviews')
    words = nltk.corpus.movie_reviews.words()

    # print(len(words))
    # print(nltk.corpus.movie_reviews.categories())   # 폴더 이름 -> 정답임 (대부분 이렇게) ['neg', 'pos']

    # print(len(nltk.corpus.movie_reviews.fileids('neg')))  # 1000개
    # print(len(nltk.corpus.movie_reviews.fileids('pos')))  # 1000개
    all_words = collections.Counter([w.lower() for w in words])
    most_2000 = all_words.most_common(vocab_size)   # 최빈 값을 찾아줌

    return [w for w, _ in most_2000]    # 최빈 값은 사용하지 않을 것임


def make_feature(filename, vocab):  # filename = 리뷰룰 앍어오는 파일 이름
    doc_words = nltk.corpus.movie_reviews.words(filename)
    feature, uniques = {}, set(doc_words)       # uniques <- 중복 x 검색 빠르게 할려고

    for v in vocab:
        feature['has_{}'.format(v)] = (v in uniques)  # uniques 안의 v를 찾아 true false 넣어줌
        # feature 수 2천개
    print(feature)
    return feature


voca = make_vocab(vocab_size=2000)

# 파일 목록을 불러옴
neg = nltk.corpus.movie_reviews.fileids('neg')      # 1000개의 목록
pos = nltk.corpus.movie_reviews.fileids('pos')      # 1000개의 목록

# 완전히 숙지하기
# 문제
# 80% 데이터로 학습하고 20% 데이터에 대해 정확도를 구하세요
neg_data = [(make_feature(filename, voca), 'neg')for filename in neg]
pos_data = [(make_feature(filename, voca), 'pos')for filename in pos]
#
# # 긍정/ 부정 불균형 ***
# # data = neg_data + pos_data
# random.shuffle(neg_data)
# random.shuffle(pos_data)
#
# # 데이터 나눔 학습 데이터와 테스트 데이터
# train_set = neg_data[:800] + pos_data[:800]
# test_set = neg_data[800:] + pos_data[800:]
# # 보통 7/8 학습 나머지는 test
# # train_set, test_set = data[:-1000], data[:1000]
# # 학습 시작
# clf = nltk.NaiveBayesClassifier.train(train_set)    # 엄청 빠름 왜? 정확도가 떨어지니깐
# print('acc :', nltk.classify.accuracy(clf, test_set))   # 결과 정답빈도를 알려줌

# doc2vec -> 사용? 기사를 분석할 때 특정 단어가 많이 나올 때