Qiita 「비엔지니어」기사를 토픽 분류(scikit-learn의 LDA가 무겁게 lda로 비교편)
이곳은 마지막 기사의 연속입니다.
아래 준비까지는 이쪽을 봐 주세요.
Qiita 「비엔지니어」기사를 토픽 분류(스크래핑·단어 분해·정규화편)
기사 개요
전회는, 169 페이지분, 1682개의 「비엔지니어」기사를 취해 왔고, 타이틀・본문・그 외의 데이터 프레임을 만들었습니다.
또한 단어로 분해하여 숫자 등 불필요한 것을 깨끗하게했습니다.
이 기사에서는 기사 본문 데이터를 사용하여 LDA에서 몇 가지 주제로 나누려고합니다.
먼저 쓰면 처음 scikit-learn의 LDA를 사용했는데, 100기사 이상이 무겁고 움직이지 않고 이쪽의 lda를 사용했습니다.
htps : // py 피. rg/p로지ぇct/l이다/
우선 scikit-learn의 LDA를 움직여 보자.
우선은 도중에 움직이지 않게 된 scikit-learn으로부터.
#必要なライブラリをimport
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import joblib
#文章×単語行列に変換
vectorizer = CountVectorizer(token_pattern=r"(?u)\b\w+\b")
#訓練データ用にBow表現に。
X = vectorizer.fit_transform(df["Content_normalization"])
↑여기서 df["Content_normalization"]라고 있습니다만, 내 PC라면 df는 100기사까지 밖에 움직이지 않았습니다! 그래서 여기의 df는 축소판입니다.
#単語番号と単語を紐づけ
index2word = {}
for word, word_id in tqdm(vectorizer.vocabulary_.items()):
index2word[word_id] = word
#3分類でインスタンス作成。モデルの作成
lda = LatentDirichletAllocation(n_components=3, n_jobs=-1, verbose=1)
X_transformed = lda.fit_transform(X)
#各トピックの特徴単語を抽出
for t in range(lda.n_components):
# トピック t における、単語の出現確率を lda.components_[t] で取得
# np.argsort で昇順に並び替えた順の index を取得、[::-1] で降順に並び替え
indices = np.argsort(lda.components_[t])[::-1]
print("Topic #{} ----------------------------------------".format(t+1))
for word_id in indices[:10]:
print(index2word[word_id])
print()
▼JupyterNotebook

흠. 라는 느낌이군요.
생각하기 위해, 아래의 순서로 퍼지 않는 원인과 대책이 있다고 생각합니다.
・「때문에」등의 쓸데없는 것이 많다. 스톱워드로 단어 데이터를 깨끗이
・데이터수가 100기사밖에 먹지 않기 때문에 적다
・카테고리수가 미묘. 바꾸어보자
· 원래 깨끗하게 나눌 리가 없다?
· 원래 뭔가 절차가 이상?
우선 이대로 타이틀 분류도 살펴보겠습니다.
for t in range(lda.n_components):
# トピック t を軸に切り出す
# np.argsort で昇順に並び替えた順の index を取得、[::-1] で降順に並び替え
indices = np.argsort(X_transformed[:,t])[::-1]
print("Topic #{} ----------------------------------------".format(t))
for document_id in indices[:10]:
print(df.iloc[document_id]["Title"])
print()
▼JupyterNotebook

어쨌든, 토픽 0 : 교육, 토픽 1 : 실용, 토픽 2 : 그 외, 라는 느낌으로 나뉘어 있다고 하면 그렇게 보이지 않아도 없는 것 같은, 어떨까・・・.
다음은 lda를 사용해 보겠습니다.
#ライブラリのimport
import lda
import lda.datasets
#インスタンスなど
X = lda.datasets.load_reuters()
vocab = lda.datasets.load_reuters_vocab()
titles = lda.datasets.load_reuters_titles()
#上のscikit-learnで作った単語行列から、欲しいモノを取ってくる。
vect = vectorizer.get_feature_names()
#3分類でモデルの生成
model = lda.LDA(n_topics=3, n_iter=1500, random_state=1, alpha = 10)
model.fit(X) # model.fit_transform(X) is also available
#単語抽出
for t in range(model.n_topics):
indices = np.argsort(model.topic_word_[t])[::-1]
print("Topic #{} ----------------------------------------".format(t+1))
for word_id in indices[:10]:
print(index2word[word_id])
print()

