BERTopic `topic_model.transform(docs)[0][i]` 有时与 `topic_model.transform(docs[i])[0][0]` 不同,

smtd7mpg  于 23天前  发布在  其他
关注(0)|答案(4)|浏览(24)

你好

我阅读了https://maartengr.github.io/BERTopic/api/bertopic.html#bertopic._bertopic.BERTopic.transform,并从文档中的参数(描述为“单个文档或要预测的文档列表”)了解到,即使使用拟合模型进行预测,我也可以将文档列表或单个文档提交,仍然可以获得相同的结果。

我发现这并不是真的。我是不是忽略了什么?

以下是一个最小工作示例:

from bertopic import BERTopic
from sklearn.datasets import fetch_20newsgroups

docs = fetch_20newsgroups(subset='all')['data'][:200]
topic_model = BERTopic().fit(docs)
topics,_=topic_model.transform(docs)

import numpy as np
topics=np.array(topics)

#calling the model with a single document several times
import tqdm

topics_single = []
for doc in tqdm.tqdm(docs):
    topic, _ = topic_model.transform([doc])
    topics_single.append(topic[0])
topics_single = np.array(topics_single)

mask_identical = topics_single == topics
percentage_equal = 100 * np.sum(mask_identical) / len(mask_identical)
print(f"{percentage_equal=}%") #returns for example about 60%, but varying

#loop till finding a different entry
for i in range(len(docs)):
    print(
        i,
        topic_model.transform(docs[i])[0][0],
        topic_model.transform([docs[i]])[0][0],
        topics[i],
        topic_model.transform(docs)[0][i],
    )
    if topic_model.transform(docs[i])[0][0] != topic_model.transform(docs)[0][i]:
        print(f"Different outcome at iteration {i}")
        break

重复执行相同文档似乎没问题:

topics2,_=topic_model.transform(docs)
percentage_equal_executed_with_multiple_docs = 100*np.sum(np.array(topics2)==topics)/len(topics)
print(f"{percentage_equal_executed_with_multiple_docs=}%") #this gives 100%

提前感谢!
PS:
Python版本是3.10.12
已安装的包列表如下:

pbwdgjma

pbwdgjma1#

使用BERTopic时,总是取决于您选择的底层模型。有些工作方式与其他的不同,因此不可能在所有算法中获得相同的行为。因此,在创建主题模型时,将BERTopic视为由各个组件构建的东西是很重要的。
在这里,您提到的推断通常是由HDBSCAN产生的结果,它使用与训练过程中不同的过程对文档进行聚类分配的近似计算。此外,它不是孤立地进行的。这意味着如果您在.transform步骤中添加了文档,HDBSCAN将使用这些文档执行分配。如果您只给出一个文档,行为将会改变。
为了进一步说明这一点,如果您使用k-Means,情况就不会是这样,因为它的推断过程不依赖于所有其他文档。
一个小提示,我相信有很多关于这个问题的开放和封闭的问题讨论,所以我建议通过它们查找更多详细信息。

zaq34kh6

zaq34kh62#

感谢您的澄清!为了防止将来出现问题,是否值得在文档中添加一条备注?

iyzzxitl

iyzzxitl3#

当然!我相信更新.transform的文档字符串是适当的。虽然它不能阻止所有未来的疑问(因为不是每个人都阅读文档字符串),但我认为那将是一个很好的第一步。如果你愿意,我很感激你能提交一个PR。

dfddblmv

dfddblmv4#

使用BERTopic时,总是取决于您选择的底层模型。有些工作方式与其他的不同,因此不可能在所有算法中获得相同的行为。因此,在创建主题模型时,将BERTopic视为由各个组件构建的东西是很重要的。
在这里,您提到的推理通常是由HDBSCAN产生的结果,它使用与训练过程中不同的过程对文档进行聚类分配的近似值。此外,它不是孤立地进行的。这意味着如果您在.transform步骤中添加了文档,HDBSCAN将使用这些文档执行分配。如果您只给出一个文档,行为将会改变。
为了进一步说明这一点,如果您使用k-Means,情况就不会是这样,因为它的推理过程不依赖于所有其他文档。
一个小提示,我相信有很多关于这个问题的开放和封闭的问题讨论,所以我建议通过它们寻找更多细节。
嗨,我不确定为什么这种(单个文档与多个文档产生不同的预测)是预期的行为;根据hdbscan文档中的“approximate_predict()”( https://hdbscan.readthedocs.io/en/latest/prediction_tutorial.html ),这是BERTopic中topic_model.transform -> hdbscan_delegator在后台使用的hdbscan_delegator的方法,我看不到任何描述这种行为的描述。
它应该冻结整个压缩树;我看不到为什么其他文档的存在会影响特定文档的分类结果。有人能向我解释一下吗?(这很重要,因为这意味着新点'依赖'于我在转换阶段构造的批次(文档),这使得整个分类结果不稳定且不可靠。)

相关问题