新词发现算法的python与分布式pyspark实现

1.Python实现新词发现算法

代码基于jupyter notebook

导库

import re 
import sys 
import math 

测试语料

text=['这个程序用来实现新词发现功能','运行完新词发现程序后会得到几个指标','这些指标包括凝固度、左邻熵和右邻熵','依靠计算的几个指标(凝固度、左邻熵和右邻熵),可以发现新词','在做新词发现前,要对语料进行清洗','比如去除字符串里面的字母或数字,像abc、123这种','完']

字符串正则清洗

#字符串正则清洗
def re_filter(line):
    #去除所有非中文汉字、给定标点符号的字符(先保留标点符号,减少一些词错误邻词的出现,包含给定标点符号的词后面会再过滤掉)
    re_comp=re.compile(r'[^-—_,,、/()().。::;;??!!\u4e00-\u9fa5]')
    line=re_comp.sub('',line) 
    return line 

筛选句子长度>=2的

#筛选句子长度>=2的
text=[re_filter(line) for line in text if len(re_filter(line))>=2]
text

切词

#切词,切分后词的长度范围:[min_w_len,max_w_len],max_w_len表示ngrams最长片段字数
def word_split(line,min_w_len,max_w_len):
    w_len=len(line)    
    result=[]
    for l in range(min_w_len,max_w_len+1): #j:切词长度:min_w_len-max_w_len
        for i in range(w_len-l,-1,-1):
            result.append((line[i:i+l],1))
    #返回(word,1)
    return result

计算词频

#计算词频,此处ngrams不建议对词长度或词频做筛选,可能会影响凝固度的计算(凝固度会取组成词的各片段的词频)
from collections import defaultdict
ngrams = defaultdict(int)
min_w_len=1
max_w_len=5
words=[word_split(line,1,5) for line in text]
len(words)
#对列表解除嵌套
words=[item for ls in words for item in ls]
len(words)
words
for item in words:
    if not re.search(r'[-—_,,、/()().。::;;??!!]',item[0]): #去除包含带给定标点符号的词汇
        ngrams[item[0]] += 1 #返回{word,词频}
len(ngrams)
ngrams

计算词总数

#词总数(用于计算凝固度使用)
total=sum([ngrams[key] for key in ngrams])*1.0
total 

获取候选词

#候选词:选长度在2-4的作为最终输出候选词
freq_filter=2 #要保留的最小词频
candi_ngrams={key:ngrams[key] for key in ngrams if len(key)>=2 and len(key)<=4 and ngrams[key]>=freq_filter}
len(candi_ngrams)
candi_ngrams

计算凝固度

#计算凝固度
def coagulation_degree(ngram,ngram_freq): #ngram:词 ngram_freq:词频
    ngram_len=len(ngram) #词的长度
    coagulation=min([ (ngram_freq*total) / (ngrams[ngram[:i+1]]*ngrams[ngram[i+1:]]) for i in range(ngram_len-1)])
    return (ngram,coagulation)
#计算每个候选词的凝固度
coagulation_ngram=[coagulation_degree(ngram,candi_ngrams[ngram]) for ngram in candi_ngrams]
len(coagulation_ngram) 
coagulation_ngram

计算熵

#计算熵
def entropy(ngram,entropy_rl_dict):
    word=ngram #词
    neighbours=entropy_rl_dict[ngram] #所有不同右邻字出现的频次组成的列表
    neighbours_sum=sum(neighbours) #所有不同右邻字出现的频次之和
    prob=map(lambda x:float(x)/neighbours_sum,neighbours) #每个右邻字出现频率/所有右邻字出现的频次之和
    entropy=sum(map(lambda x:-(x)*math.log(x),prob))
    return (word,entropy)

右邻熵

#计算右邻熵
candi_ngrams_keys=set(candi_ngrams.keys()) #所有候选词
#每个候选词的每个右邻字出现的频次,返回(候选词,其某个右邻字出现的频次)
entropy_r=[(key[0:-1],ngrams[key]) for key in ngrams if len(key)>=3 and key[0:-1] in candi_ngrams_keys]
entropy_r

#返回{word,所有不同右邻字出现的频次组成的列表}
entropy_r_dict = defaultdict(list)
for item in entropy_r:
    entropy_r_dict[item[0]].append(item[1]) 
entropy_r_dict 

#计算候选词的右邻熵
entropy_right=[entropy(ngram,entropy_r_dict) for ngram in entropy_r_dict]
entropy_right

左邻熵

#计算左邻熵
#每个候选词的每个左邻字出现的频次,返回(候选词,其某个左邻字出现的频次)
entropy_l=[(key[1:],ngrams[key]) for key in ngrams if len(key)>=3 and key[1:] in candi_ngrams_keys]
entropy_l

#返回{word,所有不同左邻字出现的频次组成的列表}
entropy_l_dict = defaultdict(list)
for item in entropy_l:
    entropy_l_dict[item[0]].append(item[1]) 
entropy_l_dict 

#计算候选词的左邻熵
entropy_left=[entropy(ngram,entropy_l_dict) for ngram in entropy_l_dict]
entropy_left

2.Pyspark实现新词发现算法

TBD…

  • 10
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值