百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 编程字典 > 正文

NLP自然语言处理入门-- 文本预处理Pre-processing

toyiye 2024-06-21 12:15 9 浏览 0 评论

引言

自然语言处理NLP(nature language processing),顾名思义,就是使用计算机对语言文字进行处理的相关技术以及应用。在对文本做数据分析时,我们一大半的时间都会花在文本预处理上,而中文和英文的预处理流程稍有不同,本文就对中、英文文本挖掘的常用的NLP的文本预处技术做一个总结。

文章内容主要按下图流程讲解:

图片来自贪心科技

1.中英文文本预处理的特点

中英文的文本预处理大体流程如上图,但是还是有部分区别。首先,中文文本是没有像英文的单词空格那样隔开的,因此不能直接像英文一样可以直接用最简单的空格和标点符号完成分词。所以一般我们需要用分词算法来完成分词,具体操作后面会讲到。

当然,英文文本的预处理也有自己特殊的地方——拼写问题,很多时候,对英文预处理要包括拼写检查,比如“Helo World”这样的错误,我们不能在分析的时候再去纠错。还有就是词干提取(stemming)和词形还原(lemmatization),主要是因为英文中一个词会会不同的形式,这个步骤有点像孙悟空的火眼金睛,直接得到单词的原始形态。比如,"faster"、"fastest", 都变为"fast";“leafs”、“leaves”,都变为"leaf"。

2. 收集数据

文本数据的获取一般有两个方法:

  • 别人已经做好的数据集,或则第三方语料库,比如wiki。这样可以省去很多麻烦。自己从网上爬取数据。但很多情况所研究的是面向某种特定的领域,这些开放语料库经常无法满足我们的需求。我们就需要用爬虫去爬取想要的信息了。可以使用如beautifulsoup、scrapy等框架编写出自己需要的爬虫。

3.文本预处理

3.1 去除数据中的非文本部分

由于爬下来的内容中有很多html的一些标签,需要去掉。还有少量的非文本内容的可以直接用Python 的正则表达式(re)删除, 另外还有一些特殊的非英文字符和标点符号,也可以用Python的正则表达式(re)删除。

import re
# 过滤不了\\ \ 中文()还有————
r1 = u'[a-zA-Z0-9’!"#$%&\'()*+,-./:;<=>?@,。?★、…【】《》?“”‘’![\\]^_`{|}~]+'#用户也可以在此进行自定义过滤字符 
# 者中规则也过滤不完全
r2 = "[\s+\.\!\/_,$%^*(+\"\']+|[+——!,。?、~@#¥%……&*()]+"
# \\\可以过滤掉反向单杠和双杠,/可以过滤掉正向单杠和双杠,第一个中括号里放的是英文符号,第二个中括号里放的是中文符号,第二个中括号前不能少|,否则过滤不完全
r3 = "[.!//_,amp;%^*()<>+\"'?@#-|:~{}]+|[——!\\\\,。=?、:“”‘’《》【】¥……()]+" 
# 去掉括号和括号内的所有内容
r4 = "\\【.*?】+|\\《.*?》+|\\#.*?#+|[.!/_,amp;%^*()<>+""'?@|:~{}#]+|[——!\\\,。=?、:“”‘’¥……()《》【】]"
sentence = "hello! wo?rd!."
cleanr = re.compile('<.*?>')
sentence = re.sub(cleanr, ' ', sentence) #去除html标签
sentence = re.sub(r4,'',sentence)
print(sentence)

3.2 分词

  • 由于英文单词间由空格分隔,所以分词分简单,只需要调用split()函数即可。对于中文来说常用的中文分词软件有很多,例如,结巴分词。安装也很简单,比如基于Python的,用"pip install jieba"就可以完成。
import jieba
sentence = "我们学习人工智能"
sentence_seg = jieba.cut(sentence)
result = ' '.join(sentence_seg)
print(result)

3.3 去掉停用词

停用词就是句子没什么必要的单词,去掉他们以后对理解整个句子的语义没有影响。文本中,会存在大量的虚词、代词或者没有特定含义的动词、名词,这些词语对文本分析起不到任何的帮助,我们往往希望能去掉这些“停用词”。

  • 在英文中,例如,"a","the",“to",“their”等冠词,借此,代词..... 我们可以直接用nltk中提供的英文停用词表。首先,"pip install nltk"安装nltk。当你完成这一步时,其实是还不够的。因为NLTK是由许多许多的包来构成的,此时运行Python,并输入下面的指令。
import nltk
from nltk.tokenize import word_tokenize
nltk.download()

然后,Python Launcher会弹出下面这个界面,你可以选择安装所有的Packages,以免去日后一而再、再而三的进行安装,也为你的后续开发提供一个稳定的环境。

我们可以运行下面的代码,看看英文的停用词库。

from nltk.corpus import stopwords 
stop = set(stopwords.words('english')) 
print(stop)

去除停用词

sentence = "this is a apple"
filter_sentence= [w for w in sentence.split(' ') if w not in stopwords.words('english')]
print(filter_sentence)

