分词研究中的最小描述长度(Minimum description length)方法

MDL(minimum description length,最小描述长度) 原理是 Rissane 在研究通用编码时提出的。其基本原理是对于一组给定的实例数据 D , 如果要对其进行保存 ,为了节省存储空间, 一般采用某种模型对其进行编码压缩,然后再保存压缩后的数据。同时, 为了以后正确恢复这些实例数据,将所用的模型也保存起来。所以需要保存的数据长度(
比特数) 等于这些实例数据进行编码压缩后的长度加上保存模型所需的数据长度,将该数据长度称为总描述长度。最小描述长度( MDL) 原理就是要求选择总描述长度最小的模型。

最小描述长度在分词中的应用也比较直接,就是将分词视为一种编码方式,如一个字符串,”iloveyou“ ,总共8个符号,就是对应的8个字母,经过分词后就是“i love you”,就只有3个符号,就是3个单词,这样总长度变小了,但是需要额外的信息来记录单词的信息,也就是模型。因此需要的总的长度不一定变小。

最小描述长度具体应用的分词中的计算方式,见paper “Shlomo Argamon, Navot Akiva, Amihood Amir, and Oren Kapah. Efficient unsupervised word
segmentation using minimum description length. In Coling 2004, 2004.”

其基本公式为:

CODE(Data|L) + CODE(L)

其中L是词典,Data是语料

CODE函数表示描述数据需要的最小位数

两个部分中,

CODE(L)就是描述词典所需的信息,也就是记录模型需要信息:

CODE(L) = b*sum(length(w))

其中b表示描述字母集所需要的位数,如2个字母,需要的位数就是1bit,4个就是2bits,依次类推

w表示词典中词的长度

CODE(Data|L)为分词后的语料,记录这样的语料需要的信息:

CODE(Data|L) = -sum[ C(w) * ( log(C(w))-  log(N) )  ]

其中C(w)为语料中词w的出现的次数,N为语料的包含总的词数。

如语料为:Data = w3www2ww3

则语料共有6个词,其中w3的数量为2,w1为1...

这个里面的log应该是以2为底的

举一个简单的例子,两行已经分好词的语料:

a b

ab a ba

字典部分:

共有两个字符,则b=1,即为用一个bit就可以表示a,b两个字母了

共有4个词,a,b,ab,ba

其长度和为1+1+2+2 = 6

则CODE(L)部分的值为1*6 = 6

分词后的语料部分:

语料长度为5个词,则N=5

其中:

a出现2次,则对应的值为2*( log(2)-log(5) ) = -2.64

b,ab,ba均出现1次,对应的值均为1*( log(1)-log(5) ) =-2.32

则CODE(Data|L) ,也就是语料部分的值为 :

-1*(-2.64 -2.32-2.32-2.32 ) = 9.61

则该词语料的总的描述长度 mdl=6+9.61 = 15.61

这个数组其实是描述这个分词方法和对应语料需要的总的信息量。对其取2为底的对数,则值为log2(15.61)=3.9,也就是编码这个分词后的数据,需要的最小2进制位数是4位。

相应的,我们可以计算一下,不经分词,就是只用字母来表示这个语料,需要的信息量约为8.8966,显然,这样的分词方式是得不偿失的,当然,如果词出现很多,分词后记录语料的信息量会是少的。

对应的python代码如下,其中输入文件为分词好的语料,词直接用空格隔开,一行一个句子

#!/usr/bin/env python
#coding=utf-8
import sys
import math
reload(sys)
sys.setdefaultencoding(‘utf-8‘)

#MDL,(minimum description length),最小描述长度
#输入,分好词的文件,格式为 词 空格 词 空格...
word_dict = {}

#加载语料,统计词和词频,用于后续的处理
def load_corpus(word_seq_file_name):
    data_file = open(word_seq_file_name, "r")
    for line in data_file:
        line = line.strip()
        word_list = line.split(" ")
        for word in word_list:
            word_dict.setdefault(word,float(0))
            word_dict[word] += 1
    return 0

#获得字母的描述长度值
#目前只处理单字节的字母
def get_letter_info():
    letter_dict = {}
    #统计letter
    for word in word_dict:
        for letter in word:
            letter_dict.setdefault(letter, 0)
            letter_dict[letter] += 1

    #计算字母的描述长度
    letter_num = float(len(letter_dict))
    letter_info = math.log(letter_num, 2)

    return letter_info

#获得词典的词的总长度
def get_dict_info():
    word_length_sum = 0
    for word in word_dict:
        word_length_sum += len(word)

    return word_length_sum

#获得单词序列的描述长度
def get_word_seq_info():
    word_info_sum = 0
    freq_sum = sum(word_dict.itervalues()) #所有词的词频
    for word in word_dict:
        word_freq = word_dict[word]
        word_info = word_freq * ( math.log(word_freq, 2) - math.log(freq_sum, 2) )
        word_info_sum += word_info

    word_seq_info = -1*word_info_sum
    return word_seq_info

