python机器学习——NLTK及分析文本数据(自然语言处理基础)

2023-11-09

NLTK

NLTK(Natural Language Toolkit),自然语言处理工具包,在NLP(自然语言处理)领域中,最常使用的一个Python库。自带语料库,词性分类库。自带分类,分词功能。
NLTK安装
安装:pip install NLTK
测试:import nltk
Anaconda不用安装
安装语料库:

import nltk
nltk.download()

执行代码后,会出现包管理器,我们下载NLTK数据,这些数据中包含很多语料和训练模型这里写图片描述
安装过程:
这里写图片描述
安装完成:
这里写图片描述
NLTK功能:
这里写图片描述
NLTK自带的语料库:
corpus语料库的集合,导入布朗语料库。
categoryies()查看种类
sents()句子数量
words()词数
这里写图片描述
如果导入的时候出现import错误,说明语料库没有下载,重新下载好,再导入。

文本处理
分词(Tokenize):word_tokenize生成一个词的列表

>>> import nltk
>>> sentence="I Love China !"
>>> tokens=nltk.word_tokenize(sentence)
>>> tokens
['I', 'Love', 'China', '!']
>>>

中文分词:用jieba

>>> import jieba
>>> seg_list=jieba.cut("我正在学习机器学习",cut_all=True)
>>> print("全模式:","/".join(seg_list))
全模式: 我/正在/学习/学习机/机器/学习
>>> seg_list=jieba.cut("我正在学习机器学习",cut_all=False)
>>> print("精确模式:","/".join(seg_list))
精确模式: 我/正在/学习/机器/学习
>>> seg_list=jieba.cut("我正在学习自然语言处理")
>>> print("默认是精确模式:","/".join(seg_list))
默认是精确模式: 我/正在/学习/自然语言/处理
>>> seg_list=jieba.cut_for_search("文本分析和自然语言处理是现在人工智能系统不可分割的一部分")
>>> print("/".join(seg_list))
文本/分析//自然/语言/自然语言/处理/是/现在/人工/智能/人工智能/系统/不可/可分/分割/不可分割/的/一部/部分/一部分
>>>

但是有时候分词并没有那么容易。文本中可能会含有各种各样的字符,如社交网络上的文本。

from nltk.tokenize import word_tokenize
tweet = 'RT @angelababy: love you baby! :D http://ah.love #168cm' 
print(word_tokenize(tweet))
 # ['RT', '@', 'angelababy', ':', 'love', 'you', 'baby', '!', ':', # ’D', 'http', ':', '//ah.love', '#', '168cm']

这时候就需要正则表达式。正则表达式参考文档:http://www.regexlab.com/zh/regref.htm

import re
emoticons_str = r"""  
  (?: 
        [:=;] # 眼睛  
        [oO\-]? # ⿐鼻⼦子
        [D\)\]\(\]/\\OpP] # 嘴
    )"""
regex_str = [
    emoticons_str,
    r'<[^>]+>',  # HTML tags  
    r'(?:@[\w_]+)',  # @某⼈人   
    r"(?:\#+[\w_]+[\w\'_\-]*[\w_]+)",  # 话题标签
    r'http[s]?://(?:[a-z]|[0-9]|[$-_@.&amp;+]|[!*\(\),]|(?:%[0-9a-f][0-9a-f]))+',  # URLs 
    r'(?:(?:\d+,?)+(?:\.?\d+)?)',  # 数字 
    r"(?:[a-z][a-z'\-_]+[a-z])",  # 含有 - 和 ‘ 的单词    
    r'(?:\S)'  # 其他 
]

tokens_re = re.compile(r'(' + '|'.join(regex_str) + ')',re.VERBOSE | re.IGNORECASE)
emoticon_re = re.compile(r'^' + emoticons_str + '$',re.VERBOSE | re.IGNORECASE)

def tokenize(s):
    return tokens_re.findall(s)
def preprocess(s, lowercase=False):
    tokens = tokenize(s)
    if lowercase:
        tokens = [token if emoticon_re.search(token) else token.lower()for token in tokens ]
    return tokens


tweet = 'RT @angelababy: love you baby! :D http://ah.love #168cm'
print(preprocess(tweet))

运行结果:

['R', 'T', '@angelababy', ':', 'love', 'you', 'baby', '!', ':D', 'http://ah.love', '#168cm']

