tagger、SentenceTokenizer方面的几段Python代码

dzhigner

Moderator
SentenceTokenizer、TreeBankWordTokenizer等Python脚本

自己写的(或修改的)几段Python代码,力求简单实用。。。

一、Tokenizers文件夹内容:
提取自NLTK的SentenceTokenizer、TreeBankWordTokenizer合并到一个punkt.py模块中。几点说明:
1. 内核含两个文件:englishPunkt.pickle和punkt.py
2. 仅保留NLTK原punkt.py的SentenceTokenizer与WordTokenizer,不含Training部分。
3. 添加了TreeBankWordTokenizer,这个Tokenizer最好用于单句,配合SentenceTokenizer
3. 为不依赖NLTK安装,修改了原始english.pickle文件。
4. NLTK里的SentenceTokenizer和TreeBankTokenizer都是性能上乘的工具,提取其核心,用于嵌入其他Python项目。

二、taggers文件夹内容:
两段脚本,演示Python如何调用TreeTagger与Hunpos Tagger,均为直接调用命令行可执行文件,在Python里可对赋码过程中的输入输出做深度处理。几点说明:
1. 均使用了梁茂成教授“TreeTagger Windows界面”包中提供的tokenize.exe。
2. TreeTagger命令行:tokenize.exe sample.txt | tree-tagger -token -lemma english.par
3. Hunpos Tagger行分隔符为"\n"(LF),而不是Windows的"\r\n"(CRLF),所以tokenize.exe在使用时替换了行分隔符
 

附件

  • PythonScripts.rar
    169.4 KB · 浏览: 27
Last edited:
回复: tagger、SentenceTokenizer方面的几段Python代码

示例代码,功能是从语料库里挖掘含某个关键词的句子,最终结果是一个分词后句子的列表,也就是一个列表的列表。
List Comprehension部分实现了一个效率很高的处理过程,仅将切句用于包含关键词的物理行。

[xcode=python]
# -*- coding: utf8 -*-
import re
import string
import punkt #若仅使用SentenceTokenizer,无须导入punkt
import cPickle
import time
t=time.time()
sent_detect=cPickle.load(open('englishPunkt.pickle','r'))
spl=[] # 物理上句子的列表
swk=[] # 包含关键词的句子列表
tknz =punkt.TreebankWordTokenizer() #初始化TreebankWordTokenizer
r=re.compile(r'\bword\b',re.IGNORECASE)
fs="c:\\apps\\sample1.txt;c:\\apps\\sample.txt;c:\\apps\\samplex.txt" #多个文件
for fx in fs.split(';'):
with open(fx,'r') as f:
for spl in [sent_detect.tokenize(line) for line in f.readlines() if r.search(line)]: #这两行使用了高效的List Comprehension
swk.extend([tknz.tokenize(line) for line in spl if r.search(line)]) #切句后使用TreebankWordTokenizer
spl=[]
for s in swk:
print s
print time.time()-t
[/xcode]
 
Last edited:
回复: tagger、SentenceTokenizer方面的几段Python代码

是否考虑过添加GUI以适合一般用户使用?当然脚本很适合批处理,适合干正事。
 
回复: tagger、SentenceTokenizer方面的几段Python代码

不错,现在我们这个论坛越来越多直接玩代码的啦,呵呵
 
回复: tagger、SentenceTokenizer方面的几段Python代码

List comprehension 用的很高级,学习一下。
 
回复: tagger、SentenceTokenizer方面的几段Python代码

忽略syntax highlighting 这个功能了,多谢Haiyang给编辑了。。
 
回复: tagger、SentenceTokenizer方面的几段Python代码

总算知道怎么搞syntax highlighting了,再贴个代码:Python里操作TreeTagger,可以轻松控制输出格式。
[xcode=python]
# -*- coding: utf8 -*-
import string
import subprocess

file="C:/apps/Samplex.txt"
tokenizer_exe="C:/treetagger/tokenize.exe"
tagger_exe="C:/treetagger/tree-tagger.exe"
tagger_par="C:/treetagger/english.par"
delimiter='_'

_tokenizing=subprocess.Popen([tokenizer_exe,file],stdout=PIPE)
_tokenizing_stdout_value,stderr_value = _tokenizing.communicate()
# 建立_tokenizing进程, 输出:_tokenizing_stdout_value