아,,, 알파벳 순서? 웃음
조금 정렬이 잘되어 있지 않습니다만, 타이틀 분류에 갑니다.
doc_topic = model.doc_topic_
for t in range(model.n_topics):
indices = np.argsort(doc_topic[:,t])[::-1]
print("Topic #{} ----------------------------------------".format(t))
for document_id in indices[:10]:
print(df.iloc[document_id]["Title"])
print()

이것은 꽤 좋은 느낌 ... 이군요! ? 웃음
주제 0은 사고방식이나 말로의 정리계, 토픽 1은 도전해 본 시스템의 기술기사, 토픽 2는 해설계(가르치는 느낌)의 기술기사, 로 나뉘어져 있는 것처럼, 나는 보입니다! ! 웃음
이 뉘앙스 느낌이 LDA 같은 ...?
개선책
이번에는 우선 출력을 내 보았습니다만, 전술한 바와 같이, 아래와 같은 방법으로도 조금 개선할 것 같습니다.
우선은 도중에 움직이지 않게 된 scikit-learn으로부터.
#必要なライブラリをimport
from sklearn.feature_extraction.text import CountVectorizer, TfidfVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import joblib
#文章×単語行列に変換
vectorizer = CountVectorizer(token_pattern=r"(?u)\b\w+\b")
#訓練データ用にBow表現に。
X = vectorizer.fit_transform(df["Content_normalization"])
↑여기서 df["Content_normalization"]라고 있습니다만, 내 PC라면 df는 100기사까지 밖에 움직이지 않았습니다! 그래서 여기의 df는 축소판입니다.
#単語番号と単語を紐づけ
index2word = {}
for word, word_id in tqdm(vectorizer.vocabulary_.items()):
index2word[word_id] = word
#3分類でインスタンス作成。モデルの作成
lda = LatentDirichletAllocation(n_components=3, n_jobs=-1, verbose=1)
X_transformed = lda.fit_transform(X)
#各トピックの特徴単語を抽出
for t in range(lda.n_components):
# トピック t における、単語の出現確率を lda.components_[t] で取得
# np.argsort で昇順に並び替えた順の index を取得、[::-1] で降順に並び替え
indices = np.argsort(lda.components_[t])[::-1]
print("Topic #{} ----------------------------------------".format(t+1))
for word_id in indices[:10]:
print(index2word[word_id])
print()
▼JupyterNotebook

흠. 라는 느낌이군요.
생각하기 위해, 아래의 순서로 퍼지 않는 원인과 대책이 있다고 생각합니다.
・「때문에」등의 쓸데없는 것이 많다. 스톱워드로 단어 데이터를 깨끗이
・데이터수가 100기사밖에 먹지 않기 때문에 적다
・카테고리수가 미묘. 바꾸어보자
· 원래 깨끗하게 나눌 리가 없다?
· 원래 뭔가 절차가 이상?
우선 이대로 타이틀 분류도 살펴보겠습니다.
for t in range(lda.n_components):
# トピック t を軸に切り出す
# np.argsort で昇順に並び替えた順の index を取得、[::-1] で降順に並び替え
indices = np.argsort(X_transformed[:,t])[::-1]
print("Topic #{} ----------------------------------------".format(t))
for document_id in indices[:10]:
print(df.iloc[document_id]["Title"])
print()
▼JupyterNotebook

