为开源项目有增无减一个新功效的开销进程,机器学习和

本篇小说不是为了记开发流水账,而是想把支付过程的相逢的题目以及缓解思路和我们举办互换和上学。我是一名普通的
PHP
工程师,希望对初级开发同学有所协助。具体的心端庄相会文末的总结

本文实例讲述了Python自然语言处理 NLTK
库用法。分享给我们供我们参考,具体如下:

简介: 机器学习取决于
IT、数学和自然语言的混杂,在大数量应用程序中会日常用到机械学习。本文将钻探Python 编程语言和它的 NLTK 库,然后将它们利用于一个机器学习项目。

前几天在网查到一篇介绍php中替换字符串中的空格为逗号’,’的篇章,作个日记保存下去。

本月首,我在 GitHub
上开源了一个协调的小品种:chinese-typesetting。那是一个纠正中文文案排版的
Composer 包。

在这篇作品中,大家将按照 Python
研讨自然语言处理(NLP)。本课程将会拔取 Python NLTK 库。NLTK
是一个及时流行的,用于自然语言处理的 Python 库。

 

复制代码 代码如下:

chinese-typesetting
包含以下职能:

这就是说 NLP 到底是何许?学习 NLP 能拉动什么便宜?

挑战:使用机器学习对 RSS 提要开展分拣

<pre name=”code” class=”php”><? php
/*
* 关键词中的空格替换为’,’
*/
public function emptyreplace($str) {
$str = str_replace(‘ ’, ‘ ‘, $str); //替换全角空格为半角
$str = str_replace(‘ ‘, ‘ ‘, $str); //替换连续的空格为一个
$noe = false; //是否遭逢不是空格的字符
for ($i=0 ; $i<strlen($str); $i++) { //遍历整个字符串
if($noe && $str[$i]==’ ‘) $str[$i] = ‘,’;
//假若当前以此空格以前现身了不是空格的字符
elseif($str[$i]!=’ ‘) $noe=true; //当前这多少个字符不是空格,定义下 $noe
变量
}
return $str;
}
?>

  • 在粤语言与英文字母/用于数学、科学和工程的希腊字母/数字之间添加空格;
  • 有限度的全角转半角(英文、数字、空格以及一些特殊字符等采用半角字符);
  • 修复错误的标点;
  • 扫除 HTML 标签的样式;
  • 清除空的 HTML 标签;
  • 清除段首缩进;

简单的讲的说,自然语言处理( NLP
)就是付出可以领略人类语言的应用程序和劳务。

 

你或许感兴趣的篇章:

  • PHP中去掉字符串首尾空格的艺术
  • php中3种方法删除字符串中间的空格
  • PHP
    将逗号、空格、回车分隔的字符串转换为数组的函数
  • PHP中空字符串介绍0、null、empty和false之间的关联
  • php读取文件内容至字符串中,同时去除换行、空行、行首行尾空格(Zjmainstay原创)
  • php中0,null,empty,空,false,字符串关系的事无巨细介绍
  • PHP中用正则表明式清除字符串的空域
  • PHP清除数组中具有字符串两端空格的主意
  • php下清空字符串中的HTML标签的代码
  • 详解php中空字符串和0之间的涉嫌

本周,集团支付业务不多,无加班,于是从头考虑新职能纠正罗马尼亚语专闻名词大小写的实现。

俺们生活中经常会接触的自然语言处理的行使,包括语音识别,语音翻译,了解句意,领会特定词语的同义词,以及写出语法正确,句意通畅的语句和段子。

前不久,我接受一项职责,要求为客户创制一个 RSS
提要分类子系统。目的是读取几十个甚至几百个 RSS
提要,将它们的多多文章自动分拣到几十个预定义的主旨领域当中。客户网站的情节、导航和查找效果都将由这么些每日活动提要寻找和分类结果驱动。

爱尔兰语专出名词的数额出自

首先,面临的率先个问题是:

保加蒙彼利埃语专知名词的数据从哪来?

自家初次想到的是 Python 有一个自然语言处理的包
NLTK,这多少个包有个名为 pos_tag
的函数,可以用来辨别并标注每个单词的词性,其中被标明为 NNP 或 NNPS
的单词就是专知名词(Proper Noun)。我预计,NLTK
数据包里应该有一个对应的专出名词数据集,可是,苦于能力有限,我从来尚未找到。

上述的门路走不通后,我又通过 Google搜索,发现经过网络字典来获取数据是一条有效的方案。通过这一办法,终于在
Wiktionary
找到了保加得梅因语专知名词列表。于是,利用 Python
写了一个爬虫小本子,爬取了相应的多少。

说到底,就是对爬取到的数据进行了部分规整和筛选。

筛选方案如下:

  • 使用 is_numeric() 方法,剔除诸如 007 等词汇;
  • 使用 '/\W/' 正则,剔除诸如 ǃXóõ 等词汇;
  • 剔除 strlen 方法,剔除 A 等单字节词汇;
  • 除去跟 HTML、CSS、JavaScript 保留字顶牛的词汇;

NLP的作用

 

什么样让使用者定制专出名词数据

为开源项目有增无减一个新功效的开销进程,机器学习和。先前时期的代码如下:

/**
 * 专有名词使用正确的大小写
 * Correct English proper nouns.
 *
 * @param $text
 *
 * @return null|string|string[]
 */
public function properNoun($text)
{
    $dict = include __DIR__ . '/../data/dict.php';
    foreach ($dict as $noun) {
        $text = preg_replace("/\b{$noun}\b/i", $noun, $text);
    }
    return $text;
}

随后想到,假诺选用这多少个主意的开发者想扩张或者忽视某些专出名词,这该如何做吧?
于是,我又将 properNoun() 方法改造如下:

/**
 * 专有名词使用正确的大小写
 * Correct English proper nouns.
 *
 * @param $text
 * @param array $extend
 * @param array $ignore
 *
 * @return null|string|string[]
 */
public function properNoun($text, array $extend = [], array $ignore = [])
{
    $dict = include __DIR__ . '/../data/dict.php';
    if ($extend) {
        $dict = array_merge($dict, $extend);
    }
    if ($ignore) {
        $dict = array_diff($dict, $ignore);
    }

    foreach ($dict as $noun) {
        $text = preg_replace("/\b{$noun}\b/i", $noun, $text);
    }
    return $text;
}

正如大家所知,天天博客,社交网站和网页会时有发生数亿字节的海量数据。

客户提议采纳机器学习,或许还会使用 Apache Mahout 和 Hadoop
来兑现该任务,因为客户如今阅读了有关这一个技能的篇章。但是,客户的付出公司和我们的付出公司都更熟稔Ruby,而不是 Java™
技术。本文将介绍解决方案的技术之旅、学习过程和末段兑现。

什么样立异和优化代码逻辑

自己在写那一个效率的时候,也在商量和参考一些存世开源项目的实现逻辑。在观望开源项目
auto-correct 的一个
commit
上后(PS:那一个 PR 是社区大神 overtrue
提交的。),我又将 properNoun() 方法改造如下:

public function properNoun($text, array $extend = [], array $ignore = [])
{
    $dict = include __DIR__ . '/../data/dict.php';
    if ($extend) {
        $dict = array_merge($dict, $extend);
    }
    if ($ignore) {
        $dict = array_diff($dict, $ignore);
    }
    foreach ($dict as $noun) {
        $text = preg_replace("/(?<!\.|[a-z]){$noun}(?!\.|[a-z])/i", $noun, $text);
    }
    return $text;
}

有那个商厦热衷收集所有那一个数据,以便更好地询问她们的用户和用户对成品的满腔热情,并对他们的制品依旧服务拓展适量的调动。

 

怎么制止超负荷替换

在我以为就要大功告成的时候,我用事先写好的 PHPUnit
单元测试代码举办了测试,结果报出了错误,在上述方法中,假如传入的参数是带有
HTML 标签的富文本,那么 HTML 的要素、元素属性以及值都有可能会被交换。

何以制止超负荷替换那一个问题吧?也就是说:

只替换文本,而忽视 HTML 标签及标签内部的始末?

本人尝试写了一些套匹配方案,都失利了。最终仍旧请出了 Google大神来增援。这里,搜索的关键字很关键,最好想把您要摸索的严重性词翻译成对应的英文单词,这样搜索出的结果会令你更中意。结果我找到明白决方案:Matching
A Word / Characters Outside Of Html
Tags。

经过地点这部小说的唤醒,我又将 properNoun() 方法改造如下:

public function properNoun($text, array $extend = [], array $ignore = [])
{
    $dict = include __DIR__ . '/../data/dict.php';
    if ($extend) {
        $dict = array_merge($dict, $extend);
    }
    if ($ignore) {
        $dict = array_diff($dict, $ignore);
    }
    foreach ($dict as $noun) {
        // Matching proper nouns Outside Of Html Tags
        $text = preg_replace("/(?<!\.|[a-z]){$noun}(?!\.|[a-z])(?!([^<]+)?>)/i", $noun, $text);
    }
    return $text;
}

