一种没有语料字典的分词方法

2024-02-04 23:50

本文主要是介绍一种没有语料字典的分词方法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

前几天在网上闲逛,看到一篇美文,说的是怎么在没有语料库的情况下从文本中提取中文词汇,理论部分讲得比较多,但都还是很浅显易懂的,其中涉及一部分信息论的理论,其实只要大学开过信息论这门课的话,看起来还是挺简单的。

信息论我忘得差不多了,但是其中主要的内容还记得,信息论最主要的就是信息其实是可以度量的,一个事件包含的信息和它发生的概率成反比,简单的说,同样一个事件,产生A结果的概率为Pa,产生B结果的概率为Pb,如果Pa大于Pb,那A所包含的信息量就比B要大。

打个简单的比喻,比如中国队和西班牙队踢足球比赛,大家都知道,西班牙队赢的概率大概是99.9999%,中国队赢的概率大概是0.0001%,假如最后的结果是中国队赢了(靠实力)的话,那这个事件(中国队赢了西班牙)就是个信息量非常巨大的事件,我相信各大报纸的头条都会报道,反而如果西班牙赢了,估计没有报纸会报道这个消息,这就是信息论的核心,也就是信息熵。

扯远了,上面只是说说我对信息论的理解,在分词技术上,目前的分词技术基本上都是基于字典的,就是看文章中有没有字典含有的词语,如果有,就把这个当成一个词来分,这样也衍生了很多分词技术,大家有兴趣可以自己去查一查。

如果我们没有词典,需要分词就比较麻烦了,假设我们最大的词长度设定为5,能想到的办法就是,从第一个字开始,把文本中所有连在一起的两个字,三个字,四个字,五个字的片段找出来,然后看这些片段在文本中出现的频率,频率高的就当成一个词汇,这样确实能分出词来,但是这样同样也分出了一些不是词的词汇,比如上面的文章中,“的话”这个词就出现的相对比较多,显然,这不是一个词。

在这种基础上怎么把类似“的话”这样的词去掉就是我们要做的工作了。这涉及到两个重要的部分,也是那篇美文提到的两个部分。

第一,怎么去掉类似于“的中国”和“中国队”这样的差异,这三个词可能出现的频率都差不多,甚至“的中国”出现的频率更高,假设对于一个长文本(假设为10000,并且是描述足球比赛的),
“的中国”出现了100次,概率是1%
“中国队”出现了60次,概率是0.6%
“中国”   出现了200次,概率为2%
“的”       出现了500次,概率为5%
“队”       出现了70次,概率为0.7%
这样的数据情况下,“的”字和“中国”随机组合在一起的概率为5%*2%=1%,而“队”和“中国”随机组合在一起的概率为0.7%*2%=0.14%,显然“的中国”的出现概率和他们组合在一起的概率差不多,所以我们认为“的中国”更像是随机组合在一起的词而不是一个固定的词汇,但“中国队”出现的概率比他们组合在一起的概率高了4.28倍,所以我们认为“中国队”更像一个词汇。
通过上面的计算,我们就可以把“的中国”这样的词丢掉了,就算他出现了很多次,但是我们一样不认为它是一个词,这就是第一部分,我们把它叫词语的凝聚程度,“的中国”显然凝聚力不够。


第二,像类似“了一”这样的词在文章中肯定也出现得很多,因为是足球比赛文章,所以经常出现摔了一跤,进了一球等等,显然,“了一”也不是一个词汇,但是单独看“了”和“一”,“了一”的概率可能比他们单独组合的概率高不少,像这样的词怎么弄呢,这就要用到开头我们讲的信息论中的信息熵了。

“信息熵”能够反映知道一个事件的结果后平均会给你带来多大的信息量。如果某个结果的发生概率为 p ,当你知道它确实发生了,你得到的信息量就被定义为 - log(p) 。 p 越小,你得到的信息量就越大。在“了一”这个词中,他的前缀为“摔”,“进”,概率分别是p1,p2那他的前缀信息熵就是- log(p1)*p1-log(p2)*p2,同样后缀的信息熵也可以算出来,算出来以后我们取其中较小的那个作为这个词的前后缀信息熵,结果算出来是一个非常小的数,比如0.2,比普通真实的词汇,比如“摔了一跤”这样的词的信息熵都要小,所以显然可能“了一”就不是一个词汇了,反而“摔了一跤”这样的词更像一个词汇。

有了这两个理论,那我们找出一个词,然后按这两个条件给出一个阈值,就能抽取出一批我们认为是词汇的词语了,不需要字典,而且从抽取出来的词根据词频排列的话,再把一般性的词如“应该”,“如果”,“似乎”这样的介词去掉的话,一般是这个文本的关键字集合了。

嗯,理论部分大概就是这样了,具体的大家要是有兴趣,可以看看这篇blog,我都是看到这个的,顺便推荐一个这个作者,他的文章基本上都是原创,而且对数学理解得很到位,很适合各种程序猿们,呵呵。
http://www.matrix67.com/blog/archives/5044

