关于我们 | 联系我们

亚美体育app官网-欢迎你

当前位置:主页 > 产品展示 > 产品一类 >

亚美体育_NLP的文天职析与特征工程

本文摘要:摘要在本文中,我将使用NLP和Python解释如作甚机械学习模型分析文本数据和提取特征。自然语言处置惩罚(NLP)是人工智能的一个研究领域,它研究盘算机与人类语言之间的相互作用,特别是如何对盘算机举行编程以处置惩罚和分析大量自然语言数据。 NLP常用于文本数据的分类。文天职类是凭据文本数据的内容对其举行分类的问题。文天职类最重要的部门是特征工程:从原始文本数据为机械学习模型建立特征的历程。在本文中,我将解释差别的方法来分析文本并提取可用于构建分类模型的特征。

亚美体育app官网

摘要在本文中,我将使用NLP和Python解释如作甚机械学习模型分析文本数据和提取特征。自然语言处置惩罚(NLP)是人工智能的一个研究领域,它研究盘算机与人类语言之间的相互作用,特别是如何对盘算机举行编程以处置惩罚和分析大量自然语言数据。

NLP常用于文本数据的分类。文天职类是凭据文本数据的内容对其举行分类的问题。文天职类最重要的部门是特征工程:从原始文本数据为机械学习模型建立特征的历程。在本文中,我将解释差别的方法来分析文本并提取可用于构建分类模型的特征。

我将先容一些有用的Python代码。这些代码可以很容易地应用于其他类似的情况(只需复制、粘贴、运行),而且我加上了注释,以便你可以明白示例(链接到下面的完整代码)。https://github.com/mdipietro09/DataScience_ArtificialIntelligence_Utils/blob/master/deep_learning_natural_language_processing/text_classification_example.ipynb我将使用“新闻种别数据集”(以下链接),其中向你提供从赫芬顿邮报获得的2012年至2018年的新闻标题,并要求你使用正确的种别对其举行分类。https://www.kaggle.com/rmisra/news-category-dataset特别是,我将通过:情况设置:导入包并读取数据。

语言检测:相识哪些自然语言数据在其中。文本预处置惩罚:文本清理和转换。长度分析:用差别的指标来权衡。

情绪分析:判断一篇文章是正面的还是负面的。命名实体识别:带有预界说种别(如人名、组织、位置)的标识文本。词频:找出最重要的n个字母。

词向量:把一个字转换成向量。主题模型:从语料库中提取主题。

情况设置首先,我需要导入以下库。## 数据import pandas as pdimport collectionsimport json## 绘图import matplotlib.pyplot as pltimport seaborn as snsimport wordcloud## 文本处置惩罚import reimport nltk## 语言检测import langdetect ## 情感分析from textblob import TextBlob## 命名实体识别import spacy## 词频from sklearn import feature_extraction, manifold## word embeddingimport gensim.downloader as gensim_api## 主题模型import gensim数据集包罗在一个json文件中,因此我将首先使用json包将其读入字典列表,然后将其转换为pandas数据帧。lst_dics = []with open('data.json', mode='r', errors='ignore') as json_file: for dic in json_file: lst_dics.append( json.loads(dic) )## 打印第一个 lst_dics[0]原始数据集包罗30多个种别,但在本教程中,我将使用3个种别的子集:娱乐、政治和技术(Entertainment, Politics, Tech)。## 建立dtfdtf = pd.DataFrame(lst_dics)## 筛选种别dtf = dtf[ dtf["category"].isin(['ENTERTAINMENT','POLITICS','TECH']) ][["category","headline"]]## 重命名列dtf = dtf.rename(columns={"category":"y", "headline":"text"})## 打印5个随机行dtf.sample(5)为了明白数据集的组成,我将通过用条形图显示标签频率来研究单变量漫衍(仅一个变量的概率漫衍)。

x = "y"fig, ax = plt.subplots()fig.suptitle(x, fontsize=12)dtf[x].reset_index().groupby(x).count().sort_values(by= "index").plot(kind="barh", legend=False, ax=ax).grid(axis='x')plt.show()数据集是不平衡的:与其他数据集相比,科技新闻的比例确实很小。这可能是建模历程中的一个问题,对数据集重新采样可能很有用。现在已经设置好了,我将从清理数据开始,然后从原始文本中提取差别的细节,并将它们作为数据帧的新列添加。