这一个海量数据可以发布很多现象,打个比方说,巴西人对成品 A
感到满足,而米利坚人却对成品 B
更感兴趣。通过NLP,这类的信息可以即时取得(即实时结果)。例如,搜索引擎正是一种
NLP,可以在正确的时间给方便的人提供合适的结果。

何以是机械学习?

付出总计

  • 学会科学上网;
  • 擅长 Google、Github 和
    StackOverflow,这三样“神器”会帮你解决掉开发进程中际遇的多头(或者说所有)问题;
  • 学会一些 Google搜索小技巧。例如将寻找关键字翻译成菲律宾语单词,这样的摸索结果会令你更中意;
  • 阿尔巴尼亚语真的很重点。最起码你应有在 Chrome 浏览器上设置一个 Google
    翻译
    的插件;
  • PHPUnit 真的很有用,特别是在频繁增改效能依旧需要代码重构的序列中。
  • 并非让祥和仅限于一个编程语言,学习其余一门或多门语言作为襄助,有益于拓展思路和开辟眼界。
  • 多逛逛 Laravel China 这样的高格调社区;

可是搜索引擎并不是自然语言处理(NLP)的绝无仅有采取。还有更好进而优异的利用。

 

说到底的话

若果还有哪些需要说的话,这就是求 Star
啦,哈哈哈哈哈。项目地址:

NLP的应用

自家的率先个问题是,“究竟怎么着是机器学习?”
我听说过那一个术语,并且隐约知道顶尖统计机 IBM® 沃特(Wat)son
目前拔取该技能在一场 Jeopardy
比赛中败北了人类竞争者。作为购物者和交际网络移动参与者,我也明白Amazon.com 和 非死不可依照其购物者数据在提供指出(如产品和人)方面表现优秀。不问可知,机器学习取决于
IT、数学和自然语言的插花。它至关紧要关注之下六个主旨,但客户的解决方案最终仅提到前两个主旨:

以下都是自然语言处理(NLP)的片段打响采用:

 

  • 搜索引擎,比如Google,雅虎等等。Google等搜寻引擎会通过NLP通晓到您是一个科技喉咙疼友,所以它会回去科技相关的结果。
  • 交际网站信息流,比如 非死不可的音讯流。信息馈送算法通过自然语言处理明白到您的兴趣,并向你显得相关的广告以及音信,而不是一些毫不相干的音讯。
  • 语音援手,诸如苹果 Siri。
  • 垃圾邮件程序,比如 Google 的垃圾邮件过滤程序
    ,这不仅仅是普普通通会用到的见怪不怪的垃圾邮件过滤,现在,垃圾邮件过滤器会对电子邮件的内容举行解析,看看该邮件是否是垃圾邮件。

分类。依据类似项目标一组训练多少,将有关的项分配到自由预定义的品类

NLP库

提出。依据类似项目的洞察来提出采用的项

明天有为数不少开源的自然语言处理(NLP)库。比如:

集群。在一组数据内确定子组

  • Natural language toolkit (NLTK)
  • Apache OpenNLP
  • Stanford NLP suite
  • Gate NLP library

Mahout 和 Ruby 的选择

自然语言工具包(NLTK)是最受欢迎的自然语言处理(NLP)库。它是用 Python
语言编写的,背后有无往不胜的社区帮忙。

 

NLTK 也很容易入门,实际上,它将是你用到的最简便易行的自然语言处理(NLP)库。

了解了机器学习是何许之后,下一步是确定哪些促成它。遵照客户的提议,Mahout
是一个适宜的起源。我从 Apache 下载了代码,并初阶了上学运用 Mahout
及其兄弟 Hadoop 实现机器学习的历程。不幸的是,我发觉就是对于有经历的
Java 开发人士而言,Mahout
的学习曲线也很陡峭,并且不存在可用的样例代码。同样不幸的是,机器学习缺少依照Ruby 的框架或 gem。

在那个 NLP 教程中,大家将使用 Python NLTK 库。在伊始设置  NLTK
往日,我假若你知道有些
Python入门知识。

 

安装 NLTK

发现 Python 和 NLTK

假设你利用的是 Windows , Linux 或 Mac,你可以
使用PIP安装NLTK:
# pip install nltk

 

在本文撰写之时,你可以在 Python 2.7 , 3.4 和 3.5
上都可以采纳NLTK。或者能够通过得到tar
举行源码安装。

自我连续查找解决方案,并且在结果集中从来遭受 “Python”。作为一名 Ruby
开发人士,即使本人还并未学过该语言,但本身也亮堂 Python
是一个面向相似对象的、基于文本的、可了然和动态的编程语言。尽管两种语言之间存在一些相似之处,但自己多年来都忽略了读书
Python,将它就是一项多余的技巧集。Python 是自身的 “盲点”,我难以置信许多 Ruby
开发人士同行都是那样认为的。

要检查 NLTK
是否科学地设置到位,可以打开你的Python终端并输入以下内容:Import
nltk。假如一切顺利,这意味你早就打响安装了 NLTK 库。

 

假如你安装了 NLTK,你可以运作下边的代码来设置 NLTK 包:

追寻机器学习的书本,并更深切钻研它们的目录,我发觉,有一定高比例的此类系统在使用
Python 作为其落实语言,并应用了一个被称为 Natural Language
Toolkit(NLTK,自然语言工具包)的库。通过更加的追寻,我发现 Python
的采纳比自己意识到的还要广泛,如 Google App Engine、YouTube 和行使 Django
框架构建的网站。它甚至还预安装在本人每一天都采纳的 Mac OS X
工作站上!另外,Python 为数学、科学和工程提供了有趣的标准库(例如,NumPy
和 SciPy)。

import nltk
nltk.download()

 

这将开辟 NLTK 下载器来采纳需要设置的软件包。

自家主宰举行一个 Python
解决方案,因为自身找到了特别好的编码示例。例如,下边这一行代码就是通过
HTTP 读取 RSS 提要并打印其内容所需的保有代码:

你可以选取安装具有的软件包,因为它们的容量不大,所以没有怎么问题。现在,大家先河攻读吧!

 

运用原生 Python 来对文本举办分词

1

首先,我们将抓取一些网页内容。然后来分析网页文本,看看爬下来的网页的主旨是关于如何。大家将运用
urllib模块来抓取网页:

print feedparser.parse(“”)

import urllib.request
response = urllib.request.urlopen('http://php.net/')
html = response.read()
print (html)

敏捷控制 Python

从打印输出中得以看出,结果中包含众多亟需清理的HTML标记。我们得以用这几个 
BeautifulSoup 库来对抓取的文本举办拍卖:

 

from bs4 import BeautifulSoup
import urllib.request
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
print (text)

在上学一门新的编程语言时,最容易的部分往往是读书语言本身。较难的有些是询问它的生态系统:咋样设置它、添加库、编写代码、构造代码文件、执行它、调试它并编制单元测试。本节将简单介绍那个大旨;请务必参阅
参考资料,以得到有关详细信息的链接。

现今,大家能将抓取的网页转换为根本的文书。这很棒,不是么?

 

最终,让我们由此以下方法将文件分词:

pip

from bs4 import BeautifulSoup
import urllib.request
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
tokens = [t for t in text.split()]
print (tokens)

 

词频总结

Python Package Index (pip) 是 Python
的正规软件包管理器。您可以应用该程序将库添加到你的系统。它相仿于 Ruby
库的 gem。为了将 NLTK 库添加到您的系统,您可以输入以下命令:

现在的文件相相比较在此以前的 html 文本好多了。我们再采纳 Python NLTK
来测算每个词的现身频率。NLTK 中的FreqDist( ) 函数可以兑现词频总括的效应

 

from bs4 import BeautifulSoup
import urllib.request
import nltk
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
tokens = [t for t in text.split()]
freq = nltk.FreqDist(tokens)
for key,val in freq.items():
  print (str(key) + ':' + str(val))

1

假如您查看输出结果,会发现最常用的用语是PHP。

$ pip install nltk

你能够用绘图函数为这一个词频绘制一个图片: freq.plot(20, cumulative=False)

为了显得在你的系统上已设置的 Python 库的列表,请运行以下命令:

从图中,你可以一定这篇文章正在钻探 PHP。这很棒!有一些词,如”the,” “of,”
“a,” “an,”
等等。那些词是终止词。一般的话,截至词语应该被去除,以预防它们影响我们的结果。

 

应用 NLTK 删除截止词

1

NLTK 具有大多数言语的平息词表。要拿到英文截止词,你可以行使以下代码:

$ pip freeze

from nltk.corpus import stopwords
stopwords.words('english')

运行程序

现行,让我们修改我们的代码,并在绘制图形在此之前清理标记。首先,大家复制一个列表。然后,我们通过对列表中的标记举办遍历并删除其中的平息词:

 

clean_tokens = tokens[:]
sr = stopwords.words('english')
for token in tokens:
  if token in stopwords.words('english'):
    clean_tokens.remove(token)

