我正在尝试使用weka来分类垃圾邮件和非垃圾邮件。
我们使用stringtowordvector
作为过滤器来训练分类器,其中包含数以千计的标记垃圾邮件,以及另外100个标记为非垃圾邮件的100个标记垃圾邮件。 crossValidateModel
的结果非常好。但我想使用一个独立的测试集来评估分类器,以确保将任何其他msg分类到训练集之外是可靠的。
我的问题:
我也必须在测试数据集上使用stringtowordvector
来创建独立的.arff文件,该文件独立于训练arff文件。两个数据集中出现的相同单词有2个这两个.arff文件中分别有不同的属性索引。例如,单词“money”在训练.arff文件中具有矩阵索引10
,但在测试.arff文件中,它被索引为50th
属性。
我担心已经训练好的分类器会使2个数据集中的所有这些单词不匹配,因为它们具有不同的矩阵索引。更具体地说,训练中的向量{1 1,2 1,3 5}
.arff代表"i want to to to to to...."
,但在测试.arff文件中,此相同的向量表示"money does not not not not ....."
。那么,这种验证如何可靠?
使用crossValidateModel
,它使用同一个arff文件中的实例,因此weka必须正确匹配索引和单词。我的目标是使用大量标记数据集对其进行训练,然后使用它对任何单个未标记的msg进行分类。每次我想要对一个单一的msg进行分类时,我必须将这个msg转换为.arff文件,该文件具有与训练.arff文件完全不同的属性列表和矩阵索引。 (我没有使用Windows工具,我在我的程序中使用了weka .jar api)。
有什么帮助吗?
答案 0 :(得分:0)
您需要从火车集创建一个功能映射文件,以实现您想要的效果。要素图文件通常采用以下格式:
someword:1
someotherword:2
yetanotherword:3
...
这有效地将每个单词映射到某个索引。所以你要做的就是遍历列车集中的所有文件,并将列车集中存在的每个单词映射到一个唯一的id,它将代表ARFF中单词的索引。
因此,假设您的火车套装中包含一个包含"i want to to to to to make money"
字样的文件,那么您的功能图就是这样的:
i:1
want:2
to:3
make:4
money:5
你的ARFF中的属性看起来像这样:
@ATTRIBUTE i NUMERIC
@ATTRIBUTE want NUMERIC
@ATTRIBUTE to NUMERIC
@ATTRIBUTE make NUMERIC
@ATTRIBUTE money NUMERIC
每个属性代表单词在电子邮件中显示的次数。
然后,如果您想为测试集制作ARFF,您将迭代测试集中的所有文件以及您遇到的每个单词,请在功能图中查找。如果单词位于要素图中,则您知道要在该单词映射到的索引处递增属性的值。如果单词不在您的要素图中,则忽略它,因为您的分类器没有经过单词训练,甚至不知道单词是否存在。
这将保持您的列车集的属性以及您完全对齐的任何测试集。
我建议您在功能映射文件中读取从单词{HashMap<String, Integer>
)到属性索引(String
)的Java Integer
映射,以便在获取时快速查找单词测试集电子邮件的属性值。