我正在使用少量机器学习算法对零售交易数据进行POC,并提出缺货分析的预测模型。我的问题可能听起来很愚蠢,但如果你或其他任何人能回答我,我真的很感激。
到目前为止,我已经能够获得数据集==>将要素转换为(标签点,要素向量)==>训练ML模型==>在Test DataSet上运行模型并且==>得到预测。
由于我没有任何JAVA / Python / Scala语言的经验,我正在数据库中构建我的功能,并将该数据保存为我的机器学习算法的CSV文件。
我们如何使用原始数据中的Scala创建功能。
源数据集包含一组(存储,产品,日期)及其记录的OOS事件(目标)的许多功能
StoreID(文本列),ProductID(文本列),TranDate,(标签/目标),Feature1,Feature2 ........................ FeatureN
由于Features只能包含数值,所以我只是从数字列而不是文本列创建功能(这对我来说是自然的键)。当我在验证集上运行模型时,我得到一个(预测,标签)数组。
现在,如何将此结果集链接回原始数据集,并查看哪个特定(商店,产品,日期)可能存在缺货事件?
我希望问题陈述足够清楚。
MJ
答案 0 :(得分:3)
这是Spark Docs Linear Regression example的一个片段,它非常有启发性且易于理解。
它解决了你的问题1"和"问题2"
它不需要加入,甚至不依赖于RDD订单。
// Load and parse the data
val data = sc.textFile("data/mllib/ridge-data/lpsa.data")
此处data
是文本行的RDD
val parsedData = data.map { line =>
val parts = line.split(',')
LabeledPoint(parts(0).toDouble, Vectors.dense(parts(1).split(' ').map(_.toDouble)))
}.cache()
这取决于数据。在这里,我们看到行正在,
分割成字段。看来这个数据是完全数字数据的CSV。
第一个字段被视为标记点(因变量)的标签,其余字段从文本转换为双(浮点)并卡在矢量中。此向量包含要素或自变量。
在您自己的项目中,您需要记住的部分是解析为LabeledPoints的RDD的目标,其中LabeledPoint的第一个参数(标签)是真正的依赖数值和特征,或第二个参数,是一个数字向量。
将数据置于此状态需要知道如何编码。 Python可能最容易进行数据解析。您始终可以使用其他工具创建纯数字CSV,第一列中包含因变量,其他列中包含数字要素,没有标题行 - 然后复制示例解析函数。
// Building the model
val numIterations = 100
val model = LinearRegressionWithSGD.train(parsedData, numIterations)
此时我们有一个训练有素的model
对象。 model
对象具有predict
method,它对特征向量进行操作并返回因变量的估计值。
ML例程通常需要数字特征向量,但您通常可以将自由文本或分类特征(颜色,大小,品牌名称)转换为某些空间中的数字向量。有多种方法可以做到这一点,例如用于文本的Bag-Of-Words,或者用于分类数据的One Hot Encoding,其中您为每个可能的类别编写1.0或0.0的成员资格(但要注意多重共线性)。这些方法可以创建大的特征向量,这就是Spark为训练模型提供迭代方法的原因。 Spark还有一个SparseVector()
类,您可以轻松创建除了某些特征尺寸设置为0.0以外的所有矢量
接下来,他们使用训练数据测试此模型,但是调用
如果测试数据是LabeledPoint的RDD(依赖值,Vector(特征)),则与外部测试数据相同。可以通过将变量parsedData
更改为其他RDD来更改输入。
// Evaluate model on training examples and compute training error
val valuesAndPreds = parsedData.map { point =>
val prediction = model.predict(point.features)
(point.label, prediction)
}
请注意,这将返回先前存储在point.label
中的真因变量的元组,以及每行或LabeledPoint的point.features
的模型预测。
现在我们已准备好做均值平方误差,因为valuesAndPreds
RDD包含真值(v,p)
的元组v
和类型为Double的预测p
。
MSE是单个数字,首先将元组分别映射到平方距离||v-p||**2
的rdd,然后取平均值,得到一个数字。
val MSE = valuesAndPreds.map{case(v, p) => math.pow((v - p), 2)}.mean()
println("training Mean Squared Error = " + MSE)
这是类似的,但在这里你可以看到数据已经被解析并分成训练和测试集。
// Split data into training (60%) and test (40%).
val splits = data.randomSplit(Array(0.6, 0.4), seed = 11L)
val training = splits(0).cache()
val test = splits(1)
此处模型针对训练集进行训练。
// Run training algorithm to build the model
val model = new LogisticRegressionWithLBFGS()
.setNumClasses(10)
.run(training)
与测试集进行测试(比较)。请注意,即使这是一个不同的模型(Logistic而不是Linear),仍然有model.predict
方法将点features
向量作为参数并返回该点的预测。
预测再次与标签中的真值配对,在元组中用于性能指标的比较。
// Compute raw scores on the test set.
val predictionAndLabels = test.map { case LabeledPoint(label, features) =>
val prediction = model.predict(features)
(prediction, label)
}
// Get evaluation metrics.
val metrics = new MulticlassMetrics(predictionAndLabels)
val precision = metrics.precision
println("Precision = " + precision)
加入怎么样?因此,如果您有两个(键,值)对的RDD,则需要RDD.join,并且需要一个与两个值的交叉点对应的RDD。但我们在这里并不需要。