2012-08-28 12 views
12

Trenowałem sortownika IBK z niektórych danych uczących, który został utworzony ręcznie, jak następuje:weka.core.UnassignedDatasetException podczas tworzenia niewyznakowanego wystąpienie

ArrayList<Attribute> atts = new ArrayList<Attribute>(); 
ArrayList<String> classVal = new ArrayList<String>(); 
classVal.add("C1"); 
classVal.add("C2"); 
atts.add(new Attribute("a")); 
atts.add(new Attribute("b")); 
atts.add(new Attribute("c")); 
atts.add(new Attribute("d")); 
atts.add(new Attribute("@@[email protected]@", classVal)); 

Instances dataRaw = new Instances("TestInstances", atts, 0); 
dataRaw.setClassIndex(dataRaw.numAttributes() - 1); 
double[] instanceValue1 = new double[]{3,0,1,0,0}; 
dataRaw.add(new DenseInstance(1.0, instanceValue1)); 

double[] instanceValue2 = new double[]{2,1,1,0,0}; 
dataRaw.add(new DenseInstance(1.0, instanceValue2)); 

double[] instanceValue3 = new double[]{2,0,2,0,0}; 
dataRaw.add(new DenseInstance(1.0, instanceValue3)); 

double[] instanceValue4 = new double[]{1,3,0,0,1}; 
dataRaw.add(new DenseInstance(1.0, instanceValue4)); 

double[] instanceValue5 = new double[]{0,3,1,0,1}; 
dataRaw.add(new DenseInstance(1.0, instanceValue5)); 

double[] instanceValue6 = new double[]{0,2,1,1,1}; 
dataRaw.add(new DenseInstance(1.0, instanceValue6)); 

Następnie tworzyć klasyfikatora:

IBk ibk = new IBk(); 
try { 
    ibk.buildClassifier(dataRaw); 

} catch (Exception e) { 
    e.printStackTrace(); 
} 

Chcę utworzyć nową instancję z nieoznaczoną klasą i sklasyfikować to wystąpienie, próbowałem następujących bez powodzenia.

IBk ibk = new IBk(); 
try { 
    ibk.buildClassifier(dataRaw); 
    double[] values = new double[]{3,1,0,0,-1}; 
    DenseInstance newInst = new DenseInstance(1.0,values); 
    double classif = ibk.classifyInstance(newInst); 
    System.out.println(classif); 
} catch (Exception e) { 
    e.printStackTrace(); 
} 

Właśnie uzyskać następujące błędy

weka.core.UnassignedDatasetException: DenseInstance doesn't have access to a dataset! 
at weka.core.AbstractInstance.classAttribute(AbstractInstance.java:98) 
at weka.classifiers.AbstractClassifier.classifyInstance(AbstractClassifier.java:74) 
at TextCategorizationTest.instancesWithDoubleValues(TextCategorizationTest.java:136) 
at TextCategorizationTest.main(TextCategorizationTest.java:33) 

wygląda robię coś źle podczas tworzenia nowej instancji. Jak mogę dokładnie utworzyć nieopisaną instancję?

Dzięki z góry

Odpowiedz

12

Problem jest z tej linii:

double classif = ibk.classifyInstance(newInst); 

Podczas próby sklasyfikowania newInst, Weka zgłasza wyjątek, ponieważ newInst nie ma instancji obiektów (czyli zbiór danych) związanego z nim - tak więc nic nie wie o jego atrybucie klasy.

należy najpierw utworzyć nowe instancje obiekt podobny do dataRaw, dodać unlabeled instancji do niej ustawiony wskaźnik klasy, a dopiero potem próbować klasyfikując je, np:

Instances dataUnlabeled = new Instances("TestInstances", atts, 0); 
dataUnlabeled.add(newInst); 
dataUnlabeled.setClassIndex(dataUnlabeled.numAttributes() - 1);   
double classif = ibk.classifyInstance(dataUnlabeled.firstInstance()); 
+3

bro odpowiedź jest siekać. Udzieliłem odpowiedzi, która jest odpowiednia w odniesieniu do dokumentacji WEKA –

+0

@ TaimoorChangaiz dlaczego ta odpowiedź jest hackerem? – Clocker

+0

@ k29, ponieważ nie jest to zgodne z dokumentacją. Dokumentacja sugeruje właściwy sposób na zrobienie tego. –

-1

Patrz strony 203 - 204 dokumentacja WEKA. To mi bardzo pomogło! (Podręcznik Weka to plik pdf, który znajduje się w folderze instalacyjnym Weka. Wystarczy otworzyć plik doucmentation.html i wyświetli się instrukcja pliku pdf.)

Kopiowanie wklejania niektórych fragmentów wykazów kodów z rozdziału 17 (Używanie API WEKA/tworzenie zbiorów danych w pamięci) powinno pomóc w rozwiązaniu zadania.

+0

Jest to zasadniczo [link only answer] (http://stackoverflow.com/help/how-to-answer), chociaż link jest odniesieniem do dokumentacji. Podaj jakiś kontekst (tj. Co mówi na stronach 203-204), aby w razie zmiany dokumentacji w przyszłości ta odpowiedź była nadal pomocna. – Cecilia

+0

Masz rację. Chodzi o to, że już nie pamiętam.Pamiętam, że przede wszystkim moim problemem było znalezienie podręcznika WEKA - nie było tak oczywiste, że znajduje się on w folderze instalacyjnym programu (szukałem go na stronie internetowej, ale może jego lokalizacja jest teraz bardziej oczywista). Pomyślałem więc, że warto wspomnieć, gdzie jest instrukcja. Ponieważ wcześniej starałem się czytać javadoki i radzić sobie z niekompletnymi fragmentami kodu z forów - to nigdy nie prowadziło do rozwiązania. Jednak po znalezieniu instrukcji udało mi się rozwiązać każdy problem - naprawdę warto na nią spojrzeć. – ndrizza

10

Ten błąd zostanie wyświetlony podczas klasyfikowania nowej instancji, która nie jest powiązana z zestawem danych. Musisz powiązać każdą nowo utworzoną instancję z obiektem Instances, używając setDataset.

//Make a place holder Instances 
//If you already have access to one, you can skip this step 
Instances dataset = new Instances("testdata", attr, 1); 
dataset.setClassIndex(classIdx); 

DenseInstance newInst = new DenseInstance(1.0,values); 

//To associate your instance with Instances object, in this case dataset 
newInst.setDataset(dataset); 

Po tym można klasyfikować nowo utworzone wystąpienie.

double classif = ibk.classifyInstance(newInst); 

http://www.cs.tufts.edu/~ablumer/weka/doc/weka.core.Instance.html

Detailed Implementation Link

+0

To jest najlepsza odpowiedź, ponieważ można bezpośrednio użyć 'Instance' zamiast używać funkcji' Instances.firstInstance() '. Dodałem nieco więcej kontekstu do kodu, aby wyjaśnić, jak używać tego podejścia, jeśli trzeba utworzyć nowe "wystąpienia". – Cecilia

+0

Dzięki, to jest rzeczywiście poprawna odpowiedź :) –

Powiązane problemy