Python文本数据分析实战

1.文本预处理

文本预处理一般包括分词、词形归一化、删除停用词,具体流程如下:
在这里插入图片描述

1.1 分词

分词是指将由连续字符组成语句,按照一定的规则划分成一个个独立词语的过程。不同的语言具有不同的语法结构。

  • 英文:以空格为分隔符
  • 中文:没有形式上的分隔符

根据中文的结构特点,可以把分词算法分为以下三类:

  1. 基于规则的分词方法:按照一定的策略将待分析的中文句子与一个“充分大的”机器词典中词条进行匹配。
  2. 基于统计的分词方法:它的基本思路是常用的词语是比较稳定的组合。
  3. 基于理解的分词方法:它的基本思路是在分词的同时进行句法、语义分析,利用句法信息和语义信息来处理歧义现象。

1.1.1 英文分词

要使用 NLTK 对英文句子分词,则可以调用 word_tokenize() 函数基于空格或标点进行划分,并返回单词列表。

import nltk
import jieba
import nltk
nltk.download('punkt')

sentence = 'I like blue.'
# 将句子切分为单词
words = nltk.word_tokenize(sentence)
print(words)
# ['I', 'like', 'blue', '.']

1.1.2 中文分词

要使用 jieba 对中文句子分词,则可以通过 jieba.cut() 函数进行划分,该函数接收如下三个参数:

  • 需要分词的字符串。
  • cut_all 参数用来空值是否采用全模式。
  • HMM 参数用来空值是否使用 HMM 模型。

如果将 cut_all 参数设置为 True,则白哦是按照全模式进行分词,示例如下:

sentence = '数学与统计学院的数学专业研究生二年级学生在此学习。'
# 全模式划分中文句子
terms_list = jieba.cut(sentence,cut_all=True)
print('【全模式】:'+'/'.join(terms_list))
# 【全模式】:数学/与/统计/统计学/计学/学院/的/数学/专业/研究/研究生/二年/二年级/年级/学生/生在/此/学习/。

如果将 cut_all 参数设为 False,则表示的是按照精确模式进行分词,示例如下:

sentence = '数学与统计学院的数学专业研究生二年级学生在此学习。'
# 全模式划分中文句子
terms_list = jieba.cut(sentence,cut_all=False)
print('【精确模式】:'+'/'.join(terms_list))
#【精确模式】:数学/与/统计/学院/的/数学/专业/研究生/二年级/学生/在/此/学习/。

1.2 词性标注

1.2.1 词性标注

词性是对词语分类的一种方式。

  • 英文词汇: 名词、形容词、动词、代词、数词、副词、介词、连词、冠词和感叹词。
  • **中文词汇:**名词、动词、形容词、数词、量词、代词、介词、副词、连词、感叹词、助词和拟声词。

1.2.2 词性标注

词性标注,又称词类标注,是指为分词结果中的每个词标注一个正确的词性。
在这里插入图片描述
NLTK库中使用不同的约定来标记单词,下面通过一张表来列举通用的词性标注集。
在这里插入图片描述
通用的词性标注集续表
在这里插入图片描述
如果希望给单词标注词性,则需要先确保已经下载了 averaged_perceptron_tagger 模块,然后再调用 pos_tag() 函数及逆行标注。

 nltk.download('averaged_perceptron_tagger')
nltk.pos_tag(words)
# [('I', 'PRP'), ('like', 'VBP'), ('blue', 'JJ'), ('.', '.')]

1.3 词形归一化

在英文中,一个单词常常是另一个单词的变种。
在这里插入图片描述
一般在信息检索和文本挖掘时,需要对一个词的不同形态进行规范化,以提高文本处理的效率。

词形规范化过程主要包括两种:词干提取和词形还原。
在这里插入图片描述
词干提取和词形还原的示例如下:

watching ==> watch
watched ==> watch

better ==> good
went ==> go
目前最受欢迎的就是波特词干提取器,它是基于波特词干算法来提取词干的,这些算法都集中在 PorterStemmer 类中。

from nltk.stem.porter import PorterStemmer
porter_stem = PorterStemmer()
porter_stem.stem('watched')
#'watch'

还可以使用兰卡斯特词干提取器,它是基于兰卡斯特词干算法来提取词干的,这些算法都集中在 LancasterStemmer 类中。

from nltk.stem.lancaster import LancasterStemmer 
lancaster_stem = LancasterStemmer()
# 按照兰卡斯特算法提取词干
lancaster_stem.stem('jumped')
# 'jump'

