【问题标题】:Accuracy issue with TF.Learn DNNClassifier and LinearClassifierTF.Learn DNNClassifier 和 LinearClassifier 的准确性问题
【发布时间】:2017-02-26 10:07:30
【问题描述】:

我编写了一小段代码来找到适合 CDC 数据集的最佳分类器。首先我尝试了各种 scikit-learn 分类器,然后我决定添加 TF.Learn 分类器(DNNClassifier 和 LinearClassifier),因为 API 几乎相同。

然后,当我比较结果时,所有 scikit-learn 模型很容易达到 60-70% 的准确率,而使用 TF.learn DNNClassifiers 和 LinearClassifier 我不能超过 38% 并且需要很多时间(如果我拟合模型时不要设置步数)。

我可能犯了一个错误,但我没有看到它......

这里是代码摘录:

X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)    

for classifier in classifiers:
    if classifier == "TF Deep Neural Network":
        feature_columns = learn.infer_real_valued_columns_from_input(X_train)   
        clf = DNNClassifier(feature_columns=feature_columns, 
                           hidden_units=[10,10,10], 
                           n_classes=2, enable_centered_bias=None);
        clf.fit(X_train, Y_train, steps=200)
    elif classifier == "TF Linear Classifier":
        feature_columns = learn.infer_real_valued_columns_from_input(X_train)   
        clf = LinearClassifier(n_classes=2, feature_columns=feature_columns)     
        clf.fit(X_train, Y_train, steps=200)
    else:
        clf = getInstance(classifiers[classifier][0], classifiers[classifier][1], classifiers[classifier][2])
        clf.fit(X_train, Y_train)


    # predict on test data
    prediction = clf.predict(X_test)

    # compute accuracy and sum it to the previous ones
    accuracy = accuracy_score(Y_test, prediction)

结果摘录:

classifier Gaussian Naive Bayes accuracy 0.85
classifier K-Nearest Neighbors accuracy 0.87
classifier TF Deep Neural Network accuracy 0.4
classifier Random Forest accuracy 0.85
classifier TF Linear Classifier accuracy 0.4
classifier Decision Tree accuracy 0.87
classifier Neural Network accuracy 0.4
classifier AdaBoost accuracy 0.86
classifier Linear Support Vector Machine accuracy 0.88
classifier Radial Basic Function Support Vector Machine accuracy 0.74

完整代码在这里:https://github.com/shazz/gender_classification_challenge/blob/master/demo_with_BRFSS_and_TF.py

因此,任何关于 TF.Learn 的准确性为何如此低(并且需要大量时间来适应)的见解都将不胜感激!

更新基于 Kumara 的回答

我将标签修改为 0 或 1(而不是原始 CDC 数据集中的 1 和 2),然后再次运行分类器测试。新结果是:

classifier AdaBoost accuracy 0.87 
classifier Linear Support Vector Machine accuracy 0.86
classifier K-Nearest Neighbors accuracy 0.86
classifier Gaussian Naive Bayes accuracy 0.85 
classifier Random Forest accuracy 0.85
classifier Radial Basic Function Support Vector Machine accuracy 0.83
classifier Decision Tree accuracy 0.83
classifier Neural Network accuracy 0.64 
classifier TF Deep Neural Network accuracy 0.63 
classifier TF Linear Classifier accuracy 0.62

所以仍然远远落后于 scikit learn 分类器。 可能有意义的是,DNNClassifier 与 scikit learn 多层感知器分类器一样“糟糕”。

您认为考虑到数据的种类和分类器,TF.Learn DNNClassifier 和 LinearClassifier 没有很好的准确率是正常的吗?

【问题讨论】:

  • 你可以尝试更长的时间(更多的步骤),看看结果是否一致? 200 步似乎非常少。
  • 我刚刚尝试了 5000 步,结果相同,准确率约为 34%(但与 scikit learn 分类器的即时结果相比,现在需要 5 秒来计算)
  • 只是好奇,tf.learn 的 RandomForestEstimator 给你什么?它的用法与例如略有不同。 DNNClassifier,以examples/random_forest_mnist.py为例。
  • @jonas25007:我看了一下例子,但我不明白如何使用这个例子中的RFE。我再看看。

标签: python scikit-learn tensorflow


【解决方案1】:

问题在于 TF.learn 分类器期望类标签作为索引(即,对于 2 类问题,y 必须为 0 或 1),而 scikit learn 分类器将 y 视为任意值(例如 77 和 99 是有效的2 类问题中 y 的值)。

在这种情况下,查看数据,类标签是 1 和 2。因此,TF.learn 训练偶尔会看到超出范围的值 2,它会忽略它。结果它总是预测'1'(如果你在调用predict()之后打印'prediction'和'Y_test',这会变得很明显)。标签值“1”可能占数据的 40%,因此它的准确度为 40%。

解决方法是将标签映射到类索引(例如,标签“1”映射到索引 0,标签“2”映射到索引 1)。例如,我在加载数据后使用“Y = Y - 1”执行此操作(尽管对于任意值,更通用的解决方案会更好):

# load data and convert Y into 1d vector
X, Y = data_importer.load_data(500)
print("X", X.shape, "Y", Y.shape)

# FIX: Y/Labels are "1" and "2" for male/female.  We should convert
# these to indices into a 2 class space
# (i.e. "1" is index 0, and "2" is index 1).
Y = Y - 1

# train and check the model against the test data for each classifier
iterations = 1
results = {}
for itr in range(iterations):

    # Resuffle training/testing datasets by sampling randomly 80/20% of the input data
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.2)
    ...

理想情况下,这两个 API 应该是兼容的,或者至少 TF.learn API 应该更清楚地记录这种区别。虽然可以说使用类索引对于任意类(例如图像类)更有效和更清洁。

【讨论】:

  • 谢谢 Kumara... 现在看起来很蠢 :) 但不容易被发现。所以我将标签修改为 0 或 1(男人/女人),然后再次运行分类器测试。那更好,但还没有那么好。我更新了主要问题。
猜你喜欢
  • 1970-01-01
  • 2017-09-23
  • 1970-01-01
  • 2016-03-18
  • 2017-11-18
  • 2018-10-07
  • 2011-06-05
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多