Python SKLearn Naive Bayes:在tfidf矢量化后添加功能

Python SKLearn Naive Bayes:在tfidf矢量化后添加功能,python,machine-learning,scikit-learn,tf-idf,naivebayes,Python,Machine Learning,Scikit Learn,Tf Idf,Naivebayes,所以我的任务是训练一名模特的电话记录。下面的代码就是这样做的。一点背景信息: -x是一个字符串列表,每个第i个元素都是一个完整的转录本 -y是布尔值的列表,表示调用的结果为正或负 下面的代码可以工作,但这是我的问题我想将呼叫持续时间作为培训的一项功能。我假设在TFIDF转换器对转录本进行矢量化之后,我会将呼叫持续时间功能连接到TFIDF输出,对吗?也许这比我想象的要容易,但是我有成绩单和持续时间,都在代码开头的pandas数据框中如果我有持续时间的数据帧列(numpy数组),我需要做什么才能将该

所以我的任务是训练一名模特的电话记录。下面的代码就是这样做的。一点背景信息: -x是一个字符串列表,每个第i个元素都是一个完整的转录本 -y是布尔值的列表,表示调用的结果为正或负

下面的代码可以工作,但这是我的问题我想将呼叫持续时间作为培训的一项功能。我假设在TFIDF转换器对转录本进行矢量化之后,我会将呼叫持续时间功能连接到TFIDF输出,对吗?也许这比我想象的要容易,但是我有成绩单和持续时间,都在代码开头的pandas数据框中如果我有持续时间的数据帧列(numpy数组),我需要做什么才能将该功能添加到我的模型中?

其他问题:

  • 我是否遗漏了一个关于朴素贝叶斯模型的基本假设,它将我限制在矢量化字符串上
  • 我应该在管道的哪一步添加新功能
  • 这甚至可以在管道中完成,还是我必须把它分开来做类似的事情
代码:


据我所知,sklearn管道是API驱动的——管道本身没有真正的魔力。因此,从这个角度来看,您应该能够围绕
TfidfVectorizer
创建自己的包装器,以实现您希望它做的事情。例如,假设您有一个如下所示的数据帧:

df = pd.DataFrame({'text': ['foo text', 'bar text'], 'duration': [1, 2]})
您可以按如下方式实现转换:

class MyVectorizer(object):
    def __init__(self, tfidf_kwargs=None):
        self._tfidf = TfidfVectorizer(**(tfidf_kwargs or None))

    def fit(self, X, y=None):
        self._tfidf.fit(X['text'], y)
        return self

    def fit_transform(self, X, y=None):
        self.fit(X)
        return self.transform(X, copy=False)

    def transform(self, X, copy=True):
        result = self._tfidf.transform(X['text'], copy=copy)
        # result is a sparse matrix.  I'm not sure of a clean way
        # to add a column to a sparse matrix.  If you have the
        # memory, you can use a dense matrix instead...
        return np.column_stack((result, X['duration']))

然后我认为您应该准备好使用它,而不是原来的tfidf矢量器。

FWIW,您可能想将CountVectorizer+TfidfTransformer压缩成一个简单的tfidf矢量器,但这只是一个次要的代码简化点。它根本不会改变算法。是的,谢谢你的观察!
class MyVectorizer(object):
    def __init__(self, tfidf_kwargs=None):
        self._tfidf = TfidfVectorizer(**(tfidf_kwargs or None))

    def fit(self, X, y=None):
        self._tfidf.fit(X['text'], y)
        return self

    def fit_transform(self, X, y=None):
        self.fit(X)
        return self.transform(X, copy=False)

    def transform(self, X, copy=True):
        result = self._tfidf.transform(X['text'], copy=copy)
        # result is a sparse matrix.  I'm not sure of a clean way
        # to add a column to a sparse matrix.  If you have the
        # memory, you can use a dense matrix instead...
        return np.column_stack((result, X['duration']))