施行 Python 程序一样很简短。得到一个名称为 locomotive_main.py
的先后和多少个参数,然后您就足以运用 Python 程序编译并举办它:

您可以在这边查看Python List
函数, 
了然哪些处理列表。

 

末尾的代码应该是这么的:

1

from bs4 import BeautifulSoup
import urllib.request
import nltk
from nltk.corpus import stopwords
response = urllib.request.urlopen('http://php.net/')
html = response.read()
soup = BeautifulSoup(html,"html5lib")
text = soup.get_text(strip=True)
tokens = [t for t in text.split()]
clean_tokens = tokens[:]
sr = stopwords.words('english')
for token in tokens:
  if token in stopwords.words('english'):
    clean_tokens.remove(token)
freq = nltk.FreqDist(clean_tokens)
for key,val in freq.items():
  print (str(key) + ':' + str(val))

$ python locomotive_main.py arg1 arg2 arg3

若果你现在检讨图表,会深感比在此以前这张图标更加清楚,因为尚未了停止词的扰乱。

Python 使用 清单 1 中的if __name__ ==
“__main__”:语法来确定文件本身是从命令行执行的要么从其余代码导入的。为了让文件变得可以举办,需要加上”__main__”检测。

freq.plot(20,cumulative=False)

 

动用 NLTK 对文件分词

清单 1. Main 检测 

俺们正好明白了什么运用 split( ) 函数将文件分割为标记
。现在,我们将见到如何行使 NLTK
对文本举办标记化。对文本举办标记化是很首要的,因为文件不可以在未曾展开标记化的情状下被拍卖。标记化意味着将较大的部分分隔成更小的单元。

1

您可以将段落划分为句子,并按照你的急需将句子分割为单词。NLTK
具有内置的语句标记器和词语标记器。

import sys

尽管我们有如下的言传身教文本:

2

Hello Adam, how are you? I hope everything is going well.  Today is a
good day, see you dude.

import time

为了将这一个文件标记化为句子,我们得以行使句子标记器:

3

from nltk.tokenize import sent_tokenize
mytext = "Hello Adam, how are you? I hope everything is going well. Today is a good day, see you dude."
print(sent_tokenize(mytext))

import locomotive

输出如下:

4

[‘Hello Adam, how are you?’, ‘I hope everything is going well.’,
‘Today is a good day, see you dude.’]

 

您或许会说,这是一件容易的政工。我不需要拔取 NLTK
标记器,并且我得以运用正则表达式来划分句子,因为各样句子前后都有标点符号或者空格。

5

这就是说,看看下边的文字:

if __name__ == “__main__”:

Hello Mr. Adam, how are you? I hope everything is going well. Today is
a good day, see you dude.

6

呃!Mr. 是一个词,即使带有一个符号。让我们来试试使用 NLTK 举行分词:

    start_time = time.time()

from nltk.tokenize import sent_tokenize
mytext = "Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude."
print(sent_tokenize(mytext))

7

出口如下所示:

    if len(sys.argv) > 1:

[‘Hello Mr. Adam, how are you?’, ‘I hope everything is going well.’,
‘Today is a good day, see you dude.’]

8

Great!结果棒极了。然后大家品尝采纳词语标记器来探望它是哪些做事的:

        app = locomotive.app.Application()

from nltk.tokenize import word_tokenize
mytext = "Hello Mr. Adam, how are you? I hope everything is going well. Today is a good day, see you dude."
print(word_tokenize(mytext))

9

出口如下:

        … additional logic …

[‘Hello’, ‘Mr.’, ‘Adam’, ‘,’, ‘how’, ‘are’, ‘you’, ‘?’, ‘I’, ‘hope’,
‘everything’, ‘is’, ‘going’, ‘well’, ‘.’, ‘Today’, ‘is’, ‘a’, ‘good’,
‘day’, ‘,’, ‘see’, ‘you’, ‘dude’, ‘.’]

virtualenv

正如所料,Mr. 是一个词,也确确实实被 NLTK 当做一个词。NLTK使用
nltk.tokenize.punkt module 中的  PunktSentenceTokenizer
举行文本分词。那多少个标记器经过了精美的练习,可以对多种语言举办分词 。

 

标记非丹麦语语言文本

绝大多数 Ruby 开发人员熟谙系统范围的库或 gem
的问题。使用一组系统范围内的库的做法一般是不可取的,因为你的里边一个档次可能凭借于某个给定的库的版本
1.0.0,而另一个系列则借助于版本 1.2.7。同样,Java
开发人士都领会系统范围的 CLASSPATH 存在一样的题材。就像 Ruby
社区接纳其rvm工具,而 Python 社区运用virtualenv工具(请参阅
参考资料,以取得有关链接)来创造独立的推行环境,其中蕴蓄特定版本的
Python 和一组库。清单 2 中的命令展现了何等为你 p1 体系创立一个名为
p1_env 的虚拟环境,其中包含feedparser、numpy、scipy和nltk库。

为了标记其他语言,可以像这么指定语言:

 

from nltk.tokenize import sent_tokenize
mytext = "Bonjour M. Adam, comment allez-vous? J'espère que tout va bien. Aujourd'hui est un bon jour."
print(sent_tokenize(mytext,"french"))

清单 2. 利用 virualenv 成立一个虚拟环境的命令 

结果将是这般的:

1

[‘Bonjour M. Adam, comment allez-vous?’, “J’espère que tout va
bien.”, “Aujourd’hui est un bon jour.”]

$ sudo pip install virtualenv $ cd ~ $ mkdir p1 $ cd p1 $ virtualenv
p1_env –distribute $ source p1_env/bin/activate  (p1_env)[~/p1]$
pip install feedparser (p1_env)[~/p1]$ pip install numpy
(p1_env)[~/p1]$ pip install scipy (p1_env)[~/p1]$ pip install nltk
(p1_env)[~/p1]$ pip freeze

NLTk 对任何非波兰语语言的支撑也要命好!

老是在一个 shell 窗口使用你的类型时,都亟待 “拿到”
您的虚拟环境激活脚本。请留心,在激活脚本被拿走后,shell
指示符会改变。当在你的系统上开创和选择 shell
窗口,轻松地导航到你的档次目录,并启动其虚拟环境时,您或许想在你的
~/.bash_profile 文件中丰硕以下条目:

从 WordNet 获取同义词

 

若果您还记得我们利用 nltk.download( ) 安装 NLTK
的恢弘包时。其中一个恢弘包名为 WordNet。WordNet
是为自然语言处理构建的数据库。它包括部分词语的一个同义词组和一个粗略的概念。

1

透过 NLTK 你可以得到给定词的概念和例句:

$ alias p1=”cd ~/p1 ; source p1_env/bin/activate”

from nltk.corpus import wordnet
syn = wordnet.synsets("pain")
print(syn[0].definition())
print(syn[0].examples())

代码库结构

结果是:

 

a symptom of some physical hurt or disorder
[‘the patient developed severe pain and distension’]

在成功简单的单文件 “Hello World” 程序的编排之后,Python
开发人士需要明白什么正确地协会其代码库的目录和文书名。Java 和 Ruby
语言在这下面都有各自的要求,Python 也远非什么样两样。简单的讲,Python
使用包
的概念对相关的代码进行分组,并提供了有目共睹的称谓空间。出于演示目标,在本文中,代码存在于某个给定项目标根目录中,例如
~/p1。在这个目录中,存在一个用以同一名称的 Python 包的 locomotive 目录。
清单 3 呈现了这一个目录结构。

WordNet 包含了成百上千词的概念:

 

from nltk.corpus import wordnet
syn = wordnet.synsets("NLP")
print(syn[0].definition())
syn = wordnet.synsets("Python")
print(syn[0].definition())

清单 3. 示范目录结构 

结果是:

01

the branch of information science that deals with natural language
information
large Old World boas

locomotive_main.py

你可以动用 WordNet 来获取同义词:

02

from nltk.corpus import wordnet
synonyms = []
for syn in wordnet.synsets('Computer'):
  for lemma in syn.lemmas():
    synonyms.append(lemma.name())
print(synonyms)

locomotive_tests.py

输出是:

03

[‘computer’, ‘computing_machine’, ‘computing_device’,
‘data_processor’, ‘electronic_computer’,
‘information_processing_system’, ‘calculator’, ‘reckoner’,
‘figurer’, ‘estimator’, ‘computer’]

 

Cool!

04

从 WordNet 获取反义词

locomotive/

您可以用平等的格局取得单词的反义词。你唯一要做的是在将 lemmas
的结果到场数组此前,检查结果是否真的是一个不易的反义词。

05

from nltk.corpus import wordnet
antonyms = []
for syn in wordnet.synsets("small"):
  for l in syn.lemmas():
    if l.antonyms():
      antonyms.append(l.antonyms()[0].name())
print(antonyms)

    __init__.py

输出是:

06

[‘large’, ‘big’, ‘big’]

    app.py

这就是 NLTK 在自然语言处理中的力量。

07

NLTK词干提取

    capture.py