_tagging=subprocess.Popen([tagger_exe,"-token", tagger_par], \
stdin=PIPE,stdout=PIPE)
_tagging_stdout_value,stderr_value=_tagging.communicate(_tokenizing_stdout_value)
# 建立_tokenizing进程, 输入:_tokenizing_stdout_value,输出:_tagging_stdout_value

stdout_value = string.replace(string.replace \
(string.replace(_tagging_stdout_value,'\t',delimiter) \
,'\r\n',' '),'_SENT ','_SENT\r\n')
# 通过文本替换将输出转换为如下形式:Cartons_NNS are_VBP seaworthy_JJ ._SENT

print stdout_value
[/xcode]
 
回复: tagger、SentenceTokenizer方面的几段Python代码

频表、词元化处理:
[xcode=python]
# -*- coding: utf8 -*-
import time
import re
import string
import os
import collections

def freqlist_l(files,pattern,lemmatizing=False): #缺省无词元化处理
files=files.split(';') #一次输入多个文件
for file in files:
if not os.path.exists(file):
files.remove(file)

if not files:
return

txt=''
ldic={}
xdic={}
ms=[]
r=re.compile(pattern, re.IGNORECASE)
if lemmatizing: #如果有词元化处理,先把.csv格式(e.g.: aborted,abort)的词元表置入一个词典
with open(r'c:\apps\lemmaplus.csv','r') as ff:
for l in ff:
ldic[l.split(',')[0]]=l.split(',')[1].strip()

def lmtz(x): # Python里可以在一个函数中定义另一个函数. lmtz函数的功能是查词元词典ldic
if ldic.has_key(x):
return ldic[x]
else: return x

for file in files: # 依次处理输入文件
with open(file,'r') as f:
ms=r.findall(f.read())
if lemmatizing: # 如果有词元化处理,把词表中的每个词语替换为词元
ms=map(lmtz,ms)
xdic.update(collections.Counter(ms)) # xdic是总词频表


xdic = sorted(xdic.iteritems(), key=lambda x: x[0],reverse=False) # 这两行是排序,先按频率排,再按字母排
xdic = sorted(xdic, key=lambda x: x[1],reverse=True)
for t in xdic:
txt+= string.lower(t[0])+'\t'+str(t[1])+'\r\n'
return txt

tm=time.time()
print freqlist_l(r'c:\apps\sample1.txt',r'\b[a-zA-Z]+\b',lemmatizing=True)
print time.time()-tm

[/xcode]
 
回复: tagger、SentenceTokenizer方面的几段Python代码

ms=r.findall(f.read()) 里面的 r 是指 re 吗?
 
回复: tagger、SentenceTokenizer方面的几段Python代码

高亮代码后方便了阅读,但对复制代码却更麻烦了啊。
 
回复: tagger、SentenceTokenizer方面的几段Python代码

ms=r.findall(f.read()) 里面的 r 是指 re 吗?
是的。。。
现在迷上了Python,功能确实强大,易学,虽然比Perl慢一些,但是程序流程设计合理的话,效率还是很高的。
 
回复: tagger、SentenceTokenizer方面的几段Python代码

我也放一个基于该版本的修改版,更亲民一点,呵呵
(1)使用方法
解压后的目录介绍:
srcendir为要处理的英文目录
dstendir为处理后的英文目录
srccndir为要处理的中文目录
dstcndir为处理后的中文目录
首先将要处理的文件放到对应的目录里面
用户只需要运行
HunposWithTokenizer.exe
或者
TreeTaggerTokenizer.exe
即可完成对英文的标注与赋码。
注意:暂时不支持中文。。。。(你也可以测试下中文)

(2)源代码
附上源代码
下面是HunposWithTokenize.py的代码
代码:
#!/usr/bin/env python
#-*-encoding:utf-8-*-

import os
import string
import subprocess
from subprocess import *

tokenizer_exe=".\\TreeTagger2\\taggerfiles\\tokenize.exe"
hunpos_exe=".\\hunpos\\hunpos-tag.exe"
hunpos_model=".\\hunpos\\english.model"
delimiter='_'

#英文
#待处理文件目录路径
srcendir=".\\srcendir\\"
#处理后文件目录路径
dstendir=".\\dstendir\\"

#中文
#待处理文件目录路径
srccndir=".\\srccndir\\"
#处理后文件目录路径
dstcndir=".\\dstcndir\\"

#设置
srcdir = srcendir
dstdir = dstendir

#进度条
spinsize = 0
spinpos = 0
spindir = 1