这些新信息可以作为分类模型的潜在特征。语言检测首先,我想确保我使用的是同一种语言,而且使用langdetect包,这很是简朴。为了举例说明,我将在数据集的第一个新闻标题上使用它:txt = dtf["text"].iloc[0]print(txt, " --> ", langdetect.detect(txt))我们为整个数据集添加一个包罗语言信息的列:dtf['lang'] = dtf["text"].apply(lambda x: langdetect.detect(x) if x.strip() != "" else "")dtf.head()数据帧现在有一个新列。

使用之前的相同代码,我可以看到有几多种差别的语言:纵然有差别的语言,英语也是主要的语言。所以我要用英语过滤新闻。dtf = dtf[dtf["lang"]=="en"]文本预处置惩罚数据预处置惩罚是准备原始数据以使其适合机械学习模型的阶段。

对于NLP,这包罗文本清理、删除停用词、词干还原。文本清理步骤因数据类型和所需任务而异。通常,在文本被标识化之前,字符串被转换为小写,标点符号被删除。

标识化(Tokenization)是将字符串拆分为字符串列表(或“标识”)的历程。再以第一条新闻标题为例:print("--- original ---")print(txt)print("--- cleaning ---")txt = re.sub(r'[^ws]', '', str(txt).lower().strip())print(txt)print("--- tokenization ---")txt = txt.split()print(txt)我们要保留列表中的所有标识吗?我们没有。

事实上,我们想删除所有不提供分外信息的单词。在这个例子中,最重要的词是“song”,因为它可以将任何分类模型指向正确的偏向。

相比之下,像“and”、“for”、“the”这样的词并不有用,因为它们可能泛起在数据集中险些所有的视察中。这些是停用词的例子。

停用词通常指的是语言中最常见的单词,可是我们没有一个通用的停用词列表。我们可以使用NLTK(自然语言工具包)为英语词汇表建立一个通用停用词列表,它是一套用于符号和统计自然语言处置惩罚的库和法式。

lst_stopwords = nltk.corpus.stopwords.words("english")lst_stopwords让我们从第一个新闻标题中删除这些停用词:print("--- remove stopwords ---")txt = [word for word in txt if word not in lst_stopwords]print(txt)我们需要很是小心的停用词,因为如果你删除了错误的标识,你可能会失去重要的信息。例如,删除了“Will”一词,我们丢失了此人是Will Smith的信息。思量到这一点,在删除停用词之前对原始文本举行一些手动修改是很有用的(例如,将“Will Smith”替换为“Will_Smith”)。既然我们有了所有有用的标识,就可以应用word转换了。

词干化(Stemming)和引理化(Lemmatization)都发生了单词的词根形式。他们的区别在于词干可能不是一个实际的单词,而引理是一个实际的语言单词(词干通常更快)。这些算法都是由NLTK提供的。继续示例:print("--- stemming ---")ps = nltk.stem.porter.PorterStemmer()print([ps.stem(word) for word in txt])print("--- lemmatisation ---")lem = nltk.stem.wordnet.WordNetLemmatizer()print([lem.lemmatize(word) for word in txt])如你所见,有些单词已经改变了:“joins”酿成了它的根形式“join”,就像“cups”。

另一方面,“official”只随着词干的变化而变化,词干“offici”不是一个词,而是通已往掉后缀“-al”而发生的。我将把所有这些预处置惩罚步骤放在一个函数中,并将其应用于整个数据集。

