参考https://blog.csdn.net/zxm1306192988/article/details/78896319

以NLTK为基础配合讲解自然语言处理的原理  http://www.nltk.org/

Python上著名的自然语⾔处理库

自带语料库,词性分类库 
自带分类,分词,等功能 
强⼤的社区⽀持 
还有N多的简单版wrapper,如 TextBlob

NLTK安装(可能需要预先安装numpy)

  1. pip install nltk

 安装语料库

  1. import nltk
  2. nltk.download()

  

NLTK自带语料库

  1. >>> from nltk.corpus import brown
  2. >>> brown.categories() # 分类
  3. ['adventure', 'belles_lettres', 'editorial',
  4. 'fiction', 'government', 'hobbies', 'humor',
  5. 'learned', 'lore', 'mystery', 'news', 'religion',
  6. 'reviews', 'romance', 'science_fiction']
  7. >>> len(brown.sents()) # 一共句子数
  8. 57340
  9. >>> len(brown.words()) # 一共单词数
  10. 1161192

  文本处理流程:

文本 -> 预处理(分词、去停用词) -> 特征工程 -> 机器学习算法 -> 标签

分词(Tokenize)

把长句⼦拆成有“意义”的⼩部件

  1. >>> import nltk
  2. >>> sentence = hello, world"
  3. >>> tokens = nltk.word_tokenize(sentence)
  4. >>> tokens
  5. ['hello', ‘,', 'world']

  中英文NLP区别: 
英文直接使用空格分词,中文需要专门的方法进行分词

中文分词

  1. import jieba
  2. seg_list = jieba.cut('我来到北京清华大学', cut_all=True)
  3. print('Full Mode:', '/'.join(seg_list)) # 全模式
  4. seg_list = jieba.cut('我来到北京清华大学', cut_all=False)
  5. print('Default Mode:', '/'.join(seg_list)) # 精确模式
  6. seg_list = jieba.cut('他来到了网易杭研大厦') # 默认是精确模式
  7. print('/'.join(seg_list))
  8. seg_list = jieba.cut_for_search('小明硕士毕业于中国科学院计算所,后在日本京都大学深造') # 搜索引擎模式
  9. print('搜索引擎模式:', '/'.join(seg_list))
  10. seg_list = jieba.cut('小明硕士毕业于中国科学院计算所,后在日本京都大学深造', cut_all=True)
  11. print('Full Mode:', '/'.join(seg_list))

  纷繁复杂的词型

  • Inflection 变化:walk=>walking=>walked 不影响词性
  • derivation 引申:nation(noun)=>national(adjective)=>nationalize(verb) 影响词性

词形归一化

  • Stemming 词干提取(词根还原):把不影响词性的inflection 的小尾巴砍掉 (使用词典,匹配最长词)
  • walking 砍掉ing=>walk
  • walked 砍掉ed=>walk
  • Lemmatization 词形归一(词形还原):把各种类型的词的变形,都归一为一个形式(使用wordnet)
  • went 归一 => go
  • are 归一 => be

NLTK实现Stemming

词干提取:3种

1、

  1. from nltk.stem.lancaster import LancasterStemmer
  2. lancaster_stemmer=LancasterStemmer()
  3. print(lancaster_stemmer.stem('maximum'))
  4. print(lancaster_stemmer.stem('multiply'))
  5. print(lancaster_stemmer.stem('provision'))
  6. print(lancaster_stemmer.stem('went'))
  7. print(lancaster_stemmer.stem('wenting'))
  8. print(lancaster_stemmer.stem('walked'))
  9. print(lancaster_stemmer.stem('national'))

2、

  1. from nltk.stem.porter import PorterStemmer
  2. porter_stemmer=PorterStemmer()
  3. print(porter_stemmer.stem('maximum'))
  4. print(porter_stemmer.stem('multiply'))
  5. print(porter_stemmer.stem('provision'))
  6. print(porter_stemmer.stem('went'))
  7. print(porter_stemmer.stem('wenting'))
  8. print(porter_stemmer.stem('walked'))
  9. print(porter_stemmer.stem('national'))

  3、

  1. from nltk.stem import SnowballStemmer
  2. snowball_stemmer=SnowballStemmer("english")
  3. print(snowball_stemmer.stem('maximum'))
  4. print(snowball_stemmer.stem('multiply'))
  5. print(snowball_stemmer.stem('provision'))
  6. print(snowball_stemmer.stem('went'))
  7. print(snowball_stemmer.stem('wenting'))
  8. print(snowball_stemmer.stem('walked'))
  9. print(snowball_stemmer.stem('national'))

  NLTK实现 Lemmatization(词形归一)

  1. from nltk.stem import WordNetLemmatizer
  2. wordnet_lemmatizer=WordNetLemmatizer()
  3. print(wordnet_lemmatizer.lemmatize('dogs'))
  4. print(wordnet_lemmatizer.lemmatize('churches'))
  5. print(wordnet_lemmatizer.lemmatize('aardwolves'))
  6. print(wordnet_lemmatizer.lemmatize('abaci'))
  7. print(wordnet_lemmatizer.lemmatize('hardrock'))

  问题:Went v.是go的过去式 n.英文名:温特 
所以增加词性信息,可使NLTK更好的 Lemmatization

  1. from nltk.stem import WordNetLemmatizer
  2. wordnet_lemmatizer = WordNetLemmatizer()
  3. # 没有POS Tag,默认是NN 名词
  4. print(wordnet_lemmatizer.lemmatize('are'))
  5. print(wordnet_lemmatizer.lemmatize('is'))
  6. # 加上POS Tag
  7. print(wordnet_lemmatizer.lemmatize('is', pos='v'))
  8. print(wordnet_lemmatizer.lemmatize('are', pos='v'))

  NLTK标注POS Tag

  1. import nltk
  2. text=nltk.word_tokenize('what does the beautiful fox say')
  3. print(text)
  4. print(nltk.pos_tag(text))

  去停用词

  1. import nltk
  2. from nltk.corpus import stopwords
  3. word_list=nltk.word_tokenize('what does the beautiful fox say')
  4. print(word_list )
  5. filter_words=[word for word in word_list if word not in stopwords.words('english')]
  6. print(filter_words)

  

根据具体task决定,如果是文本查重、写作风格判断等,可能就不需要去除停止词

什么是自然语言处理?
自然语言——> 计算机数据

文本预处理让我们得到了什么?

NLTK在NLP上的经典应⽤(重点)

  • 情感分析
  • 文本相似度
  • 文本分类

1、情感分析

最简单的方法:基于情感词典(sentiment dictionary) 
类似于关键词打分机制

like 1 
good 2 
bad -2 
terrible -3

比如:AFINN-111 
http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6010

  1. import nltk
  2. from nltk.corpus import stopwords
  3. from nltk.stem import SnowballStemmer
  4.  
  5. snowball_stemmer = SnowballStemmer("english")
  6.  
  7. sentiment_dictionary = {}
  8. for line in open('AFINN-111.txt'):
  9. word, score = line.split('\t')
  10. sentiment_dictionary[word] = int(score)
  11.  
  12. text = 'I went to Chicago yesterday, what a fucking day!'
  13. word_list = nltk.word_tokenize(text) # 分词
  14. words = [(snowball_stemmer.stem(word)) for word in word_list] # 词干提取,词形还原最好有词性,此处先不进行
  15. words = [word for word in word_list if word not in stopwords.words('english')] # 去除停用词
  16. print('预处理之后的词:', words)
  17. total_score = sum(sentiment_dictionary.get(word, 0) for word in words)
  18. print('该句子的情感得分:', total_score)
  19. if total_score > 0:
  20. print('积极')
  21. elif total_score == 0:
  22. print('中性')
  23. else:
  24. print('消极')

  缺点:新词无法处理、依赖人工主观性、无法挖掘句子深层含义

配上ML的情感分析

  1. from nltk.classify import NaiveBayesClassifier
  2.  
  3. # 随手造点训练集
  4. s1 = 'this is a good book'
  5. s2 = 'this is a awesome book'
  6. s3 = 'this is a bad book'
  7. s4 = 'this is a terrible book'
  8.  
  9. def preprocess(s):
  10. dic = ['this', 'is', 'a', 'good', 'book', 'awesome', 'bad', 'terrible']
  11. return {word: True if word in s else False for word in dic} # 返回句子的词袋向量表示
  12.  
  13. # 把训练集给做成标准形式
  14. training_data = [[preprocess(s1), 'pos'],
  15. [preprocess(s2), 'pos'],
  16. [preprocess(s3), 'neg'],
  17. [preprocess(s4), 'neg']]
  18.  
  19. # 喂给model吃
  20. model = NaiveBayesClassifier.train(training_data)
  21. # 打出结果
  22. print(model.classify(preprocess('this is a terrible book')))

  文本相似度

使用 Bag of Words 元素的频率表示文本特征

使用 余弦定理 判断向量相似度

  1. import nltk
  2. from nltk import FreqDist
  3.  
  4. corpus = 'this is my sentence ' \
  5. 'this is my life ' \
  6. 'this is the day'
  7.  
  8. # 根据需要做预处理:tokensize,stemming,lemma,stopwords 等
  9. tokens = nltk.word_tokenize(corpus)
  10. print(tokens)
  11.  
  12. # 用NLTK的FreqDist统计一下文字出现的频率
  13. fdist = FreqDist(tokens)
  14. # 类似于一个Dict,带上某个单词, 可以看到它在整个文章中出现的次数
  15. print(fdist['is'])
  16. # 把最常见的50个单词拿出来
  17. standard_freq_vector = fdist.most_common(50)
  18. size = len(standard_freq_vector)
  19. print(standard_freq_vector)
  20.  
  21. # Func:按照出现频率大小,记录下每一个单词的位置
  22. def position_lookup(v):
  23. res = {}
  24. counter = 0
  25. for word in v:
  26. res[word[0]] = counter
  27. counter += 1
  28. return res
  29.  
  30. # 把词典中每个单词的位置记录下来
  31. standard_position_dict = position_lookup(standard_freq_vector)
  32. print(standard_position_dict)
  33.  
  34. #新的句子
  35. sentence='this is cool'
  36. # 建立一个跟词典同样大小的向量
  37. freq_vector=[0]*size
  38. # 简单的预处理
  39. tokens=nltk.word_tokenize(sentence)
  40. # 对于新句子里的每个单词
  41. for word in tokens:
  42. try:
  43. # 如果在词典里有,就在标准位置上加1
  44. freq_vector[standard_position_dict[word]]+=1
  45. except KeyError:
  46. continue
  47.  
  48. print(freq_vector)

  

这里求的是一个词频率向量。

求完之后再运用上述那个公式。

应用:文本分类

TF-IDF是一个整体

TF:Term Frequency 衡量一个term 在文档中出现得有多频繁。
TF(t)=t出现在文档中的次数/文档中的term总数

IDF:Inverse Document Frequency ,衡量一个term有多重要。
有些词出现的很多,但明显不是很有用,如 ‘is’’the’ ‘and’ 之类的词。
IDF(t)=loge(文档总数/含有t的文档总数)
(如果一个词越常见,那么分母就越大,逆文档频率就越小越接近0。所以分母通常加1,是为了避免分母为0(即所有文档都不包含该词)。log表示对得到的值取对数。)
如果某个词比较少见,但是它在这篇文章中多次出现,那么它很可能就反映了这篇文章的特性,正是我们所需要的关键词。
TF−IDF=TF∗IDF

NLTK实现TF-IDF

  1. from nltk.text import TextCollection
  2.  
  3. # 首先,把所有的文档放到TextCollection类中
  4. # 这个类会自动帮你断句,做统计,做计算
  5. corpus = TextCollection(['this is sentence one',
  6. 'this is sentence two',
  7. ' is sentence three'])
  8.  
  9. # 直接就能算出tfidf
  10. # (term:一句话中的某个term,text:这句话)
  11. print(corpus.tf_idf('this', 'this is sentence four'))
  12.  
  13. # 对于每个新句子
  14. new_sentence='this is sentence five'
  15. # 遍历一遍所有的vocabulary中的词:
  16. standard_vocab=['this' 'is' 'sentence' 'one' 'two' 'five']
  17. for word in standard_vocab:
  18. print(corpus.tf_idf(word, new_sentence))

  得到了 TF-IDF的向量表示后,用ML 模型就行分类即可:

NLTK与NLP原理及基础的更多相关文章

  1. linux基础-第十四单元 Linux网络原理及基础设置

    第十四单元 Linux网络原理及基础设置 三种网卡模式图 使用ifconfig命令来维护网络 ifconfig命令的功能 ifconfig命令的用法举例 使用ifup和ifdown命令启动和停止网卡 ...

  2. Linux iptables:规则原理和基础

    什么是iptables? iptables是Linux下功能强大的应用层防火墙工具,但了解其规则原理和基础后,配置起来也非常简单. 什么是Netfilter? 说到iptables必然提到Netfil ...

  3. 【自然语言处理篇】--以NLTK为基础讲解自然语⾔处理的原理和基础知识

    一.前述 Python上著名的⾃然语⾔处理库⾃带语料库,词性分类库⾃带分类,分词,等等功能强⼤的社区⽀持,还有N多的简单版wrapper. 二.文本预处理 1.安装nltk pip install - ...

  4. MySQL运行原理与基础架构

    1.MySQL基础 MySQL是一个开放源代码的关系数据库管理系统.原开发者为瑞典的MySQL AB公司,最早是在2001年MySQL3.23进入到管理员的视野并在之后获得广泛的应用. 2008年My ...

  5. 【面试问题】—— 2019.3月前端面试之JS原理&CSS基础&Vue框架

    前言:三月中旬面试了两家公司,一家小型公司只有面试,另一家稍大型公司笔试之后一面定夺.笔试部分属于基础类型,网上的复习资料都有. 面试时两位面试官都有考到一些实际工作中会用到,但我还没接触过的知识点. ...

  6. LDAP学习小结【仅原理和基础篇】

    此篇文章花费了好几个晚上,大部分是软件翻译的英文文档,加上自己的理解所写,希望学习者能尊重每个人的努力. 我有句话想送给每个看我文章的人: 慢就是快,快就是慢!!! 另外更希望更多人能从认真从原理学习 ...

  7. iSCSI 原理和基础使用

    终于完成最后一篇了,一上午的时间就过去了. 下文主要是对基本操作和我对iSCSI的理解,网上有很多iSCSI原理,在这里我就不写了,请自行学习. 这篇文章仅对iSCSI的很多误解做一次梳理,你必须对所 ...

  8. 【git体验】git原理及基础

    原理:分布式版本号控制系统像 Git,Mercurial,Bazaar 以及 Darcs 等,client并不仅仅提取最新版本号 的文件快照,而是把原始的代码仓库完整地镜像下来. 这么一来.不论什么一 ...

  9. Kerberos原理和基础小结

    此篇文章仅做Kerberos的基本原理和基本使用做说明,本人对Kerberos了解有限,也是通过大量英文文档中翻译过来, 加上自己对Kerberos的理解所写,本人英文太菜,看文档看的头昏眼花若有写的 ...

随机推荐

  1. 吐槽XE3中的BUG:无法调试32位的应用程序

    我想用的功能在XE5中有BUG, 无奈转移到XE3中测试,发现了XE3还有另外一个问题:无法DEBUG 32位的应用程序,这算什么事啊?有人说把项目属性中的link with dynamic RTL去 ...

  2. Redis集群部署3.0

    我用的Mac的终端 ------------------------- 1.Redis简介 centos(5.4)  Redis是一个key-value存储系统.和Memcached类似,但是解决了断 ...

  3. 使用document.domain和iframe实现站内AJAX跨域

    站内AJAX跨域可以通过document.domain和iframe实现,比如www.css88.com.js.css88.com.css88.com这3个域名其实是3个不同的域,很多时候www.cs ...

  4. Mybatis_总结_03_用_动态SQL

    一.前言 MyBatis 的强大特性之一便是它的动态 SQL.如果你有使用 JDBC 或其它类似框架的经验,你就能体会到根据不同条件拼接 SQL 语句的痛苦.例如拼接时要确保不能忘记添加必要的空格,还 ...

  5. 条款39:明智的使用private继承

    首先看一下private继承的法则:class之间的继承关系如果是private的话,那么编译器不会将一个derived对象自动当作为一个base class对象. 从base class继承而来的所 ...

  6. js字符串和数组操作,容易混淆的方法总结(slice、substring、substr、splice)

    平时工作中,很少静下心来总结基础知识,总觉得自己会用了,有点飘了,直到碰壁之后才懂得基础知识的重要性.大牛告诉我,一次写对,是不是可以不用F12去调试了?是不是省了时间?简直是面红耳赤,无地自容.在这 ...

  7. RabbitMQ和Kafka可靠性

    RabbitMQ和Kafka可靠性 https://www.cnblogs.com/haolujun/p/9641840.html 我们通过前文知道,RabbitMQ的队列分为master queue ...

  8. 学习动态性能表(17)--v$segstat&v$segment_statistics

    学习动态性能表 第17篇-(1)-V$SEGSTAT  2007.6.13 本视图实时监控段级(segment-level)统计项,支持oracle9ir2及更高版本 V$SEGSTAT中的常用列 T ...

  9. jsp有哪些内置对象?作用分别是什么?

    JSP共有以下9种基本内置组件 1.request对象 客户端请求,此请求会包含来自GET/POST请求的参数通过它才能了解到客户的需求,然后做出响应. 2.response对象 响应客户请求的有关信 ...

  10. (C#)Windows Shell 外壳编程系列3 - 上下文菜单(iContextMenu)(一)右键菜单

    (本系列文章由柠檬的(lc_mtt)原创,转载请注明出处,谢谢-) 接上一节:(C#)Windows Shell 外壳编程系列2 - 解释,从“桌面”开始展开 这里解释上一节中获取名称的方法 GetD ...