Как получить 10-кратный перекрестный проверочный набор и обучающие наборы данных с помощью Apache Spark? - PullRequest
0 голосов
/ 05 января 2019

Я пытаюсь реализовать 10-кратную перекрестную проверку для своей реализации машинного обучения самостоятельно, но у меня есть некоторые проблемы с количеством функций в моем наборе данных.

У меня есть набор данных, который содержит только двоичные данные. Я пытаюсь реализовать 10-кратную перекрестную проверку самостоятельно. Я разделил набор данных, нашел тестовые и тренировочные наборы и сохранил их.

Мой фактический файл данных - разреженный вектор. После вышеописанной опции разбиения я получил 10 тестовых файлов, которые состоят из разреженных векторов, и 10 обучающих файлов снова состоят из разреженных векторов. Проблема заключается в том, что фактический файл данных имеет большее количество объектов, чем наборы тестовых и обучающих данных, поскольку тест и обучающий набор устанавливают только подмножества фактического файла. Поэтому, когда я пытаюсь применить алгоритм Spark ML, я получаю сообщение об ошибке, которое говорит об этих различиях.

        counter = 10; // fold count
        // filePath is the path of the file which contains the sparse vector file of my actual dataset, i and fileName is just for information messages, I am doing these steps for X times and getting the average of them to get more accurate result. i is the counter for X.
        ArrayList<ArrayList<Dataset<Row>>> datasets = splitAccordingTo10FoldCrossValidation(filePath, i, fileName, sparkBase); 
        for(int k=0; k<counter; k++){

            // Every row of datasets object contains test data in 0. index and training data in 1. index. Here for example 0. index is one of the folds which is a test dataset and 1. index is the sum of the rest of the folds which is training set for current iteration. datasets object has size of 10 which is equal to cross validation count.
            testData = datasets.get(k).get(0);
            trainingData = datasets.get(k).get(1);

            StringIndexerModel labelIndexer = new StringIndexer()
                    .setInputCol("label")
                    .setOutputCol("indexedLabel")
                    .fit(trainingData);

            VectorIndexerModel featureIndexer = new VectorIndexer()
                    .setInputCol("features")
                    .setOutputCol("indexedFeatures")
                    .setMaxCategories(4)
                    .fit(trainingData);

            DecisionTreeClassifier dt = new DecisionTreeClassifier()
                    .setLabelCol("indexedLabel")
                    .setFeaturesCol("indexedFeatures");

            IndexToString labelConverter = new IndexToString()
                    .setInputCol("prediction")
                    .setOutputCol("predictedLabel")
                    .setLabels(labelIndexer.labels());

            Pipeline pipeline = new Pipeline()
                    .setStages(new PipelineStage[]{labelIndexer, featureIndexer, dt, labelConverter});

            trainingData.sparkSession().read().format("libsvm");
            PipelineModel model = pipeline.fit(trainingData);

            // I got the error that I mentioned below explanations in this row.
            Dataset<Row> predictions = model.transform(testData);

            MulticlassClassificationEvaluator evaluator = new MulticlassClassificationEvaluator()
                    .setLabelCol("indexedLabel")
                    .setPredictionCol("prediction")
                    .setMetricName("accuracy");

            // I will divide these to 10 later.
            accuracySum += evaluator.evaluate(predictions);

            evaluator.setMetricName("weightedPrecision");
            precisionSum += (evaluator.evaluate(predictions));

            evaluator.setMetricName("weightedRecall");
            recallSum += (evaluator.evaluate(predictions));
        }

После разделения наборов данных я сохраняю их в разных файлах. Наборы тестовых и обучающих данных находятся в разных файлах данных для каждой итерации. Итак, у меня есть 10 тестовых и 10 обучающих наборов данных, которые состоят из разреженных векторов. Вот как я их читаю:

Dataset<Row> data = sparkBase
            .getSpark()
            .read()
            .format("libsvm")
            .load(filePath);

Часть, где я получаю предсказания, выдает «java.lang.AssertionError: сбой утверждения: VectorIndexerModel ожидал вектор длины 842, но обнаружил ошибку длины 841». Как я могу это исправить?

...