搭建中文分词工具——递归方法
基于递归方法搭建中文分词系统
step1:对于给定的字符串,找出所有可能的分割方式
step2:计算出每个切分之后句子的概率
step3:返回第二部中概率最大的结果
import pandas as pd
import math
# 读取文件中所有的中文词汇
file_path = r"./data/综合类中文词库.xlsx"
dic = pd.read_excel(file_path, header = None)
dic_words = set(dic[0].tolist()) # 保存词典库中读取的单词
# 以下是每一个单词出现的概率。为了问题的简化,我们只列出了一小部分单词的概率。 在这里没有出现的的单词但是出现在词典里的,统一把概率设置成为0.00001
# 比如 p("学院")=p("概率")=...0.00001
word_prob = {"北京":0.03,"的":0.08,"天":0.005,"气":0.005,"天气":0.06,"真":0.04,"好":0.05,"真好":0.04,"啊":0.01,"真好啊":0.02,
"今":0.01,"今天":0.07,"课程":0.06,"内容":0.06,"有":0.05,"很":0.03,"很有":0.04,"意思":0.06,"有意思":0.005,"课":0.01,
"程":0.005,"经常":0.08,"意见":0.08,"意":0.01,"见":0.005,"有意见":0.02,"分歧":0.04,"分":0.02, "歧":0.005}
print (len(dic_words))
print (sum(word_prob.values()))
# 计算 -log(x)
for i in word_prob.keys():
word_prob[i] = round(-math.log(word_prob[i]),2)
298032
1.0000000000000002
# 字符串分词
def word_segment_naive(input_str):
# 第一步: 计算所有可能的分词结果,要保证每个分完的词存在于词典里,这个结果有可能会非常多。
segments = [] # 存储所有分词的结果。如果次字符串不可能被完全切分,则返回空列表(list)
len_input_str = len(input_str)
if len_input_str == 0: # 空字符串
return [[]]
else:
result = []
for i in range(1, len(input_str) + 1):
if input_str[:i] in dic_words:
for remain_segment in word_segment_naive(input_str[i:]):
result.append([input_str[:i]] + remain_segment)
return result
segments = word_segment_naive("北京的天气真好")
print(segments)
[['北', '京', '的', '天', '气', '真', '好'], ['北', '京', '的', '天', '气', '真好'], ['北', '京', '的', '天气', '真', '好'], ['北', '京', '的', '天气', '真好'], ['北京', '的', '天', '气', '真', '好'], ['北京', '的', '天', '气', '真好'], ['北京', '的', '天气', '真', '好'], ['北京', '的', '天气', '真好']]
# 循环所有的分词结果,并计算出概率最高的分词结果,并返回
best_segment = []
best_score = math.inf
for seg in segments:
score = 0
for word in seg:
if word in word_prob.keys():
score += word_prob[word]
else:
score += round(-math.log(0.00001), 2)
if score < best_score:
best_score = score
best_segment = seg
print(best_segment)
print(best_score)
['北京', '的', '天气', '真好']
12.07