Страницы

Поиск по вопросам

понедельник, 25 ноября 2019 г.

Decision trees (деревья решений) в OpenCV


У меня есть таблица с данными о погоде и количестве лесных пожаров в некоторые дни в некотором регионе:

Температура | Влажность | Скорость ветра | ... | Количество лесных пожаров


Все данные представлены в виде чисел.

Требуется по этим данным построить дерево решений, и, с помощью него и входных параметров (температура, влажность, скорость ветра, и т.д.) спрогнозировать количество лесных пожаров.

Для работы с деревьями решений в OpenCV есть класс CvDTree. Для построения дерева решений в данном классе есть метод train:

boolean train(Mat trainData, int tflag, Mat responses) 


Как (каким образом и в каком порядке) преобразовать мои входные данные в Mat trainData?

Возможно, отвечающему поможет обсуждение по этой ссылке
    


Ответы

Ответ 1



Сделал небольшой пример (можно посмотреть тут https://github.com/NorsaG/OpenCVExample) Некоторые мысли по задаче: выбор инструмента (лично мое мнение - есть более удачные решения, тот же xgboost или spark mllib) выбор критерия (определять число - задача сложная, а вот факт преодоления определённой границы нет) Тестовые данные из головы, поэтому не сильно видны какие либо зависимости (даже очевидные для нас). ненавижу нативные инструменты для java :) Кроме того, похожий код (с минимальными исправлениями в виде имен классов) полностью отказался работать на последней версии либы. package org.firerate; import org.opencv.core.Core; import org.opencv.core.CvType; import org.opencv.core.Mat; import org.opencv.ml.CvRTParams; import org.opencv.ml.CvRTrees; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Paths; import java.util.List; public class FireRateExample { static { System.loadLibrary(Core.NATIVE_LIBRARY_NAME); } private static final int[] OFFSETS = {0, 5, 9}; // границы чисел. будем проверять и прогнозировать эти ситуации public static void main(String[] args) throws IOException { // загружаем данные List csv = loadFile("fire_test.txt"); CvRTrees tree; // настройка параметров. с этим можно долго и упорно играться, подгоняя так или иначе под модель CvRTParams params = new CvRTParams(); params.set_max_depth(2); Mat trainData; Mat labels; // строим модель для ситуаций: кол-во пожаров > 0, > 5 и > 9 for (int offset : OFFSETS) { tree = new CvRTrees(); // создаем матрицу тренировочных данных размерности: х-1 чтобы отбросит названия колонок, 3 - количество критериев (CvType.CV_32F - тип данных) trainData = new Mat(csv.size() - 1, 3, CvType.CV_32F); // классификатор -> 0 или 1 (в нашем случае - количество пожаров больше определенного значения? проставляться будет позднее) labels = new Mat(csv.size() - 1, 1, CvType.CV_32S); // загружаем построчно данные и проставляем их в матрицы for (int i = 1; i < csv.size(); i++) { String line = csv.get(i); String[] str = line.split(","); trainData.put(i - 1, 0, new float[]{Float.valueOf(str[0]), Float.valueOf(str[1]), Float.valueOf(str[2])}); labels.put(i - 1, 0, new int[]{Integer.valueOf(str[3]) > offset ? 1 : 0}); } // тренируем и тестируем модель // 1-й параметр: входная модель без класса // 2-й параметр: тип входных данных (колонки(0) или строки(1)) // 3-й параметр: значения для входных данных // tree.train(trainData, 1, labels); // 8-й параметр: параметры дерева tree.train(trainData, 1, labels, new Mat(), new Mat(), new Mat(), new Mat(), params); testModel(tree, offset); } } private static List loadFile(String fileName) throws IOException { return Files.readAllLines(Paths.get(fileName)); } private static void testModel(CvRTrees tree, int offset) { System.out.println("!!!!! Test model with count of fires more than " + offset + "!!!!!"); //пример. номер примера, температура, влажность, сила ветра testExample(tree, offset, 1, 28, 0.20f, 3); testExample(tree, offset, 2, 28, 0.90f, 3); testExample(tree, offset, 3, 35, 0.80f, 3); testExample(tree, offset, 4, 20, 0.80f, 3); testExample(tree, offset, 5, 25, 0.70f, 1); testExample(tree, offset, 6, 25, 0.70f, 6); System.out.println("!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"); } private static void testExample(CvRTrees tree, int offset, int number, float temp, float humidity, float wind) { Mat ex = new Mat(1, 3, CvType.CV_32F); ex.put(0, 0, new float[]{temp, humidity, wind}); System.out.println("Example " + number + "(count of fires -> " + offset + "): " + ex.dump()); // предсказываем событие. 1 - событие произойдет // в нашем случае означает, что произойдет число пожаров System.out.println(tree.predict(ex)); // вероятность события (появления 1) System.out.println(tree.predict_prob(ex)); } }

Комментариев нет:

Отправить комментарий