Kaggle 比赛的 ROC 分数不正确?
Posted
技术标签:
【中文标题】Kaggle 比赛的 ROC 分数不正确?【英文标题】:Incorrect ROC score for Kaggle competition? 【发布时间】:2018-05-24 11:16:18 【问题描述】:我正在研究 Kaggle 比赛并使用逻辑回归分类器来测试前 10 名竞争对手的方法。
比赛链接:https://www.kaggle.com/c/detecting-insults-in-social-commentary/leaderboard
我对分类问题还很陌生,所以我只是测试了分类器,没有做太多修改。在这种情况下,我使用了 scikit-learn 的 logreg。我清理了测试/训练数据并用它来生成 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)
说明:
-
从 Kaggle 链接下载 train.csv 和 test_with_solutions.csv。
https://www.kaggle.com/c/detecting-insults-in-social-commentary/data
将 test_with_solutions.csv 重命名为 test.csv
在代码集
path
中作为 .csv 文件的路径
对于C
参数,我不太了解它,如果这是我得分如此高的原因,请告诉我,我很感激任何建议,以找到一个好的价值。谢谢。
方法:
-
读取 .csv 文件并清理文本(使用预处理程序包并手动替换某些字符)
使用 Snowball 词干分析器并检查每个单词 isalpha()
使用 scikit-learn 的 TfidfVectorizer 对测试和训练数据进行矢量化处理
使用训练数据训练 logreg
计算并绘制 ROC 曲线
编辑:
所以我使用了 C 参数,并将 C 设置为较高的值,例如 1e5,从而降低了 ROC 曲线区域。也许现在的主要问题是,如果我的代码是正确的并且 C 是我需要调整的参数,我是否应该优化 C 以给我最高的 ROC 曲线区域?
Edit2:我使用 GridSearchSV 在 0.1 到 10 的范围内测试 C 并且仍然得到很高的结果(超过 10 和低于 0.1 没有做任何事情)。
【问题讨论】:
【参考方案1】:您使用的测试数据与可用的不同 - 仅使用 test.csv 文件来找到 C 的最佳模型和值,然后仅在 impermium_verification_set.csv 上对其进行评估。比赛进行时,看起来只有测试可以找到模型,然后模型被锁定,排行榜基于验证集。您正在使用两者的完整集合来选择最佳模型。
如果需要,您可以随时在 Kaggle 竞赛页面上的讨论板上提问 - 我相信那里的人也会提供帮助。此外,包括获胜者在内的一些排名靠前的人已在讨论页面上发布了他们的代码以引起兴趣。
【讨论】:
非常感谢。我使用了 imperium_verification_set.csv 并获得了 0.78 的 ROC。所以 test_with_solutions.csv 既有 test.csv 又有 imperium_verification_set.csv?您还提到测试用于查找模型...您的意思是训练吗? 是的,我相信它包含两套。在调整模型时,您可以使用训练集进行交叉验证,我的意思是,如果您训练了许多模型,那么您提交参加比赛的很可能是那些测试集得分最高的模型。以上是关于Kaggle 比赛的 ROC 分数不正确?的主要内容,如果未能解决你的问题,请参考以下文章