텍스트 분류 프로그램 구축: NLP 튜토리얼
게시 됨: 2022-03-11딥 러닝은 머신 러닝 워크플로의 필수 부분이 된 기술입니다. 병렬 컴퓨팅 성능 및 지원 도구의 개선을 활용하여 한때 비실용적이었던 복잡하고 심층적인 신경망이 이제 실행 가능하게 되었습니다.
Tensorflow, Torch 및 Deeplearning4j와 같은 강력하고 액세스 가능한 라이브러리의 출현은 대규모 기술 회사의 학계 및 연구 부서를 넘어 사용자에게 개발의 기회를 제공했습니다. 성장하는 편재성에 대한 증거로 Huawei 및 Apple과 같은 회사는 이제 최신 장치에 딥 러닝 애플리케이션을 구동하기 위해 딥 러닝에 최적화된 전용 프로세서를 포함하고 있습니다.
딥 러닝은 많은 영역에서 그 힘을 입증했습니다. 가장 주목할만한 점은 Google의 AlphaGo가 인간 플레이어와 경쟁할 때 컴퓨터가 극복할 수 없는 거의 극복할 수 없는 장벽으로 여겨졌던 놀라운 복잡성을 가진 바둑 게임에서 인간 플레이어를 물리칠 수 있다는 것입니다. Sony의 Flow Machines 프로젝트는 과거 유명 뮤지션의 스타일로 음악을 작곡할 수 있는 신경망을 개발했습니다. Apple에서 개발한 보안 기능인 FaceID는 딥 러닝을 사용하여 사용자의 얼굴을 인식하고 시간 경과에 따른 사용자 얼굴의 변화를 추적합니다.
이 기사에서는 내가 가장 좋아하는 두 가지 주제인 자연어 처리와 와인에 딥 러닝을 적용할 것입니다. 전문가의 자연어 와인 리뷰를 이해하고 그들이 리뷰하는 와인의 다양성을 추론하는 모델을 구축합니다.
NLP를 위한 딥 러닝
딥러닝은 문장의 복잡한 기본 구조와 다양한 단어의 의미적 근접성을 학습하는 데 적합하기 때문에 자연어 처리 (NLP)에서 광범위하게 사용되었습니다. 예를 들어, 감정 분석을 위한 최신 기술은 부정 및 혼합 감정과 같이 모델링하기 어려운 언어 개념을 포착하기 위해 딥 러닝을 사용합니다.
딥 러닝은 다른 NLP 알고리즘에 비해 몇 가지 장점이 있습니다.
- 유연한 모델: 딥 러닝 모델은 다른 ML 모델보다 훨씬 유연합니다. 필요에 따라 레이어를 추가 및 제거하면서 다양한 구조를 쉽게 실험할 수 있습니다. 딥 러닝 모델을 사용하면 유연한 출력으로 모델을 구축할 수도 있습니다. 유연성은 복잡한 언어 구조를 이해하는 데 적합한 모델을 개발하는 데 중요합니다. 번역, 챗봇, TTS(텍스트 음성 변환) 애플리케이션과 같은 NLP 애플리케이션 개발에도 필수적입니다.
- 필요한 도메인 지식 감소: 좋은 딥 러닝 모델을 개발하기 위해서는 어느 정도 도메인 지식과 직관이 필요하지만 자체적으로 기능 계층을 학습하는 딥 러닝 알고리즘의 능력은 개발자가 딥러닝 NLP 알고리즘을 개발하기 위한 문제 공간입니다. 자연어처럼 복잡한 문제 공간의 경우 이는 매우 환영할 만한 이점입니다.
- 더 쉬운 지속적인 학습: 딥 러닝 알고리즘은 새로운 데이터가 들어올 때 쉽게 훈련할 수 있습니다. 일부 기계 학습 알고리즘은 업데이트를 위해 전체 데이터 세트를 모델을 통해 보내야 하므로 라이브의 대규모 데이터 세트에 문제가 발생할 수 있습니다.
오늘의 문제
오늘 우리는 리뷰 텍스트를 기반으로 리뷰 대상 와인의 다양성을 결정하는 딥 러닝 알고리즘을 구축할 것입니다. 우리는 Kaggle 사용자 zackthoutt 가 제공하는 https://www.kaggle.com/zynicide/wine-reviews의 와인 매거진 데이터세트를 사용할 것입니다.
개념적으로 문제는 다음과 같은 와인 리뷰를 할 수 있느냐는 것입니다.
아로마는 열대 과일, 빗자루, 유황 및 말린 허브를 포함합니다. 미각은 지나치게 표현적이지 않으며, 활발한 산도와 함께 덜 익은 사과, 감귤류, 말린 세이지를 제공합니다.
… 그리고 그것이 백색 혼합에 관한 것이라는 것을 알고 계십니까? 일부 와인 애호가는 사과, 감귤류 및 뚜렷한 산도와 같은 화이트 와인의 명백한 징후를 인식할 수 있지만 이러한 신호를 인식하도록 신경망을 훈련할 수 있습니까? 또한 화이트 블렌드 리뷰와 피노 그리지오 리뷰 사이의 미묘한 차이를 인식하도록 신경망을 훈련할 수 있습니까?
유사한 알고리즘
오늘 우리가 작업하고 있는 문제는 본질적으로 NLP 분류 문제입니다. NLP의 다양한 문제에 적용된 몇 가지 NLP 분류 알고리즘이 있습니다. 예를 들어 naive Bayes는 다양한 스팸 탐지 알고리즘에 사용되어 왔으며 SVM(Support Vector Machine)은 의료 기관에서 진행 노트와 같은 텍스트를 분류하는 데 사용되었습니다. 딥 러닝 모델의 기준선 역할을 하기 위해 이러한 알고리즘의 간단한 버전을 구현하는 것은 흥미로울 것입니다.
나이브 베이즈
NLP용 naive Bayes의 널리 사용되는 구현에는 TF-IDF를 사용하여 텍스트를 전처리한 다음 전처리된 출력에서 다항 naive Bayes를 실행하는 것이 포함됩니다. 이를 통해 문서 내에서 가장 눈에 띄는 단어에 대해 알고리즘을 실행할 수 있습니다. 다음과 같이 나이브 베이즈를 구현할 수 있습니다.
import numpy as np from sklearn.naive_bayes import MultinomialNB from sklearn.feature_extraction.text import CountVectorizer import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from sklearn.feature_extraction.text import TfidfTransformer df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() varietal_list = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = np.array(varietal_list) count_vect = CountVectorizer() x_train_counts = count_vect.fit_transform(description_list) tfidf_transformer = TfidfTransformer() x_train_tfidf = tfidf_transformer.fit_transform(x_train_counts) train_x, test_x, train_y, test_y = train_test_split(x_train_tfidf, varietal_list, test_size=0.3) clf = MultinomialNB().fit(train_x, train_y) y_score = clf.predict(test_x) n_right = 0 for i in range(len(y_score)): if y_score[i] == test_y[i]: n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
위의 코드를 실행하면 다음과 같은 내용이 표시됩니다. 73.56%
10개의 클래스를 보고 있다는 점을 고려하면 상당히 좋은 결과입니다.
우리는 또한 서포트 벡터 머신을 사용할 수 있고 그것이 어떻게 작동하는지 볼 수 있습니다. 그것이 어떻게 수행되는지 보려면 분류기 정의를 다음으로 바꾸십시오.
clf = SVC(kernel='linear').fit(train_x, train_y)
이것을 실행하면 다음 출력이 표시되어야 합니다.

