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

Already on GitHub? Sign in to your account

模型的数据是如何生成的? #7

Closed
mtejiang opened this Issue Oct 23, 2012 · 37 comments

Comments

Projects
None yet

就是finalseg/prob_*.py中的这些数据

Owner

fxsjy commented Oct 23, 2012

@feriely , 来源主要有两个,一个是网上能下载到的1998人民日报的切分语料还有一个msr的切分语料。另一个是我自己收集的一些txt小说,用ictclas把他们切分(可能有一定误差)。 然后用python脚本统计词频。

要统计的主要有三个概率表:1)位置转换概率,即B(开头),M(中间),E(结尾),S(独立成词)四种状态的转移概率;2)位置到单字的发射概率,比如P("和"|M)表示一个词的中间出现”和"这个字的概率;3) 词语以某种状态开头的概率,其实只有两种,要么是B,要么是S。

Owner

fxsjy commented Oct 23, 2012

比如finalseg/prob_trans.py这个文件:

{'B': {'E': 0.8518218565181658, 'M': 0.14817814348183422},
'E': {'B': 0.5544853051164425, 'S': 0.44551469488355755},
'M': {'E': 0.7164487459986911, 'M': 0.2835512540013088},
'S': {'B': 0.48617017333894563, 'S': 0.5138298266610544}}

P(E|B) = 0.851, P(M|B) = 0.149,说明当我们处于一个词的开头时,下一个字是结尾的概率要远高于下一个字是中间字的概率,符合我们的直觉,因为二个字的词比多个字的词更常见。

@fxsjy fxsjy closed this Nov 6, 2012

pedia commented Nov 18, 2012

应该把这个写入wiki

whille commented Apr 18, 2013

BMES法是从BE改进的,M$又用到了BB1B2MES 6元法。 state越多效果越好。
但我感觉state还是不够。只用几个state是把大量样本信息模糊化了, 反过来用viterbi估计分词,是去马赛克,效果不会多好。为什么不用更多的states呢?自然理解的话,O:sentence。 States:word_cut。 这样state数是2*汉字个数。
e.g.:
X:我们|在|哈尔滨|
Y:我 们在哈尔滨

我用icwb2-data/gold/pku_test_gold.utf8训练,对比BMES 和word state的分词效果:

BMES: 改判|被|告人|死刑|立即|执行|
WORD: 改判|被告人|死刑|立即|执行|
BMES: 检察院|鲍|绍坤|检察长|
WORD: 检察院|鲍|绍坤|检察长|
BMES: 小明|硕士|毕业|于|中国|科学院|计算|所|
WORD: 小明|硕士|毕业|于|中国|科学院|计算所|
BMES: 工信|处女|干事|每月|经过|下属|科室|都|要|亲口|交代24口|交换|机等|技术|性器|件|的|安装|工作|
WORD: 工信|处女|干事|每月|经过|下属|科|室|都|要|亲|口|交代|24口|交换|机|等|技术性|器|件|的|安装|工作|

可见后者效果好一些。

Owner

fxsjy commented Apr 18, 2013

@whille , 没有看太明白,你的建议是用更多的状态? 但是加状态回导致分词速度变得更慢哦,毕竟是纯python实现。

whille commented Apr 18, 2013

慢一些,但一个ob只有两个state对应, 比如ob['工']的state只有'工_'和‘工|'两种。所以迭代时可以continue。如果利用反向dict查找,就更快了。

另外想问一下,BMES看来是统计training得到的。之前看HMM的前向-后向算法,不知道是不是可以用来迭代的更新这个model。

Owner

fxsjy commented Apr 19, 2013

@whille , 状态多一些使得分词更准确这一点我也赞同。其实,在jieba分词的词性标注子模块posseg中,就是将BMES四种状态和20集中词性做笛卡尔集得到所有的状态,最后的效果也的确比finalseg要好,尤其是人名识别方面,但是速度就严重下降了。https://github.com/fxsjy/jieba/blob/master/jieba/posseg/prob_start.py

感觉训练语料库还是比较小,对于web文本处理效果难免出现较多badcase,可否引入更多web真实文本训练?比如web网页、输入法细胞词库、wiki、问答网站的问题(相当于query)等

Owner

fxsjy commented Apr 26, 2013

@fandywang , 现在的确存在这个问题。如果你看看dict.txt,随处可以看见一些不像词的词,高质量的训练数据不好搞啊。

zjjott commented May 22, 2013

@fxsjy 谢谢你的回答,这样看来是缺少现代的词库?我想做一个语义树,主要担心一些网络流行语、学术名词的匹配,还没有做这样的词库,看来我可以找时间补充一下

中文就是分词蛋疼。一直没有较好的朗读解决方案。

sogou有一个互联网词库 和中文词语搭配库 http://www.sogou.com/labs/dl/w.html ,不知道这个词库质量怎么样?能否添加进来。

Owner

fxsjy commented Jul 30, 2013

