machine-learning - 我可以使用带有稀疏向量的数据帧进行交叉验证调整吗?

标签 machine-learning scikit-learn pyspark cross-validation apache-spark-ml

我正在训练我的多层感知器分类器。这是我的训练集。特征采用稀疏向量格式。

df_train.show(10,False)
+------+---------------------------+
|target|features                   |
+------+---------------------------+
|1.0   |(5,[0,1],[164.0,520.0])    |
|1.0   |[519.0,2723.0,0.0,3.0,4.0] |
|1.0   |(5,[0,1],[2868.0,928.0])   |
|0.0   |(5,[0,1],[57.0,2715.0])    |
|1.0   |[1241.0,2104.0,0.0,0.0,2.0]|
|1.0   |[3365.0,217.0,0.0,0.0,2.0] |
|1.0   |[60.0,1528.0,4.0,8.0,7.0]  |
|1.0   |[396.0,3810.0,0.0,0.0,2.0] |
|1.0   |(5,[0,1],[905.0,2476.0])   |
|1.0   |(5,[0,1],[905.0,1246.0])   |
+------+---------------------------+

首先,我想在保留方法上评估我的估计器,这是我的代码:

from pyspark.ml.classification import MultilayerPerceptronClassifier
from pyspark.ml.evaluation import MulticlassClassificationEvaluator

layers = [4, 5, 4, 3]
trainer = MultilayerPerceptronClassifier(maxIter=100, layers=layers, blockSize=128, seed=1234)
param = trainer.setParams(featuresCol = "features",labelCol="target")

train,test = df_train.randomSplit([0.8, 0.2])
model = trainer.fit(train)
result = model.transform(test)
evaluator = MulticlassClassificationEvaluator(
    labelCol="target", predictionCol="prediction", metricName="accuracy")
print("Test set accuracy = " + str(evaluator.evaluate(result)))

但结果是错误:无法执行用户定义的函数($anonfun$1: (vector) => double)。这是因为我的特征中有稀疏向量吗?我能做什么做什么?

对于交叉验证部分,我编码如下:

X=df_train.select("features").collect()
y=df_train.select("target").collect()
from sklearn.model_selection import cross_val_score,KFold
k_fold = KFold(n_splits=10, random_state=None, shuffle=False)
print(cross_val_score(trainer, X, y, cv=k_fold, n_jobs=1,scoring="accuracy"))

我得到:它似乎不是一个 scikit-learn 估计器,因为它没有实现“get_params”方法。 但是当我查找文档时,我没有找到 get_params 方法。有人可以帮我解决这个问题吗?

最佳答案

您的问题存在很多问题...

重点关注第二部分(实际上是一个单独的问题),错误消息声明,即

it does not seem to be a scikit-learn estimator

确实是正确的,因为您在 scikit-learn 方法 cross_val_score 中使用 PySpark ML 中的 MultilayerPerceptronClassifier 作为trainer(它们是< em>不兼容)。

此外,您的第二个代码片段根本不像 PySpark,而是像 scikit-learn:当您正确使用第一个代码片段中的输入时(单个 2 列数据帧,带有一列中的功能和另一列中的标签/目标),您似乎在第二个片段中忘记了这一课,您在其中构建了单独的数据帧 Xy输入到分类器(scikit-learn 中应该是这种情况,但 PySpark 中不是)。请参阅CrossValidator docs获取正确用法的简单示例。

从更一般的角度来看:如果您的数据适合主内存(即您可以像收集简历一样收集它们),那么绝对没有理由打扰 Spark ML,如果使用 scikit-learn,效果会更好。

--

关于第一部分:您显示的数据似乎只有2个标签0.0/1.0;我不能确定(因为你只显示 10 条记录),但如果你确实只有 2 个标签,你不应该使用 MulticlassClassificationEvaluator 而应该使用 BinaryClassificationEvaluator - 然而,没有 metricName="accuracy"选项... [编辑:尽管困难重重,似乎 MulticlassClassificationEvaluator 确实也可以用于二进制分类,这是一种获得准确度的便捷方法,而二进制对应物则没有提供这种准确度!]

但这不是您收到此错误的原因(顺便说一句,这与评估器无关 - 您可以使用 result.show()result.collect());错误的原因是第一层 (layers[0]) 中的节点数为 4,而输入向量显然是 5 维的。来自 docs :

Number of inputs has to be equal to the size of feature vectors

layers[0]更改为5可以解决该问题(未显示)。类似地,如果你确实只有 2 个类,你也应该将 layers[-1] 更改为 2 (如果你不这样做,你不会收到错误,但它没有多大意义从分类的角度来看)。

关于machine-learning - 我可以使用带有稀疏向量的数据帧进行交叉验证调整吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47131421/

相关文章:

Pyspark如何合并和分解2个数据框

python - Spark read.csv 错误地解析时间戳

python - 关于lightFM,如何嵌入特征矩阵并向用户推荐新项目

python - Scikit-learn安装: "ImportError: No module named sklearn"

python - 如何在sklearn k-means聚类中将具有较大点数的组标记为 ‘0’

python - sklearn2pmml 错误 : expected zero arguments for construction of ClassDict (for pandas. _libs.interval.Interval)

python - PySpark:在 UDF 中使用列名并根据逻辑连接列名

线性回归的 Python、GD 和 SGD 实现

python - scikit-learn 中的随机森林解释

python - 从一组文档中找到最相似的文档(最近的邻居)