单词词干提取就是从单词中去除词缀并赶回词根。(比方说 working 的词干是
work。)搜索引擎在目录页面的时候使用这种技术,所以众五人经过同一个单词的不同样式展开查找,重回的都是同一的,有关这个词干的页面。

08

词干提取的算法有许多,但最常用的算法是 Porter 提取算法。NLTK 有一个
PorterStemmer 类,使用的就是 Porter 提取算法。

    category_associations.py

from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem('working'))

09

结果是: 

    classify.py

work

10

结果很清楚。

    news.py

还有此外一些领到算法,如 Lancaster 提取算法。这多少个算法的出口同 Porter
算法的结果在多少个单词上不同。你可以品味他们两个算法来查阅有什么不同结果。

11

领取非波兰语单词词干

    recommend.py

SnowballStemmer 类,除了罗马尼亚语外,仍可以适用于其余 13
种语言。匡助的言语如下:

12

from nltk.stem import SnowballStemmer
print(SnowballStemmer.languages)
'danish', 'dutch', 'english', 'finnish', 'french', 'german', 'hungarian', 'italian', 'norwegian', 'porter', 'portuguese', 'romanian', 'russian', 'spanish', 'swedish'

    rss.py

您可以应用 斯诺(Snow)ballStemmer 类的 stem()函数来领取非西班牙语单词,如下所示:

13

from nltk.stem import SnowballStemmer
french_stemmer = SnowballStemmer('french')
print(french_stemmer.stem("French word"))

 

起点法兰西的仇敌欢迎在评论区 poll 出你们测试的结果!

14

拔取 WordNet 引入词汇

locomotive_tests/

词汇的词汇化与提取词干类似,但不同之处在于词汇化的结果是一个着实的词汇。与词干提取不同,当您准备提取部分词干时,有可能会促成这样的动静:

15

from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
print(stemmer.stem('increases'))

    __init__.py

结果是:

16

increas

    app_test.py

如今,倘使我们试图用NLTK WordNet来復苏同一个词,结果会是毋庸置疑的:

17

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('increases'))

    category_associations_test.py

结果是:

18

 increase

    feed_item_test.pyc

结果也许是同义词或具备同样含义的不同词语。有时,假诺您准备还原一个词,比如
playing,还原的结果或者
playing。这是因为默认还原的结果是名词,如若您想赢得动词,可以透过以下的章程指定。

19

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('playing', pos="v"))

    rss_item_test.py

结果是: 

请小心名称古怪的 __init__.py 文件。这个文件提示 Python
为你的包加载必要的库和特定的应用程序代码文件,它们都坐落同一的目录中。
清单 4 展现了文件 locomotive/__init__.py 的内容。

play

 

实质上,这是一个老大好的文本压缩水平。最后减弱到原文本的 50% 到 60%
左右。结果也许是动词,名词,形容词或副词:

清单 4. locomotive/__init__.py 

from nltk.stem import WordNetLemmatizer
lemmatizer = WordNetLemmatizer()
print(lemmatizer.lemmatize('playing', pos="v"))
print(lemmatizer.lemmatize('playing', pos="n"))
print(lemmatizer.lemmatize('playing', pos="a"))
print(lemmatizer.lemmatize('playing', pos="r"))

01

结果是:

# system imports; loads installed packages

play
playing
playing
playing

02

词干化和词化差别

    import codecs

好啊,让大家独家品尝一些单词的词干提取和词形还原:

03

from nltk.stem import WordNetLemmatizer
from nltk.stem import PorterStemmer
stemmer = PorterStemmer()
lemmatizer = WordNetLemmatizer()
print(stemmer.stem('stones'))
print(stemmer.stem('speaking'))
print(stemmer.stem('bedroom'))
print(stemmer.stem('jokes'))
print(stemmer.stem('lisa'))
print(stemmer.stem('purple'))
print('----------------------')
print(lemmatizer.lemmatize('stones'))
print(lemmatizer.lemmatize('speaking'))
print(lemmatizer.lemmatize('bedroom'))
print(lemmatizer.lemmatize('jokes'))
print(lemmatizer.lemmatize('lisa'))
print(lemmatizer.lemmatize('purple'))

    import locale

结果是:

04

stone
speak
bedroom
joke
lisa

purpl

stone
speaking
bedroom
joke
lisa
purple

    import sys

词干提取的法门可以在不领会语境的境况下对词汇使用,这就是干什么它相较词形还原方法速度更快但准确率更低。

05

在我看来,词形还原比提取词干的法子更好。词形还原,如果实际没辙赶回这个词的变形,也会再次回到另一个的确的单词;这么些单词可能是一个同义词,但好歹这是一个真正的单词。当有时候,你不关注准确度,需要的只是速度。在这种状态下,词干提取的措施更好。

 

咱俩在本 NLP
教程中研究的享有手续都涉嫌到文本预处理。在事后的稿子中,我们将钻探使用Python
NLTK举行文本分析。

06

更多关于Python相关内容感兴趣的读者可查看本站专题:《Python数学运算技巧总计》、《Python数据结构与算法教程》、《Python函数使用技巧总括》、《Python字符串操作技能汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

    # application imports; these load your specific *.py files

瞩望本文所述对我们Python程序设计有着帮忙。

07

您可能感兴趣的篇章:

  • Python自然语言处理之词干,词形与最大匹配算法代码详解
  • Python编程使用NLTK举行自然语言处理详解
  • 用Python举行部分粗略的自然语言处理的教程
  • Python中部分自然语言工具的应用的入门教程
  • python自然语言编码转换模块codecs介绍
  • 在Python中运用NLTK库实现对词干的领到的科目

    import app

08

    import capture

09

    import category_associations

10

    import classify

11

    import rss

12

    import news

13

    import recommend

有了社团如 清单 4 所示的 locomotive
包之后,在类型的根目录中的主程序就足以导入并应用它。例如,文件
locomotive_main.py 包含以下导入:

 

1

import sys         # >– system library

2

    import time        # >– system library

3

    importlocomotive  # >– custom application code library in the
“locomotive” directory

测试

 

Pythonunittest标准库提供一个可怜好的测试解决方案。熟稔 JUnit 的 Java
开发人员和熟练 Test::Unit 框架的 Ruby 开发人士应该会以为 清单 5 中的
Pythonunittest代码很容易驾驭。

 

清单 5. Python unittest 

01

class AppTest(unittest.TestCase):

02

 

03

      def setUp(self):

04

          self.app = locomotive.app.Application()

05

 

06

      def tearDown(self):

07

          pass

08

 

09

      def test_development_feeds_list(self):

10

          feeds_list = self.app.development_feeds_list()

11

          self.assertTrue(len(feeds_list) == 15)

12

          self.assertTrue(‘feed://news.yahoo.com/rss/stock-markets’
infeeds_list)

清单 5 中的代码还出现说法了 Python
的一个尽人皆知的特点:所有的代码必须一律缩进,否则不可能得逞编译。tearDown(self)方法恐怕在起始时看起来有点奇怪。您可能会问,为何测试总是被硬编码为通过?事实上并非如此。这只是在
Python 中编辑空方法的一种格局。

 

工具

 

自我真正需要的是一个怀有语法优异显示、代码完成和断点调试功用的融会开发环境
(IDE),用该条件救助我控制自己的 Python 学习曲线。作为利用 Eclipse IDE 举办Java
开发的一名用户,pyeclipse插件是本人着想的下一个工具。即便该插件有时相比较慢,但它工作得分外不错。我最终投资了
PyCharm IDE,它满意了自我的有着 IDE 要求。

 

在控制了 Python
及其生态系统的基本知识之后,终于来临初始兑现机械学习解决方案的时候。

 

拔取 Python 和 NLTK 实现分类

 

兑现解决方案涉及捕获模拟的 RSS
提要、整理其文件、使用一个NaiveBayesClassifier和 kNN
算法对项目举办归类。下边将会介绍这多少个操作中的每一个。

 

破获和分析提要

 

该项目专门具有挑衅性,因为客户还不曾定义目的 RSS
提要列表。因而,也不设有
“磨练多少”。所以,在上马开发期间必须模拟提要和训练多少。

 

自我用来获取示例提要多少的首先个方法是只领到在某个文本文件中指定的列表中的
RSS 提要。Python 提供了一个很好的 RSS
提要解析库,其名称为feedparser,它抽象不同的 RSS 和 Atom
格式之间的异样。简单的依照文本的目标体系化的另一个可行的库被诙谐地喻为pickle(泡菜)。这五个库在
清单 6 的代码中均有采用,清单 6 中的代码将每一个 RSS 提要捕获为
“腌制过的” 对象文件,以备后用。如您所见,Python
代码非常简短,且效能强大。

 

清单 6. CaptureFeeds 类 

01

import feedparser

02

import pickle

03

 

04

class CaptureFeeds:

05

 

06

    def __init__(self):

07

        for (i, url) in enumerate(self.rss_feeds_list()):

08

            self.capture_as_pickled_feed(url.strip(), i)

