解释StringToWordVector()的输出 - Weka

时间:2012-04-18 18:51:36

标签: java text machine-learning classification weka

我正在尝试使用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代码中发生的吗?)

1 个答案:

答案 0 :(得分:8)

  1. @attribute的巨大列表包含从您的输入中派生的所有令牌。
  2. 您的@data部分采用稀疏格式,即每个属性,只有在与零不同时才会声明该值。对于前三行,class属性是class1,你只是看不到它(如果它是未知的,你会在前三行的开头看到0 ?)。为什么会这样? Weka在内部将名义属性(包括类)表示为双精度,并从零开始计数。所以你的三个类是内部的:class1 = 0.0,class2 = 1.0,class3 = 2.0。由于零值未以稀疏格式声明,因此您无法在前三行中看到该类。 (另请参阅http://www.cs.waikato.ac.nz/ml/weka/arff.html
  3. 上的“稀疏ARFF文件”部分
  4. 要获取由索引n表示的单词/标记,您可以计算,或者,如果您有Instances对象,则可以在其上调用attribute(n).name()。为此,n从0开始计数。
  5. 要减少特征向量的维数,有很多选项。如果您只想拥有100个最常用的字词,则为stringToWordVector.setWordsToKeep(100)。请注意,这将尝试保留每个类的100个单词。如果您不想每班保留100个单词,stringToWordVector.setDoNotOperateOnPerClassBasis(true)。如果有多个具有相同频率的单词,您将略高于100,因此100只是一种目标值。
  6. 至于在测试阶段出现的新单词,我认为这不可能发生,因为你必须在分类前将stringToWordVector所有实例交给他们。我对这一点并不是100%肯定,因为我正在使用两个类的设置,我让StringToWordVector转换我的所有实例,然后再告诉分类器。
  7. 我通常可以向您推荐,尝试使用Weka KnowledgeFlow工具来学习如何使用不同的类。如果您知道如何在那里做事,那么您可以非常轻松地将这些知识用于Java代码。 希望我能帮助你,虽然答案有点晚。