我正在尝试使用Weka java API进行文档分类。
这是我的数据文件的目录结构。
+- text_example
|
+- class1
| |
| 3 html files
|
+- class2
| |
| 1 html file
|
+- class3
|
3 html files
我使用'TextDirectoryLoader'创建了'arff'文件。然后我在创建的arff文件上使用StringToWordVector
过滤器,filter.setOutputWordCounts(true)
。
下面是应用滤镜后的输出示例。我需要澄清一些事情。
@attribute </form> numeric
@attribute </h1> numeric
.
.
@attribute earth numeric
@attribute easy numeric
这个巨大的列表应该是初始html文件内容的标记化。正确?
然后我有,
@data
{1 2,3 2,4 1,11 1,12 7,..............}
{10 4,34 1,37 5,.......}
{2 1,5 6,6 16,...}
{0 class2,34 11,40 15,.....,4900 3,...
{0 class3,1 2,37 3,40 5....
{0 class3,1 2,31 20,32 17......
{0 class3,32 5,42 1,43 10.........
为什么前3项没有类属性? (它应该有class1)。 前导0表示在{0 class2,..},{0 class3 ..}中的含义。 例如,它表示在class3文件夹的第3个html文件中,由整数32标识的单词出现5次。只是为了看看如何得到由32引用的单词(标记)?
如何减少特征向量的维数?我们不需要使所有的特征向量大小相同吗? (比如只考虑训练集中最常用的100个术语,以及以后在测试时,考虑在测试文档中只出现那100个术语。因为这样,如果我们想出一个全新的词会发生什么在测试阶段,分类器会忽略它吗?)。
我在这里遗漏了什么吗?我是Weka的新手。
如果有人能解释我分类器如何使用StringToWordVector
过滤器创建的向量,我真的很感激帮助。 (比如用训练数据创建词汇表,减少维数,那些是在Weka代码中发生的吗?)
答案 0 :(得分:8)
@attribute
的巨大列表包含从您的输入中派生的所有令牌。@data
部分采用稀疏格式,即每个属性,只有在与零不同时才会声明该值。对于前三行,class属性是class1,你只是看不到它(如果它是未知的,你会在前三行的开头看到0 ?
)。为什么会这样? Weka在内部将名义属性(包括类)表示为双精度,并从零开始计数。所以你的三个类是内部的:class1 = 0.0,class2 = 1.0,class3 = 2.0。由于零值未以稀疏格式声明,因此您无法在前三行中看到该类。 (另请参阅http://www.cs.waikato.ac.nz/ml/weka/arff.html)Instances
对象,则可以在其上调用attribute(n).name()
。为此,n
从0开始计数。stringToWordVector.setWordsToKeep(100)
。请注意,这将尝试保留每个类的100个单词。如果您不想每班保留100个单词,stringToWordVector.setDoNotOperateOnPerClassBasis(true)
。如果有多个具有相同频率的单词,您将略高于100,因此100只是一种目标值。stringToWordVector
所有实例交给他们。我对这一点并不是100%肯定,因为我正在使用两个类的设置,我让StringToWordVector
转换我的所有实例,然后再告诉分类器。 我通常可以向您推荐,尝试使用Weka KnowledgeFlow工具来学习如何使用不同的类。如果您知道如何在那里做事,那么您可以非常轻松地将这些知识用于Java代码。 希望我能帮助你,虽然答案有点晚。