NLP知识整理(上)

by 翰林

数据预处理

数据清洗

  • 在拿到文本后需要使用re工具库来利用正则表达式对文本进行一些数据预处理和数据清洗的操作,目的是去除脏数据,保证数据的规范性和一致性,便于后期处理。
  • 常见的操作有:
    ①统一计量单位,如将mg,g,kg,‘克’,‘千克’统一为kg,使不同单位之间的数字可以相互比较和计算。
    ②缩略词替换,如将’can’t’转换成’can not’。
    ③标点处理,去除掉’,/./。/!/…'等文本中的标点符号。
    ④去除空格,有时文本中会穿插一些空格,需要剔除。
    ⑤词归一化,针对英文文本,需要将不同时态的变种词进行统一,如playing => play
    ⑥去除HTML标签

分词

  • 分词就是对连续完整的语料文本进行词粒度或者字粒度的切分,如将 [‘我爱自然语言处理’] 转换为 [ ‘我’,‘爱’,‘自然’,‘语言’,‘处理’ ] 。其中中文分词与英文分词略有不同,原因在于英文句子中单词之间是有空格的,而中文没有,因此在中文分词要比英文分词更麻烦一些。

  • 常见的英文分词工具有NLTK,常见的中文分词工具有jieba,SnowNLP, nlpir。

  • 分词有几种以下几种不同的模式:
    ①精确模式 ( 我/ 来到/ 北京/ 清华大学)
    ②搜索模式 (我/ 来到/ 北京/ 清华/ 清华大学/ 华大/ 大学)
    ③新词识别模式 (他/来到/了/网易/杭研/大厦)“杭研”并没有在词典中,但是也被Viterbi算法识别出来了

  • 对于一些语料库中没有的新词或者特殊词,可以构建一个自定义词表,添加到jieba中

去停用词

  • 去停用词是在分词操作后去除一些提供信息量较小同时出现频率又比较高的词汇(如:啊/哎/额/了/吗/也/的…)。
  • 具体操作方式为提供一个stop words list

特征抽取

CountVectorizer 词袋模型

  • 为了将文本型词汇表示为计算机可以理解的数字符号,我们需要进行一些特征抽取工作,其中最为简单的是词袋模型,使用的工具是CountVectorizer。首先为模型提供语料料库进行训练(fit),CountVectorizer会将出现的每一个词建立dictionary, 其中key是该单词,value是该单词在接下来向量化表示中所处的位置的index。然后我们为训练好的词袋模型提供新的文本数据,词袋模型就根据该词对应的value/index和该词出现的频次可以对文本进行向量化表示。
  • 如我们训练好了一个dictionary{‘john’: 4, ‘likes’: 5, ‘ice’: 3, ‘cream’: 1, ‘hates’: 2, ‘chocolate’: 0}
    提供文本’John likes ice cream John
    则将其转化为[0 1 0 1 2 1],注意因为John在文本中出现两次,所以index为4的位置的值为2。
  • 词袋模型值得注意的点有三个:
    ①词袋模型严格意义上说并不是一种’模型’,更像是类似OneHotEncoder一样的转换工具,并不产出预测结果,只是对文本进行向量化表示。
    ②词袋模型中出现的值并不是只产生0/1,而是该词在该条文本中出现的频次(注意是该条而不是所有)。
    ③词袋模型在生成字典时,并没有逻辑上的顺序,但是在生成字典后,每个index就固定下来,只表示一个特定的词。

N-Gram

  • 由于词袋模型在生成字典时是无序的,因此’我爱你’和’你爱我’在词袋模型进行向量化表示后的结果是一样的,都是我、爱、你三个字对应位置的value置1,其他位置置0。为了避免这种不同语义的文本产生相同向量表示的情况发生,引入N-Gram将语序也作为一个因素考虑进特征表示的过程中。
  • 以2-Gram为例,对’我爱你’的特征抽取对应词为[我,爱,你,我爱,爱你],而’你爱我’的特征抽取对应词为[你,爱,我,你爱,爱我],这样就不会将两个文本混淆了。

