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

1,00
р.
У меня есть таблица с данными о погоде и количестве лесных пожаров в некоторые дни в некотором регионе:
Температура | Влажность | Скорость ветра | ... | Количество лесных пожаров
Все данные представлены в виде чисел.
Требуется по этим данным построить дерево решений, и, с помощью него и входных параметров (температура, влажность, скорость ветра, и т.д.) спрогнозировать количество лесных пожаров.
Для работы с деревьями решений в OpenCV есть класс CvDTree. Для построения дерева решений в данном классе есть метод train:
boolean train(Mat trainData, int tflag, Mat responses)
Как (каким образом и в каком порядке) преобразовать мои входные данные в Mat trainData?
Возможно, отвечающему поможет обсуждение по этой ссылке

Ответ
Сделал небольшой пример (можно посмотреть тут 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)) }
}