# Python实现mmseg分词算法和吐嘈

1、基础的多线程爬虫

2、分词算法，对用户输入的查找文本进行切割

3、MapReduce，用来统计词语出现的次数，这个直接关系到URL在队列中的等级

4、PageRank，用来给网页排名

5、Web界面

1、南京市长江大桥欢迎您

mmseg：南京市/长江大桥/欢迎您

2、研究生命科学

mmseg：研究/生命/科学

3、长春市长春药店

mmseg：长春市/长春/药店

4、台湾国中学生

mmseg：台湾/国中/学生

Word类就相当于C语言中的结构体，用来存单词和词频的

Chunk类是用来实现具体的切割判断方法的前期预处理计算的

ComplexCompare类是用来具体实现mmseg算法的四种评估方法的

Analysis类是用来具体实现切割算法的

class Word:
def __init__(self,text = '',freq = 0):
self.text = text
self.freq = freq
self.length = len(text)

class Chunk:
def __init__(self,w1,w2 = None,w3 = None):
self.words = []
self.words.append(w1)
if w2:
self.words.append(w2)
if w3:
self.words.append(w3)

#计算chunk的总长度
def totalWordLength(self):
length = 0
for word in self.words:
length += len(word.text)
return length

#计算平均长度
def averageWordLength(self):
return float(self.totalWordLength()) / float(len(self.words))

#计算标准差
def standardDeviation(self):
average = self.averageWordLength()
sum = 0.0
for word in self.words:
tmp = (len(word.text) - average)
sum += float(tmp) * float(tmp)
return sum

#自由语素度
def wordFrequency(self):
sum = 0
for word in self.words:
sum += word.freq
return sum

class ComplexCompare:

def takeHightest(self,chunks,comparator):
i = 1
for j in range(1, len(chunks)):
rlt = comparator(chunks[j], chunks[0])
if rlt > 0:
i = 0
if rlt >= 0:
chunks[i], chunks[j] = chunks[j], chunks[i]
i += 1
return chunks[0:i]

#以下四个函数是mmseg算法的四种过滤原则，核心算法
def mmFilter(self,chunks):
def comparator(a,b):
return a.totalWordLength() - b.totalWordLength()
return self.takeHightest(chunks,comparator)

def lawlFilter(self,chunks):
def comparator(a,b):
return a.averageWordLength() - b.averageWordLength()
return self.takeHightest(chunks,comparator)

def svmlFilter(self,chunks):
def comparator(a,b):
return b.standardDeviation() - a.standardDeviation()
return self.takeHightest(chunks, comparator)

def logFreqFilter(self,chunks):
def comparator(a,b):
return a.wordFrequency() - b.wordFrequency()
return self.takeHightest(chunks, comparator)

#加载词组字典和字符字典
dictWord = {}
maxWordLength = 0

global maxWordLength
fsock = file(filepath)
freq, word = line.split(' ')
word = unicode(word.strip(), 'utf-8')
dictWord[word] = (len(word), int(freq))
maxWordLength = maxWordLength < len(word) and len(word) or maxWordLength
fsock.close()

global maxWordLength
fsock = file(filepath)
word = unicode(line.strip(), 'utf-8')
dictWord[word] = (len(word), 0)
maxWordLength = maxWordLength < len(word) and len(word) or maxWordLength
fsock.close()

#判断该词word是否在字典dictWord中
def getDictWord(word):
result = dictWord.get(word)
if result:
return Word(word,result[1])
return None

#开始加载字典
def run():
from os.path import join, dirname

class Analysis:

def __init__(self,text):
if isinstance(text,unicode):
self.text = text
else:
self.text = text.encode('utf-8')
self.cacheSize = 3
self.pos = 0
self.textLength = len(self.text)
self.cache = []
self.cacheIndex = 0
self.complexCompare = ComplexCompare()

#简单小技巧，用到个缓存，不知道具体有没有用处
for i in range(self.cacheSize):
self.cache.append([-1,Word()])

#控制字典只加载一次
if not dictWord:
run()

def __iter__(self):
while True:
token = self.getNextToken()
if token == None:
raise StopIteration
yield token

def getNextChar(self):
return self.text[self.pos]

#判断该字符是否是中文字符（不包括中文标点）
def isChineseChar(self,charater):
return 0x4e00 <= ord(charater) < 0x9fa6

#判断是否是ASCII码
def isASCIIChar(self, ch):
import string
if ch in string.whitespace:
return False
if ch in string.punctuation:
return False
return ch in string.printable

#得到下一个切割结果
def getNextToken(self):
while self.pos < self.textLength:
if self.isChineseChar(self.getNextChar()):
token = self.getChineseWords()
else :
token = self.getASCIIWords()+'/'
if len(token) > 0:
return None