按照这个东西,我自己写了个python脚本,写得很着急,而且不知道理论理解得对不对,后来我对《明朝那些事》抽了一把,出现了这些:
危险 优秀沉默李景隆影响 杨继盛 痛苦 脑袋 徐有贞厉害支持 蓝玉杨廷和瓦剌申时行 判断 记载 孙承宗坚持愤怒奏疏 锦衣卫 严世蕃 祁钰 倭寇 东林党麻烦朋友 努尔哈赤  选择喜欢容易 首辅 御史李如松 父亲戚继光投降 陈友谅 厚照 希望 蒙古简单估计消息彻底 胡宗宪 祁镇 毕竟 魏忠贤 告诉 袁崇焕 嘉靖 似乎 准备 。。。。。。。。

而对于《时间简史》,出现了这些:
空间时间 吸引增加基本尺度 效应 东西描述轨道
位置 边界产生解释夸克 广义相对论坍缩 辐射 部分
知道 状态区域距离爆炸 问题 奇点模型太阳
事件 科学预言运动膨胀 任何 必须恒星黑洞.......

你修改约束条件,就会出现不同的词语,怎么平衡这个约束条件也是个问题。

另外,如果你有兴趣,可以分析分析一些人的blog和微博之类的,再和你自己的对比一下,说不定能找到很多关键词一样哦,还有,要是你有海量的数据,也可以做一些非常有意思的事情哦,哈哈。


最后,再次推荐一下matirx67的blog:  http://www.matrix67.com/     


程序做得太快了,不好,还是把关键函数贴出来吧,就是暴力的编码,用了python自带的方便的数据结构来快速开发。所以速度上比较慢,而且内存上。。呵呵。。说不定会爆哦。。。。完整程序:
https://github.com/wyh267/ChineseWordSegmentation