还有一些其它的词干器,比如 SnowballStemmer,它除了支持英文意外,还支持其它13种不同的语言。

from nltk.stem import SnowballStemmer
snowball_stem = SnowballStemmer('english')
snowball_stem.stem('listened')
#'listen'

NLTK库中提供了一个强大的还原模块,它使用 WordNetLemmatizer 类来获得根词,使用前需要确保已经下载了 wordnet 预料库。

  • 词形还原是去除词缀以获得单词的基本形式。
  • 整个基本形式称为根刺,而不是词干。根词始终存在于字典中,词干不一定是标准的单词,它可能不存在于词典中。

WordNetLemmatizer 类里面提供了一个 lemmatize() 方法,用于获得单词的基本形式。

  • lemmatize() 方法会比对 wordnet 语料库,并采用递归技术删除词缀,直至在词汇网络中找到匹配项,最终返回输入词的基本形式。
  • 如果没有找到匹配项,则直接返回输入词,不做任何变化。

下面是一个基于WordNetLemmatizer 的词形还原示例。

# Lemmatization
nltk.download('omw-1.4')
from nltk.stem import WordNetLemmatizer
wordnet_lem = WordNetLemmatizer()
print(wordnet_lem.lemmatize('books'))  # As a noun
print(wordnet_lem.lemmatize('went', pos='v'))  # As a verb
#book
#go

1.4 删除停用词

停用词是指在信息检索中,为节省存储空间和提高效率,在处理自然语言文本之前或之后会自动过滤掉某些没有具体意义的字或词。

比如:英文单词 “I”、“the” 或中文中的 “啊”等。

如果直接用包含大量停用词的文本作为分析对象,则可能会导致分析结果存在较大偏差,通常在处理过程中会将它们从文本中删除。
在这里插入图片描述
停用词都是人工输入、非自动化生成的,生成后的停用词会形成一个停用词表,但是并没有一个明确的停用词表能够适用于所有的工具。

  • 对于中文的停用词,可以参考中文停用词库、哈工大停用词表、百度停用词列表。
  • 对于其它语言来说,可以参照
    https://www.ranks.nl/stopwords进行了解。

NLTK库里面有一个标准的停用词列表,在使用之前要确保已经下载了 stopwords 语料库,并且用 import 语句导入stopwords 模块。

nltk.download('stopwords')
from nltk.corpus import stopwords
text = 'I am a beautiful girl and I study everyday.'
words = nltk.word_tokenize(text)
stop_words = stopwords.words('english')

remain_list = []
for word in words:
    if word not in stop_words:
        remain_list.append(word)
print(remain_list)
print(words)
#['I', 'beautiful', 'girl', 'I', 'study', 'everyday', '.']
#['I', 'am', 'a', 'beautiful', 'girl', 'and', 'I', 'study', 'everyday', '.'] 

2.文本情感分析

文本情感分析,又称为倾向性分析和意见挖掘,是指对带有情感色彩的主观性文本进行分析、处理、归纳和推理的过程。
在这里插入图片描述
情感分析还可以细分为情感极性(倾向)分析、情感程度分析及主客观分析等。

其中,情感极性分析的目的在于,对文本进行褒义、贬义、中性的判断,比如对于“喜爱”和“厌恶” 这两个词,就属于不同的情感倾向。

目前,常见的情感极性分析方法主要分为两种:基于情感词典和基于机器学习。

2.1 情感词典情感分析

在这里插入图片描述
最简单的情感极性分析的方式就是情感词典,其实现的大致思路如下:
在这里插入图片描述

例如,有这么一句商品评价:
在这里插入图片描述

在这里插入图片描述

🔺使用情感词典的方式虽然简单粗暴,非常实用,不过遇到一些新词或者特殊词,就无法识别出来,扩展性非常不好。

2.2 机器学习情感分析

还可以基于机器学习模型进行情感极性分析,其中,朴素贝叶斯是经典的机器学习算法之一,也是维数不多的基于概率伦的分类算法。

  • 朴素贝叶斯的思想基础是:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。

nltk.clasify 模块中的 NaiveBayesClassifier 实现了朴素贝叶斯的分类算法,该类中有一个类方法 train(),主要用于根据训练集来训练模型。

# 准备用于训练的文本
text_one = "This is a wonderful book."
text_two = "I like reading this book very much."
text_three = "This book reads well."
text_four = "This book is not good."
text_five = "This is a very bad book."

from nltk.classify import NaiveBayesClassifier

