Ubuntu下TexLive环境构建
最近整理一些文档,又重拾了毕业那会儿对 LaTeX 的热情,下面就简单记述一下Ubuntu下LaTeX的环境配置。
准备工作
(1) 首先安装 texlive
$ sudo apt-get install texlive-full latex-beamer
|
(2) 之后安装 CJK
$ sudo apt-get install latex-cjk-all
|
(3) 再安装字体生成工具
$ sudo apt-get install fontforge
|
字体生成
(1) 准备字体文件 simsun.ttc(宋体),simhei.ttf(黑体)等
(2) 下载 字体处理文件 并解压
$ mkdir -p ~/font
$ cd ~/font
$ tar -xjvf font.tar.gz
|
(3) 生成字体(以宋体为例),这可能会花费较长时间
$ fontforge -script subfonts.pe simsun.ttc song Unicode.sfd
|
(4) 建立映射描述文件 makemap 如下:
for i in *.tfm
do
cat >> song.map << EOF
${i%.tfm} ${i%.tfm} < ${i%.tfm}.pfb
EOF
done
(5) 执行map操作
$ chmod +x makemap && ./makemap
|
环境配置
(1) 建立一个c70song.fd文件
% This is c70song.fd for CJK package.
% created by Edward G.J. Lee
\ProvidesFile{c70song.fd}
\DeclareFontFamily{C70}{song}{\hyphenchar \font\m@ne}
\DeclareFontShape{C70}{song}{m}{n}{<-> CJK * song}{}
\DeclareFontShape{C70}{song}{bx}{n}{<-> CJKb * song}{\CJKbold}
\endinput
(2) 个人LaTeX配置
$ mkdir -p ~/.texmf-var/fonts/map/dvips/CJK
$ mkdir -p ~/.texmf-var/fonts/tfm/CJK/song
$ mkdir -p ~/.texmf-var/fonts/type1/CJK/song
$ mkdir -p ~/.texmf-var/tex/latex/CJK/UTF8
|
(3) 复制字体
$ cp ~font/song.map ~/.texmf-var/fonts/map/dvips/CJK
$ cp ~/font/*.tfm ~/.texmf-var/fonts/tfm/CJK/song
$ cp ~/font/*.pfb ~/.texmf-var/fonts/type1/CJK/song
$ cp ~/font/c70song.fd ~/.texmf-var/tex/latex/CJK/UTF8
|
(4) 刷新缓存
$ sudo texhash
$ updmap --enable Map song.map
|
至此,基本的环境配种工作就已经完成了,下面可以简单测试一下。
测试
写一个简单的test.tex:
test.tex
\documentclass{article}
\usepackage{CJKutf8}
\begin{document}
\begin{CJK}{UTF8}{song}
{\LaTeX}中文环境测试!
\end{CJK}
\end{document}
编译,生成pdf看下效果吧
$ pdflatex test.tex
$ evince test.pdf
|
Linux下GappProxy翻墙
1. 到Google appengine注册appengine帐号并下载App Engine SDK
2. 登录appengine并创建application(比如my_proxy_app)
3. 下载gappproxy:
svn checkout http://gappproxy.googlecode.com/svn/trunk/ gappproxy
4. 修改gappproxy: 将fetchserver子目录下的app.yaml第一行application改为刚刚注册的应用名
application: my-proxy-app
5. 更新并上传gappproxy:
$ cd google_appengine
$ python appcfg.py update ./gappproxy/fetchserver
6. 启动proxy:
$ cd google_appengine/gappproxy/localproxy
$ nohup python proxy.py &
7. 这样就可以用GappProxy作为代理了
host: 127.0.0.1
port: 8000
结构化信息提取初探
一个季度没有记录东西了,汗一个先~~~。这三个月经历了很多事,从技术上说,做了一个结构化信息提取的项目,已经开始运营了,下面就简单记录一下吧。
0. 理论基础
先把问题简单描述一下: 要在全网上,找出某一类特定对象的结构化信息(比如酒店,要找出其名称、地址、简介、设施、评论、交通、电话、房型、价格等等),并把它们提取出来。从流程上来说,就是Unstructured data -> Structured data -> Database这样一个过程。单纯从技术上讲,这是NLP中一类典型的问题,其一般的解决方案是这样的:
这里面有两个核心问题,一是特征提取,一是分类方法。对于特征提取,一般是先分词(当然针对的是中文网页了),用词作为特征的基本单位(这是最简单也是最常用的方法);而对于分类,最“简单”的贝叶斯方法其实还蛮有效果的。
我们的目标是计算对于一个给定的文本(text),它属于某个分类(category)的概率是多少,即
,根据Bayes定理,有
而P(text|category), P(category), P(text)都是易于计算的(P(text|category)表示给定一个category, 它在text中体现多少; P(category)表示随机选择一个text, 它属于分类category的概率; P(text)作为分母对于所有category来说都是一样的,我们完全可以不关注它),计算方式为:
这样,我们就能算出某text它所应属的category.
1. 处理网页
有了上面的理论还远远不够,我们需要处理的是复杂的网页信息。这里面就需要对网页的结构进行分析:需要按网页结构进行聚类,需要定义一种数据结构来表示网页结构,需要“提取”出一簇网页的通用结构,最终形成一个个的“模板”。这里面涉及的东西很多很杂,需要考虑的细节特别多,就不详细描述了;值得一提的是,形成模板的过程仍然是一个“统计”的过程。
2. 回馈机制
回馈非常重要,至少在目前的技术水平下,你永远不能抛开人工的干预而完全相信计算机的NLP结果。在这里面的回馈就包括两个方面:一是对语义学习过程的回馈、一是对网页分析过程的回馈,在这里面非常重要的一点是回馈是多次的,需要不停迭代以达到好的结果。
最后,说两句目标导向的问题。前几天看到一句话说“工程师一个必须的突破就是化繁为简的能力”,相当有道理。在目标导向下,如果目标足够清晰就能化繁为简;同时,为了达到目标,就要求全面地考虑问题,这就是所谓的“简约而不简单”吧 (^_^)
Ubuntu9.10下tor+autoproxy翻墙
1. GFW持续发飙,tor的源已经都不能用了,只能通过源代码自己编译tor(tor的官网虽然被封,但还是能够通过搜索找到源码下载的)
2. 下载解压后
./configure && make && sudo make install
默认安装到/usr/local下(tor在/usr/local/bin下,torrc在/usr/local/etc/tor下),注意安装过程需要libevent和libopenssl支持。
3. 安装Vidalia
sudo apt-get install vidalia
安装好后,进行配置: “Setup Relaying” => “Network” => 勾选”My ISP blocks connections to the Tor network”,下面填可用网桥
4. 用gmail发送get bridges到bridges@torproject.org,等待自动回复并将回复后的网桥填入配置
5. 给firefox装autoproxy插件,选择Tor作为默认代理,启动vidalia,启用autoproxy,一切OK!
协同过滤基础
推荐系统中,协同过滤(Collaborative Filtering)技术已经获得了相当广泛的成功,最著名的就是Amazon,这里就不多说了。虽然是互联网上迟到的80后,但我们还是有热情去在互联网的舞台上脚踏实地的去拼搏、去奋斗。说到“脚踏实地”,一直以为CF没啥,现在觉得还是应该踏踏实实把它记录下来,算是对自己的积淀吧。
0. 数据准备:
阶user-item关系的rating矩阵:
— 行代表user,列代表item
1. User-Based Collaborative Filtering
STEP1. 对user u,计算u与其他每个user v的相似度:
为user u和user v都打过分的items集合

, 
表示user u对
中items打分的均值;
表示user v对
中items打分的均值。此种度量方式实际上是调整后的cosine相似度(还有很多相似度度量方式,比如Euclidean Distance, Pearson Correlation等等,具体选用哪种相似度度量方式,要根据具体应用和数据的具体特点而定)。
为排好序的与user u最近似的k个最近邻,相应的相似度为
此步的一个直接结果就是找到了相似用户。
为对item i打过分的users集合
STEP1. 对任意两个item i, j,计算它们之间的相似度:
此步的直接结果是找到了相似物品。 用user u打过分且在item i相似kNN的items集中打分的加权凭据作为u对i喜欢程度的预测,同样找到user u对起未关注国的item i的可能喜欢程度;对u所有未打分的items都这样作,就形成了一个预测列表,排序后给出推荐列表。
为对item i和item j都打过分的users集合

表示
中的users对item i打分的均值;
表示
中的users对item j打分的均值。
为排好序的与item i最近似的k个最近邻,相应的相似度为
为user u打过分的items集合


闲言碎语
最近忙得焦头烂额,休息也不好,Blog好久没更新了,先汗颜一下
无意中看到一句话,说人与人之间之所以产生差距,就在于无法改变自己,我把它转成一个流行的说法就是茶具的诞生在于自己无法改变自己(已经作为MSN签名档了,呵呵)—- 想想还是有一定的道理的。以前跟一个朋友聊天,我说我时不时会自己惊出一身冷汗:“我已经有多久没有学习到一项新的东东了?” 呵呵,算是自己没有好好向既定的方向改变自己吧!
闲言少叙,先记述一下自己自己作的东西,以后再慢慢把心得写上来。最近还在搞NLP,这一阶段的工作主要是文本分类,用了几个比较好用的开源库:
(1) FreeLing,C++写的,包括了NLP底层分析的很多方面,西班牙一个team作的,非常酷,可以看看它的online demo;我正考虑把中文支持上去。
(2) TreeTagger,Perl做的,有中文支持扩展。
(3) SVM_light,C写的,Cornell一个牛人Thorsten Joachims主持开发的,很好用。(在这里还有一个小插曲,作者发现他自己的主页从天朝连不上,于是写了一段声明,这种纯学术的东东都被block了,丢人阿丢人!Google也不是要不跟我党玩了么,……,不说了不说了,好好搞自己的事情吧)
基本流程就是底层用Freeling+TreeTagger作数据处理,SVM_light作文本分类,当然,开源代码的好处就在于自己可以修改定制,呵呵,目前实验性的效果还可以。

Resys第三次线下聚会
这次的聚会从内容到规模都可以说达到了一个新的高度,douban在这次活动中提供了鼎立的支持: 场地、精彩演讲、茶歇、文化衫…… 这个是一定要赞的
各个topic具体内容就不多说了,参看各位大拿的PPT与录音,下面就谈几点听了这些讲座的一点点个人粗浅的感受。
豆瓣算法大拿王守崑讲得很精彩,八个字概括就是深入浅出、娓娓道来。
第一个非常有趣也是很根本的问题就是“什么样的产品适合推荐?” 这里面就引申出来一个问题:推荐的维度 — 再深入一些,这正恰恰是前几天Resys引起大家热烈讨论的一个问题:多特征的推荐(关于这个问题我就不说了,围观大家的帖子去…)。
推荐的维度问题是一个非常值得探讨的问题,王守崑提出的具有“媒体性”产品概括得非常精准:我们要了解用户的“口味”、我们的推荐要对用户来说尽量降低用户的成本、我们的推荐要能传播(当然理想情况就是可进化啦)、我们的推荐要多样…… 通过这些探讨和豆瓣积累的经验,胖子给出了他们的结论:条目增长要相对稳定;能够快速获得反馈;在稀疏性、多样性与时效性之间要取得平衡。其中强调反馈 ,这跟第二次线下聚会里面有的理念是一致的,用户的反馈会对推荐结果的修正产生非常正向的影响。
下面一个问题谈到了推荐系统的可扩展性 : 看书不仔细阿,胖子说Programming Pearls告诉我们: 时间和空间不一定非得要trade-off,可以同时降!关于这个问题我确实没有仔细想过,只是理论上相信通过优美的算法设计是可以把时空都控制到非常精巧的范围内,但是没有这么确信与底气十足,说白了还是没有自己亲自动手在大型项目中实践过,看来确实是从实践出的真知才是最可靠与最有底气的阿
王守崑的例子就是矩阵与其转置矩阵相乘的上限分析,这个需要仔细的看看和推导。从这个问题中我们可以看到的是通过仔细的算法设计加上云计算,我们可以非常容易地扩展我们的推荐系统。
下面又讲到了豆瓣现在所面临的挑战,我觉得这个也是整个推荐系统所面临的挑战:
(1) 产品形态如何 ,由于是黑盒推荐,最终还是转到了是否需要区分用户群这个问题。我觉得这个问题对于推荐系统来说很重要,举个自身的例子来说,豆瓣电台是不错,偶尔也是会给我惊喜;但是这种惊喜并不足够,有太多我不喜欢或者我不surprise的歌曲给我,时间长了我就觉得很烦,我知道自己喜欢什么,所以很多时候又转到谷歌音乐去了… 这时推荐系统需要考虑的问题就是怎么样留住我这种用户?怎样很快推荐给我我真正感兴趣的歌曲?这又引申到另一个问题:“推荐的个性化”!这个王守崑讲的“下一代推荐引擎”的核心思想:需要有个性的推荐,需要有记忆、能进化的推荐!
(2) 用户收藏/推荐质量曲线问题:当维度信息增大时怎样维持推荐质量?
(3) 如何评价推荐的效果?这里面比较重要的问题是如何形成闭环的问题。
发现信息的层次:排序 –> 关联 –> 分类、聚类 –> 过滤,于是王守崑抛出的最后一个问题是:“是否人人都需要过滤器?” 这个我觉得还是回到了用户分群的问题,用户是不一样的,层次是不一样的,不是所有用户都需要过滤器,只是一些“高级”用户才需要,至少目前是如此。现在的个性化推荐,针对的只是这一小部分用户……
二. 推荐算法也是一种产品
这个topic我不是理解很深刻,但是这里面我想他们要表达与解决的问题,还是要解决不同用户分群的问题: 既然用户不一样,那么我就给你选择,在后台发现你倾向于那种方法的推荐,以后就用哪种方法给你作推荐。另外,还有众所周知的,并不是所有算法都能解决问题,人工因素的加入是提高用户体验的一种“捷径”。
张栋博士的这个presentation还是理论深度比较强的,我自己功力还不是很够,呵呵;张栋博士首先阐述了机器学习算法的前世今生:从NN到SVM到Graphical Model到CRF到DeepNet再回到NN,这是一种高屋建瓴的表述,让我们对机器学习这个领域有个比较全面的轮廓印象,xlvector在他的这次活动的回顾里面也给出了对ML的独到见解。
下面就是结合他所作的天涯问答这个产品,给我们展示了ML在对超大规模数据处理能到达的水平。正如xlvector所说,在这个领域,评价一个工程师的指标不应该是懂多少算法,而是处理过多大的数据。另外就是还有MPI vs. Map-Reduce,两个都是好东西,说东风一定压倒西风,这个还确实不好说
最后,张栋博士还谈到了社会化广告系统,“广告传播”很有意思,也是推荐系统个性化进化的一种表述吧……
Resys Group的这个平台需要我们大家共同维护、共同交流、共同进步,虽然GFW时不时抽风,虽然我们面临大中华局域网的威胁,但我们相信明天会更好!

关于重构的几点心得
写在前面,为什么要重构?
前段时间接手同事的代码,当时时间比较急,对他的代码code review了一遍,知道哪些哪些都是干什么的,然后外面作些wrapper,里面的东东都没动,就开始继续开发了。这些天发现问题还是挺多的:(1)是清晰性的问题,两个人代码,糅在一起的时候,清晰性还是打了些折扣的,尤其是两人的编程风格不大一样,更导致的清晰性的进一步下降;(2)是可扩展性问题,由于有了新的feature和新的需求,比如需要多线程环境,这时有些代码就是不安全的,架构上要稍作变动;(3)是性能与效率问题,发现要更好的掌握原代码,才有可能提高性能。于是重构就势在必行了。
通过这次重构,验证了很多程序设计实践中的原则(我骨子里还是倾向于C的),模块性是我体味最为深刻的 — 定义清晰的接口吧若干简单的模块组合起来:(1) 模块要简单;(2) 接口要清晰。下面详细记述一下:
1. 最佳模块大小
我们都知道封装是模块化代码的首要特质,API就是我们所提供的封装,那么如何验证API是否设计良好呢?

画个图就简单多了,我们应该这样理解API: 它们是各模块间进行”通信“的接口协议。于是下面的步骤就顺理成章了:
STEP1 抽象: 定义接口
STEP2 推演: 描述接口
STEP3 实现: 实际编码
谈完API,下面回到模块本身,刚才谈到模块要简单,那么如何度量模块是否“简单”?
Les Hatton在这方面做过比较细致的研究
可以看出他给出的经验数据是: 模块不能大,也不能太小,代码在200~400行之间时比较好。
2. 紧凑性与正交分解
现在我们有了模块最佳大小的尺度了,但有最佳尺寸并不意味着代码具有高质量,我们需要再进一步:紧凑性与正交性。
(1) 紧凑性
何谓“紧凑性”?形象来说,就是要“小”,小到一个人很容易地”keep in mind”。注意这里面“小”并不意味着“简单”,它可以设计得非常巧妙,让人回味无穷:)
那么我们如何做到“紧凑性”呢?一个心理学上的经验是:人类短期记忆能够容纳的不连续信息说是七,加二或减二。于是,就得出一个简单的评判 API紧凑性的经验法则:
编程者需要记忆的条目数大于7吗?如果大于,那么这个API就不大可能是严格紧凑的。
有一种提高紧凑性的一个精妙且强大的方法:围绕“解决一个定义明确的问题”的强核心算法来组织设计 — 形式化核心任务,明确任务模型,然后围绕它进行设计。
紧凑性是一个非常好的特性,但是也不能过于追求它,正确的态度是合理地对待紧凑性,设计中要尽量考虑,不强求但决不抛弃。
(2) 正交性
我曾经有幸跟C++大牛xushiwei共事过一段时间,当时他给我强调最多的一句话就是“正交分解”。正交性是使得复杂设计向紧凑性方向迈进的最有力助动。
纯粹的正交设计,任何一种操作都没有副作用,每个动作(API调用)只改变一件事而不影响其它,改变每个属性的方法有且仅有一个。“只作一件事,并把它做好”,这里面不仅仅将的是简洁,更有正交性的潜台词在里面;可以说,重构的原则性目标就是“提高正交性”!
(3) DRY/SPOT原则
DRY(Don’t Repeat Yourself)是一个广为认知的原则,它的涵义是:任何一个知识结构在系统内部都应该有一个唯一、明确、权威的表述。不要重复表述 — 因为重复可能导致前后矛盾,对一处的修改只是修改了一部分,重复的部分可能并没有修改 — 这就导致了前后的不一致。从重构的角度,在DRY原则的指导下,我们可以保持核心算法,更改代码组织进行重构过程。
DRY的另一种表述叫做SPOT(Single Point Of Truth, 真理的单点性),它提倡寻找一种数据结构,使得模型中的状态跟真实世界系统状态一一对应。
3. 软件的层次
(1) 自顶向下和自底向上
自顶向下是从抽象到具体,自底向上是从具体到抽象。其实很多情况下,从哪端开始设计相当重要,因为对端层次很可能受到最初选择的限制。很情况下取折衷:一方面用自顶向下的应用逻辑表达抽象规范,另一方面用函数或库来收集底层的域原语。
P.S. 对我来说,Linux下C程序写得最多,我觉得底层特性的固定及设计极其重要,本人更倾向于自底向上的方式。
(2) 粘合层
粘合层的概念其实很普遍(一个比较好理解的例子就是Python很多时候都作为一种“黏合剂”,连接上层和底层C/C++的),它就是协调上层抽象规范和底层域原语集的一个中间层。
“薄”的粘合层可以看作分离机制的一个升华,使得策略(应用逻辑)和机制(域原语)更为清晰地分离。
(3) 库
i. 模块性设计和良好定义的API会引领我们到达一个非常好的结果:把程序分解成有粘合层连接的库集合。
ii. 插件(plugin)
库分层的一个重要形式是plugin: 拥有一套已知入口,可以在启动以后动态从入口处加载执行特定任务的库(这种模式必须将调用程序作为文档详细的服务库组织起来,以便插件可以回调)。
总之,重构的过程是一个重复思考的过程,也是不断轮回前进的过程。

NLTK读书笔记 — 信息提取(六)
6. Relation Extraction
Relation Extraction和NER都是在实际中非常有用的东东,而且二者有一个很自然的顺承关系: 我们一旦识别出text中的NE, 我们就试图发现它们之间的关系。
一种实现方法是初始时寻找(X, a, Y)形式的元组,X,Y是NE, a是它们之间的关系; 当然a可以通过正则表达式过滤:
>>> IN = re.compile(r’.*\bin\b(?!\b.+ing)’)
>>> for doc in nltk.corpus.ieer.parsed_docs(‘NYT_19980315′):
… for rel in nltk.sem.extract_rels(‘ORG’, ‘LOC’, doc,
… corpus=’ieer’, pattern = IN):
… print nltk.sem.show_raw_rtuple(rel)
[ORG: 'WHYY'] ‘in’ [LOC: 'Philadelphia']
[ORG: 'McGlashan & Sarrail'] ‘firm in’ [LOC: 'San Mateo']
[ORG: 'Freedom Forum'] ‘in’ [LOC: 'Arlington']
[ORG: 'Brookings Institution'] ‘, the research group in’ [LOC: 'Washington']
[ORG: 'Idealab'] ‘, a self-described business incubator based in’ [LOC: 'Los Angeles']
[ORG: 'Open Text'] ‘, based in’ [LOC: 'Waterloo']
[ORG: 'WGBH'] ‘in’ [LOC: 'Boston']
[ORG: 'Bastille Opera'] ‘in’ [LOC: 'Paris']
[ORG: 'Omnicom'] ‘in’ [LOC: 'New York']
[ORG: 'DDB Needham'] ‘in’ [LOC: 'New York']
[ORG: 'Kaplan Thaler Group'] ‘in’ [LOC: 'New York']
[ORG: 'BBDO South'] ‘in’ [LOC: 'Atlanta']
[ORG: 'Georgia-Pacific'] ‘in’ [LOC: 'Atlanta']
conll2002 Dutch corpus不光包含了NE注释,还包含了POS tags — 这能帮我们设计出更合理的正则表达式
>>> from nltk.corpus import conll2002
>>> vnv = “”"
… (
… is/V| # 3rd sing present and
… was/V| # past forms of the verb zijn (‘be’)
… werd/V| # and also present
… wordt/V # past of worden (‘become)
… )
… .* # followed by anything
… van/Prep # followed by van (‘of’)
… “”"
>>> VAN = re.compile(vnv, re.VERBOSE)
>>> for doc in conll2002.chunked_sents(‘ned.train’):
… for r in nltk.sem.extract_rels(‘PER’, ‘ORG’, doc,
… corpus=’conll2002′, pattern=VAN):
… print nltk.sem.show_clause(r, relsym=”VAN”)
VAN(“cornet_d’elzius”, ‘buitenlandse_handel’)
VAN(‘johan_rottiers’, ‘kardinaal_van_roey_instituut’)
VAN(‘annie_lennox’, ‘eurythmics’)
P.S. 用NLTK进行关系识别不是一般的慢,用来作作试验很好,用在工程上的话……得想别的替代办法了。

NLTK读书笔记 — 信息提取(五)
5. Named Entity Recognition
NE(Named Entity)如下定义:它是名词短语,指代某种特定类型的单体,如组织、人、日期等等,常用的NE如下
| NE Type | Examples |
|---|---|
| ORGANIZATION | Georgia-Pacific Corp., WHO |
| PERSON | Eddy Bonte, President Obama |
| LOCATION | Murray River, Mount Everest |
| DATE | June, 2008-06-29 |
| TIME | two fifty a m, 1:30 p.m. |
| MONEY | 175 million Canadian Dollars, GBP 10.40 |
| PERCENT | twenty pct, 18.75 % |
| FACILITY | Washington Monument, Stonehenge |
| GPE | South East Asia, Midlothian |
NER (named entity recognition) 系统的目标是在text中识别出NE. 它可以分为两步进行: (1) 首先识别出NE的边界,(2) 然后识别其类型。
那么我们一般怎么进行NE识别呢?一个选择是我们对每个词查词典,这个词典是包含所有的NE. 但这时候没有看上下文、没有看语境和语义,识别出来的东西必然包括很多不是NE的东西但我们认为它是NE. 实际上这种方式是不可行的。
NLTK提供了一个训练好的classifier去进行NER — nltk.ne_chunk(). 如果我们把参数binary=True, 就简单把识别出来的entity标为NE, 否则设置category labels为PERSON, ORGANIZATION, GPE等
>>> sent = nltk.corpus.treebank.tagged_sents()[22]
/>>> print nltk.ne_chunk(sent, binary=True)
(S
The/DT
(NE U.S./NNP)
is/VBZ
one/CD
…
according/VBG
to/TO
(NE Brooke/NNP T./NNP Mossman/NNP)
…)/>>> print nltk.ne_chunk(sent)
(S
The/DT
(GPE U.S./NNP)
is/VBZ
one/CD
…
according/VBG
to/TO
(PERSON Brooke/NNP T./NNP Mossman/NNP)
…)
P.S. 就我的使用经验来看,NLTK的NER还是准确度不高,对于比较专用的领域还是自己搞个训练集自己训练比较好。



