通过用户自定义词典来增强歧义纠错能力 #14

Closed
fxsjy opened this Issue Nov 22, 2012 · 43 comments

Comments

Projects
None yet
Owner

fxsjy commented Nov 22, 2012

你好,最近在用你的分词,发现
大连 美容美发 学校 中君 意是 你 值得 信赖 的 选择

这句话被错误地切分了,我查看了dict.txt和idf.txt都没有找到“中君”和“意是”这两个词,不知道为什么>>会有这样的错分呢?

能不能从理论上解释一下?

RE:

"大连美容美发学校中君意是你值得信赖的选择" 这句话首先会按照概率连乘最大路径来切割,因为单字有一定概率,而“中君意是”这四个字中不含词典中有的词,所以会被切割成单字:

即:大连/ 美容美发/ 学校/ 中/ 君/ 意/ 是/ 你/ 值得/ 信赖/ 的/ 选择/

然后我们认为“中/ 君/ 意/ 是/ 你/ ”这几个连续的单字 中可能有词典中没有的新词,所以再用finalseg来切一遍“中君意是你 ”,finalseg是通过HMM模型来做的,简单来说就是给单字大上B,M,E,S四种标签以使得概率最大。

很遗憾,由于训练数据的问题,finalseg最终得到的标签是:

中君 意是 你
B E B E S

即认为P(B)_P(中|B)_P(E|B)_P(君|E)_P(B|E)_P(意|B)_P(E|B)_P(是|E)_P(S|E)*P(你|S) 是所有可能的标签组合中概率最大的。

B: 开头
E:结尾
M:中间
S: 独立成词的单字

解决方案是在词典中补充“君意”这个词,并给予一个词频,不用太大,比如3即可。

==user.dict===

君意 3

==test.py==

encoding=utf-8

import sys
import jieba
jieba.load_userdict("user.dict")
print ", ".join(jieba.cut("大连美容美发学校中君意是你值得信赖的选择"))

==结果===
大连, 美容美发, 学校, 中, 君意, 是, 你, 值得, 信赖, 的, 选择

Owner

fxsjy commented Nov 22, 2012

Bad Case: '江州/ 市/ 长江大桥/ 参加/ 了/ 长江大桥/ 的/ 通车/ 仪式'

目前这个方面的确还比较弱。

通过在自定义词典里提高“江大桥”的词频可以做到,但是设置多少还没有公式,词频越高则成词概率越大,不宜过大。

我是这样设置的:

==user.dict==

江大桥 20000

===test1.py======

#encoding=utf-8
import sys
sys.path.append("../")
import jieba
jieba.load_userdict("user.dict")
print ", ".join(jieba.cut("江州市长江大桥参加了长江大桥的通车仪式"))

==结果===
江州, 市长, 江大桥, 参加, 了, 长江大桥, 的, 通车, 仪式

fxsjy closed this Nov 27, 2012

hitalex commented Jan 25, 2013

请问,在提供自定义词的时候,为什么还需要指定词频?这里的词频有什么作用?

Owner

fxsjy commented Jan 25, 2013

@hitalex, 频率越高,成词的概率就越大。

比如"江州市长江大桥",既可以是”江州/市长/江大桥“,也可以是”江州/市/长江大桥“。
假设要保证第一种划分的话,我们需要保证P(江州)_P(市长)_P(江大桥)> P(江州)_P(市)_P(长江大桥)

Owner

fxsjy commented Feb 5, 2013

注意 自定义词典不要用Windows记事本保存,这样会加入BOM标志,导致第一行的词被误读。

通过在自定义词典里提高“江大桥”的词频可以做到,但是设置多少还没有公式,词频越高则成词概率越大,不宜过大。这里的“不宜过大”到底不宜大到什么程度,我看前面的词频也就2,3,4,怎么到“江大桥”的词频就要大到了20000??这个难道不是过大??

Owner

fxsjy commented Feb 27, 2013

@macknight , 这个例子比较极端,因为”长江大桥“、”市长“这些词的频率都很高,为了纠正,才把”江大桥“的词频设置的很高。而对于一般的词典中没有的新词,大多数情况下不会处于有歧义的语境中,故词频也就2,3,4就够了。

