垃圾分类任务中奇怪的FANN行为
我尝试用FANN库写一个简单的垃圾邮件分类器。为此,我收集了一些垃圾邮件和正常邮件,并整理了一个常用英语单词的词典。
我创建了一个有一个隐藏层的神经网络,代码如下:
num_input = get_input_size(dictionary_size)
num_output = 1
ann.create_standard_array((num_input, num_neurons_hidden, num_output))
ann.set_activation_function_hidden(libfann.SIGMOID_SYMMETRIC)
ann.set_activation_function_output(libfann.SIGMOID_SYMMETRIC)
ann.set_training_algorithm(libfann.TRAIN_INCREMENTAL)
当邮件是正常邮件时,输出为1;当邮件是垃圾邮件时,输出为-1。每个输入神经元表示某个特定单词是否出现在邮件中(1表示这个单词在邮件里,0表示不在)。
为了训练这个神经网络,我使用了以下代码。 (针对训练集中的每封邮件)
# Create input from train e-mail letter
input = get_input(train_res, train_file, dictionary)
ann.train(input, (train_res,))
要检查测试集中的一封邮件是否是垃圾邮件,我使用了以下代码: (针对测试集中的每封邮件)
input = get_input(SPAM, test_spam, dictionary)
res = ann.run(input)[0]
但是无论我使用多大的词典(我尝试过从1000个单词到40000个单词)或者隐藏层中的神经元数量(从20到640),训练完成后我的网络几乎总是认为所有邮件都是垃圾邮件或正常邮件。例如,我得到的结果可能是这样的:
Dictionary size: 10000
Hidden layer size: 80
Correctly classified hams: 596
Incorrectly classified hams: 3845
Correctly classified spams: 436
Incorrectly classified spams: 62
几乎所有的垃圾邮件都被正确分类,但所有的正常邮件都被错误分类,或者结果是这样的:
Dictionary size: 20000
Hidden layer size: 20
Correctly classified hams: 4124
Incorrectly classified hams: 397
Correctly classified spams: 116
Incorrectly classified spams: 385
这正好相反。
我尝试使用更多的训练数据。一开始我用大约1000封邮件进行训练(垃圾邮件和正常邮件的比例几乎是50:50),现在我用大约4000封邮件进行测试(垃圾邮件和正常邮件的比例也是大约50:50),但结果还是一样。
可能的问题是什么呢?谢谢!
2 个回答
我对FANN了解不多,但在垃圾邮件分类中,训练的方式非常重要。首先:不要先训练所有的正常邮件再训练所有的垃圾邮件。应该把它们混在一起,最好是随机挑选一封邮件来训练,无论它是正常邮件还是垃圾邮件。
除此之外,还有很多不同的方法来决定分类器是否应该对某个特定的消息进行训练。例如,如果分类器已经认为一封邮件是垃圾邮件,然后你又把它当作垃圾邮件来训练,这可能会导致它对那封邮件中的某些词产生不必要的偏见。
可能的训练方式包括(但不限于):
TEFT(训练所有内容)
把所有邮件都训练一遍。通常这不是一个好的选择。
TOE(错误训练)
只对分类器判断错误的邮件进行训练。
TTR(厚阈值训练)
对分类器判断错误的邮件,或者处于“厚阈值”范围内的邮件进行训练。例如,如果低于0.0的邮件都是垃圾邮件,那么就对所有被分类为-0.05到0.05之间的邮件进行训练。
TUNE(训练直到没有错误)
重复进行TOE或TTR,直到分类器能正确分类所有训练邮件。这可能有帮助,但也可能有害,这取决于你的训练数据。
这些方法都有一些变体,但厚阈值训练通常能得到不错的结果:因为它不会训练每一封邮件,所以对那些出现在垃圾邮件中但实际上对正常/垃圾邮件判断没有帮助的词(比如Niclas提到的贝叶斯中毒)偏见较小。而且因为它训练的是边缘案例,即使在训练时正确分类了这些邮件,它也能在实际使用中更好地处理这些边缘案例,不容易被它们欺骗。
最后补充一句:我假设你是在使用神经网络来学习更多相关知识,但如果你真的需要过滤垃圾邮件,朴素贝叶斯或Winnow算法通常更合适。
你有没有确认过垃圾邮件和正常邮件在你所列的单词内容上有明显的区别?我猜,垃圾邮件和正常邮件在常见单词的内容上可能没有特别明显的差别。
如果你使用的是“真实”的垃圾邮件,很多垃圾邮件发送者会用一种叫贝叶斯中毒的手段,他们会在邮件中加入很多“合法”的文本,以此来混淆垃圾邮件过滤器。因为你只是根据常见单词的内容来过滤,而不是根据那些在垃圾邮件和正常邮件中统计上常见的单词,所以你这种方法会对贝叶斯中毒非常敏感。