BERTopic 当尝试保存合并模型时,c_tf_idf_.indptr为None,

e3bfsja2  于 2个月前  发布在  其他
关注(0)|答案(6)|浏览(30)

在使用BERTopic.merge_models后,我无法保存生成的模型。以下是一些重现代码:

import bertopic
from bertopic import BERTopic
from sklearn.datasets import fetch_20newsgroups
from sklearn.decomposition import PCA

print(f'Using bertopic version {bertopic.__version__}')

embedding_model = 'all-mpnet-base-v2'

def new_topic_model():
    return BERTopic(
        embedding_model=embedding_model,
        # Using PCA because UMAP segfaults on my machine
        umap_model=PCA(n_components=10, random_state=40),
    )

docs = fetch_20newsgroups(subset='all',  remove=('headers', 'footers', 'quotes'))['data']
docs_a = docs[:400]
docs_b = docs[400:500]

topic_model_a = new_topic_model()
topic_model_a.fit(docs_a)
# No problem saving topic_model_a
topic_model_a.save(
    './topic_model_a',
    serialization='safetensors',
    save_embedding_model=embedding_model,
    save_ctfidf=True,
)

topic_model_b = new_topic_model()
topic_model_b.fit(docs_b)
# No problem saving topic_model_b
topic_model_b.save(
    './topic_model_b',
    serialization='safetensors',
    save_embedding_model=embedding_model,
    save_ctfidf=True,
)

topic_model = BERTopic.merge_models([topic_model_a, topic_model_b])
# Problem here: AttributeError: 'NoneType' object has no attribute 'indptr'
topic_model.save(
    './topic_model',
    serialization='safetensors',
    save_embedding_model=embedding_model,
    save_ctfidf=True,
)

我得到以下输出:

% python3 repro.py
Using bertopic version 0.16.2
Traceback (most recent call last):
  File "[...]/BERTopic/repro.py", line 43, in <module>
    topic_model.save(
  File "[...]/BERTopic/bertopic/_bertopic.py", line 3112, in save
    save_utils.save_ctfidf(model=self, save_directory=save_directory, serialization=serialization)
  File "[...]/BERTopic/bertopic/_save_utils.py", line 318, in save_ctfidf
    indptr = torch.from_numpy(model.c_tf_idf_.indptr)
                              ^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute 'indptr'
6ie5vjzr

6ie5vjzr1#

我注意到,只有在使用save_ctfidf=True运行时,这个问题才会出现。当使用save_ctfidf=False时,这段代码可以正常执行。是否支持为合并后的模型保存ctfidf状态?

zengzsys

zengzsys2#

我认为这是因为.merge_models目前不支持c-TF-IDF,因为这两个模型具有不同的词汇表和表示,合并起来可能会很棘手。所以遗憾的是,目前还不支持这个功能。

6za6bjd0

6za6bjd03#

在这种情况下,问题是:当 save_ctfidf=True 和没有 c-tf-idf 状态时,我们如何处理保存模型?
我建议这里的修复方法有两种:

  1. 静默忽略缺失的 c-tf-idf 数据并保存模型的其他部分。
  2. 抛出一个带有更好错误信息的异常,例如:“无法保存缺少 c-TF-IDF 数据的模型,可能是因为模型被合并了。请使用 save_ctfidf=False 重新尝试。”
    @MaartenGr 你更倾向于选择(1)还是(2)?
wz1wpwve

wz1wpwve4#

@ddicato,我实际上建议第三个解决方案。不要抛出异常,而是记录一个警告,提到由于使用了.merge_models(或其他与.merge_models无关的内容),无法保存c-TF-IDF表示。然后仍然保存模型的其余部分。这样,用户不必更改需要更少步骤的时间参数,同时仍然了解发生了什么。

作为旁注,我已经考虑过尝试合并两个模型的c-TF-IDF表示,因为它们通常具有相同的底层c-TF-IDF参数。很少有用户为合并后的模型使用不同的CountVectorizer。然而,这通常需要访问未保存的词袋表示(而不是已保存的c-TF-IDF表示)。嗯,值得思考一下......

8yoxcaq7

8yoxcaq75#

我更喜欢你的第三个解决方案。用户会得到一个更有用的错误信息,同时干扰最小。

这是一个有趣的附注。这个问题是否是继续讨论的好地方?

mbjcgjjk

mbjcgjjk6#

我更喜欢你的第三个解决方案。用户可以得到一个更有用的错误信息,同时干扰最小。
很高兴听到这个!我会把它放到待办事项列表中去处理,但如果你或其他人想继续做这件事的话,那将是非常感谢的。
这是一个有趣的附注。这个问题是否是继续讨论的好地方? #1878
对,这可能是一个确实适合继续讨论的好地方。

相关问题