在Python中使用NLTK库实现对词干的提取的教程


Posted in Python onApril 08, 2015

什么是词干提取?

在语言形态学和信息检索里,词干提取是去除词缀得到词根的过程─—得到单词最一般的写法。对于一个词的形态词根,词干并不需要完全相同;相关的词映射到同一个词干一般能得到满意的结果,即使该词干不是词的有效根。从1968年开始在计算机科学领域出现了词干提取的相应算法。很多搜索引擎在处理词汇时,对同义词采用相同的词干作为查询拓展,该过程叫做归并。

一个面向英语的词干提取器,例如,要识别字符串“cats”、“catlike”和“catty”是基于词根“cat”;“stemmer”、“stemming”和“stemmed”是基于词根“stem”。一根词干提取算法可以简化词 “fishing”、“fished”、“fish”和“fisher” 为同一个词根“fish”。
技术方案的选择

Python和R是数据分析的两种主要语言;相对于R,Python更适合有大量编程背景的数据分析初学者,尤其是已经掌握Python语言的程序员。所以我们选择了Python和NLTK库(Natual Language Tookit)作为文本处理的基础框架。此外,我们还需要一个数据展示工具;对于一个数据分析师来说,数据库的冗繁安装、连接、建表等操作实在是不适合进行快速的数据分析,所以我们使用Pandas作为结构化数据和分析工具。
环境搭建

我们使用的是Mac OS X,已预装Python 2.7.

安装NLTK

sudo pip install nltk

安装Pandas

sudo pip install pandas

对于数据分析来说,最重要的是分析结果,iPython notebook是必备的一款利器,它的作用在于可以保存代码的执行结果,例如数据表格,下一次打开时无需重新运行即可查看。

安装iPython notebook

sudo pip install ipython

创建一个工作目录,在工作目录下启动iPython notebook,服务器会开启http://127.0.0.1:8080页面,并将创建的代码文档保存在工作目录之下。

mkdir Codes
cd Codes
ipython notebook

文本处理

数据表创建

使用Pandas创建数据表 我们使用得到的样本数据,建立DataFrame——Pandas中一个支持行、列的2D数据结构。

from pandas import DataFrame
import pandas as pd
d = ['pets insurance','pets insure','pet insurance','pet insur','pet insurance"','pet insu']
df = DataFrame(d)
df.columns = ['Words']
df

显示结果

在Python中使用NLTK库实现对词干的提取的教程

NLTK分词器介绍

RegexpTokenizer:正则表达式分词器,使用正则表达式对文本进行处理,就不多作介绍。
PorterStemmer:波特词干算法分词器,原理可看这里:http://snowball.tartarus.org/algorithms/english/stemmer.html
第一步,我们创建一个去除标点符号等特殊字符的正则表达式分词器:

import nltk
tokenizer = nltk.RegexpTokenizer(r'w+')

接下来,对准备好的数据表进行处理,添加词干将要写入的列,以及统计列,预设默认值为1:

df["Stemming Words"] = ""
df["Count"] = 1

读取数据表中的Words列,使用波特词干提取器取得词干:

j = 0
while (j <= 5):
  for word in tokenizer.tokenize(df["Words"][j]):
    df["Stemming Words"][j] = df["Stemming Words"][j] + " " + nltk.PorterStemmer().stem_word(word)
  j += 1
df

Good!到这一步,我们已经基本上实现了文本处理,结果显示如下:

在Python中使用NLTK库实现对词干的提取的教程

分组统计

在Pandas中进行分组统计,将统计表格保存到一个新的DataFrame结构uniqueWords中:

uniqueWords = df.groupby(['Stemming Words'], as_index = False).sum().sort(['Count'])
uniqueWords

在Python中使用NLTK库实现对词干的提取的教程

注意到了吗?依然还有一个pet insu未能成功处理。

拼写检查

对于用户拼写错误的词语,我们首先想到的是拼写检查,针对Python我们可以使用enchant:

sudo pip install enchant

使用enchant进行拼写错误检查,得到推荐词:

import enchant
from nltk.metrics import edit_distance
class SpellingReplacer(object):
  def __init__(self, dict_name='en', max_dist=2):
    self.spell_dict = enchant.Dict(dict_name)
    self.max_dist = 2
  def replace(self, word):
    if self.spell_dict.check(word):
      return word
    suggestions = self.spell_dict.suggest(word)
    if suggestions and edit_distance(word, suggestions[0]) <=
      self.max_dist:
      return suggestions[0]
    else:
      return word

from replacers import SpellingReplacer
replacer = SpellingReplacer()
replacer.replace('insu')

'insu'

但是,结果依然不是我们预期的“insur”。能不能换种思路呢?
算法特殊性

用户输入非常重要的特殊性来自于行业和使用场景。采取通用的英语大词典来进行拼写检查,无疑是行不通的,并且某些词语恰恰是拼写正确,但本来却应该是另一个词。但是,我们如何把这些背景信息和数据分析关联起来呢?

经过一番思考,我认为最重要的参考库恰恰就在已有的数据分析结果中,我们回来看看:

在Python中使用NLTK库实现对词干的提取的教程