def spin():
    global spinsize, spinpos, spindir
    spinstr = '.' * spinpos + \
            '|' + '.' * (spinsize - spinpos - 1)
    sys.stdout.write('\r' + spinstr + ' ')
    sys.stdout.flush()
    spinpos += 1

def processfiles():
	files = os.listdir(srcdir)
	spinsize = len(files)-2
	print("progress:")
	for file in files:
		if os.path.splitext(file)[1] == '.txt':
			srcfile = srcdir + file
			print("\tcurrent file "+srcfile)
			p=subprocess.Popen([tokenizer_exe, srcfile],stdout=PIPE,stderr=STDOUT)
			tokens=p.stdout.read(-1).split('\r\n')
			_hunpos = Popen([hunpos_exe, hunpos_model],shell=True, stdin=PIPE, stdout=PIPE, stderr=PIPE)
			for t in tokens:
				_hunpos.stdin.write(t+'\n')
			_hunpos.stdin.write("\n")
			tagged_tokens = []
			txt=''
			for t in tokens:
				tagged = _hunpos.stdout.readline().strip().split("\t")
				if len(tagged) > 1:
					tag = tagged[1]
				else:
					tag = None
				tagged_tokens.append((t, tag))
			# We have to read (and dismiss) the final empty line:s
			tgtfile = dstdir + file
			#_hunpos.stdout.readline()
			#print tagged_tokens
			fd = open(tgtfile,"w")
			#print(type(tagged_tokens[1][1]))
			for str in tagged_tokens:
				if str[0] != '':
					fd.write(str[0]+"_"+str[1]+" ")
			fd.close()
			spin()
	print("done!\a")


if __name__ == '__main__':
    print(u"您要处理的是中文还是英文?(1为中文,2为英文):")
    opt = raw_input()
    if opt == '1':
    	srcdir = srccndir
    	dstdir = dstcndir
    else:
    	rcdir = srcendir
    	dstdir = dstendir
    processfiles()
下面是TreeTaggerTokenizer.py的源代码
代码:
#!/usr/bin/env python
#-*-encoding:utf-8-*-

import os
import sys
import string
import subprocess
from subprocess import *


#英文
#待处理文件目录路径
srcendir=".\\srcendir\\"
#处理后文件目录路径
dstendir=".\\dstendir\\"

#中文
#待处理文件目录路径
srccndir=".\\srccndir\\"
#处理后文件目录路径
dstcndir=".\\dstcndir\\"




tokenizer_exe=".\\TreeTagger2\\taggerfiles\\tokenize.exe"
tagger_exe=".\\TreeTagger2\\taggerfiles\\tree-tagger.exe" 

#标注参数文件
#英文
tagger_par_en=".\\TreeTagger2\\taggerfiles\\english.par"
#中文
tagger_par_cn=".\\TreeTagger2\\taggerfiles\\zh.par"

#设置标注参数
tagger_par = tagger_par_en
srcdir = srcendir
dstdir = dstendir



delimiter='_'


def processfiles():
	files = os.listdir(srcdir)
	print("progress:")
	for file in files:
		if os.path.splitext(file)[1] == '.txt':
			srcfile = srcdir + file
			print("\tcurrent file "+srcfile)
			#分词
			_tokenizing=subprocess.Popen([tokenizer_exe,srcfile],stdout=PIPE)
			stdout_value, stderr_value = _tokenizing.communicate()
			print(stdout_value)
			#标注
			tgtfile = dstdir + file
			_tagging=subprocess.Popen([tagger_exe,"-token", tagger_par],stdin=PIPE,stdout=PIPE)
			stdout_value,stderr_value=_tagging.communicate(stdout_value)
			stdout_value = string.replace(string.replace(string.replace(stdout_value,'\t',delimiter),'\r\n',' '),'_SENT ','_SENT\r\n')
			fd = open(tgtfile,'w')
			fd.write(stdout_value)
			fd.close()
	print("\a")

if __name__ == '__main__':
    print("您要处理的是中文还是英文?(1为中文,2为英文):")
    opt = raw_input()
    if opt == '1':
    	srcdir = srccndir
    	dstdir = dstcndir
    	tagger_par = tagger_par_cn
    else:
    	rcdir = srcendir
    	dstdir = dstendir
    	tagger_par = tagger_par_en
    processfiles()

大家见谅。
下载地址
http://pan.baidu.com/share/link?shareid=3648576550&uk=1409302838
论坛传的有问题,所以没用附件的方式传上来
 
Back
顶部