Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

关于感知机与CRF对空格与标点的词性识别问题 #797

Closed
1 task done
blizzardy opened this issue Apr 19, 2018 · 4 comments
Closed
1 task done

关于感知机与CRF对空格与标点的词性识别问题 #797

blizzardy opened this issue Apr 19, 2018 · 4 comments

Comments

@blizzardy
Copy link

blizzardy commented Apr 19, 2018

注意事项

请确认下列注意事项:

  • 我已仔细阅读下列文档,都没有找到答案:
  • 我已经通过Googleissue区检索功能搜索了我的问题,也没有找到答案。
  • 我明白开源社区是出于兴趣爱好聚集起来的自由社区,不承担任何责任或义务。我会礼貌发言,向每一个帮助我的人表示感谢。
  • 我在此括号内输入x打钩,代表上述事项确认完毕。

版本号

当前最新版本号是:1.6.3
我使用的版本是:portable-1.6.3

我的问题

综合比较其他几种分词器,感知机对词性的标注相对更准确,但是对于空格和标点符号(尤其是英文标点)的标注存在许多问题。

例如对以下这句话的标注:
"你好, 我想知道: 风是从哪里来; 雷是从哪里来; 雨是从哪里来?"

perceptron:

(你/r) (好/a) (,/w) ( /v) (我/r) (想/v) (知道/v) (:/w) ( 风/n) (是/v) (从/p) (哪里/r) (来/v) (; 雷/d) (是/v) (从/p) (哪里/r) (来/v) (;/w) ( 雨/n) (是/v) (从/p) (哪里/r) (来/v) (?/w) 

crf:

(你好/d) (,/v) ( /v) (我/r) (想/v) (知道/v) (:/w) ( 风/n) (是/v) (从/p) (哪里/r) (来;/v) ( 雷/n) (是/v) (从/p) (哪里/r) (来/v) (;/w) ( 雨/n) (是/v) (从/p) (哪里/r) (来/v) (?/v) 

viterbi:

(你好/l) (,/w) ( /w) (我/r) (想/v) (知道/v) (:/w) ( /w) (风/n) (是从/v) (哪里/r) (来/v) (;/w) ( /w) (雷/n) (是从/v) (哪里/r) (来/v) (;/w) ( /w) (雨/n) (是从/v) (哪里/r) (来/v) (?/w) 

重点关注空格与标点的分词,结果发现:感知机与CRF对有时空格与标点识别为其他词性,甚至会与前后的词成为组合,反而默认的viterbi对于标点的处理更好。

最近开始接触这方面,尚未仔细阅读源码,请问对于空格与标点是如何处理的,能否改进?请指导。

@hankcs
Copy link
Owner

hankcs commented Apr 19, 2018

一个个来说吧。

  1. 空格、制表符等等属于语料的分隔符,所以感知机默认是不认识这些字符的。建议自行预处理,预处理损失速度,不是所有人都需要,所以暂时没有默认处理。
  2. 在上层任务中,比如句法分析,语料库中也是没有空格的,所以一开始输入文本就不应该有空格。去掉空格这个工序交给谁做?我记得LTP是干脆去掉文本中所有的空格。但我比较倾向于交给用户,因为只有用户才知道他自己的文本里都有些什么奇怪的东西,比如pdf中会有很多奇怪的控制符,python读取文件默认含有换行符,html里会有标签等等。
  3. 标点大部分都在语料库中出现,所以感知机没有做额外处理。
  4. viterbi偏规则一些,根据字符类型拆分了文本。但规则永远是丑陋的,无法灵活处理文本。也许大部分程序员习惯觉得规则“可控”,但你根本想象不到自然语言灵活到什么程度。比如飞机的编号:图-160m2,轰20等,就是中英文数字和标点的组合。

用户可以考虑如下做法:

  1. sentence.replace(' ', '!') 损失一点速度
  2. CharTable.CONVERT[' '] = '!'; 不损失速度,结果会含有单个空格。

@holysoros
Copy link

如果要去掉空格、标点等分隔符,怎么表达句子与段落之间的停顿呢?

@wangzhe258369
Copy link

@hankcs 请问这里的'!'有什么特殊含义吗?
CharTable.CONVERT[' '] = '!'

@hankcs
Copy link
Owner

hankcs commented Sep 4, 2018

@holysoros 处理文章的时候一般需要先断句,你可以用空格标点等构造正则表达式split文章,HanLP也提供SentenceUtil。

@wangzhe258369 将空格转换为感叹号,感叹号是语料库中常见的断句符,你也可以转换为句号之类。

无论如何,不要把脏活全丢给分词器,就算吸尘器可以吸垃圾,一般吸之前还是要先把大型垃圾扫走的。

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants