Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

applenob/text_normalization

Repository files navigation

Text Normalization for English

问题描述

所谓"文本正则",即将手写形式的文本转换成语音形式的文本。

例子:

  • 手写:A baby giraffe is 6ft tall and weighs 150lb.
  • 语音:A baby giraffe is six feet tall and weighs one hundred fifty pounds.

调研

目前kernel上主要以收集大辞典的方法为主流。

基于RNN的方法在paper中提到说效果不佳。

token的所有类别:['PLAIN', 'PUNCT', 'DATE', 'LETTERS', 'CARDINAL', 'VERBATIM', 'DECIMAL', 'MEASURE', 'MONEY', 'ORDINAL', 'TIME', 'ELECTRONIC', 'DIGIT', 'FRACTION', 'TELEPHONE', 'ADDRESS']。 其中,'PLAIN', 'PUNCT'是输出和输入相同的类别。但训练数据中,只有'PUNCT'的输出和输入完全相同,'PLAIN'的输入和输出相同的个数是:7317175,总共个数是:7353693。比例是:0.995034059757458。这里后续需要继续调查。

在训练集中,'PLAIN', 'PUNCT'所占的比例是0.931。

解决方法进化记录

2017年11月2日

0.9937-198/489

使用kernel中提供的方法尝试了一下。大致上就是从训练语料中提取一个大辞典,这个词典包括所有词以及其映射。不同的方法引进了更多的额外训练语料。

2017年11月5日

0.9164

用xgboost训练了一个二分类器,判别某个token是不是属于'PLAIN'+'PUNCT'。是则输入和输出相同,否则输出""。得到这个准确率。

2017年11月6日

0.9835

用xgboost训练了一个三分类器,判别某个token是否属于'PLAIN', 'PUNCT'还有其他。

2017年11月8日

最终发现还是要使用全分类器full_classifier,即16个类别全都分全。然后针对每个类别手动设计normalize的过程full_replacereplace_by_rule。并使用test/test_one_class.py一个一个类别调准确率。这一阶段准确率的提升主要来自对每个单独类别的normalize的优化。

准确率:0.9908->0.9921->0.9937->0.9942->0.9951->0.9954->0.9956

排名:75/554,已经进入铜牌区域,但也进入了瓶颈,单独类别的转换准确率很难找到大幅提升的改进点。

使用脚本full_replace_train.py发现所有的训练数据,如果知道其分类,那么normalize的准确率是:9913201 / 9918441 = 0.9994716911659807。也就是说,错误的数目只有5k+了,继续修改normalize上升空间有限。

2017年11月11日

转换思路,继续提高分类器的准确率。

思路一:增加人为判定规则

根据对数据的分析,发现分类器有几类典型错误:

  • 1.被误认为是cardinal的实际上的date的年份。这类情况特征明显,长度是4的数字都判为date即可。
  • 2.被误认为是plain的实际上的electronic的网站,比如baidu.com之类的,写一个简单的规则判断。

上面总结的规则都集中在patch_classifier.py脚本中,在分类器给出判定结果之后再跑一遍,作为对分类器的修正。

思路二:直接提升模型准确率

  • 1.特征工程:token的长度;是否是一句话中第一个token。目前特征工程对模型准确率没有明显提升。v2
  • 2.调整权重:因为本次任务是非常unbalanced的分类任务,因此最好对于不同类别的数据,在计算loss的时候,采用不同的权重。v3
  • 3.调参:关键参数:max_depth, round_numv2

比赛记录

2017年11月15日

比赛第一天,新的测试数据发布。按照之前的模型跑一版,到0.9933,直接窜到第三名。也不知道可以坚挺多久。

使用大字典的方法跑了一个baseline:0.9893,用作后续提高的对比数据。

2017年11月17日

寻找错误大概从两个方向上去找:1.找分类器分错的类别。2.找normalizer没有换对的情况。

分类器分错的类别可以通过分类器输出的分类信心概率来获取。比如使用xgboost中的'objective': 'multi:softprob'参数设定。检查prob值特别小的数据。

通过最终结果去找可以直接使用大字典跑出来的baseline去比较不同,但这个方法也不尽靠谱,不同的不一定错,相同的不一定对。但也可以从中观察,找到一些规律。

还可以直接在最终的结果中去找数字和特殊符号,一般是normalize失败的情况,这个方法可以查出来。

目前是0.9947。

2017年11月20日

今天是比赛最后一天,发现之前xgboost的参数设置有问题: 'nthread': -1,直接删掉,因为默认值是最大值。果然重新运行之后cpu的8核满负荷运行。快了很多。

另外把之前的基于context的方法做了一下修正:之前每个token都会包括上一个token和下一个token。那么句子中的最后一个token的context会包含下一句的第一个token,句子的第一个token的context会包含上一句的最后一个token。这显然是不对的。因此在每句之间加入全0向量。忽略该向量本身,只是用于其他向量的context。

最后一天重新check所有类别的rule函数,发现还有不错的可改进空间。

还能继续改的:

  • ORDINAL: 前面有没有the的问题。
  • VERBATIM: # 是hash-tag还是number的问题。

其他信息

使用到的第三方包

  • roman:罗马数字和阿拉伯数字的转换。
  • num2words:文字和数字的转换,支持序数的数字。
  • inflect:单词复数形式的转换等。

About

code and notes for kaggle competetion Text Normalization Challenge - English Language(https://www.kaggle.com/c/text-normalization-challenge-english-language)

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

Contributors

AltStyle によって変換されたページ (->オリジナル) /