def pret_text(text):
    # 文本预处理:分词,词形归一化,删除停用词
    words = nltk.word_tokenize(text)
    wordnet = WordNetLemmatizer()
    words = [wordnet.lemmatize(word.lower()) for word in words]  # Added lowercasing
    # 删除停用词的操作,注意修正了条件表达式
    remain_list = [word for word in words if word not in stopwords.words("english")]
    print(remain_list)
    # 遍历词 得到的词是否在文本中,修正了返回值为字典的格式
    return {word: True for word in remain_list}

print(pret_text(text_one))

输出
[‘wonderful’, ‘book’, ‘.’]
{‘wonderful’: True, ‘book’: True, ‘.’: True}

# 构建训练文本
train_data = [[pret_text(text_one),1], [pret_text(text_two),1], [pret_text(text_three),1], [pret_text(text_four),-1],[pret_text(text_five),-1]]
print(train_data)

输出
[‘wonderful’, ‘book’, ‘.’]
[‘like’, ‘reading’, ‘book’, ‘much’, ‘.’]
[‘book’, ‘read’, ‘well’, ‘.’]
[‘book’, ‘good’, ‘.’]
[‘bad’, ‘book’, ‘.’]
[[{‘wonderful’: True, ‘book’: True, ‘.’: True}, 1], [{‘like’: True, ‘reading’: True, ‘book’: True, ‘much’: True, ‘.’: True}, 1], [{‘book’: True, ‘read’: True, ‘well’: True, ‘.’: True}, 1], [{‘book’: True, ‘good’: True, ‘.’: True}, -1], [{‘bad’: True, ‘book’: True, ‘.’: True}, -1]]

# 训练得到模型
model = NaiveBayesClassifier.train(train_data)
#模型的测试
test_text1 = "I like this movie very much."
model.classify(pret_text(test_text1))

输出
[‘like’, ‘movie’, ‘much’, ‘.’]
1
返回结果是正向的。

3.文本相似度

在这里插入图片描述

from nltk import FreqDist

text1 = "John likes to watch movies."
text2 = "John also likes to watch football games."
all_text = text1 + ' ' + text2

#分词
words = nltk.word_tokenize(all_text)
#创建FreqDist对象,记录每个词出现的频率
freq_dist = FreqDist(words)
freq_dist

输出
FreqDist({‘John’: 2, ‘likes’: 2, ‘to’: 2, ‘watch’: 2, ‘.’: 2, ‘movies’: 1, ‘also’: 1, ‘football’: 1, ‘games’: 1})

#John的词频数
freq_dist['John']

输出:2

#取出5个常用的单词
most_common_words = freq_dist.most_common(5)
most_common_words

输出
[(‘John’, 2), (‘likes’, 2), (‘to’, 2), (‘watch’, 2), (‘.’, 2)]

#找出单词所处的位置
def find_position(common_words):
    '''
    查找常用单词的位置
    '''
    result = {}
    pos = 0
    for word in common_words:
        result[word[0]] = pos
        pos +=1
    return result

result 是一个空字典,用于存储单词及其对应的位置。

pos 是一个位置指示器,初始化为 0,用于标记每个单词在列表中的索引。

遍历common_words列表:对于列表中的每一个元素(这里假设每个元素是一个元组,其中单词是元组的第一个元素),执行以下操作:

  • 将元组中的第一个元素(word[0])作为键,当前的pos值作为值,存入result字典中。这样就可以记录下每个单词在输入列表中的位置。
  • 将pos加一,以便为下一个单词记录正确的位置。 返回结果:函数返回填充好的result字典。
#调用方法,记录常用单词对应的位置
pos_dict = find_position(most_common_words)
print(pos_dict)

输出
{‘John’: 0, ‘likes’: 1, ‘to’: 2, ‘watch’: 3, ‘.’: 4}

def text_to_vector(words):
    '''
    将文本转换为词频向量
    '''
    freq_vec = [0]*5 # [0, 0, 0, 0, 0]
    #在常用的单词列表上计算词频
    for word in words:
        if word in list (pos_dict.keys()):
            freq_vec[pos_dict[word]] +=1
    return freq_vec

#获取text1的词频向量
vec1 = text_to_vector(nltk.word_tokenize(text1))
vec1

输出
[1, 1, 1, 1, 1]

vec2 = text_to_vector(nltk.word_tokenize(text2))
vec2

输出
[1, 1, 1, 1, 1]

# 计算文本相似度
from nltk.cluster.util import cosine_distance

cosine_distance(vec1,vec2)

输出
2.220446049250313e-16

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值