直观:文本剖析及可视化
优采云 发布时间: 2020-08-30 09:14文本剖析及可视化
好用的数据采集工具,造数科技
对于这篇文章,我想使用基本的关键字提取机制,来描述一个文本剖析和可视化技术,只使用一个词组计数器,从我的博客发布的文章语料库中找到前3个关键字。 为了创建这个语料库,我下载了我所有的博客文章(约1400篇),并且捉住了整篇文章的文字。 然后,我使用nltk和各类干预/缩小技术来标记贴子,计数关键字并取得前3名关键字。 然后,我将使用Gephi聚合所有贴子中的所有关键字以创建可视化。
我早已上传了一个带有完整代码集的 jupyter notebook,您也可以下载csv文件。 需要安装beautifulsoup 和nltk。 您可以安装它们:
pip install bs4 nltk
要开始,我们要导出须要的库:
import pandas as pd
import numpy as np
from nltk.tokenize import word_tokenize, sent_tokenize
from nltk.corpus import stopwords
from nltk.stem import WordNetLemmatizer, PorterStemmer
from string import punctuation
from collections import Counter
from collections import OrderedDict
import re
import warnings
warnings.filterwarnings("ignore", category=DeprecationWarning)
from HTMLParser import HTMLParser
from bs4 import BeautifulSoup
有一个关于BeautifulSoup的警告,我们可以忽视。
现在,我们来设定一些我们须要的工作。
首先,我们设置我们的停止词,词干和引语词。
porter = PorterStemmer()
wnl = WordNetLemmatizer()
stop = stopwords.words('english')
stop.append("new")
stop.append("like")
stop.append("u")
stop.append("it'")
stop.append("'s")
stop.append("n't")
stop.append('mr.')
stop = set(stop)
现在,我们建立一些须要的函数。
tokenizer函数取自此处。 如果你想听到一些太酷的主题建模,阅读怎么挖掘新闻源数据并提取Python中的交互式洞察...
它是一个非常好的文章,进入主题建模和降维...我之后也会在这里发文章。
# From http://ahmedbesbes.com/how-to-mine-newsfeed-data-and-extract-interactive-insights-in-python.html
def tokenizer(text):
tokens_ = [word_tokenize(sent) for sent in sent_tokenize(text)]
tokens = []
for token_by_sent in tokens_:
tokens += token_by_sent
tokens = list(filter(lambda t: t.lower() not in stop, tokens))
tokens = list(filter(lambda t: t not in punctuation, tokens))
tokens = list(filter(lambda t: t not in [u"'s", u"n't", u"...", u"''", u'``', u'\u2014', u'\u2026', u'\u2013'], tokens))
filtered_tokens = []
for token in tokens:
token = wnl.lemmatize(token)
if re.search('[a-zA-Z]', token):
filtered_tokens.append(token)
filtered_tokens = list(map(lambda token: token.lower(), filtered_tokens))
return filtered_tokens
接下来,我在我的文章中有一些HTML,所以在做任何事之前,我想把它的文本中删掉。这里是一个使用bs4的class。 我在Stackoverflow上找到了这个代码。
class MLStripper(HTMLParser):
def __init__(self):
self.reset()
self.fed = []
def handle_data(self, d):
self.fed.append(d)
def get_data(self):
return ''.join(self.fed)
def strip_tags(html):
s = MLStripper()
s.feed(html)
return s.get_data()
好的,现在是有趣的东西,要获取我们的关键字,我们只须要2行代码。 此函数计数并返回所述关键字数目给我们。
def get_keywords(tokens, num):
return Counter(tokens).most_common(num)
最后,我创建了一个函数来获取填充urls / pubdate / author / text的pandas 数据框,然后从中创建我的关键字。 这个函数遍历一个pandas 数据框(每一行是我博客中的一篇文章),用“关键字”,“文章的标题”以及文章的发布数据来标记“文本”并返回pandas 数据框。
def build_article_df(urls):
articles = []
for index, row in urls.iterrows():
try:
data=row['text'].strip().replace("'", "")
data = strip_tags(data)
soup = BeautifulSoup(data)
data = soup.get_text()
data = data.encode('ascii', 'ignore').decode('ascii')
document = tokenizer(data)
top_5 = get_keywords(document, 5)
unzipped = zip(*top_5)
kw= list(unzipped[0])
kw=",".join(str(x) for x in kw)
articles.append((kw, row['title'], row['pubdate']))
except Exception as e:
print e
#print data
#break
pass
#break
article_df = pd.DataFrame(articles, columns=['keywords', 'title', 'pubdate'])
return article_df
是时侯加载数据并剖析了。 这些代码在我的博客文章(在这里找到),然后仅从数据中获取有趣的列,重命名它们并打算它们进行标记化。 大多数在读取csv文件时可以一行完成,但是我早已为另一个项目写了这个文件,就像它一样。
df = pd.read_csv('../examples/tocsv.csv')
data = []
for index, row in df.iterrows():
data.append((row['Title'], row['Permalink'], row['Date'], row['Content']))
data_df = pd.DataFrame(data, columns=['title' ,'url', 'pubdate', 'text' ])
使用 tail() 有以下结果
现在,我们可以通过调用我们的 build_article_df 函数来标记和执行我们的字数。
article_df = build_article_df(data_df)
这为我们提供了一个新的dataframe ,每个文章的前3个关键字(以及文章的标题和标题)。
这本身太酷。 我们使用一个简单的计数器手动生成每位文章的关键字。 不是十分复杂,但它起作用。 有很多其他的方式可以做到这一点,但如今我们将坚持这一点。 除了关键字之外,看看那些关键字是怎样与其他关键字“连接”可能是有趣的。 例如,“data”在其他文章中出现了几次?
有多种方式来回答这个问题,但是一种方式是通过在拓扑/网络映射中可视化关键字来查看关键字之间的联接。 我们须要对我们的关键字进行“计数”,然后建立一个共现矩阵。 这个矩阵是我们可以导出Gephi来进行可视化的。 我们可以使用networkx勾画网路地图,但是从没有大量工作的角度来看,很难从中获得有用的东西...使用Gephi对用户愈发友好。
我们有我们的关键字,需要一个共现矩阵。 要完成这个目标,我们须要采取几个步骤来单独地分解关键字。
keywords_array=[]
for index, row in article_df.iterrows():
keywords=row['keywords'].split(',')
for kw in keywords:
keywords_array.append((kw.strip(' '), row['keywords']))
kw_df = pd.DataFrame(keywords_array).rename(columns={0:'keyword', 1:'keywords'})
我们现今有一个关键字dataframe kw_df,其中收录两个列:关键字和关键字
目前这并没有很大的意义,但是我们须要两列来建立一个共现矩阵。 我们通过迭代每位文档关键字列表(关键字列)来查看关键字是否收录在内。 如果是,我们添加到我们的出现矩阵,然后建立我们的共存矩阵。
document = kw_df.keywords.tolist()
names = kw_df.keyword.tolist()
document_array = []
for item in document:
items = item.split(',')
document_array.append((items))
occurrences = OrderedDict((name, OrderedDict((name, 0) for name in names)) for name in names)
# Find the co-occurrences:
for l in document_array:
for i in range(len(l)):
for item in l[:i] + l[i + 1:]:
occurrences[l[i]][item] += 1
co_occur = pd.DataFrame.from_dict(occurrences )
现在,我们在co_occur dataframe中有一个共存矩阵,可以将其导出Gephi以查看节点和边的映射。 将co_occur dataframe保存为用于Gephi的CSV文件(您可以在此下载矩阵的副本)。
co_occur.to_csv('out/ericbrown_co-occurancy_matrix.csv')
应用到Gephi
现在,是时侯上手Gephi了。 我是个菜鸟,所以不能真正给你好多的教程,但我可以告诉你须要采取的步骤来建立一个网路地图。 首先,导入共同矩阵csv文件,然后导出电子表格,并将所有内容保留为默认值。 然后,在“overview”选项卡中,您将见到一堆节点和联接,如下图所示。
文章子集的网路地图
接下来,向下联通到“layout”部分,然后选择Fruchterman Reingold布局,然后按“run”以让地图重写。 在个别时侯,您须要在屏幕上放下节点后按“stop”。 你应当见到下边的内容。
文章子集的网路地图
嗯? 现在...让我们给图片勾线。 在“appearance”部分中,选择“nodes”,然后选择“ranking”。 选择“Degree”并点击“apply”。 您应当见到网路图形发生变化,现在有一些颜色与之相关联。 您可以使用颜色来播放,但默认配色方案应如下所示:
现在依然不是太有趣,文字/关键字在那里?
嗯,你须要转入“overview”标签瞧瞧。 您应当见到如下所示(在下拉菜单中选择“Default Curved”后)。
现在这太酷。您可以看见两个特别不同的感兴趣的领域。 “Data”和“Canon”...这是有道理的,因为我写了好多关于数据和分享我的好多摄影(用Canon 相机拍摄)。
如果您有兴趣,这里是我所有1400篇文章的完整地图。 再次,有两个关于摄影和数据的主要集群,但还有一个围绕“business”,“people”和“cio”的小型集群,这符合我多年来大部分的写作习惯。
还有其他一些可视化文本剖析的方式。 我正在计划一些额外的文章,来谈论我近来使用和运行的一些更有趣的方式。 敬请关注。