如何在 Scikit-learn 的管道中创建我们的自定义特征提取器函数并将其与 countvectorizer 一起使用
Posted
技术标签:
【中文标题】如何在 Scikit-learn 的管道中创建我们的自定义特征提取器函数并将其与 countvectorizer 一起使用【英文标题】:How to create our custom feature extractor function and use it with countvectorizer in pipeline in Scikit-learn 【发布时间】:2016-11-08 19:34:19 【问题描述】:我正在尝试使用 Scikit-learn 创建一个简单的问题分类器。目前,我能够使用 Scikit 的 countvectorizer 函数使用词袋方法将问题分类为相应的类。现在,我想使用 countvectorizer 生成的现有功能创建和添加自定义功能。
假设我想创建一个检查电话号码是否存在问题的功能以及另一个提取问题长度的功能。
那么生成所有特征并将其合并在一起的方法是什么。
从这个link 我尝试使用这个模板进行自定义特征提取
`从sklearn.base导入BaseEstimator,TransformerMixin
类 SampleExtractor(BaseEstimator, TransformerMixin):
def __init__(self, vars):
self.vars = vars # e.g. pass in a column name to extract
def transform(self, X, y=None):
return do_something_to(X, self.vars) # where the actual feature extraction happens
def fit(self, X, y=None):
return self # generally does nothing`
但是当我将它的输出放入带有类似计数向量器的管道时
ppl = Pipeline([
('feats', FeatureUnion([
('ngram', CountVectorizer()), # can pass in either a pipeline
('ave', SampleExtractor()) # or a transformer
])),
('clf', LinearSVC()) # classifier
])
我得到错误
ValueError: blocks[0,:] 的行尺寸不兼容
我认为这个错误可能是由于两个特征的矩阵维度不同,但我不明白如何解决它。
【问题讨论】:
您的SampleExtractor()
转换方法会减少行数吗?如果是这样,则将其放入管道中是不可接受的转换,因为只有 X 被转换,而不是 y(并且 X 和 y 必须具有相同的行数)。
Dhiraj,你能做到吗?
【参考方案1】:
CountVectorizer
的方法transform
返回一个文档-词条矩阵,其行对应文档,列对应词条。矩阵的第 (i,j) 个元素显示第 j 个术语在第 i 个文档中出现的次数。您所要做的就是在此矩阵中添加更多列,这些列对应于新功能。
示例: 假设列表 doc_len
包含您的文档长度(以单词为单位),并且您的文档术语矩阵为 M
。然后代码:
M_arr = M.toarray()
assert len(doc_len) == M_arr.shape[0]
np.append(M_arr,np.array(doc_len),axis=1)
将在矩阵末尾添加一个包含新特征的新列。您可以重复此过程以获得其他新功能。扩展矩阵可以按通常的方式馈送到您正在使用的任何分类器。
【讨论】:
感谢您的回答,但我仍然无法合并这两个功能。以上是关于如何在 Scikit-learn 的管道中创建我们的自定义特征提取器函数并将其与 countvectorizer 一起使用的主要内容,如果未能解决你的问题,请参考以下文章