微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

文本分类 Python 上的伪标签

如何解决文本分类 Python 上的伪标签

我不擅长机器学习。有人能告诉我如何在 python 中使用伪标签进行文本分类吗?我从来不知道正确的实现,我在互联网上到处搜索,但我放弃了任何发现:'(我刚刚找到了数字数据集的实现,但我没有找到文本分类(矢量化文本)的实现。所以我写了这个语法,但我不知道我的代码是否正确。我做错了吗?请帮帮我,我真的需要你的帮助.. :'(

如果您想尝试,这是我的 datasets。我想从“内容”中对“标签”进行分类

我的步骤是:

  1. 拆分数据 0.75 未标记,0.25 标记
  2. 标记为 0.25 的我拆分:标记为 0.75 个训练,标记为 0.25 个测试
  3. 为训练、测试和未标记数据集制作矢量化器
  4. 标记的训练构建第一个模型,然后标记标记的数据集
  5. 将训练标记数据与预测值 >0.99(伪标记)的未标记数据连接起来,并制作第二个模型
  6. 从未标记的数据集中删除标记
  7. 从第二个模型中预测剩余的未标记,然后迭代步骤 3,直到预测的伪标记概率

这是我的代码

对文本分类进行伪标记

from sklearn.naive_bayes import MultinomialNB

# Initiate iteration counter
iterations = 0

# Containers to hold f1_scores and # of pseudo-labels
train_f1s = []
test_f1s = []
pseudo_labels = []

# Assign value to initiate while loop
high_prob = [1] 

# Loop will run until there are no more high-probability pseudo-labels
while len(high_prob) > 0:
    
    # Set the vector transformer (from data train)
    columnTransformer = ColumnTransformer([
    ('tfidf',TfidfVectorizer(stop_words=None,max_features=100000),'Content')
    ],remainder='drop')

    def transforms(series):
        before_vect = pd.DataFrame({'Content':series})
        vector_transformer = columnTransformer.fit(pd.DataFrame({'Content':X_train}))
        return vector_transformer.transform(before_vect)

    X_train_df = transforms(X_train);
    X_test_df = transforms(X_test);
    X_unlabeled_df = transforms(X_unlabeled)
    
    # Fit classifier and make train/test predictions
    nb = MultinomialNB()
    nb.fit(X_train_df,y_train)
    y_hat_train = nb.predict(X_train_df)
    y_hat_test = nb.predict(X_test_df)

    # Calculate and print iteration # and f1 scores,and store f1 scores
    train_f1 = f1_score(y_train,y_hat_train)
    test_f1 = f1_score(y_test,y_hat_test)
    print(f"Iteration {iterations}")
    print(f"Train f1: {train_f1}")
    print(f"Test f1: {test_f1}")
    train_f1s.append(train_f1)
    test_f1s.append(test_f1)
   
    # Generate predictions and probabilities for unlabeled data
    print(f"Now predicting labels for unlabeled data...")

    pred_probs = nb.predict_proba(X_unlabeled_df)
    preds = nb.predict(X_unlabeled_df)
    prob_0 = pred_probs[:,0]
    prob_1 = pred_probs[:,1]

    # Store predictions and probabilities in dataframe
    df_pred_prob = pd.DataFrame([])
    df_pred_prob['preds'] = preds
    df_pred_prob['prob_0'] = prob_0
    df_pred_prob['prob_1'] = prob_1
    df_pred_prob.index = X_unlabeled.index
    
    # Separate predictions with > 99% probability
    high_prob = pd.concat([df_pred_prob.loc[df_pred_prob['prob_0'] > 0.99],df_pred_prob.loc[df_pred_prob['prob_1'] > 0.99]],axis=0)
    
    print(f"{len(high_prob)} high-probability predictions added to training data.")
    
    pseudo_labels.append(len(high_prob))

    # Add pseudo-labeled data to training data
    X_train = pd.concat([X_train,X_unlabeled.loc[high_prob.index]],axis=0)
    y_train = pd.concat([y_train,high_prob.preds])      
    
    # Drop pseudo-labeled instances from unlabeled data
    X_unlabeled = X_unlabeled.drop(index=high_prob.index)
    
    print(f"{len(X_unlabeled)} unlabeled instances remaining.\n")
    
    # Update iteration counter
    iterations += 1

我想我做错了什么..因为当我看到 f1 分数正在下降。请帮帮我:'(我很紧张。 f1 scores image

==================编辑==================

所以我在journal上搜索,然后我认为我对伪标签中数据拆分的概念有误解。

我最初认为,这些步骤从将数据拆分为标记数据和未标记数据开始,然后从标记数据中拆分为训练和测试。

但是在网上冲浪和搜索之后,我在this journal中发现我的步骤是错误的。该期刊说,伪标记的步骤应该从首先将数据拆分为训练集和测试集开始,然后从该训练集将数据拆分为标记和未标记的数据集。

根据该期刊,当将数据拆分为 90% 的训练集和 10% 的测试集时,它达到了最佳结果。然后,从那 90% 的训练集中,它被分成 20% 的标记数据和 80% 的未标记数据集。这个期刊尝试的证据范围从0.7到0.9作为边界来删除标签在这个比例上,最好的证据阈值为0.74。所以我用新的比例和 0.74 的阈值修正了我的步骤,我终于得到了 F1 分数正在增加。这是我的步骤:

  1. 分割数据 0.9 个训练,0.1 个测试集(我标记了测试集,所以我可以测量 f1 分数)
  2. 从 0.9 次训练中,我拆分了:0.2 个标记数据和 0.8 个未标记数据
  3. 标记训练、测试和未标记训练数据集的 X 值制作向量化器
  4. 标记的训练构建第一个模型,然后标记标记的训练数据集。然后根据测试集(已标记的)测量 F-1 分数。
  5. 使用概率 > 0.74(基于日志的阈值)预测未标记的训练标记数据。我们称这些新数据为伪标签,类似于实际标签),并根据新的训练数据集制作第二个模型。
  6. 从未标记的数据集中删除选定的伪标记
  7. 使用第二个模型预测剩余的未标记数据,然后迭代步骤3,直到没有预测到伪标记的概率>0.74
  8. 所以最后一个模型是最终模型。

我的语法还是一样,我只是改变了分割比例,最终通过 4 次迭代我的 f1 分数增加了:my new f1 scores

我做对了吗?谢谢大家的关注..非常感谢..

解决方法

我不擅长机器学习。

总的来说,我会说您非常擅长机器学习:半监督学习是一种高级问题,我认为您的解决方案非常好。至少大体原理看起来是正确的,但是很难确定(抱歉我没有时间详细分析代码)。一些评论:

  • 可能可以改进的一件事是 0.74 阈值:该值当然取决于数据,因此您可以通过尝试不同的阈值并选择最适合您的数据的阈值来进行自己的实验。
  • 最好将最终测试放在一边,并在迭代期间使用单独的验证集。这样可以避免数据泄露的风险。
  • 我不确定循环的停止条件。可能没问题,但可能值得尝试其他选项:
    • 只需迭代固定次数(例如 10 次)。
    • 停止条件可以基于“不再有 F1 分数改进”(即性能的稳定性),但它更高级一些。

反正还是不错的,如果你想进一步改进,我的意见只是想法。请注意,我已经很长时间没有与半监督人员一起工作了,我不确定我是否记得一切都很好;)

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。