@chundong , 可以加入,结巴支持自定义词典,只要按照格式就可以。

rav009 commented Sep 30, 2013

请问中文的trie树是怎么实现的,中文词语的首字可以有成千上万种选择,怎么解决的呢?

Contributor

yanyiwu commented Sep 30, 2013

在python里面就是一个嵌套的dict实现。
在c++里面就是一个hash_map的实现。
成千上万又不是一个大数目,没什么难解决的吧。

@rav009

wuyanyi09@gmail.com

发件人: rav009
发送时间: 2013-09-30 17:20
收件人: fxsjy/jieba
主题: Re: [jieba] 模型的数据是如何生成的? (#7)
请问中文的trie树是怎么实现的,中文词语的首字可以有成千上万种选择,怎么解决的呢?

Reply to this email directly or view it on GitHub.

jannson commented Sep 30, 2013

个人觉得TRIE树占用很大的内存,一级一级的dict下来内存用得不小啊。不知道有谁亲自测试用大字典的时候耗了多少内存不?
可以不用TRIE树,用一个小循环就可以搞定,慢一点感觉影响不特别大。

2013/9/30 Wu Yanyi notifications@github.com

在python里面就是一个嵌套的dict实现。
在c++里面就是一个hash_map的实现。
成千上万又不是一个大数目,没什么难解决的吧。

wuyanyi09@gmail.com

发件人: rav009
发送时间: 2013-09-30 17:20
收件人: fxsjy/jieba
主题: Re: [jieba] 模型的数据是如何生成的? (#7)
请问中文的trie树是怎么实现的,中文词语的首字可以有成千上万种选择,怎么解决的呢?

Reply to this email directly or view it on GitHub.


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

Contributor

yanyiwu commented Sep 30, 2013

@janson
1.我的线上cppjieba程序跑着看到内存占用百分比是个位数,没仔细看多少,但是就认为没有内存问题。
2.用map会省内存,但是速度不如hash_map,所以我用hash_map(因为1得知没有内存困扰)
4.个人认为trie树是暂时对这个分词最合适的数据结构了。你的小循环能否详细说一下。

wuyanyi09@gmail.com

发件人: janson
发送时间: 2013-09-30 17:55
收件人: fxsjy/jieba
抄送: Wu Yanyi
主题: Re: [jieba] 模型的数据是如何生成的? (#7)
个人觉得TRIE树占用很大的内存,一级一级的dict下来内存用得不小啊。不知道有谁亲自测试用大字典的时候耗了多少内存不?
可以不用TRIE树,用一个小循环就可以搞定,慢一点感觉影响不特别大。

2013/9/30 Wu Yanyi notifications@github.com

在python里面就是一个嵌套的dict实现。
在c++里面就是一个hash_map的实现。
成千上万又不是一个大数目,没什么难解决的吧。

wuyanyi09@gmail.com

发件人: rav009
发送时间: 2013-09-30 17:20
收件人: fxsjy/jieba
主题: Re: [jieba] 模型的数据是如何生成的? (#7)
请问中文的trie树是怎么实现的,中文词语的首字可以有成千上万种选择,怎么解决的呢?

Reply to this email directly or view it on GitHub.


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


Reply to this email directly or view it on GitHub.

jannson commented Oct 8, 2013

通过cpp上实现的话,TRIE可能占用比较小,这个我没有试过。但通过python的dict来实现TRIE树的话,占用内存挺大,我没有认真测试。但是当时我把jieba放到一个云平台运行的时候,就提示说内存占用过大被KILL掉了。所以我当时进行了以下的小修改:(这个修改是我今天重写的,没有很多测试)
def get_DAG(sentence):
WORD_MAX = 8
n = len(sentence)
i,j = 0,0
DAG = {}
while i < n:
for j in xrange(i, min(n,i+WORD_MAX), 1):
if sentence[i:j+1] in FREQ:
if not i in DAG:
DAG[i]=[]
DAG[i].append(j)
i += 1
j = i
for i in xrange(len(sentence)):
if not i in DAG:
DAG[i] =[i]
return DAG
把get_DAG函数改成以上函数。
以上函数只用到了FREQ,没有使用TRIE树。相比TRIE树,它的缺点是每i+1,都得进行8次的循环;若是TRIE树,会根据自身有的多少词来进行循环,稍微快一些。如果在搜索环境下使用的话,可以把WORD_MAX改成5或6就可以了。

2013/9/30 Wu Yanyi notifications@github.com

@janson
1.我的线上cppjieba程序跑着看到内存占用百分比是个位数,没仔细看多少,但是就认为没有内存问题。
2.用map会省内存,但是速度不如hash_map,所以我用hash_map(因为1得知没有内存困扰)
4.个人认为trie树是暂时对这个分词最合适的数据结构了。你的小循环能否详细说一下。

wuyanyi09@gmail.com

发件人: janson
发送时间: 2013-09-30 17:55
收件人: fxsjy/jieba
抄送: Wu Yanyi
主题: Re: [jieba] 模型的数据是如何生成的? (#7)
个人觉得TRIE树占用很大的内存,一级一级的dict下来内存用得不小啊。不知道有谁亲自测试用大字典的时候耗了多少内存不?
可以不用TRIE树,用一个小循环就可以搞定,慢一点感觉影响不特别大。

2013/9/30 Wu Yanyi notifications@github.com

在python里面就是一个嵌套的dict实现。
在c++里面就是一个hash_map的实现。
成千上万又不是一个大数目,没什么难解决的吧。

wuyanyi09@gmail.com

发件人: rav009
发送时间: 2013-09-30 17:20
收件人: fxsjy/jieba
主题: Re: [jieba] 模型的数据是如何生成的? (#7)
请问中文的trie树是怎么实现的,中文词语的首字可以有成千上万种选择,怎么解决的呢?

Reply to this email directly or view it on GitHub.


Reply to this email directly or view it on GitHub<
https://github.com/fxsjy/jieba/issues/7#issuecomment-25347223>
.


Reply to this email directly or view it on GitHub.


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

Owner

fxsjy commented Oct 8, 2013

@jannson , 很好的尝试。请问去掉TRIE之后,分词速度下降的多吗?

jannson commented Oct 8, 2013

没有测试。有空我好好用cProfile来测试测试。

On Tue, Oct 8, 2013 at 9:40 AM, Sun Junyi notifications@github.com wrote:

@jannson https://github.com/jannson , 很好的尝试。请问去掉TRIE之后,分词速度下降的多吗?


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

如果可以把字典文件分成几个,然后用mmap来加载可能可以避免内存问题

lurga commented Oct 11, 2013

这么重要的问题居然在readme最后,这是要告诉大家一定要耐心看完readme吗?
感谢作者做出的工作!
不负责任的想象一下,如果有个最初始的分词器,只有一份最基本的词典,第一次只能使用trie来分词,分出词之后利用@fxsjy 说的训练hmm,之后都是trie树+viterbi分词,重复训练hmm,最后hmm中的各个参数会收敛吗?如果收敛得到的hmm是最佳的吗?

rav009 commented Oct 12, 2013

我试过,用 向前向后 迭代几次后,再用维特比解码,任何序列都会解码成 SSSSSSSS....
@lurga

lurga commented Oct 13, 2013

@rav009 很好奇每次迭代解码的序列,想不明白为什么迭代几次后会成为SSSSSS

rav009 commented Oct 13, 2013

我随便测了几句 这应该跟初始概率的设置有关系 @lurga

请问结巴里的trie树用的是原生的trie,没有用双数组优化吗?

Owner

fxsjy commented May 23, 2014

@PhanYoung , 没有什么优化,就是dict嵌套dict实现的。

@fxsjy 请问位置转换概率中 BEMS 是怎么从字、词中分析出来的?我查找了网上大量资料,都没有对此有相关的介绍,一般都是给出词性。

whille commented May 25, 2014

分词后就有了,你知道这四个字母代表什么意思吧

发自我的 iPad

在 2014年5月25日,16:27,Yaoda Liu notifications@github.com 写道:

@fxsjy 请问位置转换概率中 BEMS 是怎么从字、词中分析出来的?我查找了网上大量资料,都没有对此有相关的介绍,一般都是给出词性。


Reply to this email directly or view it on GitHub.

谢谢!突然想明白了~
-- 
shonenada http://shonenada.com

开启 2014年5月25日 at 下午4:35:22, whille (notifications@github.com) 写:

分词后就有了,你知道这四个字母代表什么意思吧

发自我的 iPad

在 2014年5月25日,16:27,Yaoda Liu notifications@github.com 写道:

@fxsjy 请问位置转换概率中 BEMS 是怎么从字、词中分析出来的?我查找了网上大量资料,都没有对此有相关的介绍,一般都是给出词性。


Reply to this email directly or view it on GitHub.

Reply to this email directly or view it on GitHub.

@fxsjy ,请问:你每次训练的时候,是把手头上所有的语料(包括人民日报、MRS,经切词软件处理过的文学材料)全部统计和计算一下吗?这样一次大概需要多长时间呢?

smallnew commented Dec 3, 2014

@fxsjy ,我看更新日志发现一开始就把搜狗的2006词库给导入工程中了,就算自己再去下载那个词库那也作用不大吧

有没有jieba分词和其他框架对比的测试?我很想知道结巴分词的排名~~

@fandywang 这个可以参考清华大学中文分词工具介绍部分

您好,有对应的模型训练代码吗?这边想重新利用自己这边的语料训练一个HMM统计分词模型

您好,假设我使用了自定义词典,那么相应的HMM参数(初始状态概率、状态转移概率、观测概率)会不会被重新训练?

@fxsjy 请问能否训练模块posseg下的各个pro_文件?

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