在scikit TFIdfVectorizer中更新特征名称
我正在尝试这段代码
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
train_data = ["football is the sport","gravity is the movie", "education is imporatant"]
vectorizer = TfidfVectorizer(sublinear_tf=True, max_df=0.5,
stop_words='english')
print "Applying first train data"
X_train = vectorizer.fit_transform(train_data)
print vectorizer.get_feature_names()
print "\n\nApplying second train data"
train_data = ["cricket", "Transformers is a film","AIMS is a college"]
X_train = vectorizer.transform(train_data)
print vectorizer.get_feature_names()
print "\n\nApplying fit transform onto second train data"
X_train = vectorizer.fit_transform(train_data)
print vectorizer.get_feature_names()
这个代码的输出是
Applying first train data
[u'education', u'football', u'gravity', u'imporatant', u'movie', u'sport']
Applying second train data
[u'education', u'football', u'gravity', u'imporatant', u'movie', u'sport']
Applying fit transform onto second train data
[u'aims', u'college', u'cricket', u'film', u'transformers']
我第一次用 fit_transform
方法给向量化器提供了一组数据,所以它给我生成了一些特征名称,比如 [u'education', u'football', u'gravity', u'imporatant', u'movie', u'sport']
。之后我又用另一组训练数据去处理同一个向量化器,但它给我的特征名称还是一样的,因为我没有使用 fit
或 fit_transform
。我想知道怎么在不覆盖之前特征的情况下更新向量化器的特征。如果我再用 fit_transform
,之前的特征就会被覆盖掉。所以我想更新向量化器的特征列表。我希望得到类似 [u'education', u'football', u'gravity', u'imporatant', u'movie', u'sport',u'aims', u'college', u'cricket', u'film', u'transformers']
这样的结果。我该怎么做呢?
2 个回答
我在网上搜索和这个问题相关的内容时,发现了这个问题。正如mbatchkarov所说,Scikit-Learn的TfidfVectorizer本身不支持部分拟合。
HashingVectorizer通常是一个很好的替代方案,但这要看你的具体需求。特别是,如果你非常在意如何准确表示那些不常见的词汇,那么碰撞(指不同词汇被映射到同一个位置)会影响性能。
所以我自己实现了TfidfVectorizer和CountVectorizer的“部分拟合”功能(可以在这里找到)。希望这对其他看到这个帖子的人有帮助。需要注意的是,这种部分拟合确实会改变向量化器输出向量的维度,因为其主要目的是更新词汇表(所以在使用时要考虑这一点)。
在sklearn的术语中,这种情况叫做“部分拟合”,但是你不能用TfidfVectorizer
来做到这一点。解决这个问题有两种方法:
- 把两个训练集合并在一起,然后重新进行向量化。
- 使用
HashingVectorizer
,它支持部分拟合。不过,由于它是通过哈希来处理特征的,所以没有get_feature_names
这个方法,原始特征不会被保留。另一个优点是,这种方法在内存使用上更高效。
第一种方法的示例:
from sklearn.feature_extraction.text import TfidfVectorizer
import numpy as np
train_data1 = ["football is the sport", "gravity is the movie", "education is important"]
vectorizer = TfidfVectorizer(stop_words='english')
print("Applying first train data")
X_train = vectorizer.fit_transform(train_data1)
print(vectorizer.get_feature_names())
print("\n\nApplying second train data")
train_data2 = ["cricket", "Transformers is a film", "AIMS is a college"]
X_train = vectorizer.transform(train_data2)
print(vectorizer.get_feature_names())
print("\n\nApplying fit transform onto second train data")
X_train = vectorizer.fit_transform(train_data1 + train_data2)
print(vectorizer.get_feature_names())
输出:
Applying first train data
['education', 'football', 'gravity', 'important', 'movie', 'sport']
Applying second train data
['education', 'football', 'gravity', 'important', 'movie', 'sport']
Applying fit transform onto second train data
['aims', 'college', 'cricket', 'education', 'film', 'football', 'gravity', 'important', 'movie', 'sport', 'transformers']