【问题标题】:custom model moved to scikit-learn自定义模型移至 scikit-learn
【发布时间】:2018-06-25 17:44:31
【问题描述】:

简而言之:我编写了一个运行良好的自定义模型,但尝试在 scikit-learn 中重新实现它,但效果不佳。 我不确定我的代码(如下)是否有问题,是否缺少推荐的 scikit-learn 项目预处理,或者我选择的模型是否错误。

该项目的目标是:给定关于产品的博客文章的标题,预测所写的实际产品。总共有大约2,000种产品。

首先,我使用从教科书中采用的一些“语言模型”原则构建了一个自定义模型。

我查看了标记的数据,并为每个产品统计了所有标题中使用的所有单词(例如 car:10,windshield:3,husband:2,tires:5})。然后为了对看不见的标题做出新的预测,我标记了标题并为每个产品构建了一个分数:score=(word1 在产品统计中的百分比频率)*(word2 在产品统计中的百分比频率)等等。我有一个默认的低百分比产品缺少的单词的频率(而不是使用会破坏排名的 0)。

然后我会按分数对产品进行排序并返回前 5 名。我发现在我这样做的 87% 的时间里,正确的产品都在前 5 名之内。

所以现在我尝试在 scikit-learn 中使用朴素贝叶斯来实现它。现在作为评估指标,我使用的是更苛刻的默认 score() 方法,因为模型的顶部(唯一)预测必须是正确的。但我得到了 44% 的准确率,这让我感到惊讶。

  • 值得注意的是,我在对训练数据进行评分时也得到了 44%;我认为这应该更高,因为模型已经看到了这些数据。
  • 使用线性回归时,我也得到了低分:在已经看到的训练数据上得分为 88%,但在未见过的测试数据上得分为 47%。

我的代码:

titles = []
products = []
with open('1pct_singlelabel.csv', 'r', encoding="utf8") as one_pct:
    reader = csv.reader(one_pct, delimiter=',', quotechar='"', lineterminator='\n')
    for i, row in enumerate(reader):
        if (i == 0):
            continue  # skip header
        titles.append(row[2])
        products.append(row[1])

text_train, text_test, y_train, y_test = train_test_split(titles, products, random_state=0)

vect = CountVectorizer(min_df=0)
vect.fit(titles)
X_train = vect.transform(text_train)
X_test = vect.transform(text_test)

le = preprocessing.LabelEncoder()
le.fit(products)
y_train = le.transform(y_train)
y_test = le.transform(y_test)

clf = LogisticRegression()
clf.fit(X_train, y_train)
print("Logistic Regression: ")
print(clf.score(X_train, y_train))
print(clf.score(X_test, y_test))

总之,我不明白为什么 scikit-learn 比我的自定义代码差这么多,我的自定义代码并不复杂并且(我被告知)类似于朴素贝叶斯。我不确定我是否正确使用了 scikit-learn。

【问题讨论】:

    标签: python machine-learning scikit-learn


    【解决方案1】:

    我认为您误解了MultinomialNB 的分数值。 Sklearn 不提供用于评估 top-k 准确性的内置方法。您看到的分数结果是模型准确预测的样本百分比。我想如果您要从 sklearn 中的朴素贝叶斯模型计算前 5 名,它会与您的自定义模型非常相似。

    您可以使用predict_proba 方法获取分配给每个类别的概率。从那里您可以对输出进行排序并获取前 k 个值并检查实际输出是否在该输出中。

    predictions = clf.predict_proba(test)
    k = 5
    top_k = np.argsort(probs, axis=1)[-k:]
    top_k_preds = clf.classes_[top_k]
    

    从那里您可以检查您的实际班级是否在前 5 名预测中。

    【讨论】:

    • 谢谢,我倾向于那个方向,所以很高兴看到你同意。我目前正在研究您的建议。
    猜你喜欢
    • 1970-01-01
    • 2014-08-09
    • 2020-02-04
    • 2020-03-19
    • 2018-09-22
    • 2018-02-22
    • 2015-09-16
    • 2014-05-01
    • 2017-12-16
    相关资源
    最近更新 更多