基于汉字字频特征实现99.99%准确率的新闻文本分类器(四)



基于汉字字频特征实现99.99%准确率的新闻文本分类器(一)

基于汉字字频特征实现99.99%准确率的新闻文本分类器(二)

基于汉字字频特征实现99.99%准确率的新闻文本分类器(三)

基于汉字字频特征实现99.99%准确率的新闻文本分类器(四)

基于汉字字频特征实现99.99%准确率的新闻文本分类器(五)

回顾

上一节中,使用五层神经网络,对抽取出的汉字字频特征向量进行分类,得到了超过99%的准确率,在高准确率的前提下,没有陷入局部最优解,对一些在训练中,被指定了上千次不是军事类的新闻,只要内容是军事类的,就能被正确的找出,同样,混在军事类新闻里的【慈善捐款】等非军事的新闻,虽然被教育了数千次是军事类的,最终也没有被五层神经网络认定为军事类的。

从某种意义上讲,五层神经网络好像是真的理解了军事类新闻的涵义一样。

他/她是怎么做到的呢?本节,将先从前面的开源代码分析入手,一探究竟。

数据清洗

源码里有对新闻文字的简单数据清洗。即对某些页面上残留的汉字污染到了新闻文本本身进行排除。例如如下正则表达式

1
2
3
4
System.Text.RegularExpressions.Regex reg2 = new System.Text.RegularExpressions.Regex(
     "共找到([\\d,\\s]+)个相关网页" ,
     System.Text.RegularExpressions.RegexOptions.Singleline |
     System.Text.RegularExpressions.RegexOptions.Compiled);

它是对搜索页面返回的汉字的清除。有趣的是,在我的第一版的实现中连这个清洗的步骤也是没有的,我根本没有兴趣去看每一个新闻文本,因为有八万个之多。所以,原来我本不知道有这些污染的数据。那么我是如何定位到它呢?并知道清除这些文本?在《提高》中,将会描述这个有趣的事。

字频特征抽取

在第二节的PreData项目中,有一个outzp.txt的资源文件,里面是统计的常用汉字在新闻资讯中出现的次数。

可以看到,【的|是|在|有】等常见汉字的出现次数,是非常高的。

在函数GetZiPin中,使用新闻文本的汉字部分的频率,即一个汉字对应此新闻文本的所有汉字的百分比作为字频特征。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
public static float [] GetZiPin( string str, int keycount)
{
     float [] res = new float [keycount];
     if (str == null || keycount > zps.Length)
         return res;
     System.Collections.Generic.Dictionary< string , int > dsi = new Dictionary< string , int >();
     var avcount = 0;
     foreach ( var k in str)
     {
         if ( char .GetUnicodeCategory(k) == System.Globalization.UnicodeCategory.OtherLetter)
         {
             var ks = k.ToString();
             if (dsi.ContainsKey(ks))
                 dsi[ks]++;
             else
                 dsi[ks] = 1;
             avcount++;
         }
     }
     for ( int i = 0; i < keycount; i++)
     {
         if (dsi.ContainsKey(zps[i].ch))
         {
             res[i] = dsi[zps[i].ch] * 1000f / avcount;
             res[i] = res[i] / zps[i].zipin / 2;
         }
     }
     return res;
}

此函数返回了一段新闻文本的1000多个常见汉字的字频数组。这是一个关键点,我没有使用全部3000多个常用汉字,而是使用了Top 1000个常见汉字,这可以减少特征向量的大小,加快训练的速度,因为输入向量比较大的时候,多层神经网络和SVM消耗的内存将会大幅增加,训练时间也会大幅增加。但是,这个向量是不能直接用作SVM或者神经网络的输入数据进行处理的。因为,特征向量还要做一步“归一化”。归一化的本质是公平的对待每一个输入,不人为改变任何汉字在特征向量中的权重

所以,特征向量的提取,是分两个阶段组成。第一个阶段,统计出每个汉字在每一个文章的频率数据,第二个阶段进行归一化。

1
2
3
var fi = textzipin.GetZiPin(txt, weishu);
for ( int t = 0; t < mms.Length; t++)
     fi[t] = fi[t] / mms[t].fmax;

归一化后,特征向量里的每个汉字的字频,被调整为从0到1的浮点数。(有两种归一化方法,一种是归一化到0-1之间,还有一种是归一化到 【-1 1】之间。在本文中,我采用0-1范围)

PreData小结

PreData项目比较短小,包含标准的命名空间代码,总共才200行左右。功能也比较单一,抽取所有八万个文本的常见汉字字频,并归一化,保存到数据文件中。数据文件中部分数据如下所示。


此处数据换行有问题,所以显示不对。


首列为0的,是搜狗文本分类语料库中非军事的新闻资讯,首列为1的,是军事类的新闻资讯。可以看到,这些资讯的文本特征,都是一个1024维的向量,每个向量最大值为1,最小值为0,多数都位于0-1之间。

数据的归一化,对SVM或者神经网络来说,是一样重要的步骤。未归一化的数据将严重降低分类器的效果。归一化除了线性归一化外,还有指数及对数的归一化,他们各自有自己擅长的数据领域。比如,声音的分贝数据,即是典型的对数归一化会拥有更好的效果。

下节预告

下节,解读五层神经网络分类器的源代码。

基于汉字字频特征实现99.99%准确率的新闻文本分类器(五)


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值