'''预处置惩罚.:parameter :param text: string - 包罗文本的列的名称 :param lst_stopwords: list - 要删除的停用词列表 :param flg_stemm: bool - 是否应用词干 :param flg_lemm: bool - 是否应用引理化:return cleaned text'''def utils_preprocess_text(text, flg_stemm=False, flg_lemm=True, lst_stopwords=None): ## 清洗(转换为小写并删除标点和字符,然后删除) text = re.sub(r'[^ws]', '', str(text).lower().strip()) ## 标识化(从字符串转换为列表) lst_text = text.split() ## 删除停用词 if lst_stopwords is not None: lst_text = [word for word in lst_text if word not in lst_stopwords] ## 词干化 if flg_stemm == True: ps = nltk.stem.porter.PorterStemmer() lst_text = [ps.stem(word) for word in lst_text] ## 引理化 if flg_lemm == True: lem = nltk.stem.wordnet.WordNetLemmatizer() lst_text = [lem.lemmatize(word) for word in lst_text] ## 从列表返回到字符串 text = " ".join(lst_text) return text请注意,你不应该同时应用词干和引理化。在这里我将使用后者。dtf["text_clean"] = dtf["text"].apply(lambda x: utils_preprocess_text(x, flg_stemm=False, flg_lemm=True, lst_stopwords))和以前一样,我建立了一个新的列:dtf.head()print(dtf["text"].iloc[0], " --> ", dtf["text_clean"].iloc[0])长度分析检察文本的长度很重要,因为这是一个简朴的盘算,可以提供许多信息。

例如,也许我们足够幸运地发现,一个种别系统地比另一个种别长,而长度只是构建模型所需的唯一特征。不幸的是,由于新闻标题的长度相似,情况并非如此,但值得一试。文本数据有几种长度怀抱。

我将举几个例子:字数:统计文本中的标识数(用空格分开)字符数:将每个标识的字符数相加句子计数:盘算句子的数量(用句点分开)平均字长:字长之和除以字数(字数/字数)平均句子长度:句子长度之和除以句子数(字数/句子数)dtf['word_count'] = dtf["text"].apply(lambda x: len(str(x).split(" ")))dtf['char_count'] = dtf["text"].apply(lambda x: sum(len(word) for word in str(x).split(" ")))dtf['sentence_count'] = dtf["text"].apply(lambda x: len(str(x).split(".")))dtf['avg_word_length'] = dtf['char_count'] / dtf['word_count']dtf['avg_sentence_lenght'] = dtf['word_count'] / dtf['sentence_count']dtf.head()让我们看看例子:这些新变量相对于目的的漫衍情况如何?为了回覆这个问题,我将研究二元漫衍(两个变量如何一起影响)。首先,我将整个视察效果分成3个样本(政治、娱乐、科技),然后比力样本的直方图和密度。如果漫衍差别,那么变量是可预测的,因为这三组有差别的模式。例如,让我们看看字符数是否与目的变量相关:x, y = "char_count", "y"fig, ax = plt.subplots(nrows=1, ncols=2)fig.suptitle(x, fontsize=12)for i in dtf[y].unique(): sns.distplot(dtf[dtf[y]==i][x], hist=True, kde=False, bins=10, hist_kws={"alpha":0.8}, axlabel="histogram", ax=ax[0]) sns.distplot(dtf[dtf[y]==i][x], hist=False, kde=True, kde_kws={"shade":True}, axlabel="density", ax=ax[1])ax[0].grid(True)ax[0].legend(dtf[y].unique())ax[1].grid(True)plt.show()这三个种别具有相似的长度漫衍。

在这里,密度图很是有用,因为样本有差别的巨细。情感分析情感分析是通过数字或类来表达文本数据的主观情感。

由于自然语言的模糊性,盘算情感是自然语言处置惩罚中最难题的任务之一。例如,短语“This is so bad that it’s good”有不止一种解释。一个模型可以给“好”这个词分配一个努力的信号,给“坏”这个词分配一个消极的信号,从而发生一种中性的情绪。

这是因为上下文未知。最好的方法是训练你自己的情绪模型,使之适合你的数据。当没有足够的时间或数据时,可以使用预训练好的模型,好比Textblob和Vader。Textblob建设在NLTK的基础上,是最盛行的一种,它可以给单词赋予极性,并作为一个平均值来预计整个文本的情绪。

另一方面,Vader(Valence-aware dictionary and mootion reasoner)是一个基于规则的模型,尤其适用于社交媒体数据。我将使用Textblob添加一个情感特征:dtf["sentiment"] = dtf[column].apply(lambda x: TextBlob(x).sentiment.polarity)dtf.head()print(dtf["text"].iloc[0], " --> ", dtf["sentiment"].iloc[0])分类和情绪之间有纪律吗?大多数的头条新闻都是中性的,除了政治新闻偏向于负面,科技新闻偏向于正面。命名实体识别命名实体识别(Named entity recognition,NER)是用预界说的种别(如人名、组织、位置、时间表达式、数量等)提取非结构化文本中的命名实体的历程。

