欢迎来到自然语言处理(NLP)文章系列。在第一篇文章中,探讨了多种文本处理技术。在系列的第二部分,了解了不同类型的特征提取技术和Python代码中的词嵌入。本文将进一步讨论一些非常重要的NLP任务,包括词性标注、实体识别和文本分类。
词性标注(POS)涉及将单词标记为它们各自的词性,例如名词、形容词、动词等。这是自然语言处理中非常关键的部分。命名实体识别基于这些现象,将在本文中进一步讨论。情感分析、命名实体解析、问答、词义消歧等都基于词性标注。
构建POS标记器有两种方式:基于规则的方法和基于随机的方法,后者依赖于单词序列和隐马尔可夫模型的帮助。在Python中实现POS标记器,首先需要过滤掉停用词,然后对文本进行标记。
# 导入库
import nltk
from nltk.corpus import stopwords
from nltk.tokenize import word_tokenize
# 加载停用词
stop_words = set(stopwords.words('english'))
# 过滤停用词
text = "爱自然语言处理,并且尝试通过阅读文章来学习它"
words = nltk.word_tokenize(text)
words = [word for word in words if word.lower() not in stop_words]
# 进行词性标注
POS = nltk.pos_tag(words)
在上面的代码中,可以看到词性被写成了它们的简写形式:NNS代表复数名词,NN代表单数名词,VBG代表动词的现在分词形式,PRP代表代词。基于这个概念,可以从文档中提取不同的词性,但如果想要提取非常具体的信息,比如提取不同国家的名称或不同组织的名称,不能使用POS标记器,这里使用命名实体识别的概念。
从文档中提取不同类型的实体是基于POS的,但它能够识别文档中的广泛实体,例如提取所有名称、国家名称等。有多个库可用于执行实体提取,如SpaCy、NLTK chunker、StanfordNER等。将使用SpaCy,因为它易于实现且结果更好。
# 安装SpaCy
!pip install spacy
!spacy download en_core_web_sm
# 加载SpaCy Pipeline
import spacy
nlp = spacy.load('en_core_web_sm')
# 处理文本
text = "三星准备在韩国推出价值1000美元的新手机"
doc = nlp(text)
# 提取实体
for ent in doc.ents:
print(ent.text, ent.label_)
在上述代码中,所有文本必须通过管道转换为SpaCy文档。ORG代表组织,1000代表货币,韩国代表地缘政治实体。SpaCy提供了准确的结果,可以用于过滤实体。
文本分类的目标是基于预训练的类别对文本进行分类。基于文本分类的应用非常广泛,包括简历筛选、垃圾邮件分类、文档分类、情感分析等。
以构建垃圾邮件分类器为例,需要一个包含所有垃圾邮件和正常邮件的数据集来训练模型。将训练一个基线文本分类器以理解训练过程。
# 导入必要的库
import pandas as pd
# 加载数据集
df = pd.read_csv(r'spam.csv', encoding='ISO-8859-1', usecols=['v1','v2'])
df.rename(columns = {'v1':'Target', 'v2':'Email'}, inplace = True)
# 数据清洗
df.Target.value_counts()
# 安装并使用text_hammer库进行文本清洗
!pip install text_hammer
import text_hammer as th
def text_cleaning(df, col_name):
# 清洗文本的函数
df[col_name] = df[col_name].progress_apply(lambda x: th.remove_stopwords(x))
df[col_name] = df[col_name].progress_apply(lambda x: th.remove_special_chars(x))
df[col_name] = df[col_name].progress_apply(lambda x: th.remove_accented_chars(x))
df[col_name] = df[col_name].progress_apply(lambda x: th.remove_html_tags(x))
df[col_name] = df[col_name].progress_apply(lambda x: th.remove_urls(x))
df[col_name] = df[col_name].progress_apply(lambda x: th.make_base(x))
return df
# 调用文本清洗函数
df = text_cleaning(df, 'Email')
# 映射标签
df['Target'] = df.Target.map({'ham':0,'spam':1})
# 划分训练和测试数据集
from sklearn import model_selection
X_train, X_test, y_train, y_test = model_selection.train_test_split(df['Email'], df['Target'],
stratify=df['Target'], test_size=0.2, random_state=42)
在上面的代码中,首先对数据集进行了清洗,然后映射了垃圾邮件和正常邮件的标签,并划分了训练和测试数据集。接下来,创建了一个训练管道,该管道结合了特征提取和模型训练。
# 创建训练管道
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline
vectorizer = TfidfVectorizer()
classifier = Pipeline([('feature_generation', vectorizer), ('model', MultinomialNB())])
# 训练管道
classifier.fit(X_train, y_train)
# 进行预测
text = ['嘿,Abhishek,能一起看足球比赛吗',
'免费参加每周竞赛,赢取足总杯决赛']
classifier.predict(text)
在上面的代码中,使用Multinomial Naive Bayes模型进行分类任务。训练完成后,可以使用相同的管道进行预测。
性能评估方面,可以使用sklearn提供的指标类来查看模型在数据集上的表现。分类报告将打印出模型的性能报告。
from sklearn import metrics
y_predicted = classifier.predict(X_test)
print(metrics.classification_report(y_test, y_predicted))
from sklearn.metrics import confusion_matrix
results = confusion_matrix(y_test, y_predicted)
print(results)
混淆矩阵显示模型正确分类了177条垃圾信息,61条垃圾信息分类错误,1434条正常信息正确分类。