어쨌든, 토픽 0 : 교육, 토픽 1 : 실용, 토픽 2 : 그 외, 라는 느낌으로 나뉘어 있다고 하면 그렇게 보이지 않아도 없는 것 같은, 어떨까・・・.
다음은 lda를 사용해 보겠습니다.
#ライブラリのimport
import lda
import lda.datasets
#インスタンスなど
X = lda.datasets.load_reuters()
vocab = lda.datasets.load_reuters_vocab()
titles = lda.datasets.load_reuters_titles()
#上のscikit-learnで作った単語行列から、欲しいモノを取ってくる。
vect = vectorizer.get_feature_names()
#3分類でモデルの生成
model = lda.LDA(n_topics=3, n_iter=1500, random_state=1, alpha = 10)
model.fit(X) # model.fit_transform(X) is also available
#単語抽出
for t in range(model.n_topics):
indices = np.argsort(model.topic_word_[t])[::-1]
print("Topic #{} ----------------------------------------".format(t+1))
for word_id in indices[:10]:
print(index2word[word_id])
print()

아,,, 알파벳 순서? 웃음
조금 정렬이 잘되어 있지 않습니다만, 타이틀 분류에 갑니다.
doc_topic = model.doc_topic_
for t in range(model.n_topics):
indices = np.argsort(doc_topic[:,t])[::-1]
print("Topic #{} ----------------------------------------".format(t))
for document_id in indices[:10]:
print(df.iloc[document_id]["Title"])
print()

이것은 꽤 좋은 느낌 ... 이군요! ? 웃음
주제 0은 사고방식이나 말로의 정리계, 토픽 1은 도전해 본 시스템의 기술기사, 토픽 2는 해설계(가르치는 느낌)의 기술기사, 로 나뉘어져 있는 것처럼, 나는 보입니다! ! 웃음
이 뉘앙스 느낌이 LDA 같은 ...?
개선책
이번에는 우선 출력을 내 보았습니다만, 전술한 바와 같이, 아래와 같은 방법으로도 조금 개선할 것 같습니다.
#ライブラリのimport
import lda
import lda.datasets
#インスタンスなど
X = lda.datasets.load_reuters()
vocab = lda.datasets.load_reuters_vocab()
titles = lda.datasets.load_reuters_titles()
#上のscikit-learnで作った単語行列から、欲しいモノを取ってくる。
vect = vectorizer.get_feature_names()
#3分類でモデルの生成
model = lda.LDA(n_topics=3, n_iter=1500, random_state=1, alpha = 10)
model.fit(X) # model.fit_transform(X) is also available
#単語抽出
for t in range(model.n_topics):
indices = np.argsort(model.topic_word_[t])[::-1]
print("Topic #{} ----------------------------------------".format(t+1))
for word_id in indices[:10]:
print(index2word[word_id])
print()
doc_topic = model.doc_topic_
for t in range(model.n_topics):
indices = np.argsort(doc_topic[:,t])[::-1]
print("Topic #{} ----------------------------------------".format(t))
for document_id in indices[:10]:
print(df.iloc[document_id]["Title"])
print()
이번에는 우선 출력을 내 보았습니다만, 전술한 바와 같이, 아래와 같은 방법으로도 조금 개선할 것 같습니다.
이 기사는 단순히 LDA를 사용하고 싶었다. 라고 하는 기분이 선행했습니다만, 「비엔지니어」기사와 다른 기사와 비교·클러스터링 등이라고 하면 조금 뭔가 보일 것 같습니다. 기사 자체는 상당히 있었으므로, 또 손이 비었을 때에, 단어 베이스로의 특징 추출이나, 시계열로 기사 천이나 좋아하는 수등을 쫓아 보자고 생각합니다.
※코드는 서포트 페이지나 책등으로부터 가져오고 있는 부분이 많아, 완전하게 이해할 수 없는 부분도 있습니다. 「더이면 좋다」 「여기 필요 없다」등 꼭 가르쳐 주세요!
Reference
이 문제에 관하여(Qiita 「비엔지니어」기사를 토픽 분류(scikit-learn의 LDA가 무겁게 lda로 비교편)), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/nakashimayugo/items/d42475c9ddd1d5697c1d텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념
(Collection and Share based on the CC Protocol.)