我正在寻找一种方法来加载之前使用scikit-learn的TfidfVectorizer生成的向量。总的来说,我希望更好地理解TfidfVectorizer的数据持久性。
例如,到目前为止我所做的如下:
vectorizer = TfidfVectorizer(stop_words=stop)vect_train = vectorizer.fit_transform(corpus)
然后我编写了两个函数,以便能够保存和加载我的向量化器:
def save_model(model,name): ''' 用于保存训练模型的函数 ''' joblib.dump(model, '{}.pkl'.format(name)) def load_model(name): ''' 用于加载已保存模型的函数 ''' return joblib.load('{}.pkl'.format(name))
我查看了类似下面的帖子,但仍然没有弄明白多少。
如何在scikit-learn中存储TfidfVectorizer以供将来使用?
我最终希望能够进行一次训练会话,然后加载这组生成的向量,基于这些向量转换一些新的文本输入,并使用旧向量和基于它们生成的新向量执行余弦相似度计算。
我希望这样做的原因之一是,在这样的大数据集上进行向量化大约需要10分钟,我希望只做一次,而不是每次有新查询时都进行。
我想我应该保存的是vect_train,对吗?但首先保存它,然后将其加载到新创建的TfidfVectorizer实例中的正确方法是什么呢?
我第一次尝试按照scikit-learn中友好的人建议的那样使用joblib保存vect_train时,我得到了4个文件:tfidf.pkl, tfidf.pkl_01.npy, tfidf.pkl_02.npy, tfidf.pkl_03.npy。如果我能知道这些文件到底是什么,以及如何将它们加载到在不同脚本中创建的新实例中,那将是非常好的
vectorizer = TfidfVectorizer(stop_words=stop)
提前感谢您。
回答:
您的vect_train = vectorizer.fit_transform(corpus)
的结果是双重的:(i) 向量化器拟合您的数据,即它学习了语料库的词汇和每个术语的idf,(ii) vect_train
被实例化为您的语料库的向量。
您提出的save_model
和load_model
函数持久化和加载向量化器,即它学到的内部参数,例如词汇和idfs。加载了向量化器后,您只需要转换一个包含数据的列表就可以获得向量。它可以是未见过的数据,或者是您在fit_transform
期间使用的原始数据。因此,您所需要的只是:
vectorizer = load_model(name)vect_train = vectorizer.transform(corpus) # (1) 或任何未见过的数据
此时,您拥有保存前的所有内容,但转换调用(1)将根据您的语料库花费一些时间。如果您想跳过这个步骤,您需要同样保存vect_train
的内容,正如您在问题中正确地疑问。这是一个稀疏矩阵,可以使用scipy保存/加载,您可以在例如这个问题中找到信息。从那个问题中复制,实际上保存csr矩阵您还需要:
def save_sparse_csr(filename,array): np.savez(filename,data = array.data ,indices=array.indices, indptr =array.indptr, shape=array.shape )def load_sparse_csr(filename): loader = np.load(filename) return csr_matrix(( loader['data'], loader['indices'], loader['indptr']), shape = loader['shape'])
总结,上述函数可用于保存/加载您的vec_train
,而您提供的函数用于保存/加载转换器,以便向量化新数据。