09

 

10

    def rss_feeds_list(self):

11

        f = open(‘feeds_list.txt’, ‘r’)

12

        list = f.readlines()

13

        f.close

14

        return list

15

 

16

    def capture_as_pickled_feed(self, url, feed_index):

17

        feed = feedparser.parse(url)

18

        f = open(‘data/feed_’ + str(feed_index) + ‘.pkl’, ‘w’)

19

        pickle.dump(feed, f)

20

        f.close()

21

 

22

if __name__ == “__main__”:

23

    cf = CaptureFeeds()

下一步的挑衅性之大是奇怪的。现在,我有了样例提要多少,必须对它举行分拣,以便将它用作磨练多少。练习数据
是向您的归类算法提供的数据集,以便你能从中举行学习。

 

诸如,我使用的样例提要包括了体育电视机网络店铺 ESPN。提要的品类之一是有关
Denver Broncos 橄榄球队的 提姆 Tebow 被转化到 New York Jets
橄榄球队,在同一时间,Broncos 签了他们新的四分卫 Peyton
Manning。提要结果中的另一个类型是 Boeing Company 和它的新喷气式飞机
(jet)。所以,那里的题材是,应该将什么具体的花色值分配给第一个故事?tebow、broncos、manning、jets、quarterback、trade和nfl这么些值都是方便的。但唯有一个值可以在训练多少中被指定为教练多少体系。同样,在第二个故事中,系列应该是boeing如故jet?困难的局部在于这个细节。假诺你的算法要爆发精确的结果,那么大型磨炼数据集的纯正手工分类相当重大。要完成这或多或少,不应当低估所需的日子。

 

我急需运用更多的数量,而且这多少个数量必须已举办了可靠的分类,这种状况很快就变得肯定。我得以在哪儿找到这样的数额吧?进入
Python
NLTK。除了是一个得天独厚的言语文本处理库之外,它还是还隐含可下载的示范数据集,或是其术语中的文集,
以及可以轻松访问此下载数据的应用程序编程接口。要设置 Reuters
文集,能够运作如下所示的命令。会有超越 10,000 篇信息著作将下载到您的
~/nltk_data/corpora/reuters/ 目录中。与 RSS 提要项目一律,每篇 Reuters
音信著作中都含有一个标题和一个正文,所以那些 NLTK
预分类的数码万分适合于模拟 RSS 提要。

 

1

$ python # enter an interactive Python shell

2

>>> import nltk        # import the nltk library

3

>>> nltk.download()    # run the NLTK Downloader, then enter
‘d’ Download

4

Identifier> reuters    # specify the ‘reuters’ corpus

特别令人感兴趣的是文件
~/nltk_data/corpora/reuters/cats.txt。它蕴含了一个列表,其中富含小说文件名称,以及为各样篇章文件分配的类型。文件看起来如下所示,所以,子目录
test 中的文件 14828 中的著作与要旨grain有关。

 

1

test/14826 trade

2

test/14828 grain

自然语言是无规律的

 

RSS 提要分类算法的原本输入,当然是以罗马尼亚语书写的文本。原始,确实这样。

 

从电脑处理的角度来看,爱尔兰语或任何自然语言(口语或普通的言语)都是极不规范和不准确的。首先,存在大小写的题目。单词
Bronco 是否等于
bronco?答案是,也许是。接下来,您要虚应故事标点和空格。bronco. 是否等于
bronco 或 bronco,?算是吧。然后,有复数情势和一般的单词。run、running 和
ran 是否等于?这取决不同的图景。这六个词有一个联袂的
词根。假设将自然语言词汇嵌入在标记语言(如
HTML)中,意况会怎样啊?在这种境况下,您必须处理像<strong>bronco</strong>这样的公文。最后,还有一个问题,就是那几个平时应用但大多毫无意义的单词,像
a、and 和
the。这么些所谓的停用词相当麻烦。自然语言非凡混乱;在处理在此以前,需要对它们举行整理。

 

幸运的是,Python 和 NLTK 让你可以处置这多少个烂摊子。在 清单 7
中,RssItem类的normalized_words方法可以拍卖所有这多少个题材。请特别注意
NLTK 如何只利用一行代码就可以净化嵌入式 HTML
标记的原始小说文本!使用一个正则表达式删除标点,然后每个单词被拆分,并规范化为小写。

 

清单 7. RssItem 类 

01

class RssItem:

02

    …

03

    regex = re.compile(‘[%s]’ % re.escape(string.punctuation))

04

    …

05

    def normalized_words(self, article_text):

06

        words   = []

07

        oneline = article_text.replace(‘\n’, ‘ ‘)

08

        cleaned = nltk.clean_html(oneline.strip())

09

        toks1   = cleaned.split()

10

        for t1 in toks1:

11

            translated = self.regex.sub(”, t1)

12

            toks2 = translated.split()

13

            for t2 in toks2:

14

                t2s = t2.strip().lower()

15

                if self.stop_words.has_key(t2s):

16

                    pass

17

                else:

18

                    words.append(t2s)

19

        return words

只需这一行代码就可以从 NLTK 得到停用词列表;并且还帮助任何自然语言:

 

1

nltk.corpus.stopwords.words(‘english’)

澳门葡京备用网址,NLTK 还提供了有的 “词干分析器”
类,以便更为规范化单词。请查看有关词干、词形归并、句子结构和语法的
NLTK 文档,了然有关的更多音讯。

 

应用 Naive Bayes 算法举办分拣

 

算法在 NLTK 中被广泛使用并动用nltk.NaiveBayesClassifier类实现。Bayes
算法按照特性在其数额汇总的每个存在或不存在对项目进行归类。在 RSS
提要项目标图景下,每一个风味都是自然语言的一个加以的(清洁过的)单词。该算法是
“朴实” 的,因为它一旦特性(在本例中,单词)之间没有此外关联。

 

不过,马耳他语这种语言包含超越 250,000 个单词。当然,我不指望为了将 RSS
提要项目传递给算法就要为各类 RSS 提要项目创建一个含有 250,000
个布尔值的对象。那么,我会使用什么单词?简单的说,答案是在培养数据组中除了停用词之外最普遍的单词。NLTK
提供了一个完美的类,即nltk.probability.FreqDist,我可以用它来鉴别这一个最常用的单词。在
清单 8
中,collect_all_words方法再次来到来自具备培训作品的装有单词的一个数组。

 

下一场,此数组被传送给identify_top_words方法,以确定最频繁的单词。nltk.FreqDist类的一个得力的特色是,它实质上是一个散列,不过它的键按其对应的值或计数
排序。因而,使用[:1000]Python 语法能够轻松获取最频繁的 1000 个单词。

 

清单 8. 使用 nltk.FreqDist 类 

01

def collect_all_words(self, items):

02

      all_words = []

03

      for item in items:

04

          for w in item.all_words:

05

              words.append(w)

06

      return all_words

07

 

08

  def identify_top_words(self, all_words):

09

      freq_dist = nltk.FreqDist(w.lower() for w in all_words)

10

      return freq_dist.keys()[:1000]

对于使用 NLTK Reuters 著作数据模拟的 RSS
提要项目,我需要规定每个类另外门类。为此,我读取后边提到的
~/nltk_data/corpora/reuters/cats.txt 文件。用 Python
读取一个文本十分简单,如下所示:

 

1

def read_reuters_metadata(self, cats_file):

2

      f = open(cats_file, ‘r’)

3

      lines = f.readlines()

4

      f.close()

5

      return lines

接下去的手续是收获每个 RSS
提要项目的特点。RssItem类的features方法(如下所示)可以成功这或多或少。在该办法中,在著作中的all_words数组首先被缩短到一个较小的set对象,以去掉重复的单词。然后会遍历top_words,并在该
set 中举办相比,确定是否存在重复的单词。随后重临 1000
个布尔值组成的一个散列,以w_为键,前面是单词本身。这么些 Python
万分简单。

 

1

def features(self, top_words):

2

      word_set = set(self.all_words)

3

      features = {}

4

      for w in top_words:

5

          features[“w_%s” % w] = (w in word_set)

6

      return features

接下去,我搜集了锻炼集的 RSS
提要项目和它们分其它性状,并将它们传递给算法。清单 9
中的代码演示了这个职责。请留心,分类器被教练成为只有一行代码。

 

1

def classify_reuters(self):

2

        …

3

        training_set = []

4

        for item in rss_items:

5

            features = item.features(top_words)

6

            tup = (features, item.category)  # tup is a 2-element tuple

7

            featuresets.append(tup)

8

        classifier = nltk.NaiveBayesClassifier.train(training_set)

NaiveBayesClassifier在运行中的 Python
程序的内存中,它现在是经过锻练的。现在,我只需遍历需要展开归类的 RSS
提要项目集,并要求分类器推断每个类其它门类。这很粗略。

 

1

for item in rss_items_to_classify:

2

      features = item.features(top_words)

3

      category = classifier.classify(feat)

变得不那么踏实

 

