双向最大匹配分词算法

#!/usr/bin/python

#encoding=gbk

import sys

dictMaxLength = 5

dctDict = {}

encoding=‘gbk‘

‘‘‘

初始化字典、初始化最大词长

‘‘‘

def initDct(dct):

global dctDict

global dictMaxLength

dctobj = open(dct)

for line in dctobj:

line = line.strip()

word = line.split("\t")[0].strip()

dctDict[word] = line

word = word.strip().decode(encoding)

if dictMaxLength < len(word):

dictMaxLength = len(word)

dctobj.close()

‘‘‘

正向最大匹配算法

‘‘‘

def maximunMathching(sent):

global dictMaxLength

global dctDict

index = 0

j = 0

result = ""

sent = sent.strip().decode(encoding)

sentLen = len(sent)

while(index < sentLen):

for i in range(dictMaxLength, 0, -1):

j = i + index

if j > sentLen:

j = sentLen

sub = sent[index:j]

if len(sub) > 1:

if dctDict.has_key(sub.encode(encoding)):

index += i

result += sub.encode(encoding) + " "

break;

else:

index += i

if not sub.encode(encoding) == " ":

result += sub.encode(encoding) + " "

break

return result.strip()

‘‘‘

逆向最大匹配算法

‘‘‘

def reverseMaximunMathching(sent):

global dctDict

global dictMaxLength

sb = ""

sent = sent.strip().decode(encoding)

index = len(sent)

j = 0

list = []

while index >= 0:

for i in range(dictMaxLength, 0, -1):

j = index - i

if j < 0: j = 0

sub = sent[j:index]

if len(sub) > 1:

if dctDict.has_key(sub.encode(encoding)):

list.append(sub.encode(encoding))

index = index - i

break;

else:

if not sub.encode(encoding) == " ":

list.append(sub.encode(encoding))

index = index - i

break

list.reverse()

return " ".join(list)

‘‘‘

非字典词、单字字典词、总词数 越少越好

‘‘‘

def segmenter(sent):

mm = maximunMathching(sent).strip()

rmm = reverseMaximunMathching(sent).strip()

if mm == rmm:

return mm

else:

return bmmResult(mm, rmm)

‘‘‘

非字典词、单字字典词、总词数 越少越好

‘‘‘

def bmmResult(mm, rmm):

#print mm

#print rmm

global dctDict

mmlist = mm.split(" ")

rmmlist = rmm.split(" ")

oovNum_mm = 0

oovNum_rmm = 0

sigNum_mm = 0

sigNum_rmm = 0

totNum_mm = len(mmlist)

totNum_rmm = len(rmmlist)

for word in mmlist:

if not dctDict.has_key(word):

oovNum_mm += 1

if len(word.decode(encoding)) == 1:

sigNum_mm += 1

for word in rmmlist:

if not dctDict.has_key(word):

oovNum_rmm += 1

if len(word.decode(encoding)) == 1:

sigNum_rmm += 1

MMWMix = 0

RMMNWMix = 0

if oovNum_mm > oovNum_rmm:

RMMNWMix += 1

elif oovNum_mm < oovNum_rmm:

MMWMix += 1

if sigNum_mm > sigNum_rmm:

RMMNWMix += 1

elif sigNum_mm < sigNum_rmm:

MMWMix += 1

if totNum_mm > totNum_rmm:

RMMNWMix += 1

elif totNum_mm < totNum_rmm:

MMWMix += 1

#print oovNum_mm, sigNum_mm, totNum_mm

#print oovNum_rmm, sigNum_rmm, totNum_rmm

if MMWMix < MMWMix:

return mm

else:

return rmm

def handleFile(input, output):

inputobj = open(input)

outputobj = open(output,"w")

index = 0

for line in inputobj:

index += 1

if index % 100000 == 0:

print str(index) + "\r"

line = line.strip().lower()

seg = segmenter(line)

outputobj.write(seg.strip() + "\n")

inputobj.close()

outputobj.close()

if __name__ == ‘__main__‘:

if len(sys.argv) != 4:

print "Usage %s dict[in] inFile[in] outFile[out]." %sys.argv[0]

sys.exit(-1)

dct = sys.argv[1]

input = sys.argv[2]

output = sys.argv[3]

initDct(dct)

#sent = "chien中华人民共和国在1949年成立了"

#print segmenter(sent)

handleFile(input, output)

时间: 2024-10-07 05:30:14

双向最大匹配分词算法的相关文章

最大匹配分词算法

全文检索有两个重要的过程: 1分词   2倒排索引 我们先看分词算法 目前对中文分词有两个方向,其中一个是利用概率的思想对文章分词. 也就是如果两个字,一起出现的频率很高的话,我们可以假设这两个字是一个词.这里可以用一个公式衡量:M(A,B)=P(AB)/P(A)P(B),其中 A表示一个字,B表示一个字,P(AB)表示AB相邻出现的概率,P(A)表示A在这篇文章中的频度,P(B)表示B在这篇文章中的频度.用概率分词的好 处是不需要借助词典的帮助,坏处是算法比较麻烦,效率不高,也存在一定的出错率