提取文本数据的词干(Stemming 词⼲提取):
处理文本文档时,可能会碰到单词的不同形式。如“paly”这个词会以各种形式出现,“play”,“plays”,“player”,“playing”等。这些是具有同样含义的单词家族,在文本分析中,提取这些词的原形非常有用,它有助于我们提取一些统计信息来分析整个文本。词干提取的目标是将不同词性的单词都变成其原形。
词干提取使用启发式处理方法截取单词的尾部,以提取单词的原形。
NLTK实现Stemmin(参照《python机器学习经典实例》分析文本数据)

from nltk.stem.porter import PorterStemmer
from nltk.stem.lancaster import LancasterStemmer
from nltk.stem.snowball import SnowballStemmer

words = ['table', 'probably', 'wolves', 'playing', 'is', 
        'dog', 'the', 'beaches', 'grounded', 'dreamt', 'envision']

#比较不同的词干提取方法
stemmers = ['PORTER', 'LANCASTER', 'SNOWBALL']
stemmer_porter = PorterStemmer()
stemmer_lancaster = LancasterStemmer()
stemmer_snowball = SnowballStemmer('english')

formatted_row = '{:>16}' * (len(stemmers) + 1)
print ('\n', formatted_row.format('WORD', *stemmers), '\n')
for word in words:
    stemmed_words = [stemmer_porter.stem(word), 
            stemmer_lancaster.stem(word), stemmer_snowball.stem(word)]
    print (formatted_row.format(word, *stemmed_words))

运行结果:
这里写图片描述

比较:3种词干提取算法的本质目标都是提取出词干,消除词影响。它们的不同之处在于操作的严格程度不同。Lancaster词干提取器比其他两个词干提取器更严格,Porter词干提取器是最宽松的。Lancaster词干提取器得到的词干往往比较模糊,难以理解。Lancaster词干提取器的速度很快,但是它会减少单词的很大部分,因此通常会选择Snowball词干提取器。

用词性还原的方法还原文本的基本形式(Lemmatization 词形归⼀):
词形还原的目标也是将单词转化为其原形,但它是一个更结构化的方法。词形还原通过对单词进行词汇和语法分析来实现,输出结果取决于标记是一个动词还是一个名词。
NLTK实现Lemm(参照《python机器学习经典实例》分析文本数据)

from nltk.stem import WordNetLemmatizer

words = ['table', 'probably', 'wolves', 'playing', 'is', 
        'dog', 'the', 'beaches', 'grounded', 'dreamt', 'envision']

# 对比不同词形的还原器
lemmatizers = ['NOUN LEMMATIZER', 'VERB LEMMATIZER']
lemmatizer_wordnet = WordNetLemmatizer()

formatted_row = '{:>24}' * (len(lemmatizers) + 1)
print('\n', formatted_row.format('WORD', *lemmatizers), '\n')
for word in words:
    lemmatized_words = [lemmatizer_wordnet.lemmatize(word, pos='n'),
           lemmatizer_wordnet.lemmatize(word, pos='v')]
    print (formatted_row.format(word, *lemmatized_words))

运行结果:
这里写图片描述

Stopwords停用词
在信息检索中,为节省存储空间和提高搜索效率,在自然语言数据(或文本)之前或之后会自动过滤某些字或词,这些字词即被称为“StopWords”。这类词基本上在任何场合任何时候都会有,因此不会影响数据的分析结果,反而对数据处理来说,是一种多余。因此,我们在进行分词和处理高频词汇的时候,一定要将其剔除。

全体stopwords列表 http://www.ranks.nl/stopwords

NLTK去除stopwords
首先要下载词库

>>> import nltk
>>> nltk.download('stopwords')

这里写图片描述

NLTK在自然语言处理中的应用

创建文本分类器

文本分类的目的是将文本文档分为不同的类,这是NLP中非常重要的手段。这里将使用一种技术,它基于一种叫作tf-idf的统计数据,它表示词频-逆文档频率。这个统计工具有助于理解一个单词在一组文档中对某一个文档的重要性。它可以作为特征向量来做文档分类。

tf-idf技术常用于信息检索领域,目的是了解文档中每个单词的重要性。如果想要识别在文档中多次出现的单词,同时像“is”和“be”这样的普通词汇并不能真正反映内容的本质,因此仅需要提供提取出具有实际意义的那些词。词频越大,则表示这个词越重要,同时,如果这个词经常出现,那么这个词频也会增加,这两个因素互相平衡。提取出每个句子的词频,然后将其转化为特征向量,用分类器来对这些句子进行分类。

