sklearn-LDA做主题分析
Published on Aug. 22, 2023, 12:10 p.m.
sklearn-LDA主题分析
LDA主题分析主要应用于文本分类和预测中,并可以做推荐依据进行针对推荐。
import numpy as np
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis
X = np.array([[-1, -1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]])
y = np.array([1, 1, 1, 2, 2, 2])
clf = LinearDiscriminantAnalysis()
clf.fit(X, y)
print(clf.predict([[-0.8, -1]]))
[1]
# -*- coding: utf-8 -*-
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
# corpus = [res1,res2,res3]
res1="""
n_components: 即我们的隐含主题数,需要调参。的大小取决于我们对主题划分的需求,比如我们只需要类似区分是动物,植物,还是非生物这样的粗粒度需求,那么值可以取的很小,个位数即可。如果我们的目标是类似区分不同的动物以及不同的植物,不同的非生物这样的细粒度需求,则值需要取的很大,比如上千上万。此时要求我们的训练文档数量要非常的多。
"""
res2="""
doc_topic_prior:即我们的文档主题先验Dirichlet分布的参数。一般如果我们没有主题分布的先验知识,可以使用默认值1/。
topic_word_prior:即我们的主题词先验Dirichlet分布的参数。一般如果我们没有主题分布的先验知识,可以使用默认值 1/.
"""
res3="""
learning_method: 即LDA的求解算法。有 ‘batch’ 和 ‘online’两种选择。 ‘batch’即我们在原理篇讲的变分推断EM算法,而"online"即在线变分推断EM算法,在"batch"的基础上引入了分步训练,将训练样本分批,逐步一批批的用样本更新主题词分布的算法。默认是"online"。选择了‘online’则我们可以在训练时使用partial_fit函数分布训练。不过在scikit-learn 0.20版本中默认算法会改回到"batch"。建议样本量不大只是用来学习的话用"batch"比较好,这样可以少很多参数要调。而样本太多太大的话,"online"则是首选了。
"""
res1=' '.join(res1)
res2=' '.join(res2)
res3=' '.join(res3)
res1
'\n \n n _ c o m p o n e n t s : 即 我 们 的 隐 含 主 题 数 , 需 要 调 参 。 的 大 小 取 决 于 我 们 对 主 题 划 分 的 需 求 , 比 如 我 们 只 需 要 类 似 区 分 是 动 物 , 植 物 , 还 是 非 生 物 这 样 的 粗 粒 度 需 求 , 那 么 值 可 以 取 的 很 小 , 个 位 数 即 可 。 如 果 我 们 的 目 标 是 类 似 区 分 不 同 的 动 物 以 及 不 同 的 植 物 , 不 同 的 非 生 物 这 样 的 细 粒 度 需 求 , 则 值 需 要 取 的 很 大 , 比 如 上 千 上 万 。 此 时 要 求 我 们 的 训 练 文 档 数 量 要 非 常 的 多 。 \n \n'
下面开始
特征选择 可以tfidfvectorizer,CountVectorizer,或者word2vec等。
当然也可以选择bert,不过,中文预训练多数都存在分词问题。
corpus = [res1,res2,res3]
cntVector = CountVectorizer()
cntTf = cntVector.fit_transform(corpus)
# print(type(cntTf))
lda = LatentDirichletAllocation(n_components=2,learning_offset=50.)
docres = lda.fit_transform(cntTf)
# print(docres)
print(lda.components_)
[[1.49848591 5.49843166 0.50126498 1.49848591 1.49848591 5.49843166
0.50126498 0.50129923 1.49848591 1.49848591 1.49848591 1.49848591
1.49848591 1.49848591 1.49848591 0.50126498 0.50126498 0.50126498
0.50126498 1.49848591 1.49848591 1.49848591 1.49848591 1.49848591
1.49848591 1.49848591 1.49848591 1.49848591]
[0.50151409 0.50156834 1.49873502 0.50151409 0.50151409 0.50156834
1.49873502 2.49870077 0.50151409 0.50151409 0.50151409 0.50151409
0.50151409 0.50151409 0.50151409 1.49873502 1.49873502 1.49873502
1.49873502 0.50151409 0.50151409 0.50151409 0.50151409 0.50151409
0.50151409 0.50151409 0.50151409 0.50151409]]
def print_top_words(model, feature_names, n_top_words):
#打印每个主题下权重较高的term
for topic_idx, topic in enumerate(model.components_):
print("Topic #%d:" % topic_idx)
print(" ".join([feature_names[i]
for i in topic.argsort()[:-n_top_words - 1:-1]]))
print
#打印主题-词语分布矩阵
print (model.components_)
n_top_words=20
tf_feature_names = cntVector.get_feature_names()
print_top_words(lda, tf_feature_names, n_top_words)
Topic #0:
batch online 默认是 即我们在原理篇讲的变分推断em算法 learn learning_method 不过在scikit 两种选择 则我们可以在训练时使用partial_fit函数分布训练 则是首选了 即lda的求解算法 逐步一批批的用样本更新主题词分布的算法 即在线变分推断em算法 将训练样本分批 建议样本量不大只是用来学习的话用 比较好 的基础上引入了分步训练 而样本太多太大的话 这样可以少很多参数要调 选择了
Topic #1:
一般如果我们没有主题分布的先验知识 doc_topic_prior topic_word_prior 可以使用默认值1 可以使用默认值 即我们的文档主题先验dirichlet分布的参数 即我们的主题词先验dirichlet分布的参数 batch online 默认是 则是首选了 learn learning_method 不过在scikit 两种选择 则我们可以在训练时使用partial_fit函数分布训练 即在线变分推断em算法 即lda的求解算法 逐步一批批的用样本更新主题词分布的算法 即我们在原理篇讲的变分推断em算法
[[1.49848591 5.49843166 0.50126498 1.49848591 1.49848591 5.49843166
0.50126498 0.50129923 1.49848591 1.49848591 1.49848591 1.49848591
1.49848591 1.49848591 1.49848591 0.50126498 0.50126498 0.50126498
0.50126498 1.49848591 1.49848591 1.49848591 1.49848591 1.49848591
1.49848591 1.49848591 1.49848591 1.49848591]
[0.50151409 0.50156834 1.49873502 0.50151409 0.50151409 0.50156834
1.49873502 2.49870077 0.50151409 0.50151409 0.50151409 0.50151409
0.50151409 0.50151409 0.50151409 1.49873502 1.49873502 1.49873502
1.49873502 0.50151409 0.50151409 0.50151409 0.50151409 0.50151409
0.50151409 0.50151409 0.50151409 0.50151409]]
/usr/local/lib/python3.7/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function get_feature_names is deprecated; get_feature_names is deprecated in 1.0 and will be removed in 1.2. Please use get_feature_names_out instead.
warnings.warn(msg, category=FutureWarning)
TF-IDF 构造词频矩阵
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
# 多个文档构成的列表
documnets = ['今天 天气 很好 啊','今天 天气 确实 很好']
tf_idf_vectorizer = TfidfVectorizer()
# 构造词频矩阵
tf_idf = tf_idf_vectorizer.fit_transform(documnets)
# 获取特征词
feature_names = tf_idf_vectorizer.get_feature_names()
# 词频矩阵
matrix = tf_idf.toarray()
df = pd.DataFrame(matrix,columns=feature_names)
df
/usr/local/lib/python3.7/dist-packages/sklearn/utils/deprecation.py:87: FutureWarning: Function get_feature_names is deprecated; get_feature_names is deprecated in 1.0 and will be removed in 1.2. Please use get_feature_names_out instead.
warnings.warn(msg, category=FutureWarning)
.dataframe tbody tr th:only-of-type {
vertical-align: middle;
}
.dataframe tbody tr th {
vertical-align: top;
}
.dataframe thead th {
text-align: right;
}
今天 | 天气 | 很好 | 确实 | |
---|---|---|---|---|
0 | 0.577350 | 0.577350 | 0.577350 | 0.000000 |
1 | 0.448321 | 0.448321 | 0.448321 | 0.630099 |
.colab-df-container {
display:flex;
flex-wrap:wrap;
gap: 12px;
}
.colab-df-convert {
background-color: #E8F0FE;
border: none;
border-radius: 50%;
cursor: pointer;
display: none;
fill: #1967D2;
height: 32px;
padding: 0 0 0 0;
width: 32px;
}
.colab-df-convert:hover {
background-color: #E2EBFA;
box-shadow: 0px 1px 2px rgba(60, 64, 67, 0.3), 0px 1px 3px 1px rgba(60, 64, 67, 0.15);
fill: #174EA6;
}
[theme=dark] .colab-df-convert {
background-color: #3B4455;
fill: #D2E3FC;
}
[theme=dark] .colab-df-convert:hover {
background-color: #434B5C;
box-shadow: 0px 1px 3px 1px rgba(0, 0, 0, 0.15);
filter: drop-shadow(0px 1px 2px rgba(0, 0, 0, 0.3));
fill: #FFFFFF;
}
const buttonEl =
document.querySelector(‘#df-06838677-5dfa-48e9-a490-fc3b735f7e79 button.colab-df-convert’);
buttonEl.style.display =
google.colab.kernel.accessAllowed ? ‘block’ : ‘none’;
async function convertToInteractive(key) {
const element = document.querySelector(‘#df-06838677-5dfa-48e9-a490-fc3b735f7e79’);
const dataTable =
await google.colab.kernel.invokeFunction(‘convertToInteractive’,
[key], {});
if (!dataTable) return;
const docLinkHtml = ‘Like what you see? Visit the ‘ +
‘<a target=”_blank” href=https://colab.research.google.com/notebooks/data_table.ipynb>data table notebook’
+ ‘ to learn more about interactive tables.’;
element.innerHTML = ‘’;
dataTable[‘output_type’] = ‘display_data’;
await google.colab.output.renderOutput(dataTable, element);
const docLink = document.createElement(‘div’);
docLink.innerHTML = docLinkHtml;
element.appendChild(docLink);
}
代码地址:
https://colab.research.google.com/drive/1hgp-XSzDKYdVUIpy31f_G6K42VzaZJKO#scrollTo=QC4gw1WojGY_