whille commented Apr 10, 2013

看到词库格式是: {word:frequency},总样本字数是多少?添加新词的频率怎么设定?
比如之前没有的词,我在5k文本中找到了"瞄星人"这个词,freq:100。 词库中怎么设置freq?
后来我又在另外10k文本中,找到了"瞄星人":30. freq怎么修改?

默认词库在这里:https://github.com/fxsjy/jieba/blob/master/jieba/dict.txt?raw=true

总样本字数??你说的是词数吧? wc -l 就好了。

一个词的举例:“一一列举 34 i”,这个词中,freq 就是 34 嘛,i 是词性。照着加进去就好。

Owner

fxsjy commented Apr 10, 2013

@while,不用设置那么高。
只要能保证:
P(喵星人) =max{ P(喵)*P(星)*P(人), P(喵星)*P(人), P(喵)*P(星人), P(喵星人) }

频率设个 4 就好了。

fxsjy comment:
是的,一般不用太大, 除非是歧义纠结的句子。

2013/4/10 Sun Junyi notifications@github.com

@while https://github.com/while,不用设置那么高。
只要能保证:
P(喵星人) =max{ P(喵)_P(星)_P(人), P(喵星)_P(人), P(喵)_P(星人), P(喵星人) }


Reply to this email directly or view it on GitHubhttps://github.com/fxsjy/jieba/issues/14#issuecomment-16159512
.

whille commented Apr 10, 2013

我想有陆续添加新词功能。 看源码里把freq取了log。 所以直接用了词频。 但是以后新的文本词频怎么整合,还想不明白?
看词库:https://github.com/fxsjy/jieba/blob/master/jieba/dict.txt?raw=true
#########
的 3188252 uj
...
龟甲 92 ns
#########
应该有个总txt长度的概念吧。

我觉得你的 comment 里,标点符号用得特别传神。

在 2013年4月10日下午3:39,whille notifications@github.com写道:

我想有陆续添加新词功能。 看源码里把freq取了log。 所以直接用了词频。 但是以后新的文本词频怎么整合,还想不明白?


Reply to this email directly or view it on GitHubhttps://github.com/fxsjy/jieba/issues/14#issuecomment-16159713
.

Owner

fxsjy commented Apr 10, 2013

@whille, 如果你添加的词语特别多的话(因为会对分母造成影响),建议直接加到dict.txt里面,否则就用jieba.load_userdict好了(这里的分母还是用的dict.txt中的总词频和,为了性能并没有重新计算一遍)。

看来dict.txt里面的词频只是为解决歧义而设置的,词典中的词频数值跟计算tf-idf时没有必然联系吧?

Owner

fxsjy commented Jan 22, 2014

@metalhammer666 ,没有必然联系。

在自定义词典中,明明把词性标为nr,print出来的却是x。请问怎么解决?是格式不对么?

Owner

fxsjy commented Mar 7, 2014

@heloowird , 按说不会啊,把你的词典发我看看?

@fxsjy “在自定义词典中,明明把词性标为nr,print出来的却是x“
我也出现了同样的问题
001

002

hitalex commented May 1, 2014

我发现一个问题:我已经将某个词加入用户自定义词典,且设置了很高的词频(例如,5),但是jieba在分词或POS时,还是没有将其作为一个词。
请问,除了设置词频外,能否保证在用户词典中的词一定能够在分词过程中被认为是一个词?

还有一个问题,在中文中含有英文,如何把一个词语分到一起来?

请问自定义字典的存放路径@fxsjy

请问自定义字典的存放路径@fxsjy

poryfly commented Dec 10, 2014

请问自定义的字典里面可以有正则表达式吗?

我在添加自定义字典时,出现这个错误UnboundLocalError: local variable 'line' referenced before assignment,请问该如何解决?

codywsy commented Jul 21, 2016

