분석doc.mindscale.kr/ngv/nlp03_02.pdf · 2020. 11. 10. · 단어 문서 행렬 만들기...

49
감성 분석 1

Upload: others

Post on 28-Jan-2021

3 views

Category:

Documents


0 download

TRANSCRIPT

  • 감성 분석

    1

  • 데이터 열기import pandas as pd df = pd.read_csv('imdb.zip')

    데이터의 초반 5개를 확인합니다.

    df.head()

    .shape 로 데이터의 크기를 확인합니다.

    df.shape

    2

  • 단어 문서 행렬 만들기CountVectorizer 를 사용하여 단어 문서 행렬을 만듭니다.

    from sklearn.feature_extraction.text import CountVectorizer

    max_features=1000 : 피처의 개수는 1000개로 설정합니다.

    영어 데이터이므로 stop_words='english' 를 통해 관사 등을 제거합니다.

    cv = CountVectorizer(max_features=1000, stop_words='english')

    tdm = cv.fit_transform(df['review'])

    3

  • 데이터 분할 (1)review 로 만든 단어 문서 행렬을 x 로 sentiment 를 y 에 할당한다.

    x = tdm y = df['sentiment']

    4

  • 데이터 분할 (2)x 와 y 를 훈련용과 테스트용으로 분할한다.

    test_size=0.2 : 20%를 무작위로 테스트용 데이터로 할당한다.

    random_state : 데이터를 할당할 때 생성할 난수의 씨앗값을 정한다. 재현가능한 결과를 위하여 하나의 숫자(예: 42)로 고정한다.

    from sklearn.model_selection import train_test_split x_train, x_test, y_train, y_test = train_test_split(x, y, test_size=0.2, random_state=42)

    5

  • 데이터 분할 (3)x_train 은 x 의 훈련용 데이터이다.

    x_train

    x_test 는 x 의 테스트용 데이터이다.

    x_test

    y_train 은 y 의 훈련용 데이터이다.

    y_train

    y_test 는 y 의 테스트용 데이터이다.

    y_test 6

  • 로지스틱 회귀분석import tensorflow as tf

    model = tf.keras.models.Sequential()

    model.add(tf.keras.layers.Dense( 1, # 출력은 긍정(1)/부정(0) 하나 input_shape=(1000,), # 입력은 단어 수 activation='sigmoid'))

    7

  • 모형 요약model.summary()

    8

  • 학습 설정학습 알고리즘( optimizer )는 경사하강법의 일종인 adam

    손실함수( loss )는 교차 엔트로피( binary_crossentropy )보조적인 지표로 정확도( accurary )를 사용한다. 정확도란 전체 사례 중 맞은 사례의비율이다.

    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

    9

  • 모형 학습batch_size 는 한 번에 데이터를 입력하는 크기로 여기서는 한 번에 32개의 데이터를 입력한다.

    모든 데이터를 한 번 입력하는 것을 1 에포크(epoch)라고 한다. 아래는 epochs=10 이므로 총 10 에포크를 진행한다.

    10

  • 학습

    model.fit(x_train.toarray(), y_train.values, batch_size=32, epochs=10)

    각 에포크마다 손실( loss )가 감소하고, 그에 따라 정확도( accuracy )가 증가하는 것을볼 수 있다.

    ValueError: A Scipy sparse matrix was passed to a model that expects dense inputs.

    Please densify your inputs first, such as calling x.toarray() 와 같은 에러가 발생할수 있다. 이때는 x_train 을 x_train.toarray() 로 바꿔준다.

    11

  • 모형 평가테스트용 데이터로 모형을 평가한다.

    model.evaluate(x_test.toarray(), y_test.values, verbose=0)

    훈련 때보다 테스트에서 손실은 높고, 정확도는 낮다. 이를 통해 과적합이 발생하였음을알 수 있다.

    12

  • 모형 저장model.save('imdb-sentiment.krs')

    13

  • 모형 불러오기import tensorflow as tf model = tf.keras.models.load_model('imdb-sentiment.krs')

    14

  • 파라미터

    모형의 파라미터는 각 단어에 대한 가중치( weight )와 y 절편( bias )이다.

    weight, bias = model.trainable_weights

    15

  • 단어와 가중치를 표로 정리단어와 가중치의 쌍을 표로 정리한다.

    import pandas as pd

    word_weight = pd.DataFrame({ '단어': cv.get_feature_names(), '가중치': weight.numpy().flat })

    16

  • 부정 단어음의 가중치를 가지는 단어가 많으면, 리뷰가 부정(0)으로 분류된다. 따라서 이들 단어는부정 단어라고 할 수 있다.

    word_weight.sort_values('가중치').head()

    나쁜(bad), 끔찍한(awful), 낭비(waste) 등이 강한 음의 가중치를 가진다.

    17

  • 긍정 단어양의 가중치를 가지는 단어가 많으면, 리뷰가 긍정(1)으로 분류된다. 따라서 이들 단어는긍정 단어라고 할 수 있다.

    word_weight.sort_values('가중치').tail()

    좋은(fine), 유쾌한(hilarious), 흥미로운(interesting) 등이 강한 양의 가중치를 가진다.

    18

  • 준단어 토큰화

    19

  • tokenizers 설치!pip install tokenizers

    20

  • 데이터 열기import pandas as pd nsmc = pd.read_csv('ratings_train.txt', sep='\t')

    21

  • 텍스트만 저장토큰화를 위해 데이터에서 텍스트만 추출하여 텍스트 파일로 저장한다.

    with open('sample.txt', 'w', encoding='utf8') as f: for row in nsmc.itertuples(): try: f.write(row.document) f.write('\n') except TypeError: pass

    !head sample.txt

    22

  • BPEfrom tokenizers import CharBPETokenizer

    bpe = CharBPETokenizer(lowercase=True)

    bpe.train(files='sample.txt', min_frequency=1, vocab_size=5000)

    23

  • BPEenc = bpe.encode( '자연어 처리는 재밌다!')

    enc.ids

    enc.tokens

    24

  • 풀어쓰기

    한글을 풀어쓰기하여 텍스트를 저장한다.

    import unicodedata

    with open('decomposed.txt', 'w', encoding='utf8') as f: for row in nsmc.itertuples(): try: q = unicodedata.normalize('NFD', row.document) f.write(q) f.write('\n') except TypeError: pass

    25

  • 풀어쓰기 BPEbpe = CharBPETokenizer(lowercase=True)

    bpe.train(files='decomposed.txt', min_frequency=1, vocab_size=5000)

    26

  • 풀어쓰기 BPE텍스트를 토큰화 전에 풀어쓰기 한다.

    text = unicodedata.normalize('NFD', '자연어 처리는 재밌다!') enc = bpe.encode(text)

    enc.ids

    enc.tokens

    27

  • Byte-level BPEfrom tokenizers import ByteLevelBPETokenizer

    byte = ByteLevelBPETokenizer(lowercase=True)

    byte.train(files='sample.txt', min_frequency=1, vocab_size=5000)

    28

  • Byte-level BPEenc = byte.encode('자연어 처리는 재밌다!')

    enc.ids

    enc.tokens

    29

  • WordPiece modelfrom tokenizers import BertWordPieceTokenizer

    wp = BertWordPieceTokenizer(lowercase=True)

    wp.train(files='sample.txt', min_frequency=1, vocab_size=5000)

    30

  • WordPiece modelenc = wp.encode('자연어 처리는 재밌다!')

    enc.ids

    enc.tokens

    31

  • SentencePiece modelfrom tokenizers import SentencePieceBPETokenizer

    sp = SentencePieceBPETokenizer()

    sp.train(files='sample.txt', min_frequency=1, vocab_size=5000)

    32

  • SentencePiece modelenc = sp.encode('자연어 처리는 재밌다!')

    enc.ids

    enc.tokens

    33

  • 저장

    저장할 폴더를 만든다

    import os

    os.mkdir('nsmc-sp')

    폴더에 저장

    sp.save('nsmc-sp')

    34

  • 토크나이저 불러오기from tokenizers import SentencePieceBPETokenizer

    sp = SentencePieceBPETokenizer( vocab_file='nsmc-sp/vocab.json', merges_file='nsmc-sp/merges.txt')

    35

  • 준단어 토큰화 함수def tokenizer(text): return sp.encode(text).tokens

    tokenizer('좋은 아침입니다.')

    36

  • 단어 문서 행렬from sklearn.feature_extraction.text import CountVectorizer

    cv = CountVectorizer(max_features=1000, tokenizer=tokenizer)

    tdm = cv.fit_transform(nsmc.loc[0:3999, 'document'])

    37

  • 데이터 분할from sklearn.model_selection import train_test_split

    y = nsmc.loc[0:3999, 'label']

    x_train, x_test, y_train, y_test = train_test_split(tdm, y, test_size=0.2, random_state=42)

    x_train.shape

    38

  • 모형

    import tensorflow as tf

    kernel_regularizer 에는 정규화를 위한 페널티 항을 추가한다. l1 , l2 그리고 l1_l2를 사용할 수 있다.

    model = tf.keras.models.Sequential() model.add( tf.keras.layers.Dense( 1, input_shape=(1000,), activation='sigmoid', kernel_regularizer=tf.keras.regularizers.l2(0.001)))

    39

  • 요약

    model.summary()

    40

  • 설정

    model.compile(optimizer='adam', loss='binary_crossentropy', metrics=['accuracy'])

    41

  • 학습

    model.fit(x_train.toarray(), y_train.values, epochs=100, validation_split=0.1, callbacks=[tf.keras.callbacks.EarlyStopping()])

    42

  • 모형 평가model.evaluate(x_test.toarray(), y_test.values, verbose=0)

    43

  • 가중치

    weights, _ = model.trainable_weights

    import pandas as pd token_weight = pd.DataFrame({ '토큰': cv.get_feature_names(), '가중치': weights.numpy().flat })

    44

  • 부정단어

    부정단어를 확인한다.

    token_weight.sort_values('가중치').head()

    45

  • 긍정단어

    긍정단어를 확인한다.

    token_weight.sort_values('가중치').tail()

    46

  • 새로운 데이터에 적용새로운 데이터

    new_data = ['뽀로로는 정말 재미있는 영화다.', '이런 영화를 만들다니 감독은 무슨 생각이냐?']

    47

  • TDM 변환새로운 데이터를 TDM으로 변환한다. 이미 TDM의 형식이 정해져 있으므로fit_transform 대신 transform 을 사용한다.

    x_new = cv.transform(new_data)

    48

  • 예측

    새로운 데이터에서 각 리뷰가 긍정( 1 )일 확률을 예측한다.

    model.predict(x_new.toarray())

    49