【问题标题】:Incremental Learning in Scikit with PassiveAggressiveClassifier's partial_fit使用 PassiveAggressiveClassifier 的 partial_fit 在 Scikit 中进行增量学习
【发布时间】:2015-08-26 21:07:12
【问题描述】:

我正在尝试在下面的脚本中使用TfidVectorizerpartial_fit 技术来训练PassiveAggressiveClassifier

代码更新:

a, ta = [], []
r, tr = [], []
g = []

vect = HashingVectorizer(ngram_range=(1,4))
model = PassiveAggressiveClassifier()
with open('files', 'rb') as f:
    for line in f:
        line = line.strip()
        with open('gau-' + line + '.csv', 'rb') as csvfile:
            reader = csv.DictReader(csvfile)
            for row in reader:
                res = row['gau']
                g.append(res)

        cls = np.unique(g)
        print(len(cls))

        with open('gau-' + line + '.csv', 'rb') as csvfile:
            reader = csv.DictReader(csvfile)
            i = 0
            j = True
            for row in reader:
                arr = row['text']
                res = row['gau']
                a.append(arr)
                if(len(res) > 0):
                    r.append(int(res))
                i = i + 1

                if i % 400 == 0:
                    training_set = vect.fit_transform(a)
                    print(training_set.shape)
                    training_result = np.array(r)
                    model = model.partial_fit(
                        training_set, training_result, classes=cls)
                    a, r, i = [], [], 0

        print(model)
        testing_set = vect.transform(ta)
        testing_result = np.array(tr)
        predicted = model.predict(testing_set)

        print "Result to be predicted: "+testing_result
        print "Prediction: "+predicted

有多个 CSV 文件,每个文件包含 4k-5k 条记录,我尝试使用 partial_fit 函数一次容纳 400 条记录。当我运行这段代码时,我遇到了以下错误:

Result to be predicted: 1742
Prediction: 2617

我该如何解决这个问题?我的 CSV 文件中的记录是可变长度的。

更新:

TfidVectorizer 替换为HashingVectorizer,我成功地创建了我的模型,但是现在在对我的测试数据执行预测时,生成的预测都是不正确的。 我的训练数据包含数百万行 csv 文件,每行最多包含 4k-5k 个文本单词。

那么我的方法有什么问题,即这些算法可以与我的数据一起使用吗?

【问题讨论】:

  • 您的代码在model = model.partial_fit 行是否失败?还是之前发生的?
  • 它显然在第二个 partial_fit 因为我们有 2 个形状输出。问题是 tdif 输出有时大小不一样。有谁知道在矢量化器的每个变换中具有相同数量的特征的方法?

标签: machine-learning scikit-learn


【解决方案1】:

我正在尝试使用带有 partial_fit 技术的 TfidVectorizer 和下面的脚本来训练 PassiveAggressiveClassifier:

您不能,因为TfidfVectorizer 不适用于在线学习。你想要HashingVectorizer

至于你的代码到底发生了什么,问题就在这里:

training_set = vect.fit_transform(a)
print(training_set.shape)
training_result = np.array(r)
model = model.partial_fit(training_set, training_result, classes=cls)

您在每一步都在改装您的 TF-IDF 对象。因此,没有什么能阻止您在一次迭代中使用字典大小,在下一次迭代中使用另一个字典大小,这正是您遇到的错误。

如果你坚持使用 TF-IDF,可以尝试一些方法:

  1. 追加零/修剪fit_transform返回的向量以使第一个向量的长度:不太可能正常工作;

  2. 在具有初始数据集(最好是大数据集)的 TF-IDF 对象上调用 fit,然后在其他对象上调用 transform。这可能会更好,但我仍然建议HashingVectorizer

【讨论】:

  • 使用 Hashing Vectorizer 后,我的预测结果不正确。实际上我的训练数据以百万计,我想从中预测一个实体。是否存在一些过度拟合问题或什么?可以指导一下吗?
  • @IVlad 为什么将 tfidf 与在线学习算法一起使用是错误的?...我不明白。
【解决方案2】:

这是我从你的问题中理解的。

1) 您需要应用部分拟合模型进行在线培训。

2) 你的特征空间太大了。

如果我做对了,我也会遇到同样的问题。如果你将使用 HashingVectorizer,则很有可能发生密钥冲突。

HashingVectorizer doc

还有几个缺点(与使用 CountVectorizer 和 内存词汇):没有办法计算逆 转换(从特征索引到字符串特征名称)可以是 试图反省哪些功能最重要时的问题 到一个模型。可能存在冲突:不同的标记可以映射到 相同的特征索引。然而在实践中,这很少是一个问题,如果 n_features 足够大(例如 2 ** 18 用于文本分类 问题)。没有 IDF 加权,因为这会使变压器 阶段性的。

如果键会发生碰撞,则可能会降低准确性。

在我的在线培训中,我首先像这样使用 partial_fit 训练分类器。

classifier = MultinomialNB(alpha=alpha_optimized).partial_fit(X_train_tfidf,y_train,classes=np.array([0,1]))

第二天我加载了第一天训练集的腌制分类器 count_vect 和 tfidf。然后我只对 count_vet 和 tfidf 应用了转换。它奏效了

X_train_counts = count_vect.transform(x_train)
X_train_tfidf = tfidf.transform(X_train_counts)
pf_classifier.partial_fit(X_train_tfidf,y_train)

如有疑问请回复。

【讨论】:

    【解决方案3】:

    作为一种解决方案,我会说使用 HashingVectorizer 可以满足您的需求,因为您可以在构造函数中设置特征数量。

    您可能更喜欢使用 TfidfVectorizer,也许它更适合您的情况。直到有人给出对你更有用的东西,我才会给出答案。

    希望会有。不要忘记接受你选择的那个

    【讨论】:

      【解决方案4】:

      对于那些 HashingVectorizer 不能满足他们需求的人,请在我对这个相关问题here 的回答中查看可能的替代方案。它基本上是针对 TfidfVectorizer 和 CountVectorizer 的 partial_fit 的自定义实现。

      这里有两个相关的具体讨论:

      • OP 的问题要求在每次调用 partial_fit 后输出向量的维度必须相同。一般来说,在调用 partial_fit 之后,预计每个实现 partial_fit 的 Scikit-Learn 估计器都能够在管道中工作,因此对于矢量化器来说,这意味着不改变输出维度,因为管道中的其他估计器可能不一定能够处理改变。我认为这就是为什么在 Scikit-Learn 中还没有为这些矢量化器实现 partial_fit 的原因(参见讨论 on an active PR),因为 partial_fit 可能会更新词汇表,这肯定会改变输出维度。

      • 所以我的回答提出的解决方案(TfidfVectorizer 的 partial_fit 方法)只能解决 OP 需求的第一部分,即增量学习。为了解决第二部分,可以将输出序列用零填充到预定向量中。这并不理想,因为当词汇量超过该限制时它会失败。

      【讨论】:

        猜你喜欢
        • 2018-03-21
        • 1970-01-01
        • 2018-08-04
        • 2019-03-06
        • 2017-04-19
        • 2020-01-11
        • 2013-06-17
        • 2021-02-24
        • 2020-12-10
        相关资源
        最近更新 更多