python中文分词统计词频,中文分词算法python
今天是星期天,天气很潮湿,回到南方的广州,无论天气多么恶劣,我都不能停止学习。
所有进入自然语言的人学习的第一步都是从分词开始的,类似于编程中的“Hello World”。以下两种方法是基于枚举法和粗糙皮卡丘算法实现分词。
1.基于枚举法构建中文分词工具。
最简单的分词和句子之间的关系无关。每个单词都是独立的,称为单字。
模型有unigram-bi-gram-n-gram,意思是n依赖于n个级别。
本项目所需的数据:
语文词典当词典用。
也可以提供一部分unigram概率word_prob作为变量,使用字典计算字数。
比如给字典=【人工智能学习人工智能的未来】,也给单组概率。P (we) is=0.25,p)学习)为0.15,p)人工)is=0.05,p)智能为0.1,p)人工智能为0.2。
第一步:对于给定的字符串,表示“学习人工智能。人工智能是未来”,找到所有可能的细分方法。
【我们,学习,人工智能,人工智能,对,未来】
【我们,学习,人工,智能,人工智能,对,未来】
【我们,学习,人工,智能,人工,智能,对,未来】
【我们,学习,人工智能,人工,智能,是的,未来】…………。
第二步:你也可以计算切割后每个句子的概率。
p)我们,学习,人工智能,人工智能,对,未来(-log p (-log p)),学习)-log p),人工智能(-log p),对(-future)。
p)我们,学习,人工,智能,人工智能,对,未来(-log p(我们)-log p),学习(-log p),人工(-log p),智能(-log p),人工智能(log p)
p)我们,学习,人工,智能,人工,智能,对,未来(-log p(我们)-log p)学习)-log p(人工)-log p(人工))智能)
p)我们,学习,人工智能,人工智能,对,未来(-log p(我们)-log p),学习)-log p),人工智能(-log p),智能(log )-log p)。
第三步:返回第二步中概率最高的结果,-log和最小的结果。
TODO:第一步:从dict.xlsx中读取所有中文
导入xlrd
导入匹配
excel _ data=xlrd.open _ workbook(。/data/dict.xlsx ).
工作表名称=excel _ data.sheet _ by _ index(
col _ data=sheet _ name . col _ values(0)
Dic_words=col_data #保存在字典中读到的单词。
使用计算中获得的下列字数。计算切分单词时,如果满足以下要求,则使用以下字数,否则,全部取0.00001。
很多字都是0.00001,小数点太多,取log的值就干净了。
Word_prob={ 北京:0.03, s: 0.08,日期:0.005,气:0.005,天气:0.06,真 33600.04
现在:0.01,今天:0.07,阶级:0.06,内容:0.05,非常:0.03,非常:0.04,非常
程:0.005,经常:0.08,意见:0.08,意向:0.001,意见:0.005,意见:0.02,不同意。
#因为所有的计算都是负数,所以当加上-减号时是正数,todo计算-log(x)
对于word_prob.keys()中的word:
word _ prob[word]=round(-math . log)word _ prob[word],1)
print(word_prob.values()
image.png
获取下一个输入句子,获取所有分词,主要使用递归。
defword_break(input_str,dic_words):
ef句子(当前) :
结果=[]
如果弯曲
fornextinrange(cur1,Len ) input_str )1):
if(input_str[cur:n])
ext] in dic_words):
result=result[input _ str[cur:next](tail和, tail) for tail in sentences(next)]
否则:
返回[]
回送结果
word_seg=[]
对于句子中的行(0):
line=line.split(,)
word_seg.append(行)
返回word_seg
划分输入字符串,返回所有可能分词后的结果。
对于每个返回的结果,计算句子的概率。
返回最高概率作为最终结果。
def word _ segment _ naive(input _ str):
1.划分输入字符串,返回所有可能分词后的结果。
2.为每个返回的结果计算句子的概率。
3.返回概率最高的一个作为最终结果
Input_str:输入字符串输入格式:“今天天气很好”
Best_segment:最佳分词结果输出格式:[Today , Weather , Good]
TODO:第一步:计算所有可能的分词结果,确保每个单词都在字典里。这个结果可能很多。
Segments=word _ break (input _ str,DIC _ words) #存储所有分词的结果。如果辅助字符串不能完全拆分,则返回一个空列表。
格式为:segments=[今日,天气,好],[日,日,气,好],[今日,日,天气,好],]
TODO:第二步:循环所有分词结果,计算概率最大的分词结果,返回。
best_segment=[]
Best_score=math.inf #无穷大
对于分段中的分段:
分数=0
# TODO.
对于seg中的单词:
如果word_prob.keys()中的字:
score=word_prob[word]
否则:
score=round(-math.log(0.00001),1)
#每次判断score的值,最小的是最有可能的。
如果得分最高_得分:
best _ score=分数
最佳细分市场=细分市场
返回最佳细分市场
试验结果
Print (word_segment_naive(你总是负责))
Print (word_segment_naive(今天的课程内容很有趣))
Print (word_segment_naive(常有意见分歧))
最佳分割结果如下图所示:
Participle.png
总结:枚举分词不仅时间复杂度高,空间复杂度也高。如果数据量很大,是一种非常悲观的实现方法。还有比这更好的方法吗?当然,算法那么厉害,只要发现点什么。然后看粗糙的皮卡丘算法(vitebi)实现分词工具。
第二,基于粗糙皮卡丘算法优化上述过程。
粗糙皮卡丘算法采用动态规划算法,解决小问题成就大问题。
粗糙皮卡丘算法通过根据前缀字典生成所有可能的分词有向无环图(DAG)来实现分词。什么是有向无环图(DAG),如下图所示:
达格map.png
第一步:根据字典、输入的句子和word_prob创建一个加权有向图。
第二步:编写粗略的viterebi算法,寻找最佳路径,即最佳句子切分。
第三步:返回结果
1.创建DAG
def DAG(句子):
DAG={}
N=长度(句子)
对于范围(N)中的k:
tmplist=[]
i=k
frag=句子[k]
当我
if frag in word_prob.keys():
tmplist.append(i)
i=1
frag=句子[k:i 1]
#如果你没有得到任何,只是你自己
如果不是tmplist:
tmplist.append(k)
DAG[k]=tmplist
返回DAG
Print(DAG(今天的课程内容很有意思))
输出结果为:{0: [0,1],1: [1],2: [2],3: [3,4],4: [4],5: [5,6],6: [6],7: [7],8: [8,8]
就是找出所有分词情况的有向图。比如0:[0,1]表示0是起始字的位置,后面跟着可以和在哪个位置的字组成的下标。意思是“经典,常”,通常有两种表达方式。
找到最好的句子分段。
def best_path(句子,DAG):
n=长度(句子)
路由={}
route[N]=(0,0)
对于范围内的idx(N- 1,-1,-1):
distance=((word _ prob . get(sentence[idx:x 1])或0) route[x 1][0],x) for x in DAG[idx])
route[idx]=min(距离)
#获取最大概率值和最后一个字
打印(路线)
返回路线
找到最佳细分。
# TODO:步骤3:根据最佳路径返回最佳分割
N=len(输入字符串)
seg=[]
x=0
而x
y=路线[x][1] 1
seg.append(输入字符串[x:y])
x=y
打印(分段)
试验
#测试
Print (word_segment_viterbi(北京多美的一天))
Print (word_segment_viterbi(今天的课程内容很有意思))
Print (word_segment_viterbi(常有意见分歧))
[北京, s ,天气,不错,啊]
[今天,课程,内容,非常,有趣]
[经常,是,意见,分歧]
TODO:第一种方法和第二种方法的时间复杂度和空间复杂度分别是多少?
第一种方法:
时间复杂度=n 2logn,空间复杂度=O(N)
第二种方法:
时间复杂度=N^2,空间复杂度=O(1)
所以显然,使用粗糙皮卡丘算法在时间和空间上都是非常经济的。
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。