新词发现算法

新词发现

基于统计的经典算法(无监督学习):基于已有的大量语料,枚举可能所有新词(原始字的顺序组合,限制长度为 n-gram),然后计算一些统计指标(主要是 凝固度、自由度)进行过滤,尽量准确地筛选出潜在的新词。产出的新词还是需要进行人工审核确认。

凝固度

这是一个类似互信息 Mutual Information 的概念,衡量两个字之间的相关性,是否经常“凝固”在一块儿出现,足够组成新的词。

2-gram 的凝固度计算

凝 固 度 = p ( a b ) p ( a ) p ( b ) 凝固度 = \frac{p(ab)}{p(a)p(b)} =p(a)p(b)p(ab)
使用两个字的联合概率与各自边缘概率乘积的比值,比值越高越发“凝固”。

  • 如果 a、b 两个字只是碰巧走到一起,足够的语料上应该会统计出 p ( a ) p ( b ) ≈ p ( a b ) p(a)p(b)\approx p(ab) p(a)p(b)p(ab),他们之间没有任何关联, 凝 固 度 ≈ 1 凝固度 \approx 1 1

  • 如果 a、b 两个字极其相关,必定同时出现,应该统计有 p ( a ) ≈ p ( a b ) p(a)\approx p(ab) p(a)p(ab) 凝 固 度 ≈ 1 / p ( b ) 凝固度 \approx 1/p(b) 1/p(b),一般情况下远远大于1。

3-gram 的凝固度计算

凝 固 度 = m i n ( p ( a b c ) p ( a b ) p ( c ) , p ( a b c ) p ( a ) p ( b c ) ) 凝固度 = min(\frac{p(abc)}{p(ab)p(c)},\frac{p(abc)}{p(a)p(bc)}) =min(p(ab)p(c)p(abc),p(a)p(bc)p(abc))
对于较长的组合,计算公式会较繁琐;分母仍然是固定的联合概率,但是分子需要在任意两个子串中,选择同时出现概率最大的组合,让凝固度最小。

对于 4-gram 的凝固 ‘abcd’,就需要考虑 (‘a’, ‘bcd’), (‘ab’, ‘cd’), (‘abc’, ‘d’) 3种子串组合。

另外注意:不同 n-gram 的凝固度数值很不一样,n-gram 字数越大,统计越不充分,越有可能偏高(所以应该设置更高阈值)。

自由度

这里统计的是候选词左、右侧的其他字词分布情况(计算信息熵),考察其上下文是否足够丰富(熵足够大,搭配足够不确定),一个足够独立的词应该会被应用在不同上下文中。

一些凝固度高的半词结果如 “俄罗”、“巧克”,可以通过自由度的阈值筛选过滤掉。当然,一些自由度高的短语组合如 “吃了一顿”、“看了一遍”,又需要使用凝固度来过滤掉。

计算

不管多长的候选词,我们看的都是其左、右侧的自由度,所以任意 n-gram 公式一致。

熵的标准公式:

H ( x ) = − ∑ ( x ∈ X ) P ( x ) l o g 2 P ( x ) H(x)=-\sum (x\in X)P(x)log_2P(x) H(x)=(xX)P(x)log2P(x)

自由度:

自 由 度 = m i n ( H ( l e f t ) , H ( r i g h t ) ) 自由度 = min(H(left), H(right)) =min(H(left),H(right))

分别求取候选词左、右侧分布的熵,选较小值为最终自由度。

  • 如果某一侧的搭配是完全确定的(如统计 “俄罗” 右侧100%搭配 “斯”),熵为0, 自 由 度 = 0 自由度 = 0 =0
  • 如果两侧都有非常多搭配,且概率平均,不确定性就很大,熵很大(接近上限 0 ≤ H ≤ l o g ∣ X ∣ 0\le H \le log|X| 0HlogX),自由度很大。

新词筛选

筛选主要涉及3个阈值:

  • 词频:出现频率越高的组合,成词可能性越大
  • 凝固度:越发凝固的组合,成词可能性越大
  • 自由度:组合对应的Context越发自由,成词可能性越大

具体阈值选择,不同语料会有较大差异。
网络blog上介绍的经验公式(30M文本,字母 n 表示 n-gram 即相关新词包含的字数):

  • 词频>200, 凝固度> 1 0 ( n − 1 ) 10^{(n-1)} 10(n1), 自由度>1.5;
  • 词频>30, 凝固度> 2 0 ( n − 1 ) 20^{(n-1)} 20(n1)也能发现很多低频的词汇。

中文编码

开发期间遇到一些 python 中文编码处理的坑,记录一下解决方法:

  • py 文件开头声明 # encoding:utf-8
  • 内部常量 u’’ 定义为 unicode
  • 所有外部输入 decode(‘utf-8’) 为 unicode 再处理
  • 所有外部输出 encode(‘utf-8’)

