为啥 MLLinearRegressor 每次都返回相同的预测?

Posted

技术标签:

【中文标题】为啥 MLLinearRegressor 每次都返回相同的预测?【英文标题】:Why is MLLinearRegressor returning the same prediction every time?为什么 MLLinearRegressor 每次都返回相同的预测? 【发布时间】:2019-01-06 00:20:31 【问题描述】:

我正在处理一个涉及 CreateML 和 MLLinearRegressor 的项目。出于某种原因,每当我尝试预测训练数据中不存在的值时,每次都会得到相同的预测。这在 Swift Playgrounds 和在 Xcode 项目中使用模型时都会发生。为什么会发生这种情况?我在下面发布了我的 Swift Playgrounds 代码。

import CreateML
import CoreML
import Foundation

do 
        let data: [String: MLDataValueConvertible] = [
     "Processor Name": ["A6", "A7", "A8", "A8X", "A9", "A9X", "A10X", "A10X", "A11"],
     "Geekbench Singlecore": [754, 1325, 1660, 1796, 2522, 3052, 3463, 3909, 4219]
     ]

    let CPURegressor = try MLLinearRegressor(trainingData: MLDataTable(dictionary: data), targetColumn: "Geekbench Singlecore", featureColumns: ["Processor Name"])

    let testData: [String: MLDataValueConvertible] = [
        "Processor Name": ["A6", "A7", "A8", "A8X", "A9", "A9X", "A10X", "A10X", "A11", "A12"],
        "Geekbench Singlecore": [754, 1325, 1660, 1796, 2522, 3052, 3463, 3909, 4219,0]
    ]

    print(try CPURegressor.predictions(from: MLDataTable(dictionary: testData))) // Notice how last (A12) and first (A6) values are the same
 catch 
    print(error)

更新: 这是调整我的Processor Name 类别后我的代码的样子

import CreateML
import CoreML
import Foundation

do 
        let data: [String: MLDataValueConvertible] = [
     "Processor Name": [6.0, 7.0, 8.0, 8.5, 9.0, 9.5, 10.0, 10.5, 11.0],
     "Geekbench Singlecore": [754, 1325, 1660, 1796, 2522, 3052, 3463, 3909, 4219]
     ]

    print(try MLDataTable(dictionary: data))
    let CPURegressor = try MLRegressor(trainingData: MLDataTable(dictionary: data), targetColumn: "Geekbench Singlecore", featureColumns: ["Processor Name"])/*, parameters: MLBoostedTreeRegressor.ModelParameters(validationData: nil, maxDepth: 1000,
                                                                                                                                                                                                                              maxIterations: 1000,
                                                                                                                                                                                                                              minLossReduction: 1))*/
    /*CPURegressor.modelParameters = MLImageClassifier.ModelParameters(featureExtractor: .scenePrint(revision: 1),
                                                                     validationData: nil,
                                                                     maxIterations: 30,
                                                                     augmentationOptions: [])*/

  /*  let testData: [String: MLDataValueConvertible] = [
        "Processor Name": [0, 1, 2, 3, 4, 5, 6, 7, 8, 14],
        "Geekbench Singlecore": [1325, 1660, 1796, 2522, 3052, 3463, 3909, 4219,0, 1325]
    ]

    print(try CPURegressor.predictions(from: MLDataTable(dictionary: testData))) // Notice how last (A12) and first (A6) values are the same*/
 catch 
    print(error)

【问题讨论】:

【参考方案1】:

线性回归计算给定输入值的输出值,这两个值都必须是数字。但是您的输入值不是数字,它们是字符串。那么线性回归如何知道"A12" 与所有其他输入值的比较呢?

对于人类来说,A12 排在 A11 之后是有道理的,但由于这些不是数字,线性回归需要以某种方式将它们转换为数字,但无法说明它将如何做到这一点。所以不可能说 A12 在“数字线”上的位置(或任何其他处理器在该线上的位置)。

换句话说,您使用分类值作为线性回归的输入,而线性回归只能处理实值输入。

尝试将"Processor Name" 替换为[0, 1, 2, 3, 4, 5, 6, 7, 8]。然后询问9 的预测,这将是 A12 处理器。 (并不是说这样做一定有任何意义,因为这假设每一代处理器之间的差异是 1,但这意味着什么?)

另外,您的数据中有两次A10X

【讨论】:

谢谢!我当然会尝试切换处理器名称,然后询问 9 的预测。我在使用 MLBoostedTreeRegressor 时也遇到了同样的问题。你认为这也能解决那里的问题吗? 我在使用数字和 MLBoostedTreeRegressor 时也遇到了同样的问题。你知道在这种情况下会发生什么吗? 我需要先看看你的实际代码才能回答这个问题。

以上是关于为啥 MLLinearRegressor 每次都返回相同的预测?的主要内容,如果未能解决你的问题,请参考以下文章

即使使用“--fake”,Django 迁移缓慢且资源密集

为啥每次都加载新的 xib 文件?为啥不替换前一个?

为啥每次都重复调用 ngOnInit

为啥 Mocha 不报告每次测试的时间?

Android:位置服务每次返回不同的数字 - 为啥?

为啥每次选择另一个 TextField 时都会调用 KeyboardWillShowNotification?