自然语言处理(NLP)入门
作者头像
  • 贾江微
  • 2022-06-11 14:52:15 11

自然语言处理(NLP)入门——预处理、单词嵌入与文本分类

在自然语言处理领域,诸如GRU、LSTM、XLNet和BERT等技术的发展使得这一领域的研究变得更为复杂。对于初学者来说,了解从何入手可能会感到困惑。本文旨在介绍自然语言处理的基础知识,包括使用基本但功能强大的Python库进行的数据清洗、标准化、编码、情感分析及简单的文本分类。

数据清洗与标准化

在处理自然语言数据时,是否需要进行数据清洗和标准化取决于具体问题的需求。如果模型需要捕捉语言中的细微差别,那么最好保持数据的原始状态,因为现代深度学习技术倾向于保留停用词、表情符号和大小写信息。然而,在进行趋势分析或分类任务时,数据清洗是有益的。以下是一些常见的预处理步骤:

  • 删除标点符号:去除标点符号有助于减少模型的过度拟合现象。但需要注意的是,标点符号(如问号)在识别问题时非常有用。
  • 删除表情符号:表情符号可能会导致单词解析困难。但在某些情况下,表情符号对于情感分析和主题分类非常有用。
  • 删除停用词:在数据探索和趋势分析中,常见的停用词(如“the”、“and”、“of”)可能不会带来太多信息。可以使用sklearn包中的停用词列表来删除这些词。
  • 统一大小写:将所有文本转换为小写是最简单的标准化方法。
  • 词干化:词干化是另一种规范化手段,将派生词转换为其词根形式(如“posting”、“posted”、“posts”转换为“post”)。
  • 提取或删除主题标签和注释:主题标签和注释有助于识别数据趋势,可以将其从文本中提取出来进行单独分析。

以下是实现这些预处理步骤的一个简单函数:

```python import re from sklearn.featureextraction.text import ENGLISHSTOP_WORDS from nltk.stem.porter import PorterStemmer import emoji import string

def preprocesstext(text, removestop=True, stemwords=False, removementionshashtags=True): """ 预处理文本 示例: 输入: preprocesstext("@water #dream hi hello where are you going be there tomorrow happening happen happens", stem_words=True) 输出: ['tomorrow', 'happen', 'go', 'hello'] """

# 删除表情符号
emoji_pattern = re.compile("[" "U0001F1E0-U0001F6FF" "]+", flags=re.UNICODE)
text = emoji_pattern.sub(r"", text)
text = "".join([x for x in text if x not in emoji.UNICODE_EMOJI])

if remove_mentions_hashtags:
    text = re.sub(r"@(w+)", " ", text)
    text = re.sub(r"#(w+)", " ", text)
    text = re.sub(r"[^x00-x7F]+", " ", text)

# 删除标点符号和数字
regex = re.compile('[' + re.escape(string.punctuation) + '0-9\r\t\n]')
nopunct = regex.sub(" ", text.lower())

words = (''.join(nopunct)).split()

if remove_stop:
    words = [w for w in words if w not in ENGLISH_STOP_WORDS]
    words = [w for w in words if len(w) > 2]

if stem_words:
    stemmer = PorterStemmer()
    words = [stemmer.stem(w) for w in words]

return list(words)

```

单词嵌入——它们是什么?

机器学习算法只能处理数字输入,因此我们需要将文本转换为数字形式。单词嵌入是一种将单词表示为固定长度向量的技术,这些向量用于编码句子。

  • One-hot编码:这是最简单的单词编码方法,它假设每个单词都是独立的实体,忽略了单词之间的关系。这种方法涉及从整个语料库中创建一个词汇表,每个单词对应一个唯一的索引。向量中的相应位置设为1,其他位置设为0。

  • Word2Vec嵌入:Word2Vec是一种通过浅层神经网络学习上下文关系的方法。它有两种主要的模型:CBOW(连续词袋模型)和Skip-gram模型。CBOW模型根据上下文单词预测当前单词,而Skip-gram模型则相反。

  • Glove嵌入:Glove也是一种单词嵌入方法,它利用了单词的全局共现信息,这使其在某些任务上表现更好。

如何使用单词嵌入?

了解了单词嵌入的概念后,接下来是如何应用它们。一种方法是使用预训练的单词向量,如Glove和fastText。这些向量已经在大规模语料库上进行了训练,可以下载并在自己的数据上使用。