如前所述,算法假如每个特性之间是没有涉嫌的。由此,像 “machine learning”
和 “learning machine”,或者 “New York Jet” 和 “jet to New York”
这样的短语是一样的(to
是一个停用词)。在自然的语言上下文中,这个单词之间有强烈的关联。所以,我怎么会让算法变得
“不那么天真”,并识别这个单词的涉及?

 

中间一个技能是在特点集内包括常见的双字词(多少个单词为一组)和三字词(两个单词为一组)。NLTK
以nltk.bigrams(…)和nltk.trigrams(…)的款型对此提供了支撑,现在大家对此应当不再感到好奇了。正如可以从练习数据组收集最常用的
n 个单词这样,也足以辨别最常用的双字词和三字词,并将它们作为特性。

 

您的结果会并辔齐驱

 

对数据和算法举办完美是一门艺术。您是不是合宜尤其规范化单词集,也许应该包括词根?或者包括超越1000
个最常用单词?少一些是否适合?或者是否应当利用更大的操练多少集?是否合宜加上更多信用词或
“停用词根”?这一个都是您要问自己的不利问题。使用它们进行实验,通过试错法,您可以会为你的多寡实现最佳算法。我意识,85%
是一个很好的归类成功率。

 

应用 k-Nearest Neighbors 算法提议提出

 

客户愿意呈现在选定连串或一般序列中的 RSS 提要项目。现在,这一个体系已经用
Naive Bayes
算法举行分拣,这一渴求的率先有些已得到了满意。较难的有的是贯彻
“或相似序列”
的渴求。这是机器学习指出器系统起首发挥功效的地点。指出器系统
按照其余系列的相似性来指出一个品种。Amazon.com 的制品提出和 非死不可的心上人指出就是此成效的很好的示范。

 

k-Nearest Neighbors (kNN)
是最常用的指出算法。思路是向它提供一组标签(即序列),
并且每个标签都对应一个数据集。然后,该算法对各数据集举办了比较,以识别相似的花色。数据集由六个数值数组构成,数值的限制往往被规范化为从
0 到 1。然后,它可以从数量集识别相似的价签。与只爆发一个结实的 Naive
Bayes 不同,kNN 可以生出一个有排行的列表,其中蕴蓄若干(即,k
的值)个提议。

 

自己发现,提出器算法比分类算法更便于了然和兑现,但对于本文来说,其代码过于冗长,并且有千丝万缕的数学,不可能在此间详述。请参阅由
Manning 出版的一本很好的新书 Machine Learning in Action,获取 kNN
编码示例(请参阅 参考资料 中的链接)。在 RSS
提要项目实现的过程中,标签值是项目项目,而数据集是最常用的 1000
个单词的值数组。同样,在构建这多少个数组时,一部分属于科学范畴,一部分属于数学范畴,还有一些属于艺术范畴。在数组中,每个单词的值都可以是大概的
0 或 1
的布尔值、小说中单词出现次数的百分比、该比例的指数值,或部分其他值。

 

结束语

 

追究 Python、NLTK 和机器学习一直是一个有趣的、令人喜欢的经验。Python
语言强大而又简单,现在已变为自己的开发工具包的中央部分。它万分适合于机器学习、自然语言和数学/科学应用程序。尽管本文中并从未提到,但我还发现
Python 对于图片和制图分外管用。假诺 Python
同样是您的盲点,我提出你领会一下它。

 

简介: 机器学习取决于
IT、数学和自然语言的鱼龙混杂,在大数量应用程序中会平时用到机械学习。本文将啄磨Python 编程语言和它的 NLTK 库,然后将它们接纳于一个机器学习项目。

 

挑战:使用机器学习对 RSS 提要开展分拣

 

近年,我收下一项职责,要求为客户创制一个 RSS
提要分类子系统。指标是读取几十个甚至几百个 RSS
提要,将它们的广大稿子自动分类到几十个预定义的核心领域当中。客户网站的情节、导航和搜索效果都将由那么些每日活动提要寻找和归类结果驱动。

 

客户指出利用机器学习,或许还会采用 Apache Mahout 和 Hadoop
来兑现该任务,因为客户近日读书了关于这个技巧的稿子。然则,客户的开发团队和大家的开销集团都更熟练Ruby,而不是 Java™
技术。本文将介绍解决方案的技术之旅、学习过程和终极落实。

 

何以是机械学习?

 

我的首先个问题是,“究竟咋样是机器学习?”
我听说过那么些术语,并且隐约知道一级总括机 IBM® 沃特(Wat)son
如今使用该技术在一场 Jeopardy
比赛中制伏了人类竞争者。作为购物者和社交网络移动出席者,我也清楚
Amazon.com 和 Facebook遵照其购物者数据在提供提议(如产品和人)方面显示完美。总而言之,机器学习取决于
IT、数学和自然语言的混合。它最重要关心以下两个主题,但客户的化解方案最后仅涉及前五个大旨:

 

分拣。按照类似项目标一组操练多少,将相关的项分配到自由预定义的门类

指出。按照类似项目标考察来指出使用的项

集群。在一组数据内确定子组

Mahout 和 Ruby 的选择

 

知晓了机械学习是什么之后,下一步是规定什么促成它。按照客户的提出,Mahout
是一个合适的起点。我从 Apache 下载了代码,并起首了读书运用 Mahout
及其兄弟 Hadoop 实现机械学习的经过。不幸的是,我发现即便对于有经历的
Java 开发人士而言,Mahout
的求学曲线也很陡峭,并且不存在可用的样例代码。同样不幸的是,机器学习贫乏按照Ruby 的框架或 gem。

 

发现 Python 和 NLTK

 

本人继续查找解决方案,并且在结果集中一向遭受 “Python”。作为一名 Ruby
开发人员,就算本人还未曾学过该语言,但自身也领会 Python
是一个面向相似对象的、基于文本的、可领会和动态的编程语言。即使二种语言之间存在一些相似之处,但自己多年来都忽略了学习
Python,将它就是一项多余的技巧集。Python 是我的 “盲点”,我怀疑许多 Ruby
开发人士同行都是这么认为的。

 

查找机器学习的书籍,并更深刻钻研它们的目录,我发现,有一定高比例的此类系统在拔取Python 作为其实现语言,并运用了一个被誉为 Natural Language
Toolkit(NLTK,自然语言工具包)的库。通过更加的检索,我意识 Python
的行使比我发觉到的还要广泛,如 Google App Engine、YouTube 和使用 Django
框架构建的网站。它依然还预安装在我每一日都采取的 Mac OS X
工作站上!其它,Python 为数学、科学和工程提供了妙趣横生的标准库(例如,NumPy
和 SciPy)。

 

自我决定执行一个 Python
解决方案,因为自身找到了特别好的编码示例。例如,下面这一行代码就是经过
HTTP 读取 RSS 提要并打印其内容所需的享有代码:

 

1

print feedparser.parse(“”)

高效控制 Python

 

在学习一门新的编程语言时,最容易的局部往往是上学语言本身。较难的片段是探听它的生态系统:怎样设置它、添加库、编写代码、构造代码文件、执行它、调试它并编制单元测试。本节将简单介绍这个核心;请务必参阅
参考资料,以博取有关详细信息的链接。

 

pip

 

Python Package Index (pip) 是 Python
的正规化软件包管理器。您可以动用该程序将库添加到你的系统。它好像于 Ruby
库的 gem。为了将 NLTK 库添加到你的系统,您可以输入以下命令:

 

1

$ pip install nltk

为了显得在你的系统上已设置的 Python 库的列表,请运行以下命令:

 

1

$ pip freeze

运作程序

 

施行 Python 程序一样很粗略。获得一个称呼为 locomotive_main.py
的程序和多个参数,然后你就足以采纳 Python 程序编译并执行它:

 

1

$ python locomotive_main.py arg1 arg2 arg3

Python 使用 清单 1 中的if __name__ ==
“__main__”:语法来规定文件本身是从命令行执行的仍旧从任何代码导入的。为了让文件变得可以进行,需要添加”__main__”检测。

 

清单 1. Main 检测 

1

import sys

2

import time

3

import locomotive

4

 

5

if __name__ == “__main__”:

6

    start_time = time.time()

7

    if len(sys.argv) > 1:

8

        app = locomotive.app.Application()

9

        … additional logic …

virtualenv

 

绝大多数 Ruby 开发人士熟习系统范围的库或 gem
的题目。使用一组系统范围内的库的做法一般是不可取的,因为您的中间一个品种或者借助于某个给定的库的本子
1.0.0,而另一个档次则借助于版本 1.2.7。同样,Java
开发人员都精通系统范围的 CLASSPATH 存在一样的题材。就像 Ruby
社区利用其rvm工具,而 Python 社区利用virtualenv工具(请参阅
参考资料,以取得有关链接)来成立独立的推行环境,其中含有特定版本的
Python 和一组库。清单 2 中的命令展现了何等为你 p1 品种创设一个名为
p1_env 的虚拟环境,其中饱含feedparser、numpy、scipy和nltk库。

 

