2012-08-28 24 views
12

que entrenó a un clasificador IBK con un poco de datos de entrenamiento que he creado manualmente de la siguiente manera:weka.core.UnassignedDatasetException al crear una instancia sin etiqueta

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)); 

Entonces me ayudan a reconstruir el clasificador:

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

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

Quiero crear una nueva instancia con la clase no etiquetada y clasificar esta instancia, intenté lo siguiente sin suerte.

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(); 
} 

acabo obtienen los siguientes errores

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) 

parece que yo estoy haciendo algo mal mientras se crea una nueva instancia. ¿Cómo puedo crear una instancia sin etiqueta exactamente?

Gracias de antemano

Respuesta

12

El problema es con esta línea:

double classif = ibk.classifyInstance(newInst); 

Cuando intenta clasificar newInst, Weka emite una excepción porque newInst tiene Referencia No instancias (es decir, el conjunto de datos) asociada a ella - por lo tanto, no sabe nada sobre su atributo de clase.

primer lugar, debe crear una nueva instancias de objeto similar a la dataRaw, añadir la instancia sin etiqueta a ella, índice de clase establecido, y sólo entonces intentar clasificarlo, por ejemplo:

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

bro su respuesta es truco. He dado una respuesta que es apropiada con respecto a la documentación weka –

+0

@TaimoorChangaiz ¿por qué esta respuesta es un truco? – Clocker

+0

@ k29 porque no está de acuerdo con la documentación. La documentación sugiere la forma correcta de hacerlo. –

-1

Ver páginas 203 - 204 de la documentación WEKA. ¡Eso me ayudó mucho! (El Manual de Weka es un archivo pdf que se encuentra en su carpeta de instalación de weka. Simplemente abra doucmentation.html y lo dirigirá al manual en pdf.)

Copiando y pegando algunos fragmentos de las listas de códigos del Capítulo 17 (Usar la API de WEKA/Crear conjuntos de datos en la memoria) debería ayudarlo a resolver la tarea.

+0

Esto es esencialmente una [respuesta solo de enlace] (http://stackoverflow.com/help/how-to-answer), aunque el enlace es una referencia a la documentación. Proporcione algún contexto (es decir, qué dice en las páginas 203-204) de modo que si la documentación cambia en el futuro, esta respuesta sigue siendo útil – Cecilia

+0

Tiene razón. El caso es que ya no recuerdo.Recuerdo que, en primer lugar, mi problema era encontrar el manual de WEKA; no era tan obvio que estuviera en la carpeta de instalación del programa (lo estaba buscando en el sitio web, pero tal vez ahora su ubicación se hace más obvia). Así que pensé que podría ser útil mencionar dónde está el manual. Porque antes estaba tratando de leer los javadocs y lidiar con fragmentos de código incompletos de los foros, esto nunca conduce a una solución. Sin embargo, una vez que encontré el manual, pude resolver todos los problemas, realmente vale la pena echarle un vistazo. – ndrizza

10

Aparecerá este error cuando clasifique una nueva instancia que no esté asociada a un conjunto de datos. Debe asociar cada nueva instancia que cree a un objeto Instances utilizando 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); 

Después de esto, puede clasificar la instancia recién creada.

double classif = ibk.classifyInstance(newInst); 

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

Detailed Implementation Link

+0

Esta es la mejor respuesta porque puede usar 'Instance' directamente en lugar de usar la función' Instances.firstInstance() '. Agregué un poco más de contexto al código para aclarar cómo usar este enfoque si necesitas crear una nueva 'Instancia'. – Cecilia

+0

Gracias, esta es de hecho la respuesta correcta :) –

Cuestiones relacionadas