训练一个NER模型是很是耗时的,因为它需要一个很是富厚的数据集。幸运的是有人已经为我们做了这项事情。最好的开源NER工具之一是SpaCy。

它提供了差别的NLP模型,这些模型能够识别多种类型的实体。我将在我们通常的标题(未经预处置惩罚的原始文本)中使用SpaCy模型en_core_web_lg(网络数据上训练的英语的大型模型),给出一个例子:## 挪用ner = spacy.load("en_core_web_lg")## 打标签txt = dtf["text"].iloc[0]doc = ner(txt)## 展示效果spacy.displacy.render(doc, style="ent")这很酷,可是我们怎么能把它酿成有用的特征呢?这就是我要做的:对数据集中的每个文本视察运行NER模型,就像我在前面的示例中所做的那样。对于每个新闻标题,我将把所有被认可的实体以及同一实体泛起在文本中的次数放入一个新的列(称为“tags”)。

在这个例子中:{ (‘Will Smith’, ‘PERSON’):1, (‘Diplo’, ‘PERSON’):1, (‘Nicky Jam’, ‘PERSON’):1, (“The 2018 World Cup’s”, ‘EVENT’):1 }然后,我将为每个标识种别(Person、Org、Event,…)建立一个新列,并盘算每个标识种别找到的实体数。在上面的例子中,特征将是tags_PERSON = 3tags_EVENT = 1## 标识文本并将标识导出到列表中dtf["tags"] = dtf["text"].apply(lambda x: [(tag.text, tag.label_) for tag in ner(x).ents] )## utils函数盘算列表元素def utils_lst_count(lst): dic_counter = collections.Counter() for x in lst: dic_counter[x] += 1 dic_counter = collections.OrderedDict( sorted(dic_counter.items(), key=lambda x: x[1], reverse=True)) lst_count = [ {key:value} for key,value in dic_counter.items() ] return lst_count## 计数dtf["tags"] = dtf["tags"].apply(lambda x: utils_lst_count(x))## utils函数为每个标识种别建立新列def utils_ner_features(lst_dics_tuples, tag): if len(lst_dics_tuples) > 0: tag_type = [] for dic_tuples in lst_dics_tuples: for tuple in dic_tuples: type, n = tuple[1], dic_tuples[tuple] tag_type = tag_type + [type]*n dic_counter = collections.Counter() for x in tag_type: dic_counter[x] += 1 return dic_counter[tag] else: return 0## 提取特征tags_set = []for lst in dtf["tags"].tolist(): for dic in lst: for k in dic.keys(): tags_set.append(k[1])tags_set = list(set(tags_set))for feature in tags_set: dtf["tags_"+feature] = dtf["tags"].apply(lambda x: utils_ner_features(x, feature))## 效果dtf.head()现在我们可以在标识类型漫衍上有一个视图。以组织标签(公司和组织)为例:为了更深入地分析,我们需要使用在前面的代码中建立的列“tags”。

让我们为标题种别之一绘制最常用的标识:y = "ENTERTAINMENT"tags_list = dtf[dtf["y"]==y]["tags"].sum()map_lst = list(map(lambda x: list(x.keys())[0], tags_list))dtf_tags = pd.DataFrame(map_lst, columns=['tag','type'])dtf_tags["count"] = 1dtf_tags = dtf_tags.groupby(['type', 'tag']).count().reset_index().sort_values("count", ascending=False)fig, ax = plt.subplots()fig.suptitle("Top frequent tags", fontsize=12)sns.barplot(x="count", y="tag", hue="type", data=dtf_tags.iloc[:top,:], dodge=False, ax=ax)ax.grid(axis="x")plt.show()接着先容NER的另一个有用的应用法式:你还记得我们从“Will Smith”的名称中删除了“Will”这个单词的停用词吗?解决这个问题的一个有趣的方法是将“Will Smith”替换为“Will_Smith”,这样它就不会受到停用词删除的影响。遍历数据集中的所有文原来更更名称是不行能的,所以让我们使用SpaCy。如我们所知,SpaCy可以识别一小我私家名,因此我们可以使用它来检测姓名,然后修改字符串。## 预测txt = dtf["text"].iloc[0]entities = ner(txt).ents## 打标签tagged_txt = txtfor tag in entities: tagged_txt = re.sub(tag.text, "_".join(tag.text.split()), tagged_txt) ## 效果print(tagged_txt)词频到现在为止,我们已经看到了如何通太过析和处置惩罚整个文原来举行特征工程。