#获得最终的mdl
def get_mdl():
    letter_info = get_letter_info()
    dict_info = get_dict_info()
    word_seq_info = get_word_seq_info()
    mdl = letter_info*dict_info + word_seq_info
    return mdl

if __name__=="__main__":
    if len(sys.argv)!=2:
        print "please input word corpus filename"
        sys.exit()
    load_corpus(sys.argv[1])
    print get_mdl()

数据文件例子:

a b
ab a ba

处理这个文件,获得的值得应该是

15.61

分词研究中的最小描述长度(Minimum description length)方法

时间: 2024-08-27 07:25:25

分词研究中的最小描述长度(Minimum description length)方法的相关文章

java中数组有没有length()方法?string没有lenght()方法?

java中数组有没有length()方法,求数组的长度可以使用数组的length属性. int[] arr={1,2,3,4,5}; int length=arr.length;//求数组的长度 ---------------------------------------------------------------------------------------- String 有length()方法,用来求字符串的长度 String  str="Hello"; int leng

Android开发中,那些让你觉得相见恨晚的方法、类或接口

本篇文章内容提取自知乎android开发中,有哪些让你觉得相见恨晚的方法.类或接口?,其实有一部是JAVA的,但是在android开发中也算常见.大多数的函数自己还是见过的,这里记录一下备忘.同时呢,也推荐一个github项目,里面记录了自己日常开发中见过的比较有用的东西开发中常用的工具.链接 Throwable类中的getStackTrace()方法,根据这个方法可以得到函数的逐层调用地址,其返回值为StackTraceElement[],而在StackTraceElement类中有四个方法g

在传统以太网中,为什么要有最小帧长度和最大帧长度的限制

在传统以太网中,为什么要有最小帧长度和最大帧长度的限制? 以太网(IEEE 802.3)帧格式: 1.前导码:7字节0x55,一串1.0间隔,用于信号同步 2.帧起始定界符:1字节0xD5(10101011),表示一帧开始 3.DA(目的MAC):6字节 4.SA(源MAC):6字节 5.类型/长度:2字节,0-1500保留为长度域值,1536-65535保留为类型域值(0x0600-0xFFFF) 6.数据:46-1500字节 7.帧校验序列(FCS):4字节,使用CRC计算从目的MAC到数据

【LeetCode-面试算法经典-Java实现】【153-Find Minimum in Rotated Sorted Array(找旋转数组中的最小数字)】

[153-Find Minimum in Rotated Sorted Array(找旋转数组中的最小数字)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Suppose a sorted array is rotated at some pivot unknown to you beforehand. (i.e., 0 1 2 4 5 6 7 might become 4 5 6 7 0 1 2). Find the minimum element. You m

【LeetCode-面试算法经典-Java实现】【155-Find Minimum in Rotated Sorted Array II(找旋转数组中的最小数字II)】

[154-Find Minimum in Rotated Sorted Array II(找旋转数组中的最小数字II)] [LeetCode-面试算法经典-Java实现][所有题目目录索引] 原题 Follow up for "Find Minimum in Rotated Sorted Array": What if duplicates are allowed? Would this affect the run-time complexity? How and why? Supp

隐马尔科夫模型(HMM)分词研究

第一部分 模型简介 隐马尔可夫模型是马尔可夫链的一种,它的状态不能直接观察到,但能通过观测向量序列观察到,每个观测向量都是通过某些概率密度分布表现为各种状态,每一个观测向量是由一个具有相应概率密度分布的状态序列产生.所以,隐马尔可夫模型是一个双重随机过程 ----具有一定状态数的隐马尔可夫链和显示随机函数集.自20 世纪80年代以来,HMM被应用于语音识别,取得重大成功.到了90年代,HMM还被引入计算机文字识别和移动通信核心技术"多用户的检测".HMM在生物信息科学.故障诊断等领域也

leetCode 76.Minimum Window Substring(最小窗口子串) 解题思路和方法

Given a string S and a string T, find the minimum window in S which will contain all the characters in T in complexity O(n). For example, S = "ADOBECODEBANC" T = "ABC" Minimum window is "BANC". Note: If there is no such windo

Linux中的文件描述符与打开文件之间的关系

1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符.程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误.如果此时去打开一个新的文件,它的文件描述符会是3.POSIX标准要求每次打开文件时(含socket)必须使用当前进程中最小可用的文件描述符号

每天进步一点点——Linux中的文件描述符与打开文件之间的关系

转载请说明出处:http://blog.csdn.net/cywosp/article/details/38965239 1. 概述 在Linux系统中一切皆可以看成是文件,文件又可分为:普通文件.目录文件.链接文件和设备文件.文件描述符(file descriptor)是内核为了高效管理已被打开的文件所创建的索引,其是一个非负整数(通常是小整数),用于指代被打开的文件,所有执行I/O操作的系统调用都通过文件描述符.程序刚刚启动的时候,0是标准输入,1是标准输出,2是标准错误.如果此时去打开一个