清单 2. 施用 virualenv 创造一个虚拟环境的命令 

1

$ sudo pip install virtualenv $ cd ~ $ mkdir p1 $ cd p1 $ virtualenv
p1_env –distribute $ source p1_env/bin/activate  (p1_env)[~/p1]$
pip install feedparser (p1_env)[~/p1]$ pip install numpy
(p1_env)[~/p1]$ pip install scipy (p1_env)[~/p1]$ pip install nltk
(p1_env)[~/p1]$ pip freeze

每便在一个 shell 窗口使用你的体系时,都急需 “得到”
您的虚拟环境激活脚本。请留意,在激活脚本被拿走后,shell
指示符会改变。当在你的系统上创制和行使 shell
窗口,轻松地导航到你的品种目录,并启动其虚拟环境时,您可能想在您的
~/.bash_profile 文件中加上以下条目:

 

1

$ alias p1=”cd ~/p1 ; source p1_env/bin/activate”

代码库结构

 

在完成简单的单文件 “Hello World” 程序的编排之后,Python
开发职员需要了解什么正确地公司其代码库的目录和文件名。Java 和 Ruby
语言在这上边都有各自的要求,Python 也尚无什么样两样。简单的话,Python
使用包
的定义对有关的代码举行分组,并提供了醒目标名号空间。出于演示目标,在本文中,代码存在于某个给定项目的根目录中,例如
~/p1。在这几个目录中,存在一个用于同一名称的 Python 包的 locomotive 目录。
清单 3 显示了这多少个目录结构。

 

清单 3. 示范目录结构 

01

locomotive_main.py

02

locomotive_tests.py

03

 

04

locomotive/

05

    __init__.py

06

    app.py

07

    capture.py

08

    category_associations.py

09

    classify.py

10

    news.py

11

    recommend.py

12

    rss.py

13

 

14

locomotive_tests/

15

    __init__.py

16

    app_test.py

17

    category_associations_test.py

18

    feed_item_test.pyc

19

    rss_item_test.py

请留心名称古怪的 __init__.py 文件。这个文件指示 Python
为您的包加载必要的库和特定的应用程序代码文件,它们都置身同一的目录中。
清单 4 展现了文件 locomotive/__init__.py 的内容。

 

清单 4. locomotive/__init__.py 

01

# system imports; loads installed packages

02

    import codecs

03

    import locale

04

    import sys

05

 

06

    # application imports; these load your specific *.py files

07

    import app

08

    import capture

09

    import category_associations

10

    import classify

11

    import rss

12

    import news

13

    import recommend

有了结构如 清单 4 所示的 locomotive
包之后,在类型的根目录中的主程序就可以导入并应用它。例如,文件
locomotive_main.py 包含以下导入:

 

1

import sys         # >– system library

2

    import time        # >– system library

3

    importlocomotive  # >– custom application code library in the
“locomotive” directory

测试

 

Pythonunittest标准库提供一个特别好的测试解决方案。熟谙 JUnit 的 Java
开发人士和熟练 Test::Unit 框架的 Ruby 开发人士应该会以为 清单 5 中的
Pythonunittest代码很容易了然。

 

清单 5. Python unittest 

01

class AppTest(unittest.TestCase):

02

 

03

      def setUp(self):

04

          self.app = locomotive.app.Application()

05

 

06

      def tearDown(self):

07

          pass

08

 

09

      def test_development_feeds_list(self):

10

          feeds_list = self.app.development_feeds_list()

11

          self.assertTrue(len(feeds_list) == 15)

12

          self.assertTrue(‘feed://news.yahoo.com/rss/stock-markets’
infeeds_list)

清单 5 中的代码还出现说法了 Python
的一个显著的风味:所有的代码必须一律缩进,否则不可能得逞编译。tearDown(self)方法恐怕在最先时看起来有点蹊跷。您可能会问,为何测试总是被硬编码为通过?事实上并非如此。这只是在
Python 中编辑空方法的一种形式。

 

工具

 

自身的确需要的是一个所有语法非凡显示、代码完成和断点调试效率的并轨开发环境
(IDE),用该环境救助自己控制自己的 Python 学习曲线。作为利用 Eclipse IDE 进行Java
开发的一名用户,pyeclipse插件是本人着想的下一个工具。虽然该插件有时相比较慢,但它工作得分外不错。我最终投资了
PyCharm IDE,它满意了自我的装有 IDE 要求。

 

在支配了 Python
及其生态系统的基本知识之后,终于赶到起头实现机械学习解决方案的时候。

 

应用 Python 和 NLTK 实现分类

 

兑现解决方案涉及捕获模拟的 RSS
提要、整理其文件、使用一个NaiveBayesClassifier和 kNN
算法对品种举行归类。下面将会介绍那多少个操作中的每一个。

 

破获和分析提要

 

该品种专门具有挑战性,因为客户还尚无定义目的 RSS
提要列表。因而,也不设有
“磨练多少”。所以,在起始开发期间总得模拟提要和教练多少。

 

我用来收获示例提要多少的第一个章程是只领到在某个文本文件中指定的列表中的
RSS 提要。Python 提供了一个很好的 RSS
提要解析库,其名称为feedparser,它抽象不同的 RSS 和 Atom
格式之间的差距。简单的遵照文本的目的序列化的另一个使得的库被诙谐地喻为pickle(泡菜)。这五个库在
清单 6 的代码中均有使用,清单 6 中的代码将每一个 RSS 提要捕获为
“腌制过的” 对象文件,以备后用。如你所见,Python
代码分外简短,且效用强大。

 

清单 6. CaptureFeeds 类 

01

import feedparser

02

import pickle

03

 

04

class CaptureFeeds:

05

 

06

    def __init__(self):

07

        for (i, url) in enumerate(self.rss_feeds_list()):

08

            self.capture_as_pickled_feed(url.strip(), i)

09

 

10

    def rss_feeds_list(self):

11

        f = open(‘feeds_list.txt’, ‘r’)

12

        list = f.readlines()

13

        f.close

14

        return list

15

 

16

    def capture_as_pickled_feed(self, url, feed_index):

17

        feed = feedparser.parse(url)

18

        f = open(‘data/feed_’ + str(feed_index) + ‘.pkl’, ‘w’)

19

        pickle.dump(feed, f)

20

        f.close()

21

 

22

if __name__ == “__main__”:

23

    cf = CaptureFeeds()

下一步的挑衅性之大是奇怪的。现在,我有了样例提要多少,必须对它举办分拣,以便将它用作磨练多少。磨练数据
是向您的归类算法提供的数据集,以便你能从中举办学习。

 

诸如,我使用的样例提要包括了体育电视网络店铺 ESPN。提要的档次之一是有关
Denver Broncos 橄榄球队的 提姆 Tebow 被转发到 New York Jets
橄榄球队,在同一时间,Broncos 签了她们新的四分卫 Peyton
Manning。提要结果中的另一个品类是 Boeing Company 和它的新喷气式飞机
(jet)。所以,这里的题材是,应该将何以具体的门类值分配给第一个故事?tebow、broncos、manning、jets、quarterback、trade和nfl这多少个值都是适当的。但只有一个值可以在磨练多少中被指定为教练多少连串。同样,在第二个故事中,连串应该是boeing仍然jet?困难的有些在于这么些细节。固然你的算法要发出精确的结果,那么大型磨练数据集的标准手工分类非凡首要。要完成这或多或少,不应当低估所需的岁月。

 

本身需要运用更多的多少,而且这么些多少必须已展开了纯正的归类,这种景观很快就变得分明。我可以在哪个地方找到这么的数量吧?进入
Python
NLTK。除了是一个完美的语言文本处理库之外,它竟然还含有可下载的演示数据集,或是其术语中的文集,
以及可以轻松访问此下载数据的应用程序编程接口。要设置 Reuters
文集,可以运行如下所示的吩咐。会有超常 10,000 篇音讯文章将下载到您的
~/nltk_data/corpora/reuters/ 目录中。与 RSS 提要项目雷同,每篇 Reuters
音讯著作中都带有一个题目和一个正文,所以这多少个 NLTK
预分类的数据非常适合于模拟 RSS 提要。

 

1

$ python # enter an interactive Python shell

2

>>> import nltk        # import the nltk library

3

>>> nltk.download()    # run the NLTK Downloader, then enter
‘d’ Download

4

Identifier> reuters    # specify the ‘reuters’ corpus

特意令人感兴趣的是文本
~/nltk_data/corpora/reuters/cats.txt。它蕴含了一个列表,其中蕴涵作品文件名称,以及为每个篇章文件分配的体系。文件看起来如下所示,所以,子目录
test 中的文件 14828 中的小说与要旨grain有关。

 

1

test/14826 trade

2

test/14828 grain

自然语言是乱套的

 

RSS 提要分类算法的本来面目输入,当然是以日语书写的文书。原始,确实这样。

 