现在,我们将通过盘算n-grams频率来研究单个单词的重要性。n-gram是给定文本样本中n个项的一连序列。当n-gram的巨细为1时,称为unigram(巨细为2是一个bigram)。例如,短语“I like this article”可以剖析为:4个unigram: “I”, “like”, “this”, “article”3个bigrams:“I like”, “like this”, “this article”我将以政治新闻为例说明如何盘算unigram和bigrams频率。

y = "POLITICS"corpus = dtf[dtf["y"]==y]["text_clean"]lst_tokens = nltk.tokenize.word_tokenize(corpus.str.cat(sep=" "))fig, ax = plt.subplots(nrows=1, ncols=2)fig.suptitle("Most frequent words", fontsize=15)## unigramsdic_words_freq = nltk.FreqDist(lst_tokens)dtf_uni = pd.DataFrame(dic_words_freq.most_common(), columns=["Word","Freq"])dtf_uni.set_index("Word").iloc[:top,:].sort_values(by="Freq").plot( kind="barh", title="Unigrams", ax=ax[0], legend=False).grid(axis='x')ax[0].set(ylabel=None)## bigramsdic_words_freq = nltk.FreqDist(nltk.ngrams(lst_tokens, 2))dtf_bi = pd.DataFrame(dic_words_freq.most_common(), columns=["Word","Freq"])dtf_bi["Word"] = dtf_bi["Word"].apply(lambda x: " ".join( string for string in x) )dtf_bi.set_index("Word").iloc[:top,:].sort_values(by="Freq").plot( kind="barh", title="Bigrams", ax=ax[1], legend=False).grid(axis='x')ax[1].set(ylabel=None)plt.show()如果有n个字母只泛起在一个种别中(即政治新闻中的“Republican”),那么这些就可能成为新的特征。一种更为艰苦的方法是对整个语料库举行向量化,并使用所有的单词作为特征(单词包方法)。现在我将向你展示如何在数据帧中添加单词频率作为特征。我们只需要Scikit learn中的CountVectorizer,它是Python中最盛行的机械学习库之一。

CountVectorizer将文本文档荟萃转换为计数矩阵。我将用3个n-grams来举例:“box office”(经常泛起在娱乐圈)、“republican”(经常泛起在政界)、“apple”(经常泛起在科技界)。

lst_words = ["box office", "republican", "apple"]## 计数lst_grams = [len(word.split(" ")) for word in lst_words]vectorizer = feature_extraction.text.CountVectorizer( vocabulary=lst_words, ngram_range=(min(lst_grams),max(lst_grams)))dtf_X = pd.DataFrame(vectorizer.fit_transform(dtf["text_clean"]).todense(), columns=lst_words)## 将新特征添加为列dtf = pd.concat([dtf, dtf_X.set_index(dtf.index)], axis=1)dtf.head()可视化相同信息的一个很好的方法是使用word cloud,其中每个标识的频率用字体巨细和颜色显示。wc = wordcloud.WordCloud(background_color='black', max_words=100, max_font_size=35)wc = wc.generate(str(corpus))fig = plt.figure(num=1)plt.axis('off')plt.imshow(wc, cmap=None)plt.show()词向量最近,NLP领域开发了新的语言模型,这些模型依赖于神经网络结构,而不是更传统的n-gram模型。

这些新技术是一套语言建模和特征学习技术,将单词转换为实数向量,因此称为词嵌入。词嵌入模型通过构建所选单词前后泛起的标识的概率漫衍,将特定单词映射到向量。这些模型很快变得盛行,因为一旦你有了实数而不是字符串,你就可以执行盘算了。

例如,要查找相同上下文的单词,可以简朴地盘算向量距离。有几个Python库可以使用这种模型。SpaCy是其中之一,但由于我们已经使用过它,我将谈论另一个著名的包:Gensim。它是使用现代统计机械学习的用于无监视主题模型和自然语言处置惩罚的开源库。

