Java 在具有内部数据结构的Weka中使用StringToWordVector
我正在尝试使用Weka获得文档聚类。这个过程是一个更大管道的一部分,我真的负担不起编写arff文件。我将所有文档和每个文档中的单词包作为Java 在具有内部数据结构的Weka中使用StringToWordVector,java,machine-learning,nlp,cluster-analysis,weka,Java,Machine Learning,Nlp,Cluster Analysis,Weka,我正在尝试使用Weka获得文档聚类。这个过程是一个更大管道的一部分,我真的负担不起编写arff文件。我将所有文档和每个文档中的单词包作为Map结构,其中键是文档名称,Multiset值是文档中的单词包。我有两个问题,真的: (1)当前的方法最终是对术语进行聚类,而不是对文档进行聚类: public final Instances buildDocumentInstances(TreeMap<String, Multiset<String>> docToTermsMap,
Map
结构,其中键是文档名称,Multiset
值是文档中的单词包。我有两个问题,真的:
(1)当前的方法最终是对术语进行聚类,而不是对文档进行聚类:
public final Instances buildDocumentInstances(TreeMap<String, Multiset<String>> docToTermsMap, String encoding) throws IOException {
int dimension = TermToDocumentFrequencyMap.navigableKeySet().size();
FastVector attributes = new FastVector(dimension);
for (String s : TermToDocumentFrequencyMap.navigableKeySet()) attributes.addElement(new Attribute(s));
List<Instance> instances = Lists.newArrayList();
for (Map.Entry<String, Multiset<String>> entry : docToTermsMap.entrySet()) {
Instance instance = new Instance(dimension);
for (Multiset.Entry<String> ms_entry : entry.getValue().entrySet()) {
Integer index = TermToIndexMap.get(ms_entry.getElement());
if (index != null)
switch (encoding) {
case "tf":
instance.setValue(index, ms_entry.getCount());
break;
case "binary":
instance.setValue(index, ms_entry.getCount() > 0 ? 1 : 0);
break;
case "tfidf":
double tf = ms_entry.getCount();
double df = TermToDocumentFrequencyMap.get(ms_entry.getElement());
double idf = Math.log(TermToIndexMap.size() / df);
instance.setValue(index, tf * idf);
break;
}
}
instances.add(instance);
}
Instances dataset = new Instances("My Dataset Name", attributes, instances.size());
for (Instance instance : instances) dataset.add(instance);
return dataset;
}
public final Instances buildDocumentInstances(TreeMap docToTermsMap,字符串编码)抛出IOException{
int dimension=TermToDocumentFrequencyMap.navigableKeySet().size();
FastVector属性=新的FastVector(维度);
对于(字符串s:TermToDocumentFrequencyMap.navigableKeySet())attributes.addElement(新属性);
List instances=Lists.newArrayList();
对于(Map.Entry:docToTermsMap.entrySet()){
实例实例=新实例(维度);
对于(Multiset.Entry ms_Entry:Entry.getValue().entrySet()){
整数索引=TermToIndexMap.get(ms_entry.getElement());
如果(索引!=null)
开关(编码){
案例“tf”:
setValue(index,ms_entry.getCount());
打破
“二进制”情况:
setValue(索引,ms_entry.getCount()>0?1:0);
打破
“tfidf”案:
double tf=ms_entry.getCount();
double df=TermToDocumentFrequencyMap.get(ms_entry.getElement());
double idf=Math.log(TermToIndexMap.size()/df);
实例.setValue(索引,tf*idf);
打破
}
}
实例。添加(实例);
}
实例数据集=新实例(“我的数据集名称”,属性,Instances.size());
例如(实例实例:实例)dataset.add(实例);
返回数据集;
}
我试图创建单个实例
对象,然后通过将它们添加到实例
对象来创建数据集。每个实例都是一个文档向量(使用0/1、tf或tf idf编码)。此外,每个单词都是一个单独的属性。但是当我运行SimpleKMeans#buildcluster
时,输出显示它是在对单词进行聚类,而不是对文档进行聚类。我显然做错了一些可怕的事情,但我不知道那是什么错误
(2)如何在此场景中使用StringToOrdVector?
在我看过的每一处地方,人们都建议使用
weka.filters.unsupervised.attribute.StringToWordVector
对文档进行聚类。但是,我找不到任何可以从文档-->单词包结构中提取单词的示例。[注意:在我的情况下,这是一个MAPI如果你无法将数据写入.arff
文件,请不要使用Weka。这样你也就无法使用Weka了……事实证明,我问题的第一部分与此无关:我误解了集群输出。我现在可以在没有任何.arff文件的情况下使用Weka。这只是让人惊讶告诉我像StringToWordVector
这样的类是如此的不灵活和不透明(我试着理解源代码,但要弄清楚到底发生了什么并不容易)。NLP的大部分依赖于词性标记、PCFG解析树等过程。Weka的当前设计迫使所有此类工作求助于其他工具。这真是太遗憾了,因为他们构建了一个优秀的资源!使用多个工具没有错。我总是将预处理与分析分开进行,以这不是一个更灵活的过程。无法达成更多一致意见…因此投票结果:-)