中文分词之隐马尔可夫模型

隐马尔可夫模型理论知识:
角色:收拾烂摊子的角色
1) 生成方式
2) 路径选择(viterbi算法)——>动态规划

上篇文章讲到语言模型(1,2,3)
二元语言模型 == 一阶马尔科夫模型

马尔科夫模型有3类重要参数:
1、状态
2、初始概率

初始概率计算方法举例:
    假设有100篇文章,
    时光荏苒 30篇   -> 30 / 100
    今天 10篇
    开心 5篇
    加班 1篇

3.转移概率计算方法举例:

x x x x x x x x x x x x x x A B x x x x x A B x x x x  A C x x x x
P(B|A) = 2/3
P(C|A) = 1/3

计算的前提条件:大量的文章

因为马尔科夫模型是针对一个序列建模的,现实中会有多个序列(比如语音识别),因此而产生隐马尔可夫模型

双序列举例:

词性标注

隐马尔科夫模型中有5类重要参数:
1、状态,M个 = 4(位置信息)*20(词性信息) = 80(大概有80个状态)
2、初始概率:M个
3、转移概率:M*M(一个状态到另外一个状态的概率)
4、发射概率:M*N
5、观察,N个 = 2000(有多少个汉字,就有多少个观察)

BMES状态:举例:

初始概率:

获取方法:统计

假设有100篇文章,
    时光荏苒 30篇   那么初始概率为-> 30 / 100

转移概率:

状态概率:每一个状态到一个汉字的概率

P(S1,S2,S3,O1,O2,O3) 联合概率
= P(S1) * P(O1|S1) * P(S2|S1) ***  **


 

viterbi动态规划最优路径算法

目的:将零散的词汇粘在一起

实践:倒排索引

1.原始数据:

思路:

1.map做分词:name->token,token,token

2.reduce(聚合)
token1 -> name name name

代码:

map.py:

#!/usr/bin/python

import os
import sys

os.system('tar xvzf jieba.tar.gz > /dev/null')

reload(sys)
sys.setdefaultencoding('utf-8')

sys.path.append("./")

import jieba
import jieba.posseg
import jieba.analyse

def mapper_func():
    for line in sys.stdin:
        ss = line.strip().split('\t')
        if len(ss) != 2:
            continue
        music_id = ss[0].strip()
        music_name = ss[1].strip()

        tmp_list = []
        for x, w in jieba.analyse.extract_tags(music_name, withWeight=True):
            tmp_list.append((x, float(w)))

        final_token_score_list = sorted(tmp_list, key=lambda x: x[1], reverse=True)

        print '\t'.join([music_id, music_name, ''.join([''.join([t_w[0], str(t_w[1])]) for t_w in final_token_score_list])])

 

if __name__ == "__main__":
    module = sys.modules[__name__]
    func = getattr(module, sys.argv[1])
    args = None
    if len(sys.argv) > 1:
        args = sys.argv[2:]
    func(*args)


倒排map_inverted.py:

#!/usr/bin/python

import os
import sys

def mapper_func():
    for line in sys.stdin:
        ss = line.strip().split('\t')
        if len(ss) != 3:
            continue
        music_id = ss[0].strip()
        music_name = ss[1].strip()
        music_fealist = ss[2].strip()

        for fea in music_fealist.split(''):
            token, weight = fea.strip().split('')
            print '\t'.join([token, music_name, weight])

 

if __name__ == "__main__":
    module = sys.modules[__name__]
    func = getattr(module, sys.argv[1])
    args = None
    if len(sys.argv) > 1:
        args = sys.argv[2:]
    func(*args)

red_inverted.py:

#!/usr/bin/python

import os
import sys


def reducer_func():

    cur_token = None
    m_list = []

    for line in sys.stdin:
        ss = line.strip().split('\t')
        if len(ss) != 3:
            continue
        token = ss[0].strip()
        name = ss[1].strip()
        weight = float(ss[2].strip())

        if cur_token == None:
            cur_token = token
        if cur_token != token:

            final_list = sorted(m_list, key=lambda x: x[1], reverse=True)
            print '\t'.join([cur_token, ''.join([''.join([name_weight[0], str(name_weight[1])]) for name_weight in final_list])])

            cur_token = token
            m_list = []

        m_list.append((name, weight))

    final_list = sorted(m_list, key=lambda x: x[1], reverse=True)
    print '\t'.join([cur_token, ''.join([''.join([name_weight[0], str(name_weight[1])]) for name_weight in final_list])])

 

if __name__ == "__main__":
    module = sys.modules[__name__]
    func = getattr(module, sys.argv[1])
    args = None
    if len(sys.argv) > 1:
        args = sys.argv[2:]
    func(*args)

 

 

脚本run.sh:

HADOOP_CMD="/usr/local/src/hadoop-2.6.5/bin/hadoop"
STREAM_JAR_PATH="/usr/local/src/hadoop-2.6.5/share/hadoop/tools/lib/hadoop-streaming-2.6.5.jar
"

INPUT_FILE_PATH_1="/music_meta.txt.small"
OUTPUT_Z_PATH="/output_z_fenci"
OUTPUT_D_PATH="/output_d_fenci"

$HADOOP_CMD fs -rmr $OUTPUT_Z_PATH
$HADOOP_CMD fs -rmr $OUTPUT_D_PATH

# Step 1.
$HADOOP_CMD jar $STREAM_JAR_PATH \
    -input $INPUT_FILE_PATH_1 \
    -output $OUTPUT_Z_PATH \
    -mapper "python map.py mapper_func" \
    -jobconf "mapred.reduce.tasks=0" \
    -jobconf "mapreduce.map.memory.mb=4096" \
    -jobconf  "mapred.job.name=jieba_fenci_demo" \
    -file "./jieba.tar.gz" \
    -file "./map.py"

 

# Step 2.
$HADOOP_CMD jar $STREAM_JAR_PATH \
    -input $OUTPUT_Z_PATH \
    -output $OUTPUT_D_PATH \
    -mapper "python map_inverted.py mapper_func" \
    -reducer "python red_inverted.py reducer_func" \
    -jobconf "mapred.reduce.tasks=2" \
    -jobconf "mapreduce.map.memory.mb=4096" \
    -jobconf  "mapred.job.name=jieba_fenci" \
    -file "./map_inverted.py" \
    -file "./red_inverted.py"

第一阶段中间结果:

最后结果:

这就是召回:token检索item

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

曾牛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值