#切割出非中文词
def getASCIIWords(self):
# Skip pre-word whitespaces and punctuations
#跳过中英文标点和空格
while self.pos < self.textLength:
ch = self.getNextChar()
if self.isASCIIChar(ch) or self.isChineseChar(ch):
break
self.pos += 1
#得到英文单词的起始位置
start = self.pos

#找出英文单词的结束位置
while self.pos < self.textLength:
ch = self.getNextChar()
if not self.isASCIIChar(ch):
break
self.pos += 1
end = self.pos

#Skip chinese word whitespaces and punctuations
#跳过中英文标点和空格
while self.pos < self.textLength:
ch = self.getNextChar()
if self.isASCIIChar(ch) or self.isChineseChar(ch):
break
self.pos += 1

#返回英文单词
return self.text[start:end]

#切割出中文词，并且做处理，用上述4种方法
def getChineseWords(self):
chunks = self.createChunks()
if len(chunks) > 1:
chunks = self.complexCompare.mmFilter(chunks)
if len(chunks) > 1:
chunks = self.complexCompare.lawlFilter(chunks)
if len(chunks) > 1:
chunks = self.complexCompare.svmlFilter(chunks)
if len(chunks) > 1:
chunks = self.complexCompare.logFreqFilter(chunks)
if len(chunks) == 0 :
return ''

#最后只有一种切割方法
word = chunks[0].words
token = ""
length = 0
for x in word:
if x.length <> -1:
token += x.text + "/"
length += len(x.text)
self.pos += length

#三重循环来枚举切割方法，这里也可以运用递归来实现
def createChunks(self):
chunks = []
originalPos = self.pos
words1 = self.getMatchChineseWords()

for word1 in words1:
self.pos += len(word1.text)
if self.pos < self.textLength:
words2 = self.getMatchChineseWords()
for word2 in words2:
self.pos += len(word2.text)
if self.pos < self.textLength:
words3 = self.getMatchChineseWords()
for word3 in words3:
print word3.length,word3.text
if word3.length == -1:
chunk = Chunk(word1,word2)
print "Ture"
else :
chunk = Chunk(word1,word2,word3)
chunks.append(chunk)
elif self.pos == self.textLength:
chunks.append(Chunk(word1,word2))
self.pos -= len(word2.text)
elif self.pos == self.textLength:
chunks.append(Chunk(word1))
self.pos -= len(word1.text)

self.pos = originalPos
return chunks

#运用正向最大匹配算法结合字典来切割中文文本
def getMatchChineseWords(self):
#use cache,check it
for i in range(self.cacheSize):
if self.cache[i][0] == self.pos:
return self.cache[i][1]

originalPos = self.pos
words = []
index = 0
while self.pos < self.textLength:
if index >= maxWordLength :
break
if not self.isChineseChar(self.getNextChar()):
break
self.pos += 1
index += 1

text = self.text[originalPos:self.pos]
word = getDictWord(text)
if word:
words.append(word)

self.pos = originalPos
#没有词则放置个‘X’，将文本长度标记为-1
if not words:
word = Word()
word.length = -1
word.text = 'X'
words.append(word)

self.cache[self.cacheIndex] = (self.pos,words)
self.cacheIndex += 1
if self.cacheIndex >= self.cacheSize:
self.cacheIndex = 0
return words

#-*- coding: utf-8 -*-

from PyMmseg import Analysis

def cuttest(text):
#cut =  Analysis(text)
wlist = [word for word in Analysis(text)]
tmp = ""
for w in wlist:
tmp += w
print tmp
print "================================"