# -*- coding=utf-8 -*-
'''
Created on 2013-5-9@author: Wu YingHao@email:  wyh817@gmail.com该程序可以在没有语料库的情况下从文本中抽取出中文词汇
理论支持:
http://www.matrix67.com/blog/archives/5044'''import math"""计算每个字和词的出现频率输入: words 字符串内容num 需要截取的最长字串输出: split_words 分割好的所有子串的数据,以字典形式返回split_words 说明{"字串" : [ 出现次数,出现概率,凝固程度,凝固程度*出现次数,自由程度,前缀集合,后缀集合] .....}
"""
def find_words(words,num=6):split_words={}lens=len(words)for i in range(0,lens):for j in range(1,num+1):if i+j < lens -num-2:if words[i:i+j] in split_words:split_words[words[i:i+j]][0]+=1split_words[words[i:i+j]][1]=float(split_words[words[i:i+j]][0])/float(lens)split_words[words[i:i+j]][6].append(words[i-1])split_words[words[i:i+j]][7].append(words[i+j])else:split_words[words[i:i+j]]=[1,1/float(lens),words[i:i+j],1,1,0,[words[i-1]],[words[i+j]]]if(i%10000==0):print "完成 :" + str(float(i)/float(len(words))*100) + " %"return split_words"""计算凝聚程度输入:words_dic 已经拆分好的字符串字典输出:填充好凝聚程度的字典
"""
def find_nh(words_dic):for key in words_dic.keys():if(len(key)>1):#左凝聚程度left_p=words_dic[key][1]/(words_dic[key[:1]][1]*words_dic[key[1:]][1])#右凝聚程度right_p=words_dic[key][1]/(words_dic[key[:-1]][1]*words_dic[key[:-1]][1])if(left_p<right_p):words_dic[key][3]=left_pelse:words_dic[key][3]=right_p"""计算自由程度输入: word_dic 字典文件返回:word_dic 添加自由程度以后的字典
"""
def calc_free(word_dic):for key in word_dic.keys():front_free=0end_free=0for front in word_dic[key][6]:if front in word_dic:front_free-=math.log(word_dic[front][1])*word_dic[front][1]for end in word_dic[key][7]:if end in word_dic:end_free-=math.log(word_dic[end][1])*word_dic[end][1]if(front_free < end_free):word_dic[key][5]=front_freeelse:word_dic[key][5]=end_freereturn word_dic  


注:本文虽然不是转帖,但是内容参考了matrix67的博客,地址为  http://www.matrix67.com/blog/archives/5044  ,特此声明。


===========================================================================================
欢迎大家关注我的微信号: XJJ267    西加加语言
或者扫描下面的二维码也行哦。


转载于:https://my.oschina.net/wuyinghao/blog/666146

这篇关于一种没有语料字典的分词方法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/679172

相关文章

豆包 MarsCode 不允许你还没有女朋友

在这个喧嚣的世界里,爱意需要被温柔地唤醒。为心爱的她制作每日一句小工具,就像是一场永不落幕的浪漫仪式,每天都在她的心田播撒爱的种子,让她的每一天都充满甜蜜与期待。 背景 在这个瞬息万变的时代,我们都在寻找那些能让我们慢下来,感受生活美好的瞬间。为了让这份浪漫持久而深刻,我们决定为女朋友定制一个每日一句小工具。这个工具会在她意想不到的时刻,为她呈现一句充满爱意的话语,让她的每一天都充满惊喜和感动

中文分词jieba库的使用与实景应用(一)

知识星球:https://articles.zsxq.com/id_fxvgc803qmr2.html 目录 一.定义: 精确模式(默认模式): 全模式: 搜索引擎模式: paddle 模式(基于深度学习的分词模式): 二 自定义词典 三.文本解析   调整词出现的频率 四. 关键词提取 A. 基于TF-IDF算法的关键词提取 B. 基于TextRank算法的关键词提取

【C++】_list常用方法解析及模拟实现

相信自己的力量,只要对自己始终保持信心,尽自己最大努力去完成任何事,就算事情最终结果是失败了,努力了也不留遗憾。💓💓💓 目录   ✨说在前面 🍋知识点一:什么是list? •🌰1.list的定义 •🌰2.list的基本特性 •🌰3.常用接口介绍 🍋知识点二:list常用接口 •🌰1.默认成员函数 🔥构造函数(⭐) 🔥析构函数 •🌰2.list对象

浅谈主机加固,六种有效的主机加固方法

在数字化时代,数据的价值不言而喻,但随之而来的安全威胁也日益严峻。从勒索病毒到内部泄露,企业的数据安全面临着前所未有的挑战。为了应对这些挑战,一种全新的主机加固解决方案应运而生。 MCK主机加固解决方案,采用先进的安全容器中间件技术,构建起一套内核级的纵深立体防护体系。这一体系突破了传统安全防护的局限,即使在管理员权限被恶意利用的情况下,也能确保服务器的安全稳定运行。 普适主机加固措施:

webm怎么转换成mp4?这几种方法超多人在用!

webm怎么转换成mp4?WebM作为一种新兴的视频编码格式,近年来逐渐进入大众视野,其背后承载着诸多优势,但同时也伴随着不容忽视的局限性,首要挑战在于其兼容性边界,尽管WebM已广泛适应于众多网站与软件平台,但在特定应用环境或老旧设备上,其兼容难题依旧凸显,为用户体验带来不便,再者,WebM格式的非普适性也体现在编辑流程上,由于它并非行业内的通用标准,编辑过程中可能会遭遇格式不兼容的障碍,导致操

透彻!驯服大型语言模型(LLMs)的五种方法,及具体方法选择思路

引言 随着时间的发展,大型语言模型不再停留在演示阶段而是逐步面向生产系统的应用,随着人们期望的不断增加,目标也发生了巨大的变化。在短短的几个月的时间里,人们对大模型的认识已经从对其zero-shot能力感到惊讶,转变为考虑改进模型质量、提高模型可用性。 「大语言模型(LLMs)其实就是利用高容量的模型架构(例如Transformer)对海量的、多种多样的数据分布进行建模得到,它包含了大量的先验

【北交大信息所AI-Max2】使用方法

BJTU信息所集群AI_MAX2使用方法 使用的前提是预约到相应的算力卡,拥有登录权限的账号密码,一般为导师组共用一个。 有浏览器、ssh工具就可以。 1.新建集群Terminal 浏览器登陆10.126.62.75 (如果是1集群把75改成66) 交互式开发 执行器选Terminal 密码随便设一个(需记住) 工作空间:私有数据、全部文件 加速器选GeForce_RTX_2080_Ti

【VUE】跨域问题的概念,以及解决方法。

目录 1.跨域概念 2.解决方法 2.1 配置网络请求代理 2.2 使用@CrossOrigin 注解 2.3 通过配置文件实现跨域 2.4 添加 CorsWebFilter 来解决跨域问题 1.跨域概念 跨域问题是由于浏览器实施了同源策略,该策略要求请求的域名、协议和端口必须与提供资源的服务相同。如果不相同,则需要服务器显式地允许这种跨域请求。一般在springbo

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出

AI(文生语音)-TTS 技术线路探索学习:从拼接式参数化方法到Tacotron端到端输出 在数字化时代,文本到语音(Text-to-Speech, TTS)技术已成为人机交互的关键桥梁,无论是为视障人士提供辅助阅读,还是为智能助手注入声音的灵魂,TTS 技术都扮演着至关重要的角色。从最初的拼接式方法到参数化技术,再到现今的深度学习解决方案,TTS 技术经历了一段长足的进步。这篇文章将带您穿越时

POJ2001字典树

给出n个单词,求出每个单词的非公共前缀,如果没有,则输出自己。 import java.io.BufferedReader;import java.io.InputStream;import java.io.InputStreamReader;import java.io.PrintWriter;import java.io.UnsupportedEncodingException;