Могу ли я использовать фрейм данных с разреженным вектором для настройки перекрестной проверки?
Я тренирую свой многослойный классификатор Перцептрон. Вот мой тренировочный набор. Особенности в редком векторном формате.
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"))
И я понимаю: это не похоже на оценку научного знания, так как он не реализует методы get_params. Но когда я посмотрел документ, я не нашел метод get_params. Может кто-нибудь помочь мне с этим?
1 ответ
Есть несколько проблем с вашим вопросом...
Ориентируясь на вторую часть (это на самом деле отдельный вопрос), утверждение об ошибке, то есть
это не похоже на научную оценку
действительно правильно, так как вы используете MultilayerPerceptronClassifier
от PySpark ML as trainer
в методе scikit-learn cross_val_score
(они не совместимы).
Кроме того, ваш второй фрагмент кода совсем не похож на PySpark, а похож на scikit: при правильном использовании ввода в первом фрагменте (одном кадре данных с двумя столбцами, с функциями в одном столбце и метками / целями) в другом) вы, кажется, забыли этот урок во втором фрагменте, где вы создаете отдельные кадры данных X
а также y
для ввода в ваш классификатор (что должно быть в scikit-learn, но не в PySpark). Увидеть CrossValidator
документы для простого примера правильного использования.
С более общей точки зрения: если ваши данные помещаются в основную память (т.е. вы можете collect
их, как вы делаете для своего резюме), нет абсолютно никаких причин беспокоиться о Spark ML, и вам будет гораздо лучше с scikit-learn.
-
Что касается 1-й части: показанные вами данные, похоже, имеют только 2 ярлыка 0.0/1.0
; Я не могу быть уверен (так как вы показываете только 10 записей), но если у вас действительно есть только 2 ярлыка, вы не должны использовать MulticlassClassificationEvaluator
но BinaryClassificationEvaluator
- который, однако, не имеет metricName="accuracy"
вариант... [РЕДАКТИРОВАТЬ: несмотря ни на что, кажется, что MulticlassClassificationEvaluator
действительно может работать и для двоичной классификации, и это удобный способ получить точность, которая не обеспечивается его двоичным аналогом!]
Но это не то, почему вы получаете эту ошибку (что, кстати, не имеет ничего общего с evaluator
- вы получите это с result.show()
или же result.collect()
); причина ошибки в том, что количество узлов в вашем первом слое (layers[0]
) равен 4, тогда как ваши входные векторы, очевидно, 5-мерные. Из документов:
Количество входов должно быть равно размеру векторов объектов
изменения layers[0]
до 5 решает проблему (не показана). Точно так же, если у вас действительно есть только 2 класса, вы также должны изменить layers[-1]
до 2 (вы не получите ошибку, если не получите, но это не будет иметь большого смысла с точки зрения классификации).