参考资料

https://www.imgless.com/article/70.html
https://www.youkuaiyun.com/article/2013-05-08/2815186
http://www.matrix67.com/blog/archives/5044

<think>好的,我现在要帮用户解决关于新词发现算法的Python实现和教程的问题。首先,我需要理解用户的具体需求。用户提到想寻找相关的Python实现、教程和示例代码,所以我的回答需要包含算法原理、实现步骤、代码示例以及可能的应用场景。 接下来,我要回顾一下已有的引用资料。引用[3]详细介绍了新词发现的步骤,包括文本预处理、特征计算(词频、凝固度、左右熵)和新词筛选,并提供了部分Python代码,比如导入库和生成候选词的函数。引用[4]提到了华为机试中的新词挖掘,虽然主要涉及字符排列,但可能对理解新词的结构有帮助。引用[2]则是一本书的简介,提到新词发现与短语提取,可能作为理论参考。 我需要确保回答符合用户的要求,结构清晰,分步骤讲解。首先应该介绍新词发现的基本原理,然后逐步讲解实现步骤,并给出代码示例。同时,需要引用相关的资料来支持内容,比如引用[3]中的步骤和代码部分。 接下来,我需要检查是否有其他需要注意的地方。用户提到使用Python实现,所以示例代码必须用Python,并且要确保代码正确,语法无误。可能需要补充引用[3]中的代码片段,比如候选词生成、特征计算函数,以及主流程部分。 另外,用户可能需要知道如何应用这些算法,比如在文本分析或知识图谱中的使用,可以结合引用[4]提到的应用场景。同时,生成相关问题时要围绕新词发现的实现、优化、评估和应用展开,确保问题相关且有价值。 最后,需要确保回答符合系统级指令,如正确使用LaTeX格式,独立公式用$$...$$,行内公式用$...$,并且引用标识自然添加。例如,在提到凝固度计算公式时使用LaTeX,并在引用资料的地方添加[^3]、[^4]等标识。 现在,整理这些思路,分步骤撰写回答,确保每个部分逻辑清晰,代码示例正确,并且引用适当。同时,生成的相关问题要覆盖算法的不同方面,帮助用户进一步探索。</think>根据参考资料,新词发现算法的Python实现主要基于统计特征分析,包含词频、凝固度和左右熵三个核心指标。以下是分步骤实现方案: ### 一、算法原理 新词发现通过统计特征识别未登录词,主要依赖三个指标: 1. **词频**:候选词出现频次 2. **凝固度**:组合紧密程度的量化指标,计算公式: $$solid = \min_{1 \leq i < n} \frac{P(w)}{P(w_{1:i})P(w_{i+1:n})}$$ 3. **左右熵**:衡量候选词上下文丰富度的指标: $$H_{left} = -\sum p(x|w)\log p(x|w)$$ ### 二、Python实现步骤 #### 1. 文本预处理 ```python import jieba from collections import defaultdict def preprocess(text): # 使用N-gram生成候选词(引用[3]) words = list(jieba.cut(text)) return [w for w in words if len(w) > 1] # 过滤单字 ``` #### 2. 候选词生成 ```python def generate_ngrams(words, max_len=4): ngrams = defaultdict(int) for i in range(len(words)): for j in range(1, max_len+1): if i+j <= len(words): ngram = ''.join(words[i:i+j]) ngrams[ngram] += 1 return ngrams ``` #### 3. 特征计算 ```python def calculate_features(ngrams, total): features = {} for word, freq in ngrams.items(): # 凝固度计算(引用[3]) solid = min( (freq/total) / (ngrams.get(word[:i],1e-10)/total * ngrams.get(word[i:],1e-10)/total) for i in range(1, len(word)) ) # 左右熵计算(需要上下文统计) features[word] = { 'freq': freq, 'solid': solid, 'entropy': 0 # 需补充上下文统计 } return features ``` #### 4. 新词筛选 ```python def filter_new_words(features, freq_thresh=5, solid_thresh=10): return [ word for word, feat in features.items() if feat['freq'] >= freq_thresh and feat['solid'] >= solid_thresh ] ``` ### 三、完整调用示例 ```python text = "自然语言处理需要发现新词如深度学习模型transformer" words = preprocess(text) ngrams = generate_ngrams(words, max_len=4) features = calculate_features(ngrams, len(words)) new_words = filter_new_words(features) print("发现新词:", new_words) # 输出可能包含"深度学习","transformer"等 ``` ### 四、应用场景 1. 知识图谱补全(引用[4]) 2. 搜索引擎查询扩展 3. 社交媒体新热词挖掘
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值