详细步骤及代码(步骤在代码注释中)

from sklearn.datasets import fetch_20newsgroups

#选择一个类型列表,并用词典映射的方式定义
#这些类型是加载的新闻组数据集的一部分
category_map = {'misc.forsale': 'Sales', 'rec.motorcycles': 'Motorcycles', 
        'rec.sport.baseball': 'Baseball', 'sci.crypt': 'Cryptography', 
        'sci.space': 'Space'}
#基于刚刚定义的类型加载训练数据
training_data = fetch_20newsgroups(subset='train', 
        categories=category_map.keys(), shuffle=True, random_state=7)

#特征提取
from sklearn.feature_extraction.text import CountVectorizer

#用训练数据提取特征
vectorizer = CountVectorizer()
X_train_termcounts = vectorizer.fit_transform(training_data.data)
print("\nDimensions of training data:", X_train_termcounts.shape)

# 训练分类器
from sklearn.naive_bayes import MultinomialNB
from sklearn.feature_extraction.text import TfidfTransformer
#定义一些随机输入的句子
input_data = [
    "The curveballs of right handed pitchers tend to curve to the left", 
    "Caesar cipher is an ancient form of encryption",
    "This two-wheeler is really good on slippery roads"
]

# tf-idf 变换器
tfidf_transformer = TfidfTransformer()
X_train_tfidf = tfidf_transformer.fit_transform(X_train_termcounts)

# 多项式朴素贝叶斯分类器
classifier = MultinomialNB().fit(X_train_tfidf, training_data.target)
#用词频统计转换输入数据
X_input_termcounts = vectorizer.transform(input_data)
#用tf-idf变换器变换输入数据
X_input_tfidf = tfidf_transformer.transform(X_input_termcounts)

#预测输出类型
predicted_categories = classifier.predict(X_input_tfidf)

#打印输出
for sentence, category in zip(input_data, predicted_categories):
    print ('\nInput:', sentence, '\nPredicted category:', \
            category_map[training_data.target_names[category]])

运行结果:
这里写图片描述

识别性别

在NPL中,通过姓名识别性别是一个有趣的任务。这里用启发式方法,即姓名的最后几个字符可以界定性别特征。如名字以“la”结尾,那么可能是一个女性的名字,如“Angela”,“Layla”。如果以“im”结尾,可能是一个男性的名字,如“Tim”,“Jim”。

详细步骤及代码(步骤在 代码注释中)

import random
from nltk.corpus import names
from nltk import NaiveBayesClassifier
from nltk.classify import accuracy as nltk_accuracy

#定义一个用于提取输入单词的特征函数
#提取输入单词的特征
def gender_features(word, num_letters=2):
    return {'feature': word[-num_letters:].lower()}


#定义主函数,需要一些带标记的训练数据
if __name__=='__main__':
    #提取标记名称
    labeled_names = ([(name, 'male') for name in names.words('male.txt')] +
            [(name, 'female') for name in names.words('female.txt')])

    #设置随机生成数的种子值,并混合搅乱训练数据
    random.seed(7)
    random.shuffle(labeled_names)
    #定义一些输入的名字
    input_names = ['Leonardo', 'Amy', 'Sam']

#因为不知道需要多少个末尾字符,这里将这个参数设置为1~5。每次循环执行,都会截取相应大小的末尾字符个数
    #搜索参数空间
    for i in range(1, 5):
        print ('\nNumber of letters:', i)
        featuresets = [(gender_features(n, i), gender) for (n, gender) in labeled_names]
        #将数据分为训练数据集和测试数据集
        train_set, test_set = featuresets[500:], featuresets[:500]
        #用朴素贝叶斯分类器做分类
        classifier = NaiveBayesClassifier.train(train_set)
        #用参数空间的每一个值评分类器的效果
        # 打印分类器的准确性
        print ('Accuracy ==>', str(100 * nltk_accuracy(classifier, test_set)) + str('%'))

        # 为新输入预测输出结果
        for name in input_names:
            print (name, '==>', classifier.classify(gender_features(name, i)))

运行结果:
这里写图片描述

分析句子的情感

情感分析是NLP最受欢迎的应用之一。情感分析是指确定一段给定的文本是积极还是消极的过程。有一些场景中,我们还会将“中性“作为第三个选项。情感分析常用于发现人们对于一个特定主题的看法。情感分析用于分析很多场景中用户的情绪,如营销活动、社交媒体、电子商务客户等。