逆向最大匹配分词算法C#

逆向顺序 句子:大家好我叫XX我是一名程序员 程序员 -> 序员 -> 员 名程序 -> 程序 -> 序 一名程 -> 名程 -> 程 是一名 -> 一名 -> 名 我是一 -> 是一 -> 一 X我是 -> 我是 -> 是 XX我  -> X我 -> 我 叫XX  -> XX -> X 我叫X -> 叫X -> X 好我叫 -> 我叫 -> 叫 家好我 -> 好我 -> 我

中文分词常用算法之基于词典的双向最大匹配

算法描述: S1为带切分字符串,FMM为S1正向最大匹配切分结果,BMM为S1逆向最大匹配切分结果 如果FMM和BMM长度不相等则输出长度较短的那个否则转3 如果FMM和BMM的结果相同则输出任意一个否则输出单个字字数最少的结果 Java实现代码: 1 public static List<String> SegDouble(String text) { 2 List<String> FMM = FMM(text); 3 List<String> BMM = BMM(t

NLP: 中文分词算法--正向最大匹配 Forward Maximum Matching

最近接触NLP中文分词, 在lunr.js的基础上, 实现了中文的最大正向匹配分词. 某些情况下, 我们在服务器端进行中文文本分词可以使用完整的基于mmseg算法的分词模块, 例如nodejieba, node-segment, 盘古分词等等,  但是在客户端环境下, 我们不能使用这些复杂的分词算法进行分词, 这个时候可以根据已经生成的索引进行简单的客户端分词, 就是所说的FMM (Forward Maximum Matching, 正向最大匹配), 有时候也可以使用正向匹配. 在做FMM的时候

浅谈分词算法(2)基于词典的分词方法

[TOC] 前言 在浅谈分词算法(1)分词中的基本问题中我们探讨了分词中的基本问题,也提到了基于词典的分词方法.基于词典的分词方法是一种比较传统的方式,这类分词方法有很多,如:正向最大匹配(forward maximum matching method, FMM).逆向最大匹配(backward maximum matching method,BMM).双向扫描法.逐词遍历法.N-最短路径方法以及基于词的n-gram语法模型的分词方法等等.对于这类方法,词典的整理选择在其中占到了很重要的作用,本

机器学习基础——一文讲懂中文分词算法

在前文当中,我们介绍了搜索引擎的大致原理.有错过或者不熟悉的同学,可以点击下方的链接回顾一下前文的内容. ML基础--搜索引擎基本原理 在介绍爬虫部分的时候,我们知道,爬虫在爬取到网页的内容之后,会先进行一些处理.首先要做的就是过滤掉HTML当中的各种标签信息,只保留最原生的网页内容.之后,程序会对这些文本内容提取关键词. 今天我们就来讲讲关键词提取当中最重要的一个部分--中文分词. 在世界上众多的语言当中,中文算是比较特殊的一种.许多语言自带分词信息,比如英文,机器学习写作machine le

Mmseg中文分词算法解析

@author linjiexing 开发中文搜索和中文词库语义自己主动识别的时候,我採用都是基于mmseg中文分词算法开发的Jcseg开源project.使用场景涉及搜索索引创建时的中文分词.新词发现的中文分词.语义词向量空间构建过程的中文分词和文章特征向量提取前的中文分词等,整体使用下来,感觉jcseg是一个非常优秀的开源中文分词工具,并且可配置和开源的情况下,能够满足非常多场景的中文分词逻辑.本文先把jcseg使用到最主要的mmseg算法解析一下. 1. 中文分词算法之争 在分析mmseg

浅谈分词算法(1)分词中的基本问题

[TOC] 前言 分词或说切词是自然语言处理中一个经典且基础的问题,在平时的工作中也反复的接触到分词问题,用到了不同的模型,不同的方法应用在各个领域中,所以想对分词问题做一个系统的梳理.大多数分词问题主要是针对类似汉语.韩语.日语等,词语之间并没有天然的分割,而像英语等,句子中是带有天然的分割的.但是英语也会涉及到分词问题,比如实体识别.词性标注等内容.而本系列文章更多的是讨论汉语中的分词问题,首先我们从分词问题的基本出发,之后从传统的词典分词到将分词转为序列标注问题的分词,以及最新的结合深度学

中文分词算法综述

英文文本词与词之间以空格分隔,方便计算机识别,但是中文以字为单位,句子所有字连起来才能表达一个完整的意思.如英文"I am writing a blog",英文词与词之间有空格进行隔开,而对应的中文"我在写博客",所有的词连在一起,计算机能很容易的识别"blog"是一个单词,而很难知道"博"."客"是一个词,因此对中文文本序列进行切分的过程称为"分词".中文分词算法是自然语言处理的基础,