例如,可以使用预训练的单词向量来查找与给定文档最相似的文档:

```python import numpy as np import gensim

加载预训练的单词向量

def loadglove(filename): glovedict = {} with open(filename) as f: filecontent = f.readlines() for line in filecontent: linecontent = line.split() glovedict[linecontent[0]] = np.array(linecontent[1:], dtype=float) return glove_dict

计算文档质心

def getcentroid(text, gloves): wordslist = preprocesstext(text) wordvecsum = 0 wordscount = 0 for w in wordslist: if w in gloves: wordvecsum += gloves[w] wordscount += 1 if wordscount: return wordvecsum / wordscount else: return 0

计算两个质心之间的距离

def get_distance(a, b): return np.linalg.norm(a - b)

加载预训练的Glove向量

glovedict = loadglove('pathtoglove_file')

计算训练集中每个文档的质心

trainsetcentroids = [] for doc in trainset: centroid = getcentroid(doc, glovedict) trainset_centroids.append(centroid)

查找新文档的质心

newdoccentroid = getcentroid(newdoc, glove_dict)

找到与新文档最相似的文档

mindistance = float('inf') closestdoc = None for i, centroid in enumerate(trainsetcentroids): distance = getdistance(centroid, newdoccentroid) if distance < mindistance: mindistance = distance closestdoc = train_set[i] ```

训练自定义单词向量

如果你需要为特定语料库训练单词向量,可以使用gensim包。例如:

```python import gensim

加载数据

with open('./potato.txt') as f: text = f.read()

预处理文本

wordslist = [preprocesstext(text)]

训练Word2Vec模型

model = gensim.models.Word2Vec( wordslist, size=150, window=2, mincount=1, workers=10, iter=10 )

输出训练结果

print('词汇表:', model.wv.vocab.keys()) print('最相似的词:', model.wv.mostsimilar('starchy')) print('potato的向量:', model.wv.wordvec('potato')) ```

数据探索

对于带有文本数据的探索性数据分析(EDA),可以使用一些强大的工具,如Spacy和WordCloud。

  • 使用Spacy探索:Spacy是一个功能强大的NLP库,可用于命名实体识别、词性标注、情感分析等。

```python import spacy

加载Spacy模型

nlp = spacy.load("encoreweb_sm")

预处理文本

text = ' '.join(toxicdata[:1000]['commenttext']) doc = nlp(' '.join(preprocess_text(text)))

输出单词属性

x = doc[0] print('单词:', x) print('词性:', x.pos_) print('情感:', x.sentiment) print('向量:', x.vector) ```

  • 使用WordCloud可视化:WordCloud是一种简单而有趣的方法,用于可视化文本中词语的频率。

```python from wordcloud import WordCloud import matplotlib.pyplot as plt

def makewc(wordlist): wordcloud = WordCloud() wordcloud.fitwords(dict(Counter(wordlist).most_common(40))) fig = plt.figure(figsize=(10, 10)) plt.imshow(wordcloud) plt.axis("off") plt.show()

获取名词列表

nouns = [token.text for token in doc if token.pos_ in ['NOUN']] make_wc(nouns) ```

情感分析

情感分析是NLP中的一项常见任务,用于判断文本的情感倾向。VaderSentiment库提供了一种快速简便的方法来进行情感分析。

```python from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer

初始化情感分析器

sentiment_analyzer = SentimentIntensityAnalyzer()

获取情感得分

def getsentimentscore(text): return sentimentanalyzer.polarityscores(text)['compound']

示例输出

sentimentscore = getsentimentscore(toxiccomment) print('情感得分:', sentiment_score) ```

文本分类

对于文本分类任务,FastText是一个简单而有效的库。它使用线性技术将单词向量组合成文本向量,用于计算分类标准。

```python import fasttext

训练FastText模型

model = fasttext.trainsupervised('pathtotrainingdata.txt')

输出训练结果

print('准确率:', model.test('pathtotest_data.txt')) ```

以上就是自然语言处理的一些基础知识。希望这些内容能够帮助初学者更好地理解和应用自然语言处理技术。

    本文来源:图灵汇
责任编辑: : 贾江微
声明:本文系图灵汇原创稿件,版权属图灵汇所有,未经授权不得转载,已经协议授权的媒体下载使用时须注明"稿件来源:图灵汇",违者将依法追究责任。
    分享
自然语言入门处理NLP
    下一篇