Gensim - Tạo mô hình chủ đề LDA
Chương này sẽ giúp bạn tìm hiểu cách tạo mô hình chủ đề Latent Dirichlet phân bổ (LDA) trong Gensim.
Tự động trích xuất thông tin về các chủ đề từ khối lượng lớn văn bản trong một trong những ứng dụng chính của NLP (xử lý ngôn ngữ tự nhiên). Khối lượng lớn văn bản có thể là nguồn cấp dữ liệu từ đánh giá khách sạn, tweet, bài đăng trên Facebook, nguồn cấp dữ liệu từ bất kỳ kênh truyền thông xã hội nào khác, đánh giá phim, câu chuyện tin tức, phản hồi của người dùng, e-mail, v.v.
Trong kỷ nguyên kỹ thuật số này, để biết mọi người / khách hàng đang nói về điều gì, hiểu ý kiến và vấn đề của họ, có thể rất có giá trị đối với các doanh nghiệp, chiến dịch chính trị và quản trị viên. Tuy nhiên, liệu có thể đọc thủ công một lượng lớn văn bản như vậy và sau đó trích xuất thông tin từ các chủ đề?
Không, không phải. Nó yêu cầu một thuật toán tự động có thể đọc qua khối lượng lớn tài liệu văn bản này và tự động trích xuất thông tin / chủ đề cần thiết được thảo luận từ nó.
Vai trò của LDA
Cách tiếp cận của LDA đối với mô hình chủ đề là phân loại văn bản trong tài liệu theo một chủ đề cụ thể. Được mô hình hóa như các bản phân phối Dirichlet, các bản dựng LDA -
- Một chủ đề cho mỗi mô hình tài liệu và
- Từ cho mỗi mô hình chủ đề
Sau khi cung cấp thuật toán mô hình chủ đề LDA, để có được thành phần phân phối từ khóa-chủ đề tốt, nó sẽ sắp xếp lại -
- Các chủ đề phân phối trong tài liệu và
- Phân phối từ khóa trong các chủ đề
Trong khi xử lý, một số giả định do LDA đưa ra là:
- Mỗi tài liệu được mô hình hóa dưới dạng các bản phân phối nhiều danh nghĩa của các chủ đề.
- Mọi chủ đề đều được mô hình hóa dưới dạng phân phối nhiều danh nghĩa của các từ.
- Chúng ta nên chọn kho dữ liệu phù hợp vì LDA giả định rằng mỗi đoạn văn bản chứa các từ liên quan.
- LDA cũng giả định rằng các tài liệu được tạo ra từ một hỗn hợp các chủ đề.
Thực hiện với Gensim
Ở đây, chúng ta sẽ sử dụng LDA (Phân bổ Dirichlet tiềm ẩn) để trích xuất các chủ đề được thảo luận tự nhiên từ tập dữ liệu.
Đang tải tập dữ liệu
Tập dữ liệu mà chúng tôi sẽ sử dụng là tập dữ liệu của ’20 Newsgroups’có hàng nghìn tin bài từ các phần khác nhau của một bản tin. Nó có sẵn dướiSklearncác tập dữ liệu. Chúng tôi có thể dễ dàng tải xuống với sự trợ giúp của tập lệnh Python sau:
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
Hãy xem một số tin tức mẫu với sự trợ giúp của tập lệnh sau:
newsgroups_train.data[:4]
["From: [email protected] (where's my thing)\nSubject:
WHAT car is this!?\nNntp-Posting-Host: rac3.wam.umd.edu\nOrganization:
University of Maryland, College Park\nLines:
15\n\n I was wondering if anyone out there could enlighten me on this car
I saw\nthe other day. It was a 2-door sports car, looked to be from the
late 60s/\nearly 70s. It was called a Bricklin. The doors were really small.
In addition,\nthe front bumper was separate from the rest of the body.
This is \nall I know. If anyone can tellme a model name,
engine specs, years\nof production, where this car is made, history, or
whatever info you\nhave on this funky looking car, please e-mail.\n\nThanks,
\n- IL\n ---- brought to you by your neighborhood Lerxst ----\n\n\n\n\n",
"From: [email protected] (Guy Kuo)\nSubject: SI Clock Poll - Final
Call\nSummary: Final call for SI clock reports\nKeywords:
SI,acceleration,clock,upgrade\nArticle-I.D.: shelley.1qvfo9INNc3s\nOrganization:
University of Washington\nLines: 11\nNNTP-Posting-Host: carson.u.washington.edu\n\nA
fair number of brave souls who upgraded their SI clock oscillator have\nshared their
experiences for this poll. Please send a brief message detailing\nyour experiences with
the procedure. Top speed attained, CPU rated speed,\nadd on cards and adapters, heat
sinks, hour of usage per day, floppy disk\nfunctionality with 800 and 1.4 m floppies
are especially requested.\n\nI will be summarizing in the next two days, so please add
to the network\nknowledge base if you have done the clock upgrade and haven't answered
this\npoll. Thanks.\n\nGuy Kuo <;[email protected]>\n",
'From: [email protected] (Thomas E Willis)\nSubject:
PB questions...\nOrganization: Purdue University Engineering
Computer Network\nDistribution: usa\nLines: 36\n\nwell folks,
my mac plus finally gave up the ghost this weekend after\nstarting
life as a 512k way back in 1985. sooo, i\'m in the market for
a\nnew machine a bit sooner than i intended to be...\n\ni\'m looking
into picking up a powerbook 160 or maybe 180 and have a bunch\nof
questions that (hopefully) somebody can answer:\n\n* does anybody
know any dirt on when the next round of powerbook\nintroductions
are expected? i\'d heard the 185c was supposed to make an\nappearence
"this summer" but haven\'t heard anymore on it - and since i\ndon\'t
have access to macleak, i was wondering if anybody out there had\nmore
info...\n\n* has anybody heard rumors about price drops to the powerbook
line like the\nones the duo\'s just went through recently?\n\n* what\'s
the impression of the display on the 180? i could probably swing\na 180
if i got the 80Mb disk rather than the 120, but i don\'t really have\na
feel for how much "better" the display is (yea, it looks great in the\nstore,
but is that all "wow" or is it really that good?). could i solicit\nsome
opinions of people who use the 160 and 180 day-to-day on if its
worth\ntaking the disk size and money hit to get the active display?
(i realize\nthis is a real subjective question, but i\'ve only played around
with the\nmachines in a computer store breifly and figured the opinions
of somebody\nwho actually uses the machine daily might prove helpful).\n\n*
how well does hellcats perform? ;)\n\nthanks a bunch in advance for any info -
if you could email, i\'ll post a\nsummary (news reading time is at a premium
with finals just around the\ncorner... :
( )\n--\nTom Willis \\ [email protected] \\ Purdue Electrical
Engineering\n---------------------------------------------------------------------------\
n"Convictions are more dangerous enemies of truth than lies." - F. W.\nNietzsche\n',
'From: jgreen@amber (Joe Green)\nSubject: Re: Weitek P9000 ?\nOrganization:
Harris Computer Systems Division\nLines: 14\nDistribution: world\nNNTP-Posting-Host:
amber.ssd.csd.harris.com\nX-Newsreader: TIN [version 1.1 PL9]\n\nRobert
J.C. Kyanko ([email protected]) wrote:\n >[email protected] writes in article
<[email protected] >:\n> > Anyone know about the
Weitek P9000 graphics chip?\n > As far as the low-level stuff goes, it looks
pretty nice. It\'s got this\n> quadrilateral fill command that requires just
the four points.\n\nDo you have Weitek\'s address/phone number? I\'d like to get
some information\nabout this chip.\n\n--\nJoe Green\t\t\t\tHarris
Corporation\[email protected]\t\t\tComputer Systems Division\n"The only
thing that really scares me is a person with no sense of humor.
"\n\t\t\t\t\t\t-- Jonathan Winters\n']
Điều kiện tiên quyết
Chúng tôi cần từ dừng từ NLTK và mô hình tiếng Anh từ Scapy. Cả hai đều có thể được tải xuống như sau:
import nltk;
nltk.download('stopwords')
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])
Nhập các gói cần thiết
Để xây dựng mô hình LDA, chúng ta cần nhập gói cần thiết sau:
import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import pyLDAvis
import pyLDAvis.gensim
import matplotlib.pyplot as plt
Chuẩn bị từ dừng
Bây giờ, chúng ta cần nhập các Từ dừng và sử dụng chúng -
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])
Xóa văn bản
Bây giờ, với sự giúp đỡ của Gensim's simple_preprocess()chúng ta cần phân tách từng câu thành một danh sách các từ. Chúng ta cũng nên loại bỏ các dấu câu và các ký tự không cần thiết. Để làm điều này, chúng tôi sẽ tạo một hàm có tênsent_to_words() -
def sent_to_words(sentences):
for sentence in sentences:
yield(gensim.utils.simple_preprocess(str(sentence), deacc=True))
data_words = list(sent_to_words(data))
Xây dựng mô hình Bigram & Trigram
Như chúng ta đã biết, bigram là hai từ thường xuyên xuất hiện cùng nhau trong tài liệu và bát quái là ba từ thường xuyên xuất hiện cùng nhau trong tài liệu. Với sự giúp đỡ của Gensim'sPhrases mô hình, chúng tôi có thể làm điều này -
bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)
Lọc ra các từ dừng
Tiếp theo, chúng ta cần lọc ra các Từ dừng. Cùng với đó, chúng tôi cũng sẽ tạo ra các chức năng để tạo ra bigrams, bát quái và cho lemmatisation -
def remove_stopwords(texts):
return [[word for word in simple_preprocess(str(doc))
if word not in stop_words] for doc in texts]
def make_bigrams(texts):
return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
return [trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
texts_out = []
for sent in texts:
doc = nlp(" ".join(sent))
texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
return texts_out
Xây dựng Từ điển & Tập đoàn cho Mô hình Chủ đề
Bây giờ chúng ta cần xây dựng từ điển & kho ngữ liệu. Chúng tôi cũng đã làm điều đó trong các ví dụ trước -
id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]
Xây dựng mô hình chủ đề LDA
Chúng tôi đã triển khai mọi thứ cần thiết để đào tạo mô hình LDA. Bây giờ, đã đến lúc xây dựng mô hình chủ đề LDA. Đối với ví dụ triển khai của chúng tôi, nó có thể được thực hiện với sự trợ giúp của dòng mã sau:
lda_model = gensim.models.ldamodel.LdaModel(
corpus=corpus, id2word=id2word, num_topics=20, random_state=100,
update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True
)
Ví dụ triển khai
Hãy xem ví dụ triển khai hoàn chỉnh để xây dựng mô hình chủ đề LDA -
import re
import numpy as np
import pandas as pd
from pprint import pprint
import gensim
import gensim.corpora as corpora
from gensim.utils import simple_preprocess
from gensim.models import CoherenceModel
import spacy
import pyLDAvis
import pyLDAvis.gensim
import matplotlib.pyplot as plt
from nltk.corpus import stopwords
stop_words = stopwords.words('english')
stop_words.extend(['from', 'subject', 're', 'edu', 'use'])
from sklearn.datasets import fetch_20newsgroups
newsgroups_train = fetch_20newsgroups(subset='train')
data = newsgroups_train.data
data = [re.sub('\S*@\S*\s?', '', sent) for sent in data]
data = [re.sub('\s+', ' ', sent) for sent in data]
data = [re.sub("\'", "", sent) for sent in data]
print(data_words[:4]) #it will print the data after prepared for stopwords
bigram = gensim.models.Phrases(data_words, min_count=5, threshold=100)
trigram = gensim.models.Phrases(bigram[data_words], threshold=100)
bigram_mod = gensim.models.phrases.Phraser(bigram)
trigram_mod = gensim.models.phrases.Phraser(trigram)
def remove_stopwords(texts):
return [[word for word in simple_preprocess(str(doc))
if word not in stop_words] for doc in texts]
def make_bigrams(texts):
return [bigram_mod[doc] for doc in texts]
def make_trigrams(texts):
[trigram_mod[bigram_mod[doc]] for doc in texts]
def lemmatization(texts, allowed_postags=['NOUN', 'ADJ', 'VERB', 'ADV']):
texts_out = []
for sent in texts:
doc = nlp(" ".join(sent))
texts_out.append([token.lemma_ for token in doc if token.pos_ in allowed_postags])
return texts_out
data_words_nostops = remove_stopwords(data_words)
data_words_bigrams = make_bigrams(data_words_nostops)
nlp = spacy.load('en_core_web_md', disable=['parser', 'ner'])
data_lemmatized = lemmatization(data_words_bigrams, allowed_postags=[
'NOUN', 'ADJ', 'VERB', 'ADV'
])
print(data_lemmatized[:4]) #it will print the lemmatized data.
id2word = corpora.Dictionary(data_lemmatized)
texts = data_lemmatized
corpus = [id2word.doc2bow(text) for text in texts]
print(corpus[:4]) #it will print the corpus we created above.
[[(id2word[id], freq) for id, freq in cp] for cp in corpus[:4]]
#it will print the words with their frequencies.
lda_model = gensim.models.ldamodel.LdaModel(
corpus=corpus, id2word=id2word, num_topics=20, random_state=100,
update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True
)
Bây giờ chúng ta có thể sử dụng mô hình LDA đã tạo ở trên để lấy các chủ đề, để tính toán Độ phức tạp của mô hình.