从电脑处理的角度来看,罗马尼亚语或此外自然语言(口语或一般的言语)都是极不规范和不可靠的。首先,存在大小写的题目。单词
Bronco 是否等于
bronco?答案是,也许是。接下来,您要应付标点和空格。bronco. 是否等于
bronco 或 bronco,?算是吧。然后,有复数形式和一般的单词。run、running 和
ran 是否等于?这有赖于不同的图景。那六个词有一个一并的
词根。要是将自然语言词汇嵌入在标记语言(如
HTML)中,情形会怎样呢?在这种情景下,您必须处理像<strong>bronco</strong>这样的文本。最终,还有一个题材,就是这些平时选用但基本上毫无意义的单词,像
a、and 和
the。这个所谓的停用词相当难以。自然语言很是混乱;在处理在此之前,需要对它们举行重整。

 

碰巧的是,Python 和 NLTK 让你可以处以那些烂摊子。在 清单 7
中,RssItem类的normalized_words方法可以处理所有这么些题目。请特别注意
NLTK 咋样只行使一行代码就可知净化嵌入式 HTML
标记的原始作品文本!使用一个正则表明式删除标点,然后每个单词被拆分,并规范化为小写。

 

清单 7. RssItem 类 

01

class RssItem:

02

    …

03

    regex = re.compile(‘[%s]’ % re.escape(string.punctuation))

04

    …

05

    def normalized_words(self, article_text):

06

        words   = []

07

        oneline = article_text.replace(‘\n’, ‘ ‘)

08

        cleaned = nltk.clean_html(oneline.strip())

09

        toks1   = cleaned.split()

10

        for t1 in toks1:

11

            translated = self.regex.sub(”, t1)

12

            toks2 = translated.split()

13

            for t2 in toks2:

14

                t2s = t2.strip().lower()

15

                if self.stop_words.has_key(t2s):

16

                    pass

17

                else:

18

                    words.append(t2s)

19

        return words

只需这一行代码就足以从 NLTK 拿到停用词列表;并且还协理其他自然语言:

 

1

nltk.corpus.stopwords.words(‘english’)

NLTK 还提供了有些 “词干分析器”
类,以便更为规范化单词。请查看有关词干、词形归并、句子结构和语法的
NLTK 文档,了然有关的更多音讯。

 

采用 Naive Bayes 算法举办分类

 

算法在 NLTK 中被大规模运用并应用nltk.NaiveBayesClassifier类实现。Bayes
算法遵照特性在其数量集中的每个存在或不存在对项目举行分类。在 RSS
提要项目标情形下,每一个表征都是自然语言的一个加以的(清洁过的)单词。该算法是
“朴实” 的,因为它一旦特性(在本例中,单词)之间一向不其他涉及。

 

然则,越南语这种语言包含超越 250,000 个单词。当然,我不希望为了将 RSS
提要项目传递给算法就要为每个 RSS 提要项目成立一个涵盖 250,000
个布尔值的对象。那么,我会使用什么单词?简单的话,答案是在培育数据组中除去停用词之外最广大的单词。NLTK
提供了一个绝妙的类,即nltk.probability.FreqDist,我得以用它来识别那个最常用的单词。在
清单 8
中,collect_all_words方法重临来自具备培训随笔的兼具单词的一个数组。

 

接下来,此数组被传送给identify_top_words方法,以确定最频繁的单词。nltk.FreqDist类的一个使得的性状是,它实质上是一个散列,然而它的键按其对应的值或计数
排序。因而,使用[:1000]Python 语法可以轻松获取最频繁的 1000 个单词。

 

清单 8. 使用 nltk.FreqDist 类 

01

def collect_all_words(self, items):

02

      all_words = []

03

      for item in items:

04

          for w in item.all_words:

05

              words.append(w)

06

      return all_words

07

 

08

  def identify_top_words(self, all_words):

09

      freq_dist = nltk.FreqDist(w.lower() for w in all_words)

10

      return freq_dist.keys()[:1000]

对此使用 NLTK Reuters 作品数据模拟的 RSS
提要项目,我需要确定每个品种的品种。为此,我读取前边提到的
~/nltk_data/corpora/reuters/cats.txt 文件。用 Python
读取一个文书相当简单,如下所示:

 

1

def read_reuters_metadata(self, cats_file):

2

      f = open(cats_file, ‘r’)

3

      lines = f.readlines()

4

      f.close()

5

      return lines

接下去的步子是获取每个 RSS
提要项目标特性。RssItem类的features方法(如下所示)可以完成这一点。在该办法中,在篇章中的all_words数组首先被减少到一个较小的set对象,以扫除重复的单词。然后会遍历top_words,并在该
set 中举行相比,确定是否存在重复的单词。随后重回 1000
个布尔值组成的一个散列,以w_为键,前面是单词本身。这多少个 Python
非常简短。

 

1

def features(self, top_words):

2

      word_set = set(self.all_words)

3

      features = {}

4

      for w in top_words:

5

          features[“w_%s” % w] = (w in word_set)

6

      return features

接下去,我搜集了训练集的 RSS
提要项目和它们各自的特点,并将它们传递给算法。清单 9
中的代码演示了这个任务。请留意,分类器被锻练成为只有一行代码。

 

1

def classify_reuters(self):

2

        …

3

        training_set = []

4

        for item in rss_items:

5

            features = item.features(top_words)

6

            tup = (features, item.category)  # tup is a 2-element tuple

7

            featuresets.append(tup)

8

        classifier = nltk.NaiveBayesClassifier.train(training_set)

NaiveBayesClassifier在运行中的 Python
程序的内存中,它现在是经过磨炼的。现在,我只需遍历需要举行分类的 RSS
提要项目集,并要求分类器估摸每个类此外档次。这很粗略。

 

1

for item in rss_items_to_classify:

2

      features = item.features(top_words)

3

      category = classifier.classify(feat)

变得不那么踏实

 

如前所述,算法倘诺每个特性之间是从未有过关系的。由此,像 “machine learning”
和 “learning machine”,或者 “New York Jet” 和 “jet to New York”
这样的短语是同一的(to
是一个停用词)。在当然的言语上下文中,这一个单词之间有肯定的涉及。所以,我怎么会让算法变得
“不那么天真”,并识别这多少个单词的涉嫌?

 

其间一个技术是在特点集内包括周边的双字词(五个单词为一组)和三字词(六个单词为一组)。NLTK
以nltk.bigrams(…)和nltk.trigrams(…)的花样对此提供了支撑,现在我们对此应当不再感到好奇了。正如可以从锻炼数据组收集最常用的
n 个单词这样,也可以辨认最常用的双字词和三字词,并将它们作为特性。

 

您的结果会背道而驰

 

对数据和算法举行全面是一门艺术。您是否应当尤为规范化单词集,也许应该包括词根?或者包括超过1000
个最常用单词?少一些是否合宜?或者是不是应该使用更大的教练多少集?是否应当加上更多信用词或
“停用词根”?那多少个都是您要问自己的不易问题。使用它们举行试验,通过试错法,您可以会为您的数据实现最佳算法。我意识,85%
是一个很好的归类成功率。

 

行使 k-Nearest Neighbors 算法指出指出

 

客户愿意呈现在选定系列或一般体系中的 RSS 提要项目。现在,这一个序列已经用
Naive Bayes
算法举行分拣,这一渴求的率先有的已拿到了满足。较难的一对是落实
“或相似体系”
的渴求。这是机器学习指出器系统最先发挥功效的地方。提出器系统
依据其余类其它相似性来提议一个品类。亚马逊.com 的成品提出和 非死不可的意中人提出就是此意义的很好的演示。 www.2cto.com

 

k-Nearest Neighbors (kNN)
是最常用的提出算法。思路是向它提供一组标签(即序列),
并且每个标签都对应一个数据集。然后,该算法对各数据集举行了比较,以识别相似的系列。数据集由两个数值数组构成,数值的限制往往被规范化为从
0 到 1。然后,它可以从数量集识别相似的标签。与只暴发一个结实的 Naive
Bayes 不同,kNN 能够生出一个有排行的列表,其中蕴涵若干(即,k
的值)个指出。

 

自己意识,提议器算法比分类算法更便于了然和落实,但对于本文来说,其代码过于冗长,并且有千丝万缕的数学,无法在这里详述。请参阅由
Manning 出版的一本很好的新书 Machine Learning in Action,获取 kNN
编码示例(请参阅 参考资料 中的链接)。在 RSS
提要项目实现的历程中,标签值是系列项目,而数据集是最常用的 1000
个单词的值数组。同样,在构建这个数组时,一部分属于科学范畴,一部分属于数学范畴,还有局部属于艺术范畴。在数组中,每个单词的值都得以是简约的
0 或 1
的布尔值、小说中单词出现次数的比重、该比例的指数值,或局部别样值。

机器学习取决于
IT、数学和自然语言的插花,在大数额应用程序中会日常用到机械学习。本文将探究Python 编程语言和它的 NLTK 库,…

相关文章

发表评论

电子邮件地址不会被公开。 必填项已用*标注

*
*
Website