@fxsjy 我想问,我在使用自定义词典的时候,分词“藏宝阁太贵”,我成功把“藏宝阁”分成一起了,但是“太贵”却不能分成“太”和“贵”。
我尝试过将jieba的字典dict.txt中的“太贵”直接删掉,也尝试过加入语句jieba.suggest_freq(('太','贵'),True),也都没有用。
请问,怎么才能成功把“太贵”分开

@codywsy 个人认为有两种方式:1)你可以在字典dict.txt中先找出“太贵”的词频,然后在后面加上“太” ,“贵”,但是词频要比“太贵”高;
2)添加自定义字典,字典里写上“太” ,“贵”,分别加词频,词频设置跟前面的方法一样

怎么结合其他输入法之类的词库??

vkjuju commented Nov 1, 2016

請問Jieba有沒有辦法將英文片語分出來, 例如我要的是: "get out", 而不是"get" 和 "out" ,謝謝

vkjuju commented Nov 1, 2016

再請教可以保留標點符號嗎?例如我要分的詞是"不要,停止",而不是"不要"和"停止"

您好,我发现在使用自定义词典时,我设置了A320词频为4,但我又想在有A320-200的时候分出A320-200,但即使我把A320-200的词频设置到2000,他还是会分成A320 - 200,请问这是什么原因,谢谢您!

@vkjuju "get out", 而不是"get" 和 "out"这个问题最后怎么解决的,我也遇到很多英文专有名字词组,想把他们放在一起,自定义字典似乎不起作用

如何强制把地名分开,比如:北京饭店 -> 北京/饭店

现在是:北京饭店连起来的

kute commented Mar 12, 2017

@alexlee728

my_dict.txt

北京 4 n
饭店 4 n
jieba.set_dictionary('my_dict.txt')
print(" ".join(jieba.cut('我们来到了北京饭店')))
# 我们 来 到 了 北京 饭店

请问怎样才能又能自己定义字典又输出词性啊?
自己定义字典是用jieba.loaduserdict
输出词性用的是posseg.cut
怎样结合呢?

@fxsjy 您好,最近使用您的工具发现 “常用的数据挖掘方法包括向量机等”这句话被分成了
常用 \ 的 \ 数据挖掘 \ 方法 \ 包括 \ 向量 \ 机 \ 等
于是自己加了词典,写的是 向量机 5 n
结果分词变成了
常用 \ 的 \ 数据 \ 挖掘 \ 方法 \ 包括 \ 向 \ 量机 \ 等
数据挖掘这个词也分错了,另外向量机也没分出来
还望不吝赐教,谢谢!

09wthe commented Apr 16, 2017

@Azusamio 直接在自定义词典里加入“向量机”,不要加词频和词性

09wthe commented Apr 16, 2017

@bill4mobile 请问“get out”这种问题解决了吗?我也遇到这个问题

print '/'.join( jieba.cut("谁拍板谁负责任"))
输出的是:/谁/拍板/谁/负责/任/
除了自定义词典外,如何解决这类似的错误?

@09wthe 我后来发现问题是jieba在分词时只能引用一个词典,我导入了自己的词典后jieba分词就没有使用原来的词典,之所以还能分词是因为HMM处在开启状态。
我后来直接把发现的新词加入到原词典里就没问题了。
另外我发现如果不写词频的话会报
ValueError: invalid dictionary entry
这样一个bug,似乎是字典格式要求必须有词频才可以,我试了一下,可以没有词性但必须要有词频才能不报错。
另外感谢您的指导

@fxsjy 您好,我也想问您一下,我把发现的新词添加到词典当中,还要使用标记词性的方法,请问,这时候词典起作用吗,因为我并不能分出来我添加的这些新词,分词结果和没有添加新词的时候是一样的,就是楼上呢 @SunflowerSmileYY 的问题。

@SunflowerSmileYY 您好,我想问您一下,你说那个词性标记和自定义词典的功能结合问题,你有知道方法了吗?我现在也遇到这个问题,想请教一下,能麻烦你和我讲一下吗

你好,我想问一下自定义词典中“词频省略时使用自动计算的能保证分出该词的词频。”是如何使用自动计算词频的?谢谢!

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