文本处理


在现有数据中,文本是最非结构化的形式,里面有各种各样的噪声;如果没有预处理,文本数据都不能分析。清理和标准化文本的整个过程叫做文本预处理(text

preprocessing)其作用是使文本数据没有噪声并且可以分析。

具体包含以下三个内容:去噪声;词汇归一化;目标标准化

去噪声


噪声是指和需要的输出没有关系的文本。例如:语言的停用词(is,am, the, of等),URLs, 链接,社交媒体实体,标点符合和行业特定词。这一步主要是移除文本中的噪声因

子。

noise_list=['is','a','this','...']
def _remove_noise(input_text):
    words = input_text.split()
    noise_free_words=[word for word in words if word not in noise_list]
    noise_free_text = " ".join(noise_free_words)
    return noise_free_text

_remove_noise("this is a sample text")
>>> "sample text"


归一化

文本噪声的另一种类型是关于单个单词所表现的多个表示。

例如:“play”,“player”,“played",“plays” 和 ”playing"是“play"的多种表示形式。虽然他们的含义不一样,但是上下文中是相似的。这一步就是要把这些各种形式的单词归一化。

归一化是具有文本特征工程的关键步骤,因为它将高纬特征(N个不同特征)转化成低维空间(1特征)。

最常用的归一化方法是:

1、词干(Steamming):词干是消除后缀的一个基本的基于规则的过程,比如 “ing”, “ly”, “es”等。

2、词元化(Lemmatization): 词元化是一个有组织性的,逐步地获得词根的过程,他利用词汇(单词的词典重要性)和词法分析(词法结构和词法关系)。

from nltk.stem.wordnet import WordNetLemmatizer
lem = WordNetLemmatizer()
  
from nltk.stem.porter import PorterStemmer
stem = PorterStemmer()

word = "multiplying"
lem.lemmatize(word, 'v')
>>> "multiply"

stem.stem(word)
>>>"multipli"


标准化

文本数据通常包含不存在于任何标准词汇词典中的词或者短语。这些片段不被搜索引擎和模型所识别。

lookup_dict = {'rt':'Retweet','dm':'direct message','awsm':'awesome','luv':'love','...'}

def _look_words(input_text):
    words = input_text.split()
    new_words = []
    for word in words:
        if word.lower() in lookup_dict:
            word = lookup_dict[word.lower()]
        new_words.append(word)
    new_text = " ".join(new_words)
    return new_text

_lookup_words("RT this is a retweeted tweet by me")
>>>> "Retweet this is a tetweeted tweet by me"


特征工程

数据经过预处理以后,需要转化成可用的特征,文本特征可用句法分析,实体N-gram, 基于单词的特征, 统计特征和单词嵌入等方法来构造。

句法分析

句法分析包括语法分析和句子排序中单词的分析,他们显示单词之间的关系。依存语法和词性标注是文本句法的重要属性。

依赖树:句子是由缝在一起的单词组成。句子中的词之间的关系是由基本依存语法决定的 。依存语法是一类句法分析,涉及两个词 之间的非对称二元关系。每一个关系都可以

用三元组的形式来表示(主语,谓语和宾语)。

词性标注:除了语法关系外,句子中的 每个词也与词性(名词,动词,形容词,副词等)相关。词性定义了句子中单词的用法和功能。

from nltk import word_tokenize, pos_tag
 text = "I am learning Natural Language Processing on Analytic Vidhya"
 tokens = word_tokenize(text)
 print pos_tag(tokens)
 >>>[('I','PRP'),('am','VBP'),('learning','VBG'),('Natural','NNP'),('Language',"NNP"),......]


N-gram


基于 N-Gram 的方法是把文章序列,通过大小为 N 的窗口,形成一个个 Group。然后对这些 Group 做统计,滤除出现频次较低的 Group,再把这些 Group 组成特征空间,传入

分类器,进行分类。

def generate_ngrams(text,n):
        words = text.split()
        output = []
        for i in range(len(word)-n +1):
            output.append(word[i:i+n])
        return output
    
generate_ngrams("this is a sample text",2)
 >>>>[['this','is'],['is','a'],['a','sample'],['sample','text']]


频次法


记录每篇文章的次数分布,然后将分布输入机器学习模型,训练一个合适的分类模型。对这类数据进行分类,需要指出的是:在统计次数分布时,可合理提出假设,频次比较小

的词对文章分类的影响比较小。因此,我们可合理地假设阈值,滤除频次小于阈值的词,减少特征空间维度。

TF-IDF


TF-IDF是一种常用的信息检索问题的加权模型。它的目的是将文本文档转化成向量模型,而不是考虑文档中单词出现的次数。

from sklearn.feature_extraction.text import TfidfVectorizer

obj = TfidfVectorizer()
corpus = ['This is sample document', 'another random document', 'third sample document text']

X = obj.fit_transform(corpus)
>>>>
(0,1) 0.345
(0,4) ...0.4444

该模型创建词汇字典并为每个单词分配索引。输出中的每一行包含元组(i, j)和文档i中索引j的单词的tf-idf值。

词嵌入


基于神经网络的分布表示又称为词向量、词嵌入,神经网络词向量模型与其它分布表示方法一样,均基于分布假说,核心依然是上下文的表示以及上下文与目标词之间的关系的

建模。

one-hot表示法具有维度过大的缺点,那么现在将vector做一些改进:

1、将vector每一个元素由整形改为浮点型,变为整个实数范围的表示;

2、将原来稀疏的巨大维度压缩嵌入到一个更小维度的空间。

Word2Vec 和 GloVe 是两种比较流行的文本嵌入模型,这些模型以文本语料库作为输入,并产生词向量作为输出。

实现Word2Vec有两种方式:连续词袋模型(CBOW)和Skip-Gram

from  gensim.models import Word2Vec
sentences = [['data','science'],['vidhya','science','data','analytics'],['machine','learning'],['deep','learning']]

#在词库中训练模型
model = Word2Vec(sentences, min_count = 1)

print(model.similarity('data','science'))
>>>0.1122
print(model['learning'])
>>> array([0.0034,0.00305,......])


他们可以被用作ML模型的特征向量,用于使用余弦相似性技术,词聚类和文本分类技术测试文本相似度。

Word embedding的训练方法大致可以分为两类:一类是无监督或弱监督的预训练;一类是端对端(end to end)的有监督训练。无监督或弱监督的预训练以word2vec和auto-

encoder为代表。这一类模型的特点是,不需要大量的人工标记样本就可以得到质量还不错的embedding向量。不过因为缺少了任务导向,可能和我们要解决的问题还有一定的

距离。因此,我们往往会在得到预训练的embedding向量后,用少量人工标注的样本去fine-tune整个模型。

相比之下,端对端的有监督模型在最近几年里越来越受到人们的关注。与无监督模型相比,端对端的模型在结构上往往更加复杂。同时,也因为有着明确的任务导向,端对端模

型学习到的embedding向量也往往更加准确。例如,通过一个embedding层和若干个卷积层连接而成的深度神经网络以实现对句子的情感分类,可以学习到语义更丰富的词向量

表达。