Kaggle 比赛的 ROC 分数不正确?

Incorrect ROC score for Kaggle competition?

我正在研究 Kaggle 竞赛并使用逻辑回归分类器来测试前 10 名参赛者的方法。

Link参加比赛:https://www.kaggle.com/c/detecting-insults-in-social-commentary/leaderboard

我对分类问题还很陌生,所以我只是测试了分类器而没有做太多修改。在本例中,我使用了 scikit-learn 的 logreg。我清理了 test/train 数据并用它来生成 ROC 曲线。

我的曲线下面积是 0.89,这本可以让我以显着的领先优势排在第一位,但考虑到我的实现很简单,这对我来说似乎是不可能的。有人能告诉我我的程序是否做错了某件事而给出了这样的分数(例如,不知何故过度拟合或代码中的错误)吗?

import csv
import preprocessor as p
import matplotlib.pyplot as plt
from sklearn import linear_model
from sklearn.feature_extraction.text import TfidfVectorizer
from nltk.stem.snowball import SnowballStemmer
from nltk.tokenize import word_tokenize
from sklearn.metrics import roc_curve
from sklearn.metrics import auc

path = "C:\Users\Mike\Desktop"

def vectorize_dataset(subpath, stem, vectorizer):
    comments = []
    labels = []
    stemmer = SnowballStemmer("english")
    with open(path + subpath + '.csv', 'r') as f:
        data_csv = csv.reader(f)

        for row in data_csv:
            clean_txt = p.clean(row[2])
            clean_txt = clean_txt.strip().replace('"', '').replace('\\', '\').replace('_', ' ')
            clean_txt = bytes(clean_txt, 'utf-8').decode('unicode_escape', 'ignore')
            if stem:
                clean_txt = [stemmer.stem(word.lower()) for word in word_tokenize(clean_txt)]
            clean_txt = [word for word in clean_txt if word.isalpha()]      
            clean_txt = " ".join(clean_txt)

            if clean_txt != "":
                if row[0] == str(1) or row[0] == str(0):
                    comments.append(clean_txt) 
                    labels.append(int(row[0]))
    if subpath == "\train":
        return (vectorizer.fit_transform(comments), labels)
    return (vectorizer.transform(comments), labels) 

def print_auroc_for_classifier(vect_tuple, classifier):
    y_true, y_score = [], []

    for sample, label in zip(vect_tuple[0], vect_tuple[1]):
        y_true.append(label)
        y_score.append(classifier.predict_proba(sample)[0][1])

    fpr, tpr, thresholds = roc_curve(y_true, y_score)
    roc_auc = auc(fpr, tpr)
    print("ROC AUC: %.2f" % roc_auc)  

    plt.plot(fpr, tpr)

if __name__ == '__main__':     
    plt.figure()
    plt.xlim([0.0, 1.0])
    plt.ylim([0.0, 1.05])
    plt.xlabel('False Positive Rate')
    plt.ylabel('True Positive Rate')
    plt.title('Receiver operating characteristic example')
    plt.plot([0, 1], [0, 1], color='navy', lw=2, linestyle='--')

    vectorizer = TfidfVectorizer()
    train_tuple = vectorize_dataset('\train', True, vectorizer)
    test_tuple = vectorize_dataset('\test', True, vectorizer)

    logreg = linear_model.LogisticRegression(C=7)
    logreg.fit(train_tuple[0].toarray(), train_tuple[1])

    print_auroc_for_classifier(test_tuple, logreg)

说明:

  1. 从 Kaggle link 下载 train.csv 和 test_with_solutions.csv。 https://www.kaggle.com/c/detecting-insults-in-social-commentary/data
  2. 将 test_with_solutions.csv 重命名为 test.csv
  3. 在代码中设置 path 为 .csv 文件的路径

对于 C 参数,我不太了解它,如果这是我得分这么高的原因,请告诉我,我很感激为它找到一个好的价值的任何建议。谢谢。

方法:

  1. 读取 .csv 文件并清理文本(使用预处理器包并手动替换某些字符)
  2. 使用 Snowball 词干分析器并检查每个单词 isalpha()
  3. 使用 scikit-learn 的 TfidfVectorizer 向量化测试和训练数据
  4. 用训练数据训练 logreg
  5. 计算并绘制 ROC 曲线

编辑:

所以我尝试使用 C 参数,将 C 设置为较高的值(例如 1e5)可以降低 ROC 曲线面积。也许现在的主要问题是,假设我的代码是正确的并且 C 是我需要调整的参数,我是否应该优化 C 以给我最高的 ROC 曲线区域?

Edit2:我使用 GridSearchSV 在 0.1 到 10 的范围内测试 C,仍然得到了很高的结果(超过 10 和低于 0.1 没有做任何事情)。

您使用的测试数据与可用数据不同 - 仅使用 test.csv 文件来查找 C 的最佳模型和值,然后仅在 impermium_verification_set.csv 上对其进行评估。在比赛运行的时候,貌似只有test才能找到模型,然后模型就被锁定了,排行榜是基于验证集的。您正在使用两者的全套 select 最佳模型。

如果需要,您可以随时在 Kaggle 竞赛页面的讨论板上提问 - 我相信那里的人也会提供帮助。此外,包括获胜者在内的一些名列前茅的人已将他们的代码发布在讨论页面上以引起兴趣。