最近公司在做一个推荐系统,让我给论坛上的帖子找关键字,当时给我说让我用jieba分词,我周末回去看了看,感觉不错,还学习了一下具体的原理

首先,通过正则表达式,将文章内容切分,形成一个句子数组,这个比较好理解

然后构造出句子的有向无环图(DAG)

    def get_DAG(self, sentence):
self.check_initialized()
DAG = {}
N = len(sentence)
for k in xrange(N):
tmplist = []
i = k
frag = sentence[k]
while i < N and frag in self.FREQ:#对每一个字从这个字开始搜索成词位置
if self.FREQ[frag]:
tmplist.append(i)#如果可以成词就加入到DAG中
i += 1
frag = sentence[k:i + 1]
if not tmplist:
tmplist.append(k)#如果找不到词语,就将自己加入DAG
DAG[k] = tmplist
return DAG
  1. 对句子中的每个字进行分析,从右边一位开始,看sentence[k:i+1]这个词语是否在预设的字典中,这个字典保存了常用的词语(和词语的一部分,但权重为0)和其权重.如果有,并且如果字典中的这个词的权值不等于0,那么就将i放到tmplist里,然后i+=1,继续下一轮循环,如果没有这个词,那就停下来,然后移动k,让k=k+1,找下一个字的成词位置
    1. 比如有这样一个句子:'我从海淀区搬到了朝阳区',一共11个字
    2. 通过上面的计算,得到一个字典:<class 'dict'>: {0: [0], 1: [1], 2: [2, 3, 4], 3: [3, 4], 4: [4], 5: [5, 6], 6: [6], 7: [7], 8: [8, 9, 10], 9: [9], 10: [10]},字典键代表每个字在字符串中的位置,比如,0代表'我',1代表'从',而每个键对应一个数组,比如2对应[2,3,4],这个表示:'海'(2)/'海淀'(2-3)/'海淀区'(2-4),这三个字符串可以成为词语
    3. 这样,我们就得到了所有可以成词的位置了

选出成词概率最大的位置

    def calc(self, sentence, DAG, route):
N = len(sentence)
route[N] = (0, 0)
logtotal = log(self.total)#常数值
for idx in xrange(N - 1, -1, -1):#从后往前分析
route[idx] = max((log(self.FREQ.get(sentence[idx:x + 1]) or 1) -
logtotal + route[x + 1][0], x) for x in DAG[idx])
  1. 对于句子中的每一个字,计算候选位置中,哪个成词概率最大
    1. 比如2:[2,3,4],分别对2/3/4进行计算,计算公式:log(词的概率)-常数+下一个字的成词概率
    2. 词语的概率还是用之前保存了所有常用词的字典(也可以自己定义字典),下一个字的成词概率是上一个循环计算出来的,我们要从末尾开始计算,得到的结果作为下一个循环的参数,这样我们就找到了最大成词概率的切分位置
    3. 为什么要加上下一个字的成词概率的呢?因为下一个词的成词概率高的话,我们做出的切分就越正确,越有可能切成两个正确的词语,而不是左边的词语概率高,而右边根本不是一个正确的词语

如上图,蓝色圈中的部分,括号右边代表了成词的位置,比如2,括号的右边是4,说明2-4这个词的成词概率高,我们就切成'海淀区'

切分的过程是这样的

  1. 从头开始,寻找每个位置对应的成词位置,取出来
  2. 跳到成词位置的下一个位置开始循环

这样,我们就能得到:0/1/2-4/5/6/7/8-10

具体为:我/从/海淀区/搬/到/了/朝阳区

到此为止整个过程就结束了

不过,官方默认算法还有个hmm,这次先不说了,请听下回分解

最新文章

  1. 常见的HTTP Headers
  2. [bzoj1087][scoi2005]互不侵犯king
  3. [实变函数]5.2 非负简单函数的 Lebesgue 积分
  4. POJ 1496
  5. Thrift框架介绍
  6. 多线程和并发管理 .NET多线程服务
  7. [转]一个备份MySQL数据库的简单Shell脚本
  8. qrcode各版本/各类型容量支持表
  9. React.js终探(五)
  10. 芝麻HTTP:代理的基本原理
  11. freemarker的使用
  12. pymongo连接MongoDB
  13. elasticsearch数据备份与sshfs建立共享文件
  14. Why Everyone Should Lift Weights
  15. 单片机AT和STC区别
  16. Redis雪崩、穿透、热点key等优化
  17. 用JS制作《飞机大作战》游戏_第1讲(素材查找和界面框架搭建)-陈远波
  18. React-Native 之 ListView使用
  19. 2017面向对象程序设计(Java)第十五周学习总结
  20. [bzoj4444] 国旗计划 双指针+倍增

热门文章

  1. H5常用新特性
  2. js验证手机号、身份证等
  3. 顺F速运国际版,你的密码漏点了
  4. Python图像处理库Pillow常用使用方法
  5. 一文解读Spring全家桶 (转)
  6. ABP进阶教程8 - 自定义按钮
  7. PyCharm颜色设置
  8. OSI网络模型和网络连接设备
  9. [Go] 分页计算页码的主要逻辑
  10. 苏州市java岗位的薪资状况(1)