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