资源技术动态Web 抓取和文本分析实例

Web 抓取和文本分析实例

2019-10-26 | |  67 |   0

原标题: Web 抓取和文本分析实例      

来源:AI研习社         链接:https://www.yanxishe.com/TextTranslation/2011


在这篇文章中,我们将深入探讨抓取网站、清理文本数据和自然语言处理(NLP)的基础知识。我以爱丁堡艺穗节为背景,爱丁堡艺穗节是世界上最大的艺术节,目前正在8月2日至26日之间举行。

通过web抓取将数据导入Python

为了便于分析,我想获得关于艺穗节期间发生的所有事件的文本。此文本数据位于多个web页面之间,手动提取需要很长时间。

这就是用到Python库requests的地方,因为它可以用于向特定的页面发出HTTP请求。从HTTP请求的响应中,可以获得网站的文本数据。然而,这个文本数据是一个很大的文本,在这里使用了BeautifulSoup库来解析从页面返回的HTML,这样我们就可以有效地提取我们想要的内容。

下面的代码片段演示了向网页发出请求并通过BeautifulSoup解析响应:

import requests
from bs4 import BeautifulSoup

# URL to query
url = 'https://url_to_query'

# Scrape html from the URL
response = requests.get(url)

# Use html parser on webpage text
soup = BeautifulSoup(response.text, 'html.parser')


在返回的变量soup中,我们可以使用以下命令在HTML中搜索特定的类:soup.find_all(‘’, class_=’CLASS_NAME’)

使用这种方法,我获得了5254个节日活动的数据,包括活动名称的字段、活动的简要描述、票价和正在演出的节目数量。


探索边缘数据

在获得数据集之后,通常下一步是研究您拥有的内容。我很想知道各个赛事的票价分布情况。这些数据的限制视图如下所示:

1565261021832709.png

按门票价格分配活动(门票价格上限为60英镑)

从图表中我们可以看到超过25%的活动是免费参加的,其中5 - 20英镑占了很大一部分。对数据进行更深入的分析显示,这些课程的花费超过60英镑,其中大部分是技术大师课程或食品/饮料品尝课程。不过,我真正感兴趣的是正在进行的显示类型,我们需要开始处理文本数据。

清洗数据

在为数据科学项目使用用到文本时,数据在传递到我们想要应用的任何模型之前,几乎总是需要某种程度的清理。在当前数据下,我将事件名称和描述文本合并到一个名为df[' text ']的字段中。以下代码显示了清理文本的一些步骤:

import string
import pandas

def remove_punctuation(s):
s = ‘’.join([i for i in s if i not in frozenset((string.punctuation))])
return s

# Transform the text to lowercase
df[‘text’] = df[‘text’].str.lower()

# Remove the newline characters
df[‘text’] = df[‘text’].replace(‘n’,’ ‘, regex=True)

# Remove punctuation
df[‘text’] = df[‘text’].apply(remove_punctuation)


词袋模型(BOW)

现在DataFrame中的每一行都包含一个已清理文本数据字段,我们可以继续检查它背后的语言。其中一个比较简单的方法叫做词袋模型(BOW),它创建了一个词汇表,其中包含数据中出现的所有惟一单词。我们可以使用从sklearn导入的CountVectorizer来实现这一点。作为设置矢量化器的一部分,我们让stopword的参数为stopwords= ' english ',它从数据集中删除常见的单词,如the、and、of、to、in等。下面的代码对我们的文本执行此操作:

from sklearn.feature_extraction.text import CountVectorizer

# Initialise our CountVectorizer object
vectorizer = CountVectorizer(analyzer=”word”, tokenizer=None, preprocessor=None, stop_words='english')

# fit_transform fits our data and learns the vocabulary whilst transforming the data into feature vectors
word_bag = vectorizer.fit_transform(df.text)

# print the shape of our feature matrix
word_bag.shape

最后一行打印我们创建的矩阵的形状,在本例中它的形状为(5254,26,869)。这是一个稀疏矩阵,包含语料库中的所有单词以及它们在每个提供的句子中的存在。这个矩阵的一个好处是它可以显示数据集中最常见的单词;以下是代码片段:

# Get and display the top 10 most frequent words
freqs = [(word, word_bag.getcol(idx).sum()) for word, idx in vectorizer.vocabulary_.items()]
freqs_sort = sorted(freqs, key = lambda x: -x[1])
for i in freqs_sort[:10]:
   print(i)

从边缘数据来看,我们数据中出现频率最高的十个单词是:

('comedy', 1411)
('fringe', 1293)
('new', 927)
('theatre', 852)
('edinburgh', 741)
('world', 651)
('life', 612)
('festival', 561)
('music', 557)
('join', 534)

这是意料之中的,并不能告诉我们提供了多少深度。让我们尝试绘制事件之间的关联方式。

TF-IDF和余弦相似性

在NLP中工作,我们的目标通常是通过查看组成文本的单词来了解特定文本字符串的含义。衡量一个单词重要性的一个标准是它的词频(TF);这是一个单词在文档中出现的频率。然而,有些词可能会出现很多次,但可能并不重要;其中一些停止词(stopwords)已经被删除了。