对于中文停用词,由于nlkt不支持中文,所以需要自己构造中文停用词。常用的中文停用词表是1208个,下载地址在这 。有了中文停用词表,去除停用词的代码和英文类似,这里就不赘述了。

3.4 英文单词--stemming和lemmatization

词干提取(stemming)和词型还原(lemmatization)是英文文本预处理的特色。两者其实有共同点,即都是要找到词的原始形式。只不过词干提取(stemming)会更加激进一点,它在寻找词干的时候可以会得到不是词的词干。比如"leaves"的词干可能得到的是"leav", 并不是一个词。而词形还原则保守一些,它一般只对能够还原成一个正确的词的词进行处理。nltk中提供了很多方法,wordnet的方式比较好用,不会把单词过分精简。

from nltk.stem import SnowballStemmer
stemmer = SnowballStemmer("english") # 选择语言
stemmer.stem("leaves") # 词干化单词
from nltk.stem import WordNetLemmatizer 
wnl = WordNetLemmatizer() 
print(wnl.lemmatize('leaves')) 

3.5 英文单词--转换为小写

英文单词有大小写之分,Python和python是同一个单词,所以转换为小写可以减少单词数量。

word = "Python"
word = word.lower() #转换成lower_case
print(word)

3.6 特征处理

数据处理到这里,基本上是干净的文本了,现在可以调用sklearn来对我们的文本特征进行处理了。常用的方法如下:

  • Bag of Words词袋模型BowTf-idfN-gram语言模型BigramTrigramWord2vec分布式模型Word2vec

接下来我将结合代码简单讲解一下Tf-idf,Bigram,word2vec的用法。语言模型这一块内容,可以在之后的文章深入了解。

Tf-idf(Term Frequency-Inverse Document Frequency)

该模型基于词频,将文本转换成向量,而不考虑词序。假设现在有N篇文档,在其中一篇文档D中,词汇x的TF、IDF、TF-IDF定义如下:

1.Term Frequency(TF(x)):指词x在当前文本D中的词频

2.Inverse Document Frequency(IDF): N代表语料库中文本的总数,而N(x)代表语料库中包含词x的文本总数,平滑后的IDF如下:

3.TF-IDF :

使用sklearn库里的TfidfVectorizer类可以帮助我们完成向量化,TF-IDF和标准化三步。

from sklearn.feature_extraction.text import TfidfVectorizer
corpus = ["This is sample document.", "another random document.", "third sample document text"]
vector = TfidfVectorizer()
tf_data = vector.fit_transform(corpus)
print(tf_data) #(句子下标, 单词特征下标) 权重
print(vector.vocabulary_) #单词特征
df1 = pd.DataFrame(tf_data.toarray(), columns=vector.get_feature_names()) # to DataFrame
df1

N-gram语言模型

词袋模型不考虑每个单词的顺序。有时候把一句话顺序捣乱,我们可能就看不懂这句话在说什么了,例如:

我玩电脑 = 电脑玩我 ?

N-gram模型是一种语言模型(Language Model),语言模型是一个基于概率的判别模型,它的输入是一句话(单词的顺序序列),输出是这句话的概率,即这些单词的联合概率(joint probability)。N-gram本身也指一个由N个单词组成的集合,各单词具有先后顺序,且不要求单词之间互不相同。常用的有 Bi-gram (N=2N=2) 和 Tri-gram (N=3N=3),一般已经够用了。例如,"I love deep learning",可以分解的 Bi-gram 和 Tri-gram :

Bi-gram : {I, love}, {love, deep}, {love, deep}, {deep, learning}

Tri-gram : {I, love, deep}, {love, deep, learning}

sklearn库中的CountVectorizer 有一个参数ngram_range,如果赋值为(2,2)则为Bigram,当然使用语言模型会大大增加我们字典的大小。

ram_range=(1,1) 表示 unigram, ngram_range=(2,2) 表示 bigram, ngram_range=(3,3) 表示 thirgram
from sklearn.feature_extraction.text import CountVectorizer
import pandas as pd
import jieba
data = ["为了祖国,为了胜利,向我开炮!向我开炮!",
 "记者:你怎么会说出那番话",
 "我只是觉得,对准我自己打"]
data = [" ".join(jieba.lcut(e)) for e in data] # 分词,并用" "连接
vector = CountVectorizer(min_df=1, ngram_range=(2,2)) # bigram
X = vector.fit_transform(data) # 将分词好的文本转换为矩阵
print(vector.vocabulary_ ) # 得到特征
print(X) #(句子下标, 单词特征下标) 频数
df1 = pd.DataFrame(X.toarray(), columns=vector.get_feature_names()) # to DataFrame
df1.head()

Word2vec词向量

Word2Vec使用一系列的文档的词语去训练模型,把文章的词映射到一个固定长度的连续向量

。一般维数较小,通常为100 ~ 500。意义相近的词之间的向量距离较小。它以稠密的向量形式表示单词。有两种模式:

CBOW(Continuous Bag-Of-Words):利用词的上下文预测当前的词。

Skip-Gram:利用当前的词来预测上下文。

