在这篇文章中,我将使用NLP和Python来解释如何机器学习的文本数据和模型分析来提取特征。
自然语言处理(NLP)是人工智能的研究领域,它研究计算机和人类语言之间的相互作用,特别是如何编程电脑大量的自然语言处理和分析数据。
NLP的分类通常是用于文本数据。文本分类是基于内容的文本数据的分类问题。文本分类是最重要的部分项目的特点:从原始文本数据的机器学习模型创建过程。
在这篇文章中,我将解释不同的方法来分析和提取文本可以用来构建分类模型的特点。我将介绍一些有用的Python代码。
这段代码可以很容易地应用到其他类似的情况(只复制粘贴,运行),我添加了评论,这样你就可以了解样品(链接下面的完整代码)。
我将使用“新闻类别数据集”(下面的链接),为您提供从《赫芬顿邮报》从2012年到2018年,新闻标题,要求您使用正确的类别进行分类。
/ rmisra……
特别是,我将通过:
环境设置:导入包和读取数据。语言测试:了解什么是自然语言数据。清晰的文本预处理、文本和转换。的长度分析:使用不同的指标来衡量。情绪分析:判断一篇文章是积极的还是消极的。命名实体识别:预定义的类别(如名称、组织位置)的身份文本。N字母词:找出最重要的。词向量:将一个单词转换成向量。主题模型:从语料库中提取主题。环境设置
首先,我需要导入以下库。
# # #数据导入大熊猫作为pdimport collectionsimport json #图纸导入matplotlib。Pyplot作为pltimport seaborn作为snsimport wordcloud进口再输入nltk # # # #文本处理语言测试从textblob进口langdetect # #情绪分析导入进口宽大的# # # TextBlob #命名实体识别词从sklearn进口feature_extraction,廖# #字embeddingimport gensim。下载器的模型导入gensim gensim_api # #主题
json文件中包含的数据集,所以我将是第一个使用json包读字典列表中,然后将其转换成熊猫数据帧。
Lst_dics =[]开放(的数据。Json模式= ' r ' json_file错误=“忽略”):在json_file dic: lst_dics。附加(json。负载(dic) # #打印第一lst_dics [0]
原始数据集包含30多个类别,但在本教程中,我将使用一个集合的子集的三类:娱乐,政治,科技,娱乐,政治说,科技)。
# #创建DTFDTF = pd。DataFrame (lst_dics) # #过滤器类别DTF = DTF (DTF) [r]。“类别”型号([“娱乐”,“政治说”,“科技”]]][[“类别”,“标题”]]# # DTF = DTF重命名列。重命名列(={“类别”:“y”,“标题”:“文本”})# # 5随机DTF打印行。样本(5)
为了理解数据的组件集,我将通过一个条形图显示标记研究单变量频率分布(仅一个变量的概率分布)。
X = " y "无花果,ax = PLT,次要情节(图Suptitle (X,字形大小= 12)DTF [X]。ResEt_index ()。groupby (x)数()sort_values(=“指数”)。情节(类型=“barh”,传说= False, ax = ax)。网格(轴=“x”) PLT。show ()
数据集是不均衡的:与其他数据集相比,科技新闻的比例很小。这可能是一个问题在建模的过程中,重采样的数据收集是非常有用的。
现在已经设置,我将开始用干净的数据,然后从原始文本中提取不同的细节,并将它们添加新列的数据帧。可以使用这些新的信息作为一个潜在分类模型的特性。
语言测试
首先,我要确保我使用相同的语言,使用langdetect包,它是非常简单的。说明,我将第一个新闻标题数据集使用它:
TXT = DTF [r]。“文本”iloc [0] print (TXT,“- - >”, langdetect。检测(TXT))
我们对整个数据集添加一列与语言信息:
DTF['朗]= DTF [r]。“文本”(λx: langdetect申请。检测如果x (x)。旅行()!DTF = " " " ")。头()
数据帧现在有一个新列。在使用相同的代码之前,我可以看到很多不同的语言是:
即使是不同的语言,英语是主要语言。所以我想过滤新闻英语。
DTF = DTF (DTF[]“朗”= =“en”]文本预处理
数据预处理是准备原始数据,使其适合于机器学习模型的阶段。NLP,包括文本清晰,删除停止,减少杆。
文本清理步骤由于不同的数据类型和所需的任务。确定之前,通常在一个文本,删除字符串转换为小写字母,标点符号。标识符(标记)在字符串拆分为一个字符串列表(或“身份”)的过程。
比如说第一个标题:
打印(“- - - - - -原始——“)打印(TXT)打印(“——清洗——”)。TXT = re子(r ' \ [^ \ w s] ', ' ', STR (TXT)。较低的()。加沙地带())打印(TXT)打印(“标记- - - - - - - -”)三种=三种。split()打印(TXT)
保持所有我们的标志的列表?我们没有任何。事实上,我们想要删除所有不提供额外的信息。
在这种情况下,最重要的词是“歌”,因为它可以是任何分类模型在正确的方向上。相比之下,像”和“,”“和”“这个词不是很有用,因为它们可能出现几乎所有的观测数据集。
这些都是停止词的例子。停止词通常指语言中最常见的一个词,但我们没有一个共同的停止词列表。
我们可以使用我(自然语言工具包)英语词汇创造一个共同的停止词列表,它是一种象征和统计自然语言处理库和程序。
Lst_stopwords =我。语料库。Stopwords。话说lst_stopwords(英语)
让我们从第一个开始移除这些停止词在新闻标题:
Print(“- - - - - -删除stopwords——”)三种=(逐字TXT如果词不是lst_stopwords)印刷(TXT)
我们应该停止仔细的话,因为如果你删除错误的标志,你可能会失去重要的信息。删除“将”一词,例如,我们已经失去了人将史密斯的信息。
有鉴于此,在删除之前停止对一些手动修改的原始文本是有用的(例如,将“将”替换为“Will_Smith”)。
现在我们已经都有这个词标志,您可以应用转换。茎(阻止)和物理和化学(词元化)一词的词根形式。
他们的区别在于遏制可能不是一个真正的词,和引理是一种实用的语言单词(茎通常更快)。这些算法由我提供。
继续示例:
打印(“阻止——”)ps =我。阀杆。波特。PorterStemmer()打印([ps。茎(逐字)TXT)打印登月舱(“lemmatisation————”) =我。阀杆。Wordnet。打印([lem WordNetLemmatizer ()。Lemmatize (TXT)逐字))
正如你所看到的,有些单词改变了:“连接”到它的根形成“加入”,像“杯”。另一方面,“官方”仅作为干细胞的变化,遏制“offici”不是一个词,但在后缀“- al”。
我将把所有这些预处理步骤放在一个函数,并应用于整个数据集。
“预处理。:参数:参数文本:字符串,包含列的文本的名称:param lst_stopwords:停止词列表:一个列表,要删除参数flg_stemm: bool——无论是应用茎:param flg_lemm: bool——无论是应用指南:返回清洁文本“def utils_preprocess_text(文本、flg_stemm = False flg_lemm = True, lst_stopwords = None): # #清洗(转换为小写字母和删除标点符号和字符,然后删除)文本=再保险。子(r (^\ w \ s] ', ' ', STR(文本)。较低的()。加沙地带())# #标识符(从一个字符串列表)lst_text =文本。split() # #删除停止词如果lst_stopwords不是没有:lst_text =(逐字lst_text如果词不是lst_stopwords] # #茎把如果flg_stemm = = True: ps =我。阀杆。波特。PorterStemmer () lst_text = [ps。茎(逐字)lst_text) # #导致物理和化学如果flg_lemm = = True:登月舱=我。阀杆。wordnet。lst_text = (lem WordNetLemmatizer ()。Lemmatize(逐字)lst_text]从列表中# #文本字符串= "。加入(lst_text)返回文本
请注意,您不应该阻止和应用物理和化学在同一时间。在这里,我将使用后者。
DTF [“text_clean”] = DTF [r]。“文本”应用(λx: utils_preprocess_text (x, flg_stemm = False, flg_lemm = True, lst_stopwords))
像以前一样,我创建了一个新的列:
DTF。头()
Print (DTF) [r]。“文本”iloc [0],“- - >”, DTF [r]。“text_clean iloc [0])
的长度分析
检查文本的长度是非常重要的,因为这是一个简单的计算,可以提供大量的信息。
例如,也许我们很幸运地找到一个比另一个分类系统类别是漫长的,唯一的特点和长度是需要构建模型。不幸的是,由于新闻标题的长度是相似的,这并非如此,但它值得一试。
文本数据有几种长度测量。我给几个例子:
词:统计识别号码(文本,用空格分隔)的字符数:每个id数的字符数增加一句话:计算句子的数量(分裂)平均单词长度:单词长度的总和除以的字数(字/词)平均句子长度:句子长度的总和除以句子(单词/句子)DTF [' word_count] = DTF [r]。“文本”应用(λx: len (STR (x)分割(" ")))DTF [' char_count] = DTF [r]。“文本”应用(λx: sum (len(逐字)STR (x)分割(" ")))DTF [' sentence_count] = DTF [r]。“文本”应用(λx: len (STR (x) split (”。")))DTF [' avg_word_length] = DTF [' char_count '] / DTF DTF [' word_count] [' avg_sentence_lenght] = DTF [' word_count '] / DTF [' sentence_count] DTF。头()
让我们看看这个例子:
这些新变量的分布相对于目标?要回答这个问题,我将研究二元分布(两个变量如何影响)。
首先,我将整个观测分成三个样本(政治、娱乐、科技),然后比较直方图和样品的密度。如果分布是不同的,那么变量是可预测的,因为三组有不同的模式。
例如,让我们看一看相关的字符数是目标变量:
X, y = " char_count”、“y”无花果、ax = PLT,次要情节(ncols = nrows = 1, 2)图Suptitle f (X)Ontsize = 12)因为我DTF [y]。独特的():社交。Distplot (DTF [DTF [y] = =我][x],嘘= True, kde = False,垃圾箱= 10,hist_kws ={}“α”:0.8,axlabel =“直方图”,ax = ax [0]) SNS。Distplot (DTF [DTF [y] = =我][x],嘘= False, kde = True, kde_kws ={“阴影”:真},axlabel =“密度”,ax = ax [1]) ax [0]。网格(真正的)ax [0]。传奇(DTF [y]。独特的())ax [1]。网格PLT(真正的)。show ()
这三个类别相似的长度分布。在这里,密度图是非常有用的,因为样品有不同的大小。
情绪分析
情感分析是通过数字或类来表达主观情感的文本数据。由于自然语言的歧义,计算出的情感是最困难的任务之一,在自然语言处理。
例如,“这是如此糟糕,它的好”有一个以上的解释。模型可以给“好”这个词分配一个积极的信号,给这个词“坏”分配一个消极的信号,产生一个中性的情绪。这是因为上下文是未知的。
是最好的方法来训练自己的情感模型,使其适用于您的数据。当没有足够的时间或数据,您可以使用训练模型,如Textblob和维德。
Textblob建立在我的基础上,它是最受欢迎的,它可以给极性词,意思估计整个文本。另一方面,维达(价-知道字典和mootion reasoner)是一个基于规则的模型,特别是在社交媒体数据。
我将使用Textblob添加一个情感特点:
DTF["情绪"]= DTF(列)。应用(λx: TextBlob (x)的情绪。极性DTF), ()
Print (DTF) [r]。“文本”iloc [0],“- - >”, DTF [r]。“人气”iloc [0])
分类和情绪之间定期?
大多数的头条新闻是中性的,除了政治新闻偏向负面,科技走向积极的消息。
命名实体识别
命名实体识别(命名实体识别、尼珥)是使用一个预定义的类别(如名称、组织、位置、时间表达式,号码,等等)来提取非结构化文本的命名实体的过程。
训练一个尼珥模型非常耗费时间,因为它需要非常丰富的数据集。幸运的是,有人为我们工作。最好的开源尼珥工具是宽大的。它提供了不同的NLP模型,该模型可以识别各种类型的实体。
我将在我们通常的标题(没有原始文本的预处理)用于广大的模型en_core_web_lg(网络上的数据训练英语的大型模型),给出了一个例子:
尼珥= # #叫宽大的。负载(“en_core_web_lg”) # #标签TXT = DTF [r]。“文本”iloc [0] doc =宽大的尼珥(TXT) # #显示结果。Displacy。呈现(医生,风格=“花”)
它很酷,但是我们怎样才能把它变成一个有用的功能?这是我想做的:
观察每个文本数据集尼珥的操作模式,就像我在上一个示例中所做的那样。
为每个新闻标题,我将把所有经批准的实体和实体数量出现在一个新列中的文本(称为“标记”)。
在这种情况下:
{(威尔·史密斯,“人”):1,(‘Diplo’,‘人’):1(“尼基果酱”、“人”):1(“2018年世界杯的”、“事件”):1}
然后,我将会为每个类别(人、组织、事件,……)。创建一个新的列,找到实体的数量,计算每个身份类别。在上面的示例中,该特性
Tags_PERSON = 3
Tags_EVENT = 1
# #标识文本并将标识导出到列表中dtf["标签"]= dtf(“文本”)。应用(λx:[(标签。标签的文本、tag.label_)尼珥(x)。树人])# #跑龙套函数计算列表元素def utils_lst_count (lst): dic_counter = collections.Counter lst (x): dic_counter [x] + = 1 dic_counter =集合。OrderedDict(排序(dic_counter.items(),关键=λx: x[1],反向= True)) lst_count =[{键:值}为关键,价值dic_counter.items()返回lst_count # #计数dtf["标签"]= dtf(“标记”)。应用(λx: utils_lst_count (x)) # #跑龙套函数为每个标识类别创建新列def utils_ner_features (lst_dics_tuples、标记):如果len (lst_dics_tuples) > 0: tag_type = [] lst_dics_t dic_tuples推:tuple dic_tuples:类型,n =元组[1],dic_tuples tag_type = tag_type(元组)+[型]* n dic_counter =集合。计数器()x tag_type: dic_counter [x] + = 1返回dic_counter[标记]其他:返回特征提取tags_set = 0 # # LST DTF[]的[r]。“标签”tolist (): dic的LST: dic的k。键():tags_set。附加tags_set [1] (k) =(套)(tags_set)列表功能tags_set: DTF [“tags_”+功能]= DTF [r]。“标签”应用(λx: utils_ner_features (x,特性)# # DTF。头()
现在我们可以对标识视图类型分布。组织标记(公司和组织),例如:
更深入的分析,我们需要使用在前面的代码中创建列“标签”。让我们作为一个整体类画最常用的标识:
Y = "娱乐" tags_list = DTF (DTF (" Y ") = = Y) [r]。“标签”和()map_lst =列表(地图(λx:列表(x。k的眼睛())[0],tags_list) dtf_tags = pd。DataFrame (map_lst列=['标签','类型'])dtf_tags(“计数”)= 1 dtf_tags = dtf_tags。Groupby(['类型','标签'])。reset_index count () () sort_values(“计数”,提升= False)无花果、ax = PLT,次要情节(图Suptitle(经常“标签”,字形大小= 12)SNS。barplot (x =“计数”,y =“标签”,色调=“类型”,data = dtf_tags。Iloc:,:,道奇= False, ax = ax) ax。网格(轴= " x ") PLT。show ()
然后介绍尼珥的另一个有用的应用程序:你还记得我们离开的“将”字的名称”将“停止词呢?一个有趣的解决这个问题的方法是“将”替换为“Will_Smith”,所以它不是影响停止词删除。
遍历所有文本改变数据集的名字是不可能的,所以我们用宽大的。正如我们所知,宽大的可以识别一个人的名字,所以我们可以使用它来测试名称,然后修改字符串。
TXT = # #预测DTF [r]。“文本”iloc[0] =尼珥的实体(三)。#树人#标签tagged_txt = txtfor标签实体:tagged_txt =再保险。子(标签。文本,“_”。加入(标签。文本。split ()), tagged_txt) # #结果打印(tagged_txt)
词频
到目前为止,我们已经看到了如何通过工程特点的分析和处理整个文本。
现在,我们将通过n - g频率的计算来研究一个词的重要性。N——“格拉姆是一个给定的文本样本连续序列。当“格拉姆的大小n - 1,称为unigram(2元)的大小。
例如,“我喜欢这篇文章”可以分解如下:
四个unigram:“我”,“喜欢”,“这”,“文章”三元:“我喜欢”,“这样”、“本文”
我将在政治新闻,例如解释如何计算unigram和一定范围的频率。
Y =“政治说“语料库= DTF (DTF (" Y ") = = Y) (“text_clean”) lst_tokens =我。标记。Word_tokenize(语料库。STR。猫(9月= " "))、无花果、ax = PLT,次要情节(ncols = nrows = 1, 2)图Suptitle(“最频繁的词语”,字形大小= 15)# # unigramsdic_words_freq =我。FreqDist dtf_uni = pd (lst_tokens)。DataFrame (dic_words_freq。Most_common(),列=[“词”、“频率)dtf_uni。Set_index (“话:,:”).iloc .sort_values(=“频率”)。情节(类型=“barh”, title =“Unigrams”, ax = ax[0],传奇= False) .grid(轴=“x”) ax[0]这里(ylabel = None) # # bigramsdic_words_freq = nltk.FreqDist (nltk。ngrams (lst_tokens, 2)) dtf_bi = pd.DataFrame (dic_words_freq.most_common(),列=[“词”、“频率”])dtf_bi[“单词”]= dtf_bi(“单词”)。应用(λx:“”。加入(x)字符串的字符串)dtf_bi.set_index(“单词”).iloc [:,:] .sort_values(=“频率”)。情节(类型=“barh”, title =“三元”,ax = ax[1],传奇= False) .grid(轴=“x”) ax[1]这里(ylabel = None) plt.show ()
如果有n个字母只出现在“共和党”)的类别(即政治新闻,所以这些可能成为新的特征。一个更加艰巨的向量化方法是整个语料库,并使用所有单词作为一个特性包方法(词)。
现在我将向您展示如何词频添加数据帧的功能。我们只需要Scikit CountVectorizer在学习,这是一个最流行的Python中的机器学习库。
数矩阵CountVectorizer转换文本文档集合。我将使用三个n -克为例:“票房”(通常出现在娱乐圈),”共和党人”(通常出现在政治),“苹果”(通常出现在科技世界)。
Lst_words =[“票房”,“共和党”和“苹果”)# # lst_grams = (len(词数。词的分裂(" "))lst_words] vectorizer = feature_extraction。文本。CountVectorizer(词汇= lst_words, ngram_range = (min (lst_grams), Max (lst_grams))) dtf_X = pd。DataFrame (vectorizer。Fit_transform (DTF [" text_clean "])。Todense(),列= lst_words) # #新特性添加到列DTF = pd。concat ((DTF dtf_X set_index (DTF)指数),轴= 1)DTF,头()
可视化信息的好方法是使用相同的词云,每个标志的频率与字体大小和颜色显示。
Wc = wordcloud。Wordcloud (background_color =‘黑’,max_words = 100, max_font_size = 35) wc = wc。生成(STR)(语料库)图= PLT图(num = 1) PLT。轴PLT(“关闭”)。Imshow PLT (wc,提出= None)。show ()
这个词向量
最近,NLP开发一个新的语言模型,该模型依赖于神经网络的结构,而不是传统的n - gram模型。这些新技术是一套建模语言学习的技术和特点,将这个词转换为真正的向量,所谓的嵌入式的词。
字嵌入模型通过构建所选单词前后出现的概率分布的身份,将向量映射到特定的词。这些模型迅速成为流行,因为一旦你有一个实数,而不是一个字符串,可以执行计算。例如,找到相同的语境,可以简单向量距离计算。
有几个Python库可以使用这个模型。宽大的是其中之一,但因为我们使用它,我将谈论另一个著名的包:Gensim。
它是利用现代统计主题为无监督机器学习和自然语言处理模型的开源库。使用Gensim,我将加载一个手套过程中训练模型。
手套是一种无监督学习算法用于获取300个单词向量。
NLP = gensim_api。负载(“手套-维基gigaword - 300)”
我们可以使用这个对象映射这个词向量:
“爱”这个词= NLP(单词)
NLP[字]。形状
现在让我们来看看什么是最接近这个词向量,换句话说,是最相似的一个词的上下文。
为了画出二维空间矢量图,我需要尺寸将从300减少到2。我将使用Scikit学习t -分布的随机邻居嵌入来实现这一点。
T -新力是一种高维数据的可视化工具,它将转换为联合概率数据点之间的相似性。
# #找到最近的向量标签,X, X, y = [], [], [], [] nlp的t。most_similar(词,topn = 20): X.append (nlp [t [0]]) labels.append (t[0]) # #降维pca =歧管。TSNE(困惑= 40 n_components = 2, init = pca) new_value = pca.fit_transform new_value价值(X): x.append(价值[0])y.append(价值[1])# #绘图图= plt.figure()我的范围(len (X)): plt。散射(x[我],[我],c =“黑色”)plt。注释(标签[我],xy = (x[我],[我]),xytext = (5, 2), textcoords =“抵消点”,哈=‘正确的’,va =“底部”)# #添加中心plt。散射(x = 0, y = 0, c =“红色”)plt。注释(词,xy = (0, 0), xytext = (5, 2), textcoords =“抵消点”,哈=‘正确的’,va =“底部”)
主题模型
Genism包专用模型的主题。主题模型是发现在文档的收集统计模型的抽象的“主题”。
我将向您展示如何使用LDA(潜在狄利克雷分布)中提取主题:它是一个生成的统计模型,它允许观察结果集是由一个不解释观察到的组织,解释为什么有些部分的数据是相似的。
基本上,文档被表示为随机混合的基本主题,每个主题的特征的分布在这个词。
看看我们可以从科技新闻一些话题。我需要指定集群的模型必须主题数,我将尝试使用3:
y = "科技"语料库= dtf (dtf [y] = = y] (“text_clean”) # #预处理语料库lst_corpus =[]语料库的字符串:lst_words = string.split () lst_grams = ["。加入(lst_words[我+ 2])我的范围(0,len (lst_words), 2)] lst_corpus.append (lst_grams) # #将单词映射到idid2word = gensim.corpora.Dictionary (lst_corpus) # #创建词典词:freqdic_corpus = [id2word.doc2bow(字)字lst_corpus) # #训练LDAlda_model = gensim.models.ldamodel。LdaModel(语料库= dic_corpus id2word = id2word num_topics = 3, random_state = 123, update_every = 1, chunksize = 100,通过= 10,α=‘汽车’,per_word_topics = True) # #输出lst_dics =[]我的范围(0,3):lst_tuples = lda_model.get_topic_terms(我)在lst_tuples tupla: lst_dics。追加({“主题”:我,“id”: tupla[0],“词”:id2word [tupla[0]],“体重”:tupla [1]}) dtf_topics = pD。D ataFrame (lst_dics列=[“主题”、“id”,“词”,“体重”])# # plotfig, ax = PLT,次要情节(SNS)。barplot (y =“单词”,x =“重量”,色调=“话题”,data = dtf_topics,道奇= False, ax = ax)。set_title (ax的主要查看切换)。集(ylabel = " ",包含=“重要性”)PLT。show ()
尽量只使用三个主题捕捉六年的内容可能有点困难,但正如我们所看到的,关于苹果的一切最终相同的主题。
结论
本文演示如何使用NLP为机器学习模型分析和文本数据中提取的特征教程。
我演示了如何检测数据所使用的语言,以及如何预处理和清晰的文本。然后我解释的不同测量长度、情绪分析,使用Textblob宽大的,用于命名实体识别。最后,我解释了Scikit学习词频的传统方法和Gensim现代语言模型之间的区别。
现在,你知道一开始处理所有的NLP文本数据的基本知识。
请先 后发表评论~
非常好用
很好,感谢。
得到
复习一遍
学习了啊!
学习了啊!
厉害,这软件太牛了,让人惊讶。
这软件太牛了
很好的软件,赞!!!
感谢
感谢分享