我们可以采用的另一种方法是查看术语的逆文档频率(IDF),它减少了常用单词的权重,并增加了文档集合中不经常使用的单词的权重。我们可以结合TF和IDF (TF-IDF)。TF-IDF是一种方法,用于强调在给定的观察中频繁出现的单词,同时对多次观察中频繁出现的单词进行去强调。这种技术在确定哪些单词将成为好的特性方面非常有用。在这个项目中,我们将使用来自scikit-learn的TF-IDF矢量转换器。我们可以使用以下代码,以适应我们的文本的TF-IDF模型:

from sklearn.feature_extraction.text import TfidfVectorizer as TFIV

vctr = TFIV(min_df=2,
max_features=None,
strip_accents=’unicode’,
analyzer=’word’,
token_pattern=r’w{1,}’,
ngram_range=(1, 2),
use_idf=True,
smooth_idf=1,
sublinear_tf=1,
stop_words = ‘english’)

X = vctr.fit_transform(df.text)

从矩阵X中,我们可以以单词向量的形式理解每个事件的文本。为了找到相似的事件,我们将使用一个叫做余弦相似性的方法,同样,我们可以从sklearn中导入这个方法。下面的代码片段演示了如何在单个事件(X[5])上执行此操作,输出显示了最相关的事件及其相似度评分(1分表示相同的文本)

from sklearn.metrics.pairwise import linear_kernelcosine_similarities = linear_kernel(X[5], X).flatten()
related_docs_indices = cosine_similarities.argsort()[:-5:-1]
cos = cosine_similarities[related_docs_indices]print(related_docs_indices)
print(cos)[5  33         696        1041      ]
[1. 0.60378536 0.18632652 0.14713335]

在所有事件中重复此过程将创建所有事件的映射,以及相似的事件如何链接在一起。

1565261023665636.png

Gephi网络图显示所有事件的余弦相似度>0.2,由LDA主题着色

关于上面的网络图,有趣的是大量的事件与网络中的其他事件没有关系。这些作品散落在网络的边缘,凸显了艺穗节的创意程度。在中间,我们可以看到一些事件之间高度重叠的集群。在项目的最后阶段,我们对这些集群进行建模,并尝试为它们分配主题。


主题模型

隐含狄利克雷分布(LDA)是一个基于词频生成主题的模型。我们在这里使用它来在我们的边缘数据中寻找关于正在发生的事件类型的特定主题。下面的代码展示了如何开始使用这种方法:

from sklearn.decomposition import LatentDirichletAllocationvectorizer = CountVectorizer(analyzer="word",
                            min_df=20,
                            token_pattern=r'w{1,}',
                            ngram_range=(2, 4),
                            preprocessor=None,
                            stop_words='english')

word_bag = vectorizer.fit_transform(df.text)lda = LatentDirichletAllocation(n_topics=25,
  max_iter=50,
  learning_method=’online’,
  learning_offset=40.,
  random_state=0).fit(word_bag)names = vectorizer_stop.get_feature_names()for topic_idx, topic in enumerate(lda.components_):
   print("Topic %d:" % (topic_idx))
   print(" ".join([names[i]
                   for i in topic.argsort()[:-5 - 1:-1]]))

上面的代码只是运行LDA模型并打印输出主题和最重要的单词的一个例子。从LDA的输出,我使用主成分分析,能够创建我们的主题的2D投影:

1565261022112322.png

基于LDA方法的主题建模

能够通过运行LDA来绘制主题图,对于观察主题在何处重叠和调优模型非常有用。它还提供了一种方法来理解节日期间发生的不同类型的事件,如音乐、喜剧、诗歌、舞蹈和写作。

结论

我们的分析表明,使用NLP方法和技术的基础知识,我们可以从一个小的文本数据集入手来获得深入的了解。尽管BOW模型很简单,但它提供了一个关于单词数量和文本中使用的主要单词的快速视图,对于我们的数据来说,“comedy”、“fringe”和“edinburgh”等单词是最常见的。

在此基础上,TF-IDF提供了一种开始思考句子而不是单词的方法,并添加了余弦相似性,从而提供了一种开始分组观察的方法。这向我们展示了原始事件在边缘所呈现的程度,与其他事件之间的共同文本很低。

最后,使用LDA,我们得到模型来生成主题,其中将事件组分配给一个主题。这使我们能够衡量节日期间发生的主要事件类型。

还有一些其他的NLP方法值得研究,作为项目的一部分,我还使用了Word2Vec和TSNE,不过我还没有发表研究结果。

THE END

免责声明:本文来自互联网新闻客户端自媒体,不代表本网的观点和立场。

合作及投稿邮箱:E-mail:editor@tusaishared.com

上一篇:图像分类基础指南

下一篇:我们分析了最流行的歌词,教你用RNN写词编曲(附代码)

用户评价
全部评价

热门资源

  • 应用笔画宽度变换...

    应用背景:是盲人辅助系统,城市环境中的机器导航...

  • GAN之根据文本描述...

    一些比较好玩的任务也就应运而生,比如图像修复、...

  • 端到端语音识别时...

    从上世纪 50 年代诞生到 2012 年引入 DNN 后识别效...

  • 人体姿态估计的过...

    人体姿态估计是计算机视觉中一个很基础的问题。从...

  • 谷歌发布TyDi QA语...

    为了鼓励对多语言问答技术的研究,谷歌发布了 TyDi...