因为word2vector模型的得到的是词向量,如何表示句子呢?最简单的方法就是,将每个句子中的词向量相加取平均值,即每个句子的平均词向量来表示句子的向量。

from gensim.models import Word2Vec 
import numpy as np
data = ["I love deep learning","I love studying","I want to travel"]
#词频少于min_count次数的单词会被丢弃掉
#size指特征向量的维度为50
#workers参数控制训练的并行数
train_w2v = Word2Vec(data,min_count=5,size=50, workers=4)
for row in data: #计算平均词向量,表示句子向量
 vec = np.zeros(50)
 count = 0
 for word in row:
 try:
 vec += train_w2v[word]
 count += 1
 except:
 pass
 avg_data.append(vec/count) 
print(avg_data[1])

4. 建立分析模型

有了每段文本的特征向量后,我们就可以利用这些数据建立分类模型,或者聚类模型了,或者进行相似度的分析。

5.总结

3.6小节中的特征提取一块,为了demo演示的方便,没有和前面的分词,清洗,标准化结合在一起。如果是从分词步骤开始做的文本预处理,需要注意:在特征提取时,要将每个句子的单词以空格连接起来。

相关推荐

为何越来越多的编程语言使用JSON(为什么编程)

JSON是JavascriptObjectNotation的缩写,意思是Javascript对象表示法,是一种易于人类阅读和对编程友好的文本数据传递方法,是JavaScript语言规范定义的一个子...

何时在数据库中使用 JSON(数据库用json格式存储)

在本文中,您将了解何时应考虑将JSON数据类型添加到表中以及何时应避免使用它们。每天?分享?最新?软件?开发?,Devops,敏捷?,测试?以及?项目?管理?最新?,最热门?的?文章?,每天?花?...

MySQL 从零开始:05 数据类型(mysql数据类型有哪些,并举例)

前面的讲解中已经接触到了表的创建,表的创建是对字段的声明,比如:上述语句声明了字段的名称、类型、所占空间、默认值和是否可以为空等信息。其中的int、varchar、char和decimal都...

JSON对象花样进阶(json格式对象)

一、引言在现代Web开发中,JSON(JavaScriptObjectNotation)已经成为数据交换的标准格式。无论是从前端向后端发送数据,还是从后端接收数据,JSON都是不可或缺的一部分。...

深入理解 JSON 和 Form-data(json和formdata提交区别)

在讨论现代网络开发与API设计的语境下,理解客户端和服务器间如何有效且可靠地交换数据变得尤为关键。这里,特别值得关注的是两种主流数据格式:...

JSON 语法(json 语法 priority)

JSON语法是JavaScript语法的子集。JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔花括号保存对象方括号保存数组JS...

JSON语法详解(json的语法规则)

JSON语法规则JSON语法是JavaScript对象表示法语法的子集。数据在名称/值对中数据由逗号分隔大括号保存对象中括号保存数组注意:json的key是字符串,且必须是双引号,不能是单引号...

MySQL JSON数据类型操作(mysql的json)

概述mysql自5.7.8版本开始,就支持了json结构的数据存储和查询,这表明了mysql也在不断的学习和增加nosql数据库的有点。但mysql毕竟是关系型数据库,在处理json这种非结构化的数据...

JSON的数据模式(json数据格式示例)

像XML模式一样,JSON数据格式也有Schema,这是一个基于JSON格式的规范。JSON模式也以JSON格式编写。它用于验证JSON数据。JSON模式示例以下代码显示了基本的JSON模式。{"...

前端学习——JSON格式详解(后端json格式)

JSON(JavaScriptObjectNotation)是一种轻量级的数据交换格式。易于人阅读和编写。同时也易于机器解析和生成。它基于JavaScriptProgrammingLa...

什么是 JSON:详解 JSON 及其优势(什么叫json)

现在程序员还有谁不知道JSON吗?无论对于前端还是后端,JSON都是一种常见的数据格式。那么JSON到底是什么呢?JSON的定义...

PostgreSQL JSON 类型:处理结构化数据

PostgreSQL提供JSON类型,以存储结构化数据。JSON是一种开放的数据格式,可用于存储各种类型的值。什么是JSON类型?JSON类型表示JSON(JavaScriptO...

JavaScript:JSON、三种包装类(javascript 包)

JOSN:我们希望可以将一个对象在不同的语言中进行传递,以达到通信的目的,最佳方式就是将一个对象转换为字符串的形式JSON(JavaScriptObjectNotation)-JS的对象表示法...

Python数据分析 只要1分钟 教你玩转JSON 全程干货

Json简介:Json,全名JavaScriptObjectNotation,JSON(JavaScriptObjectNotation(记号、标记))是一种轻量级的数据交换格式。它基于J...

比较一下JSON与XML两种数据格式?(json和xml哪个好)

JSON(JavaScriptObjectNotation)和XML(eXtensibleMarkupLanguage)是在日常开发中比较常用的两种数据格式,它们主要的作用就是用来进行数据的传...

取消回复欢迎 发表评论:

请填写验证码