Перекрестная проверка в Weka с использованием предопределенных сверток

Я хочу запустить 10-кратный эксперимент с перекрестной проверкой / тестированием с использованием Weka для набора данных, который уже разделен на 10 складок (т.е. каждый экземпляр уже выделен в свертку). Я знаю, что если вы дадите Weka полный набор данных, он может создать для вас свертки и запустить 10-кратное резюме, но есть ли способ указать ему, какие экземпляры должны принадлежать какой свертке, кроме ручного разделения набора данных на 10 поездов / test sets и запускать каждый из 10 экспериментов независимо?

Спасибо


person jjs    schedule 01.04.2014    source источник


Ответы (1)


Будете ли вы использовать Java? Здесь приводится простой пример обучения и оценки классификаторов с использованием интерфейса Java: http://www.programcreek.com/2013/01/a-simple-machine-learning-example-in-java/

Первый шаг - создание разделений:

// Do 10-split cross validation
Instances[][] split = crossValidationSplit(data, 10);

// Separate split into training and testing arrays
Instances[] trainingSplits = split[0];
Instances[] testingSplits = split[1];

А затем выполните типичное обучение / оценку:

// For each training-testing split pair, train and test the classifier
for (int i = 0; i < trainingSplits.length; i++) {
    Evaluation validation = classify(models[j], trainingSplits[i], testingSplits[i]);

    predictions.appendElements(validation.predictions());
}

Напротив, в некоторых из моих предыдущих кодов для получения этих наборов экземпляров использовались функции _3 _ / _ 4_. Вы можете написать новую функцию, возвращающую эти подмножества данных для ваших известных сверток.

Возможно, исходный код Instances.trainCV является хорошим примером того, как создавать наборы экземпляров: http://grepcode.com/file/repo1.maven.org/maven2/nz.ac.waikato.cms.weka/weka-stable/3.6.7/weka/core/Instances.java

Ключевые строки - это звонки на copyInstances.

copyInstances(0, train, first);
copyInstances(first + numInstForFold, train,
      numInstances() - first - numInstForFold);
return train;

Возможно, также можно просто создать пустые экземпляры с помощью new Instances(java.lang.String name, java.util.ArrayList<Attribute> attInfo, int capacity) и заполнить с помощью Instances.get из надмножества всех экземпляров.

Другой способ - использовать фильтр, как в следующем отрывочном примере, когда я тренировал несколько классификаторов с одинаковыми разбиениями (в Matlab / java):

filterRand = Randomize();
filterRange = RemoveRange();

%if the filterInst parameter is active, take a subsample of training
if doFilterTrain
    rangeStr = sprintf('%g-%g', 1, learnParams.trainSizeMax );
    filterRange.setInstancesIndices( rangeStr );
    filterRange.setInvertSelection( 1 );
end

if doFilterTrain
    filterRand.setInputFormat( instTrain );
    filterRange.setInputFormat( instTrain );

    instTrainSub = Filter.useFilter(instTrain, filterRand);
    instTrainSub = Filter.useFilter(instTrainSub, filterRange);
end

Удачи!

person Graham    schedule 01.04.2014
comment
На самом деле я использую python (да, я знаю, что должен использовать scikitlearn, в конце концов я доберусь до этого). В основном мой вопрос был в том, есть ли простой способ сообщить Weka, где находятся складки, а не писать свою собственную функцию trainCV. Если его нет, я могу просто использовать python для создания 10 разделов поездов / тестов и запускать Weka для каждого разделения по отдельности, я думаю .. - person jjs; 02.04.2014
comment
Указания экземпляров для обучения / тестирования должно быть достаточно, чтобы сообщить Weka, где находятся складки, и самостоятельно провести обучение / оценку. С вашей точки зрения, это больше для управления (на самом деле, это было больно), но это единственный способ, который я знаю (какое-то время я не использовал Weka). - person Graham; 02.04.2014