if __name__=="__main__":
#    cuttest(u"研究生命来源")
#    cuttest(u"南京市长江大桥欢迎您")
#    cuttest(u"请把手抬高一点儿")
#    cuttest(u"长春市长春节致词。")
#    cuttest(u"长春市长春药店。")
#    cuttest(u"我的和服务必在明天做好。")
#    cuttest(u"我发现有很多人喜欢他。")
#    cuttest(u"我喜欢看电视剧大长今。")
#    cuttest(u"半夜给拎起来陪看欧洲杯糊着两眼半晌没搞明白谁和谁踢。")
#    cuttest(u"李智伟高高兴兴以及王晓薇出去玩，后来智伟和晓薇又单独去玩了。")
#    cuttest(u"一次性交出去很多钱。 ")
#    cuttest(u"这是一个伸手不见五指的黑夜。我叫孙悟空，我爱北京，我爱Python和C++。")
#    cuttest(u"我不喜欢日本和服。")
#    cuttest(u"雷猴回归人间。")
#    cuttest(u"工信处女干事每月经过下属科室都要亲口交代24口交换机等技术性器件的安装工作")
#    cuttest(u"我需要廉租房")
#    cuttest(u"永和服装饰品有限公司")
#    cuttest(u"我爱北京天安门")
#    cuttest(u"abc")
#    cuttest(u"隐马尔可夫")
#    cuttest(u"雷猴是个好网站")
#    cuttest(u"“Microsoft”一词由“MICROcomputer（微型计算机）”和“SOFTware（软件）”两部分组成")
#    cuttest(u"草泥马和欺实马是今年的流行词汇")
#    cuttest(u"伊藤洋华堂总府店")
#    cuttest(u"中国科学院计算技术研究所")
#    cuttest(u"罗密欧与朱丽叶")
#    cuttest(u"我购买了道具和服装")
#    cuttest(u"PS: 我觉得开源有一个好处，就是能够敦促自己不断改进，避免敞帚自珍")
#    cuttest(u"湖北省石首市")
#    cuttest(u"总经理完成了这件事情")
#    cuttest(u"电脑修好了")
#    cuttest(u"做好了这件事情就一了百了了")
#    cuttest(u"人们审美的观点是不同的")
#    cuttest(u"我们买了一个美的空调")
#    cuttest(u"线程初始化时我们要注意")
#    cuttest(u"一个分子是由好多原子组织成的")
#    cuttest(u"祝你马到功成")
#    cuttest(u"他掉进了无底洞里")
#    cuttest(u"中国的首都是北京")
#    cuttest(u"孙君意")
#    cuttest(u"外交部发言人马朝旭")
#    cuttest(u"领导人会议和第四届东亚峰会")
#    cuttest(u"在过去的这五年")
#    cuttest(u"还需要很长的路要走")
#    cuttest(u"60周年首都阅兵")
#    cuttest(u"你好人们审美的观点是不同的")
#    cuttest(u"买水果然后来世博园")
#    cuttest(u"买水果然后去世博园")
#    cuttest(u"但是后来我才知道你是对的")
#    cuttest(u"存在即合理")
#    cuttest(u"的的的的的在的的的的就以和和和")
#    cuttest(u"I love你，不以为耻，反以为rong")
#    cuttest(u" ")
#    cuttest(u"")
#    cuttest(u"hello你好人们审美的观点是不同的")
#    cuttest(u"很好但主要是基于网页形式")
#    cuttest(u"hello你好人们审美的观点是不同的")
#    cuttest(u"为什么我不能拥有想要的生活")
#    cuttest(u"后来我才")
#    cuttest(u"此次来中国是为了")
#    cuttest(u"使用了它就可以解决一些问题")
#    cuttest(u",使用了它就可以解决一些问题")
#    cuttest(u"其实使用了它就可以解决一些问题")
#    cuttest(u"好人使用了它就可以解决一些问题")
#    cuttest(u"是因为和国家")
#    cuttest(u"老年搜索还支持")
cuttest(u"干脆就把那部蒙人的闲法给废了拉倒！RT @laoshipukong : 27日，全国人大常委会第三次审议侵权责任法草案，删除了有关医疗损害责任“举证倒置”的规定。在医患纠纷中本已处于弱势地位的消费者由此将陷入万劫不复的境地。 ")


mmseg算法虽然比正向最大匹配算法在错误率上要好很多，但是也不是很完美，如果想让其比较好的运行需要一个很庞大的字典库外加词频库，其中词频库很重要，而且个人觉得判断依据3（标准差）的判断比较不靠谱，这里应该优化一下，能加上词频就更完美了。

• 本文已收录于以下专栏：

## 矩阵形式的MMSE算法推导

• lipengcn
• 2016年03月12日 22:00
• 4513

## python 中文分词，安装 pymmseg

• zhangxinrun
• 2012年05月01日 14:58
• 4773

## 为coreseek添加mmseg分词

• u013699800
• 2015年09月22日 16:54
• 626

## 中文分词的python实现-基于HMM算法

• orlandowww
• 2016年09月29日 23:44
• 3997

## MMSEG 中文分词算法

• sunlylorn
• 2012年06月11日 15:27
• 23591

## 浅谈MMSEG分词算法

• pwlazy
• 2013年12月25日 20:38
• 11427

## mmseg分词算法及实现

• gfsfg8545
• 2016年01月10日 20:07
• 6488

## Sphinx中文分词Coreseek+Mmseg安装配置和示例

Coreseek+Mmseg 实现中文分词的安装配置的记录笔记。 安装前首先安装依赖的软件包 yum install make gcc g++ gcc-c++ libtool autoconf aut...
• l1028386804
• 2015年10月04日 18:06
• 1516

## 最简单的介绍如何使用mmseg进行自然语言处理

• duhaomin
• 2015年11月25日 16:17
• 608

## mmseg中文分词算法的python实现及其优化

mmseg中文分词算法的python实现及其优化任务定义实现一个中文分词系统并对其性能做测试。输入输出该分词的训练语料取自人民日报1998年公开的语料库。为了保证测试的严谨性，选择另一份语料库做测试文...
• say_c_box
• 2017年11月16日 14:23
• 315

举报原因： 您举报文章：Python实现mmseg分词算法和吐嘈 色情 政治 抄袭 广告 招聘 骂人 其他 (最多只允许输入30个字)