已有的5个“pet insur”,其实就已经给我们提供了一份数据参考,我们已经可以对这份数据进行聚类,进一步除噪。

相似度计算

对已有的结果进行相似度计算,将满足最小偏差的数据归类到相似集中:

import Levenshtein
minDistance = 0.8
distance = -1
lastWord = ""
j = 0
while (j < 1):
   lastWord = uniqueWords["Stemming Words"][j]
   distance = Levenshtein.ratio(uniqueWords["Stemming Words"][j], uniqueWords["Stemming Words"][j + 1])
   if (distance > minDistance):
    uniqueWords["Stemming Words"][j] = uniqueWords["Stemming Words"][j + 1]
  j += 1
uniqueWords

查看结果,已经匹配成功!

在Python中使用NLTK库实现对词干的提取的教程

最后一步,重新对数据结果进行分组统计:

uniqueWords = uniqueWords.groupby(['Stemming Words'], as_index = False).sum()
uniqueWords

到此,我们已经完成了初步的文本处理。

在Python中使用NLTK库实现对词干的提取的教程

Python 相关文章推荐
python文件操作之目录遍历实例分析
May 20 Python
Python+Socket实现基于UDP协议的局域网广播功能示例
Aug 31 Python
Python简单定义与使用二叉树示例
May 11 Python
解决pycharm无法调用pip安装的包问题
May 18 Python
解决pytorch 交叉熵损失输出为负数的问题
Jul 07 Python
PyTorch: Softmax多分类实战操作
Jul 07 Python
python定义类的简单用法
Jul 24 Python
python如何将图片转换素描画
Sep 08 Python
python MD5加密的示例
Oct 19 Python
python中的插入排序的简单用法
Jan 19 Python
Python+tkinter实现高清图片保存
Mar 13 Python
Python识别花卉种类鉴定网络热门植物并自动整理分类
Apr 08 Python
使用Python操作Elasticsearch数据索引的教程
Apr 08 #Python
用Python实现协同过滤的教程
Apr 08 #Python
在Python中调用ggplot的三种方法
Apr 08 #Python
Python字符串和文件操作常用函数分析
Apr 08 #Python
Python遍历zip文件输出名称时出现乱码问题的解决方法
Apr 08 #Python
python smtplib模块发送SSL/TLS安全邮件实例
Apr 08 #Python
python复制与引用用法分析
Apr 08 #Python
You might like
杏林同学录(六)
2006/10/09 PHP
php+redis实现注册、删除、编辑、分页、登录、关注等功能示例
2017/02/15 PHP
PHP精确到毫秒秒杀倒计时实例详解
2019/03/14 PHP
设置下载不需要倒计时cookie(倒计时代码)
2008/11/19 Javascript
&amp;lt;script defer&amp;gt; defer 是什么意思
2009/05/10 Javascript
javascript中的prototype属性实例分析说明
2010/08/09 Javascript
基于jQuery的倒计时实现代码
2012/05/30 Javascript
原始的js代码和jquery对比体会
2013/09/10 Javascript
getJSON调用后台json数据时函数被调用两次的原因猜想
2013/09/29 Javascript
JavaScript获取多个数组的交集简单实例
2013/11/11 Javascript
button没写type=button会导致点击时提交
2014/03/06 Javascript
教你使用javascript简单写一个页面模板引擎
2015/05/05 Javascript
一张Web前端的思维导图分享
2015/07/03 Javascript
基于jQuery实现的美观星级评论打分组件代码
2015/10/30 Javascript
BootStrap 可编辑表Table格
2016/11/24 Javascript
Mint UI 基于 Vue.js 移动端组件库
2017/11/07 Javascript
vue2.0 computed 计算list循环后累加值的实例
2018/03/07 Javascript
原生js代码能实现call和bind吗
2019/07/31 Javascript
js实现树形数据转成扁平数据的方法示例
2020/02/27 Javascript
JS XMLHttpRequest原理与使用方法深入详解
2020/04/30 Javascript
vue项目使用$router.go(-1)返回时刷新原来的界面操作
2020/07/26 Javascript
js实现QQ邮箱邮件拖拽删除功能
2020/08/27 Javascript
[46:44]VG vs TNC Supermajor小组赛B组败者组决赛 BO3 第一场 6.2
2018/06/03 DOTA
在Python中使用SQLite的简单教程
2015/04/29 Python
解决Python获取字典dict中不存在的值时出错问题
2018/10/17 Python
python 将list转成字符串,中间用符号分隔的方法
2018/10/23 Python
python识别图像并提取文字的实现方法
2019/06/28 Python
Jupyter安装链接aconda实现过程图解
2020/11/02 Python
html5绘制时钟动画
2014/12/15 HTML / CSS
GUESS盖尔斯法国官网:美国时尚品牌
2016/09/23 全球购物
波兰家居和花园家具专家:4Home
2019/05/26 全球购物
酒店中秋节促销方案
2014/01/30 职场文书
四风问题个人自查剖析材料思想汇报
2014/09/21 职场文书
2015年社区服务活动总结
2015/03/25 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
新娘婚礼致辞
2015/07/27 职场文书