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

时间:2018-07-29 16:21:35

标签: swift macos coreml macos-mojave createml

我正在从事一个涉及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 个答案:

答案 0 :(得分:1)

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

对于人类来说,A12在A11之后是有意义的,但是由于它们不是数字,因此线性回归需要以某种方式将它们转换为数字,但是无法说明如何实现。因此,不可能说出A12在“数字行”上的位置(或其他任何处理器在该行的位置)。

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

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

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