新词发现的学习和代码
梳理一遍整个思路:
目的:新词发现
为此,你需要干嘛?
- 文本, 文本的词的划分, 划分的合理性
1.1 文本: 网上随便download一个
1.2 文本的词的划分:划窗—ngram() - 划分的合理性
2.1 内部的稳定性—内部的凝固度–互信息
1nlogp(W)p(c1)p(c2)⋅(cn)\cfrac{1}{n}\log{\cfrac{p(W)}{p(c_1)p(c_2)\cdotp(c_n)}} n1logp(c1)p(c2)⋅(cn)p(W)
- p(W)p(W)p(W)表示该划分下,该词词出现的概率,
- p(c1),p(c2),…,p(cn)p(c_1), p(c_2), \dots, p(c_n)p(c1),p(c2),…,p(cn)表示该词对应的每一个字出现的概率,
- nnn表示nnn个字的词组成WWW
2.2 外部的多变—熵---左右熵
H(U)=E[−logpi]=∑i=1npilogpiH(U) = E{[-\log{p_i}]} = \sum\limits_{i=1}^{n}{p_i \log{p_i}} H(U)=E[−logpi]=i=1∑npilogpi
代码实现:用类来实现
- 文本加载 load_corpus
class NewWordDetect:def __init__(self, corpus_path):self.corpus_path = corpus_pathself.max_word_length = 5self.word_count = defaultdict(int)self.left_neighbor = defaultdict(dict)self.right_neighbor = defaultdict(dict)self.load_corpus(self.corpus_path)self.calc_pmi()self.calc_entropy()self.calc_word_values()
之后对于每一个函数的定义,第一个加载load_corpus(), 加载的同时 我希望实现划分,对于划分,定义一个函数来实现(ngram_count)-----
对于ngram_count函数,需要实现划分,对于一个未知的新词,可以直接用划窗实现, 但是我们还需要考虑左右邻,用于计算左右熵,因此可以同时进行,这样一次文本的扫描就可以完成我们对于任务的需求,节约时间成本。
接下来实现ngram_count函数
def ngram_count(self, sentence, word_length):for i in range(len(sentence) - word_length + 1):word = sentence[i:i + word_length]word_count[word] += 1# 是否为第一个词if i > 1:char = sentence[i-1]self.left_neighbor[word][char] = self.left_neighbor[word].get(char, 0) + 1if i + word_length < len(sentence):char = sentence[i + word_length]self.right_neighbor[word][char] = self.right_neighbor[word].get(char, 0) + 1return
接下来可以加载语料了
def load_corpus(self):with open(self.corpus_path, encoding='utf8') as f:for line in f:sentence = line.strip()for word_length in range(1, self.max_word_length):self.ngram_count(sentence, word_length)return
接下来 计算互信息和左右熵,先计算左右熵,需要先计算出每一个词的左熵,右熵
先根据公式定义熵函数
def calc_entropy_by_word_count_dict(self, word_count_dict):total = sum(word_count_dict.values())entropy = sum([-(c / total) * math.log((c / total), 10) for c in word_count_dict.values()])return entropy
计算左右熵
def calc_entropy(self):self.word_left_entropy = {}self.word_right_entropy = {}for word, count_dict in self.left_neighbor.items():self.word_left_entropy = self.calc_entropy_by_word_count_dict(count_dict)for word, count_dict in self.right_neighbor.items():self.word_right_entropy = self.calc_entropy_by_word_count_dict(count_dict)return
接下来计算互信息,内部凝固度,p(ci)p(c_i)p(ci)是字的概率,p(W)p(W)p(W)是词的概率,所以需要先计算出不同词长度的个数(字是词长度为1的词长度)
def calc_total_count_by_lenght(self):self.word_count_by_length = defaultdict(int)for word, count in word_count.items():word_count_by_length[len(word)] += count return
计算互信息
def calc_pmi(self):self.calc_total_count_by_lenght()self.pmi = {}for word, count in self.word_count.items():p_word = count / self.word_count_by_length(len(word))p_char = 1for char in word:p_char *= self.word_count[char] / self.word_count_by_length[1]self.pmi[word] = math.log(p_word / p_char, 10) / len(word)return
计算词的值
def calc_word_values(self):self.word_values = {}for word in self.pmi:if len(word) < 2:continuele = self.word_left_entropy.get(word, 1e-3)re = self.word_right_entropy.get(word, 1e-3)self.word_values[word] = self.pmi[word] * min(re, le)return
运行
if __name__ == "__main__":nwd = NewWordDetect("sample_corpus.txt")# print(nwd.word_count)# print(nwd.left_neighbor)# print(nwd.right_neighbor)# print(nwd.pmi)# print(nwd.word_left_entropy)# print(nwd.word_right_entropy)value_sort = sorted([(word, count) for word, count in nwd.word_values.items()], key=lambda x:x[1], reverse=True)print([x for x, c in value_sort if len(x) == 2][:10])print([x for x, c in value_sort if len(x) == 3][:10])print([x for x, c in value_sort if len(x) == 4][:10])
结果:
['迁移', '考虑', '尽管', '任务', '整句', '优势', '研究', '接受', '包括', '语言']
['训练集', '经网络', '大匹配', '情况下', '历史性', 'CRF', '半监督', '然语言', 'Kit', '事实上']
['神经网络', '自然语言', '最大匹配', 'RF标注', '信息处理', '十年回顾', 'gram', ' Kit', '技术进步', '统计度量']
新词发现的学习和代码相关推荐
- 无监督构建词库:更快更好的新词发现算法
作者丨苏剑林 单位丨追一科技 研究方向丨NLP,神经网络 个人主页丨kexue.fm 新词发现是 NLP 的基础任务之一,主要是希望通过无监督发掘一些语言特征(主要是统计特征),来判断一批语料中哪些字 ...
- Python自然语言处理相,新词发现,主题模型,隐马尔模型词性标注,Word2Vec,情感分析...
向AI转型的程序员都关注了这个号???????????? 机器学习AI算法工程 公众号:datayx 代码环境:python --version 3.5.2 tensorflow keras 代码 ...
- 切切切词!新词发现算法TopWORDS的原理及实现|实在智能AI+RPA学院
切切切词!新词发现算法TopWORDS的原理及实现|实在智能AI+RPA学院 一.介绍 TopWORDS [参考文献1]是发表在PNAS的一种新词发现算法,它在没有任何先验知识的条件下,快速地从大规模 ...
- python实现词语填空_python简单实现新词发现
基于新信息熵的新词发现原理<互联网时代的社会语言学:基于SNS的文本数据挖掘>这篇文章已经讲得非常清楚了,在这里主要是通过代码复现这篇文章. 实现的模块主要分为四个部分:从文章中提取所有可 ...
- 全员学习低代码,一汽大众领跑数智化转型背后的秘密
简介:500位低代码开发者,90%来自一线,低代码开发在一汽-大众百花齐放. 一汽-大众有500位低代码开发者,90%是来自一线的业务人员,他们如何用低代码解决身边的数字化需求?钉钉宜搭<102 ...
- python | 高效统计语言模型kenlm:新词发现、分词、智能纠错
之前看到苏神[重新写了之前的新词发现算法:更快更好的新词发现]中提到了kenlm,之前也自己玩过,没在意,现在遇到一些大规模的文本问题,模块确实好用,前几天还遇到几个差点"弃疗"的 ...
- 互信息和左右熵的新词发现(笔记)
推荐:http://spaces.ac.cn/archives/3491/ http://www.matrix67.com/blog/archives/5044 http://www.hankcs.c ...
- 零基础可以学习低代码吗
有粉丝问,零基础可以学习低代码吗?今天就写一篇博客回答一下这个问题. 先解决零基础学习低代码的原因 我不知道这位粉丝的背景和个人履历,说一说我自己为啥学习低代码.博主08年进入计算机这个行业,头三年是 ...
- 坐标变换学习笔记—代码篇Matlab
坐标变换学习笔记-代码篇Matlab 四元数 →\to→ 旋转矩阵 quat2dcm quat2rotm 四元数 →\to→ 欧拉角 quat2angle quat2eul 旋转矩阵 →\to→ 四元 ...
- Webpack从入门到进阶(二)---附沿路学习案例代码
文章目录 Webpack从入门到进阶(一)---附沿路学习案例代码 一.Webpack简介 1.前端发展的几个阶段 2.前端三个框架的脚手架 3.Webpack是什么? 4.webpack和vite ...
最新文章
- Github标星9k+,超赞的 PyTorch 资源大列表!
- 用1天快速上手org-mode(windows系统)
- Exchange企业实战技巧(16)发布SMTP、POP、IMAP连接信息设置
- 【Tools】XMind8安装教程详解
- CF1540B Tree Array(期望,dp)
- 进程的优先级设置与获取,进程时间
- java手机验证码注册_Java手机验证码注册
- js拆分百分数_计算百分比Javascript
- Linux系统 查看 Vendor id 和Device id
- 信用评分模型详解(下)之 信用评分系统搭建
- 配音是怎么制作出来的,想做出让人惊艳的配音,只需一个小技巧
- 基于OpenCV做图像数据增强(平移、镜像、缩放、旋转、仿射)
- Java 提供给第三方使用接口方法
- anyconnect免密码登录
- c++numeric
- 如何成为专业大数据架构师?
- 百度网址批量提交 百度网站快速收录批量推送提交工具【批量版】
- MAC 与密钥派生函数 KDF
- MySQL与Oracle的应用区别
- Visual Effect Graph魔改录