TF-IDF

  • TF-IDF分为TF(词频)和IDF(逆文档频率)两个部分,
  • TF词频统计的意义在于,在一篇文本中出现频次越高的单词越能表征这篇文本的特点。
    如:我爱中文自然语言处理,因为自然语言处理很有趣。'自然语言处理’出现频次较多的自然语言处理一定程度上更能代表该文本的含义。
  • IDF逆文档频率的意义在于,在其他文本中出现频率很低但在该文本中出现的词,IDF认为该词比较能表征这篇文章的特点。
    如: 我爱中文自然语言处理,其中我、爱、自然语言处理都只出现了一次,但自然语言处理相对于中文、我、爱更属于稀有词,因此这篇文本的内容更可能是关于自然语言处理的而不是关于中文的。
  • CountVectorizer是将文本表示为[0,1,0,2,0]这样形式,每个值是离散的,代表的是该词出现的词频。
  • TfidfVectorizer是将文本表示为[0.213,1.982,3.456,4.768,9.231]这样的形式,每个值是连续的,代表的是该词计算出的权重。值越高,代表该词在该文本中越重要
  • CountVectorizer和TfidfVectorizer为了节省存储资源,将向量存储成了特殊的形式,取出需要使用.toarray()操作,但要注意内存容量。
  • CountVectorizer和TfidfVectorizer本质上都是稀疏的存储形式,因为语料库训练出来的每一个词都在该向量中占有一个位置,实际使用过程中,该向量会非常稀疏(有很多位置是0)。

TextRank

  • 常见的针对关键词抽取的方式有两种,一种是基于上文的TF-IDF给出权重最高的n个词作为该文本的关键词,另外一种就是基于TextRank的方式。
  • TextRank和搜索引擎中使用的PageRank很像,区别在于PageRank是通过网页和网页之间链接的指向来构建图,而TextRank是通过构建N-Gram滑窗,通过词与词之间的共现关系来构建图,再通过指向分配权重,选取权重最大的n个词作为文本的关键词。

Tokenizer

  • 不论是CountVectorizer还是TfidfVectorizer,产出的都是稀疏矩阵,对于计算和存储都带来了很多的不便。若想用稠密向量来表示文本则可以使用Tokenizer。
  • Tokenizer直接使用对应的索引做为值来表示。如’I love you’如果使用CountVectorizer表示可能是[0,1,0,0,0,1,0,1],而使用Tokenizer则表示为[1,5,7],其中1,5,7分别为I、love、you三个词在字典中对应的索引。
  • 但Tokenizer依然不能很好的解决一些问题:
    ① Tokenizer表征后的向量维度和原文本词汇数是相同的,但不同文本的词汇数又是不同的,这会导致产出的特征维度不一致。解决的方法是使用pad_sequence()来填充0补齐向量
    ② Tokenizer表征后的向量依然不能很好的捕捉词与词之间的相关性,如男人/女人两个词的相关性和皇帝/女王两个词应该类似,为了解决这个问题我们可以使用下文提到的词嵌入。

Word Embedding 词嵌入

  • Word Embedding通过神经网络训练出稠密向量来表示文本,能够很好的捕捉词与词之间的相关性。
    可采用的方式有:
    ①Word2vec的特点是层次化softmax(构建哈夫曼树将搜索时间指数级别下降)和负例采样(对词频加权的欠采样操作),大幅缩短了训练时间。
    ②Glove
    ③使用Gensim自定义训练。
  • Word2vec是最为常见的一种词嵌入模型,具体分为CBOW和Skip-Gram两种方式,前者用周围的词来预测中心词,后者用中心词来预测周围词,这样就将没有标签的文本数据转化成为了有标签的监督学习模式,具体操作方式为:
    ①下载并读取预训练好的Word2vec模型
    ②构建神经网络嵌入层,其中需要指定input_dim(词典长度),output_dim(设定的词向量表示维度),input_length(输入数据长度)
    ③通过weight=word2vec_matrix将预训练好的word2vec对嵌入层参数进行填充(预训练的向量维度可能与我们设定的目标维度不一致,需要做填充或者截断)
    ④将参数trainable设为True,训练模型,得到微调后的参数矩阵。

猜你喜欢

转载自blog.csdn.net/qq_26413541/article/details/85997991