使用Gensim,我将加载一个预训练的GloVe模型。GloVe是一种无监视学习算法,用于获取300个单词的向量表现。nlp = gensim_api.load("glove-wiki-gigaword-300")我们可以使用此工具将单词映射到向量:word = "love"nlp[word]nlp[word].shape现在让我们来看看什么是最靠近的词向量,换句话说,就是大多数泛起在相似上下文中的词。

为了在二维空间中绘制向量图,我需要将维数从300降到2。我将使用Scikit learn中的t-漫衍随机邻人嵌入来实现这一点。t-SNE是一种可视化高维数据的工具,它将数据点之间的相似性转换为团结概率。

## 找到最近的向量labels, X, x, y = [], [], [], []for t in nlp.most_similar(word, topn=20): X.append(nlp[t[0]]) labels.append(t[0])## 降维pca = manifold.TSNE(perplexity=40, n_components=2, init='pca')new_values = pca.fit_transform(X)for value in new_values: x.append(value[0]) y.append(value[1])## 绘图fig = plt.figure()for i in range(len(x)): plt.scatter(x[i], y[i], c="black") plt.annotate(labels[i], xy=(x[i],y[i]), xytext=(5,2), textcoords='offset points', ha='right', va='bottom')## 添加中心plt.scatter(x=0, y=0, c="red")plt.annotate(word, xy=(0,0), xytext=(5,2), textcoords='offset points', ha='right', va='bottom')主题模型Genism包专门用于主题模型。主题模型是一种用于发现文档荟萃中泛起的抽象“主题”的统计模型。我将展示如何使用LDA(潜Dirichlet漫衍)提取主题:它是一个生成统计模型,它允许由未视察到的组解释视察效果集,解释为什么数据的某些部门是相似的。

基本上,文档被表现为潜在主题上的随机混淆,每个主题的特征是在单词上的漫衍。让我们看看我们可以从科技新闻中提取哪些主题。我需要指定模型必须簇的主题数,我将实验使用3:y = "TECH"corpus = dtf[dtf["y"]==y]["text_clean"]## 预处置惩罚语料库lst_corpus = []for string in corpus: lst_words = string.split() lst_grams = [" ".join(lst_words[i:i + 2]) for i in range(0, len(lst_words), 2)] lst_corpus.append(lst_grams)## 将单词映射到idid2word = gensim.corpora.Dictionary(lst_corpus)## 建立词典 word:freqdic_corpus = [id2word.doc2bow(word) for word in lst_corpus] ## 训练LDAlda_model = gensim.models.ldamodel.LdaModel(corpus=dic_corpus, id2word=id2word, num_topics=3, random_state=123, update_every=1, chunksize=100, passes=10, alpha='auto', per_word_topics=True)## 输出lst_dics = []for i in range(0,3): lst_tuples = lda_model.get_topic_terms(i) for tupla in lst_tuples: lst_dics.append({"topic":i, "id":tupla[0], "word":id2word[tupla[0]], "weight":tupla[1]})dtf_topics = pd.DataFrame(lst_dics, columns=['topic','id','word','weight'])## plotfig, ax = plt.subplots()sns.barplot(y="word", x="weight", hue="topic", data=dtf_topics, dodge=False, ax=ax).set_title('Main Topics')ax.set(ylabel="", xlabel="Word Importance")plt.show()试图仅用3个主题捕捉6年的内容可能有点难题,但正如我们所看到的,关于苹果公司的一切都以同一个主题竣事。

结论本文是演示如何使用NLP分析文本数据并为机械学习模型提取特征的教程。我演示了如何检测数据所使用的语言,以及如何预处置惩罚和清除文本。然后我解释了长度的差别怀抱,用Textblob举行了情绪分析,并使用SpaCy举行命名实体识别。

最后,我解释了Scikit学习的传统词频方法与Gensim的现代语言模型之间的区别。现在,你已经相识了开始处置惩罚文本数据的所有NLP基础知识。


本文关键词:亚美体育,亚美,体育,NLP,的,文天职,文,天职,析,与,特征

本文来源:亚美体育-www.0351brand-ad.com

Copyright © 2007-2021 www.0351brand-ad.com. 亚美体育科技 版权所有 备案号:ICP备52640042号-3