import nltk.classify.util
from nltk.classify import NaiveBayesClassifier
from nltk.corpus import movie_reviews

 #定义一个用于提取特征的函数
def extract_features(word_list):
    return dict([(word, True) for word in word_list])


 #我们需要训练数据,这里将用NLTK提供的电影评论数据
if __name__=='__main__':
    # 加载积极与消极评论 
    positive_fileids = movie_reviews.fileids('pos')
    negative_fileids = movie_reviews.fileids('neg')

    #将这些评论数据分成积极评论和消极评论 
    features_positive = [(extract_features(movie_reviews.words(fileids=[f])), 
            'Positive') for f in positive_fileids]
    features_negative = [(extract_features(movie_reviews.words(fileids=[f])), 
            'Negative') for f in negative_fileids]

    #分成训练数据集(80%)和测试数据集(20%)
    threshold_factor = 0.8
    threshold_positive = int(threshold_factor * len(features_positive))
    threshold_negative = int(threshold_factor * len(features_negative))
     #提取特征
    features_train = features_positive[:threshold_positive] + features_negative[:threshold_negative]
    features_test = features_positive[threshold_positive:] + features_negative[threshold_negative:]  
    print ("\nNumber of training datapoints:", len(features_train))
    print ("Number of test datapoints:", len(features_test))

    #训练朴素贝叶斯分类器
    classifier = NaiveBayesClassifier.train(features_train)
    print ("\nAccuracy of the classifier:", nltk.classify.util.accuracy(classifier, features_test))

    print ("\nTop 10 most informative words:")
    for item in classifier.most_informative_features()[:10]:
        print (item[0])

    # 输入一些简单的评论
    input_reviews = [
        "It is an amazing movie", 
        "This is a dull movie. I would never recommend it to anyone.",
        "The cinematography is pretty great in this movie", 
        "The direction was terrible and the story was all over the place" 
    ]
#运行分类器,获得预测结果
    print ("\nPredictions:")
    for review in input_reviews:
        print ("\nReview:", review)
        probdist = classifier.prob_classify(extract_features(review.split()))
        pred_sentiment = probdist.max()
        #打印输出
        print ("Predicted sentiment:", pred_sentiment) 
        print ("Probability:", round(probdist.prob(pred_sentiment), 2))

运行结果:
这里写图片描述

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

python机器学习——NLTK及分析文本数据(自然语言处理基础) 的相关文章

