我的Java代码中的Weka-使用StringToWordVector进行文本分类似乎不起作用

我的Java代码中的Weka-使用StringToWordVector进行文本分类似乎不起作用,java,text,weka,categorization,Java,Text,Weka,Categorization,我是文本分类的新手,我正尝试使用weka建立一个基于单个术语和n-gram以及相关tf idf的决策树,根据其中包含的观点,将一些文本分类为肯定类或否定类。这是文本分类的一项特殊任务,通常被称为“情感分类”。 所以我找到了很多关于这个话题的有趣的指南。 我试图在一个标记的训练集上使用J48,使用StringToOrdVector过滤器,使用tf idf转换,并使用NGramWordTokenizer标记训练集语料库的输入文档 public class TextIndexer { public

我是文本分类的新手,我正尝试使用weka建立一个基于单个术语和n-gram以及相关tf idf的决策树,根据其中包含的观点,将一些文本分类为肯定类或否定类。这是文本分类的一项特殊任务,通常被称为“情感分类”。 所以我找到了很多关于这个话题的有趣的指南。 我试图在一个标记的训练集上使用J48,使用StringToOrdVector过滤器,使用tf idf转换,并使用NGramWordTokenizer标记训练集语料库的输入文档

public class TextIndexer {

public static final int TFIDF=1;
public static final int TF=2;
public static final int BOW=3;

private static String sourceDirectory;
private static Instances inputInstances;
private static WordTokenizer singleWordTokenizer;
private static NGramTokenizer nGramTokenizer;
private static StringToWordVector wv;
private static boolean ngram;
private static int minOccSingleWords;
private static int minOccNGrams;

public TextIndexer (String fileDir) throws IOException {
    BufferedReader reader = new BufferedReader(new FileReader(fileDir));
    ArffReader arff = new ArffReader(reader);

    inputInstances = arff.getData();

    reader.close();
    minOccSingleWords=minOccNGrams=2;
    ngram=false;
    tdl=new TextDirectoryLoader();
    wv=new StringToWordVector();
    singleWordTokenizer = new WordTokenizer();

    defaultConfig();
    }

private static final void defaultConfig() {
    singleWordTokenizer.setDelimiters("\\W");
    wv.setDoNotOperateOnPerClassBasis(true);
    wv.setUseStoplist(false);
    wv.setLowerCaseTokens(true);
    wv.setWordsToKeep(1000000);
    wv.setIDFTransform(true);
}
因此,在TextIndexer中,我有一些方法来设置出现的最小次数、用于功能的权重,以最终启用ngrams,等等

我在我的主类中调用TextIndexer,它使用方法toWordVector基于过滤的实例构建J48:

public  Instances toWordVector() throws NullPointerException {
    try {
        wv.setInputFormat(inputInstances);
        System.out.println(inputInstances.numInstances());
        wv.setTokenizer(singleWordTokenizer);
        wv.setMinTermFreq(minOccSingleWords);
        Instances i = Filter.useFilter(inputInstances, wv);
        System.out.println(i);
            //i.setClass(i.attribute("class"));

        if(ngram) {
            wv.setInputFormat(inputInstances);
            wv.setTokenizer(nGramTokenizer);
            wv.setMinTermFreq(minOccNGrams);
            Instances i2 = Filter.useFilter(inputInstances, wv);
            i2.deleteAttributeAt(0);
            for(int ie=0;ie<i2.numAttributes();ie++)
            System.out.println(i2.attribute(ie));
            i= Instances.mergeInstances(i, i2);
        }

        i.setClassIndex(0);
        return i;


    } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        throw new NullPointerException("Cannot find instances from selected source file");
    }

}
好吧,我的分类器已经构建好了。 现在,我试图用它来对一些文本进行分类,所以我使用从训练集中保留的10个文本(5个正文本,5个负文本),创建一个带有两个属性的arff文件:文档(类型字符串)和类(正文本或负文本),将数据设置为类“?”

当我尝试使用classifyInstance(实例I)时,结果总是0.0(或正)。这是分类代码,在我的主要课程中使用:

Instances unlabeled = new Instances(new BufferedReader(
                new FileReader("C:/Users/Honestus_/Desktop/TRAINING SET WEKA/TEST.arff")));
// set class attribute
unlabeled.setClassIndex(unlabeled.numAttributes() - 1);
// create copy
Instances labeled = new Instances(unlabeled);
// label instances
for (int i = 0; i < unlabeled.numInstances(); i++) {
double clsLabel = tree.classifyInstance(unlabeled.instance(i));
labeled.instance(i).setClassValue(clsLabel);
}
实例未标记=新实例(新BufferedReader(
新的文件阅读器(“C:/Users/Honestusè/Desktop/TRAINING SET-WEKA/TEST.arff”);
//设置类属性
未标记的.setClassIndex(未标记的.numAttributes()-1);
//创建副本
已标记的实例=新实例(未标记);
//标签实例
for(int i=0;i
正如您所看到的,这部分代码与。发生了什么?我也尝试过使用FilteredClassifier,但没什么区别。 我读过一些类似的问题,答案谈到了训练集中的一些错误。我使用的培训集是:,使用“服装”类别的1000条正面评论和1000条负面评论

我希望我的问题很清楚,谢谢

Instances unlabeled = new Instances(new BufferedReader(
                new FileReader("C:/Users/Honestus_/Desktop/TRAINING SET WEKA/TEST.arff")));
// set class attribute
unlabeled.setClassIndex(unlabeled.numAttributes() - 1);
// create copy
Instances labeled = new Instances(unlabeled);
// label instances
for (int i = 0; i < unlabeled.numInstances(); i++) {
double clsLabel = tree.classifyInstance(unlabeled.instance(i));
labeled.instance(i).setClassValue(clsLabel);
}