정확도: 80.66%
너무 초라하지도 않습니다.
이러한 결과를 능가하거나 최소한 일치시킬 수 있는 딥 러닝 모델을 구축할 수 있는지 봅시다. 우리가 그것을 관리한다면, 우리의 딥 러닝 모델이 적어도 도메인 전문 지식에 의해 알려진 인기 있는 머신 러닝 모델의 결과를 복제하는 데 효과적이라는 큰 표시가 될 것입니다.
모델 구축
오늘 우리는 Tensorflow와 함께 Keras를 사용하여 모델을 구축할 것입니다. Keras는 Tensorflow API의 상대적으로 낮은 수준의 인터페이스에 비해 딥 러닝 모델을 매우 쉽게 구축할 수 있게 해주는 Python 라이브러리입니다. 조밀한 레이어 외에도 임베딩 및 컨볼루션 레이어를 사용하여 데이터 내의 단어 및 잠재적인 구조적 패턴의 기본 의미 정보를 학습합니다.
데이터 정리
먼저 신경망에서 쉽게 처리하고 이해할 수 있는 방식으로 데이터를 재구성해야 합니다. 단어를 고유하게 식별되는 숫자로 교체하여 이를 수행할 수 있습니다. 임베딩 벡터와 결합하여 유연하고 의미론적으로 민감한 방식으로 단어를 표현할 수 있습니다.
실제로, 우리는 이 전처리에 대해 조금 더 똑똑해지고 싶을 것입니다. 일반적으로 사용되는 단어에 초점을 맞추고 가장 일반적으로 사용되는 단어(예: this, a)도 걸러내는 것이 좋습니다.
Defaultdict 및 NLTK를 사용하여 이 기능을 구현할 수 있습니다. 다음 코드를 별도의 Python 모듈에 작성합니다. 나는 그것을 lib/get_top_x_words.py
에 넣었다.
from nltk import word_tokenize from collections import defaultdict def count_top_x_words(corpus, top_x, skip_top_n): count = defaultdict(lambda: 0) for c in corpus: for w in word_tokenize(c): count[w] += 1 count_tuples = sorted([(w, c) for w, c in count.items()], key=lambda x: x[1], reverse=True) return [i[0] for i in count_tuples[skip_top_n: skip_top_n + top_x]] def replace_top_x_words_with_vectors(corpus, top_x): topx_dict = {top_x[i]: i for i in range(len(top_x))} return [ [topx_dict[w] for w in word_tokenize(s) if w in topx_dict] for s in corpus ], topx_dict def filter_to_top_x(corpus, n_top, skip_n_top=0): top_x = count_top_x_words(corpus, n_top, skip_n_top) return replace_top_x_words_with_vectors(corpus, top_x)
이제 모델을 만들 준비가 되었습니다. 우리는 임베딩 레이어, 컨볼루션 레이어, 밀집 레이어가 애플리케이션에 도움이 될 수 있는 모든 딥 러닝 기능을 활용하기를 원합니다. Keras를 사용하면 모델을 매우 간단하게 구축할 수 있습니다.
from keras.models import Sequential from keras.layers import Dense, Conv1D, Flatten from keras.layers.embeddings import Embedding from keras.preprocessing import sequence from keras.utils import to_categorical import pandas as pd from collections import Counter from sklearn.model_selection import train_test_split from lib.get_top_xwords import filter_to_top_x df = pd.read_csv('data/wine_data.csv') counter = Counter(df['variety'].tolist()) top_10_varieties = {i[0]: idx for idx, i in enumerate(counter.most_common(10))} df = df[df['variety'].map(lambda x: x in top_10_varieties)] description_list = df['description'].tolist() mapped_list, word_list = filter_to_top_x(description_list, 2500, 10) varietal_list_o = [top_10_varieties[i] for i in df['variety'].tolist()] varietal_list = to_categorical(varietal_list_o) max_review_length = 150 mapped_list = sequence.pad_sequences(mapped_list, maxlen=max_review_length) train_x, test_x, train_y, test_y = train_test_split(mapped_list, varietal_list, test_size=0.3) max_review_length = 150 embedding_vector_length = 64 model = Sequential() model.add(Embedding(2500, embedding_vector_length, input_length=max_review_length)) model.add(Conv1D(50, 5)) model.add(Flatten()) model.add(Dense(100, activation='relu')) model.add(Dense(max(varietal_list_o) + 1, activation='softmax')) model.compile(loss='categorical_crossentropy', optimizer='adam', metrics=['accuracy']) model.fit(train_x, train_y, epochs=3, batch_size=64) y_score = model.predict(test_x) y_score = [[1 if i == max(sc) else 0 for i in sc] for sc in y_score] n_right = 0 for i in range(len(y_score)): if all(y_score[i][j] == test_y[i][j] for j in range(len(y_score[i]))): n_right += 1 print("Accuracy: %.2f%%" % ((n_right/float(len(test_y)) * 100)))
코드를 실행하면 다음 출력이 표시되어야 합니다.
정확도: 77.20%
나이브 베이즈와 SVC의 정확도는 각각 73.56%와 80.66%였습니다. 따라서 우리의 신경망은 더 일반적인 텍스트 분류 방법 중 일부에 대해 자체적으로 매우 중요합니다.
결론
오늘은 와인 리뷰를 분석하기 위한 분류 딥 러닝 모델 구축에 대해 알아보았습니다.
우리는 다른 기계 학습 알고리즘 중 일부와 경쟁하고 능가할 수 있는 모델을 구축할 수 있음을 발견했습니다. 이 정보를 사용하여 더 복잡한 데이터 세트를 분석하고 더 복잡한 출력을 생성하는 애플리케이션을 구축할 수 있기를 바랍니다!
참고: 이 기사에 사용한 코드는 GitHub에서 찾을 수 있습니다.
Toptal 엔지니어링 블로그에 대한 추가 정보:
- 더 깊은 의미: Python의 주제 모델링
- 이메일 감정 분석 봇을 구축하는 방법: NLP 자습서