随机推荐

  • js删除对象中的某一个属性

    目标对象 let obj id 001 name 张三 age 18 方法一 将对象的属性值赋值为undefined 对象的属性不变 属性值发生了变化 改变了原对象 obj name undefined console log obj gt
  • 线索二叉树,画图教你秒懂线索二叉树(线索二叉树的建立和简单操作)逻辑代码分析

    数据结构专升本学习 线索二叉树 前言 前面我们学习树和二叉树的一些基本操作 今天我们学习一个新的知识 学习一下线索二叉树 线索二叉树是由二叉链存储结构变化而来的 我们先得有个二叉链树 再做处理 就是将原来的空域链改为莫种遍历次序下该结点的前
  • mysql5.7安装及配置超详细教程_MySQL5.7的安装与配置详细操作步骤

    一 MySQL的下载 二 解压安装包 将下载的ZIP压缩包解压到任意文件夹 此处为 C mysql5 7 三 修改配置文件 将解压文件夹目录下的my default ini 文件重命名为 my ini 用文本编辑器打开并清空其中内容 添加内
  • InetAddress的用法

    InetAddress的用法 下面这个程序利用InetAddress getByName 来得到你的和百度IP地址 马克 to win 马克 java社区 防盗版实名手机尾号 73203 例 2 1 1 import java net pu
  • 【工具】网站工具转换链接推荐

    1 Json 解析及格式化验证工具 Json 在线解析及格式化验证 JSON cn 2 Properties 和 Yaml 格式互转工具 在线 yaml 转 properties 在线 properties 转 yaml ToYaml co
  • uni-app实现广告滚动条

    参数说明 circular Boolean false 是否采用衔接滑动 即播放到末尾后重新回到开头 vertical Boolean false 滑动方向是否为纵向 previous margin String 0px 前边距 可用于露出
  • 网络的基本概念

    网络 网络是由若干节点和连接这些结点的链路组成 网络中的节点可以是计算机 交换机 路由器等设备 网络设备有 交换机 路由器 集线器 传输介质有 双绞线 同轴电缆 光纤 简单的网络示意图 互联网 把多个网络连接起来就构成了互联网 目前最大的互
  • 朴素贝叶斯分类

    先上问题吧 我们统计了14天的气象数据 指标包括outlook temperature humidity windy 并已知这些天气是否打球 play 如果给出新一天的气象指标数据 sunny cool high TRUE 判断一下会不会去
  • 解决 Fedora 下部分网页不能正常打开的问题(Linux 通用)

    使用命令 ifconfig 可以查看本地的网卡信息 ifconfig a 一般以wlp开头的为无线网卡 用 ifconfig XXXX 网卡名可以单独查看某一个网卡的信息 如下所示 wlp0s20f3 flags 4163
  • 异常的笔记

    异常 很重要 有利于我们平时处理问题 异常就是代表程序出现了问题 常见的异常比如说 数组越界 除法除0 异常的体系是什么 java lang Throwable Error Exception RuntimeException 其他异常 E
  • UE4 Niagara粒子系统基础笔记

    目录 Niagara基础概念 Niagara官方建议 Niagara堆栈面板 Niagara渲染模式 材质 Niagara和蓝图 Niagara常用模块 Niagara常用技巧 Niagara ModuleScript Niagara基础概
  • RTP和RTCP详解

    1 RTP和RTCP详解 文章目录 1 RTP和RTCP详解 1 1 概述 1 2 RTP协议详解 1 3 RTCP协议详解 1 1 概述 在流媒体相关的领域 我们进场会看到RTP RTCP 其用于流式传输的最常见的码流传输协议 位于传输层
  • Python单元测试:pytest

    pytest默认使用的是main system packages 如果需要在虚拟环境中运行 需要运行 python m pytest test py 如果需要打印中间结果 pytest test py s
  • 跨时钟域电路设计——多bit信号&FIFO

    多个bit信号的跨时钟域仅仅通过简单的同步器同步时不安全的 如下图 虽然信号都同步到目的时钟域 可完成的功能却与设计的初衷不相符 解决方案之一为对信号进行格雷码编码 但此方案只适用于连续变化的信号 另一种方案为增加新的控制信号en 确保传输
  • 机器学习和深度学习引用量最高的20篇论文(2014-2017)

    机器学习和深度学习的研究进展正深刻变革着人类的技术 本文列出了自 2014 年以来这两个领域发表的最重要 被引用次数最多 的 20 篇科学论文 以飨读者 机器学习 尤其是其子领域深度学习 在近些年来取得了许多惊人的进展 重要的研究论文可能带
  • 1200兆路由器网速_家庭网络配置问题案例:六类网线上网速度只有100兆

    有这样一个案例 家中布置了一根6类网线 8芯中间带个塑料十字的双绞线 网线约10米长 全部为埋地管道暗线 水晶头为568B线序 电脑插也为6类 西门子 568B线序接法 现在出现一个问题 就是网线一个连接移动光猫 为路由器模式 千兆口 然后
  • mac-右键-用VSCode打开

    1 点击访达 搜索自动操作 2 选择快速操作 3 执行shell脚本 替换代码如下 for f in do open a Visual Studio Code f done command s保存会出现一个弹框 保存为 用VSCode打开
  • IDEA2021.2创建java web项目(很详细,手把手创建)

    该文章适合人群 初学java web 不用maven或者gradle创建java web项目 忘记了怎么创建web项目 错误示范 上来直接创建java ee 项目 这样创建出来的项目有Maven或者Gradle包管理 正确演示 1 创建项目
  • “威胁”员工全来上班后,马斯克“尴尬”了:车没地停、工位不够坐、Wi-Fi 还太差

    点击蓝色 程序员黄小斜 关注我哟 加个 星标 每天和你一起多进步一点点 整理 郑丽媛 出品 程序人生 ID coder life 每一个特斯拉员工每周都要在办公室工作 40 个小时 如果你不来 那么我们就认为你辞职了 在马斯克 蛮横 地放出
  • python机器学习——NLTK及分析文本数据(自然语言处理基础)

    NLTK NLTK Natural Language Toolkit 自然语言处理工具包 在NLP 自然语言处理 领域中 最常使用的一个Python库 自带语料库 词性分类库 自带分类 分词功能 NLTK安装 安装 pip install