×

乱炖数据之2700余篇“简书交友”专题文章数据的花式玩法

96
Deserts_X
2018.06.02 19:15* 字数 3487
简书交友人群“画像”-人脸照片墙

想看小姐姐的请拖到最后,一次性看个够(侵删),看完后请点下贤者之赞再走哦。

一、背景介绍

简书交友专题.png

简书上有个“简书交友”专题,经常会有人写些自己的情况、贴贴自己的照片然后投稿到这一专题,有介绍的比较详细的比如下图所示(侵删),较为规整和全面;

但大多比较芜杂凌乱,可能文章中不拘哪里就会出现城市、年龄等等,对于这样的非结构化文本数据,想要提取高质量的结构化数据并挖掘出某些信息,似乎不太容易。虽然很感兴趣,但奈何水平不够,因而很久以前,一位小编私信我爬取和分析下该专题时也只是推说“猴年马月”再看看。

如今卷土重来,爬取了该专题2700余篇文章(思考题:为什么不是爬取全部文章呢?),并使出一套乱披风锤法,各种文本挖掘,人脸识别、颜值打分、照片墙拼接等等都来一遍,美其名曰“乱炖”简书交友数据,其实也是为了练手,熟悉、回顾和应用下各种技术。


斗罗大陆.jpg

二、“乱炖”简书交友数据

2.1 数据一览

由于爬虫部分有小小的问题,所以就先跳过这部分内容,爬取的数据格式如下,主要涵盖:作者,主页URL,文章标题,发布时间,阅读量,评论数,喜欢数,文章摘要,文章URL,文中图片URL列表,文章内容等等维度。


数据格式.JPG

首先看看爬取的文章都是发布于哪年哪月的?套用以前用来可视化的ECharts3代码模板:图表太丑怎么破,ECharts神器带你飞!,可以清楚的看到2018年文章占比数接近75%。可见简书上活跃的人还是不少的,该专题多次举办主题征文活动,看来反响也不错。

“简书交友”专题文章之年度月份分布情况.png

如果再看看文章发布时间的24分布情况,可以看出22点虽然小有高峰,但差距相对不大,除却1点至8点的睡觉时间,并没有明显的深夜寂寞寂寞,想交友的倾向==。


“简书交友”专题文章之24小时分布情况.png

以阅读量、评论数和点赞数的数据绘制3D图表,可以看出有些文章有着超高的阅读量,超多的评论数,较多的点赞数,具体是那些文章此处就不罗列和深挖了,感兴趣的可以自行去该专题“热门”一栏下一探究竟。此外原本想看看能不能用K-Means进行聚类,但如图所示似乎也不太可分?遂弃之。


阅读量-评论数-点赞数

接下来看看文章字数与配图数之间的关系,两者不是直接提供的,但能分别计算出来,线性相关性不明显,但却发现有些文章配图数高达几十,挺让人惊讶的。

文章长度与配图数

接着看下配图数量与文章长度会对阅读量、点赞数、评论数有什么影响吗?用seaborn库分别绘制heatmap图和pairplot图可知,仅评论数和点赞数,阅读量和点赞数线性相关性稍强。


heatmap图
pairplot图

2.2 文本挖掘

在对专题文章数据有了初步了解后,我们对文章文本内容进行简单的挖掘。首先用jieba分词中文文本,并去掉停用词,统计出Top30的高频词语:

segment 计数
19510 喜欢 9535
2574 一个 9314
41918 没有 4949
48850 知道 3571
3530 一起 3481
50805 简书 2948
46592 生活 2787
27192 希望 2735
57188 觉得 2636
38347 朋友 2621
46137 现在 2365
28984 很多 2363
4634 不会 2069
35718 文章 1981
3342 一直 1926
48521 真的 1697
36888 时间 1606
17484 可能 1567
48268 看到 1539
12231 其实 1505
35200 故事 1452
35642 文字 1448
26817 工作 1440
31077 感觉 1368
2901 一定 1326
27022 已经 1290
7464 事情 1283
31458 我会 1264
21945 大学 1231
5641 世界 1229

表格数据看起来不够直观,做成词云可能效果更好。但用wordcloud库生成的词云图都不太美观,于是借助在线词云生成网站:HTML5 Word Cloud。下图是否符合你对这一专题的心理预期?

文章内容词云图

再对文章标题进行同样的操作,统计出Top30的高频词语:

segment 计数
3525 简书 733
655 交友 658
2813 树洞 303
205 一个 190
1867 少年 158
1271 同学 149
2164 怦然心动 144
1365 喜欢 119
2733 未来 109
4231 遇见 91
2192 情书 80
939 写给 78
2709 朋友 73
246 一封信 63
468 专题 59
3277 男朋友 54
2924 求脱 53
783 你好 52
299 一起 50
1663 姑娘 48
3107 点名 47
2052 征文 47
318 七夕 47
2461 故事 44
2991 活动 43
1941 希望 42
3728 联合 41
778 作战 40
3101 灵魂 40
2707 有趣 39

并绘制出词云图:


标题词云图

可以看出确实有大量的文章是征文活动系列的,比如“简书交友”、“怦然心动”,“七夕”,“情书”等等。

由于手头还有以前爬取简书“今日看点”热门文章数据。并调用bosonNLP绘制的Top100关键词的词云图:简书=鸡汤?爬取今日看点数据:1916篇简书热门文章可视化。从横向比较中可以看出些区别,本次没有对更多热门专题进行比较,有识之士可自行挖掘。

“今日看点”热门文章标题词云图

再回到文章文本内容来,高频词中有诸如“一个”、“一起”等出现次数多但信息量少的词,因而继续调用jieba库

import jieba.analyse as analyse
textrank = "  ".join(analyse.textrank(contents, topK=200, withWeight=False, allowPOS=('ns', 'n')))
print(textrank)

基于 TextRank 算法抽取Top200的普通名词(n)和地名(ns)关键词:

时候 简书 朋友 文章 大家 交友 时间 大学 文字 故事 简友 感觉 老师 我会 爱情 学校 专题 世界 职业 人生 投稿 电影 地方 有点 作者 城市 东西 同学 学生 树洞 地点 经历 事情 照片 读书 孩子 问题 专业 毕业 性格 姑娘 北京 校园 交流 小说 昵称 女生 上海 摄影 手机 内心 女孩 中国 个人 梦想 星座 父母 名字 男生 音乐 青春 年龄 家乡 时光 感情 文学 对方 文化 样子 无法 公司 美丽 素材 文艺 社会 记录 哥哥 灵魂 妈妈 单身 美食 日子 家庭 回家 情书 平台 心情 关系 结果 性别 原因 能力 眼睛 方面 咖啡 编辑 唱歌 游戏 评论 小时 现实 画画 声音 小时候 历史 姐姐 情感 理想 方式 跑步 男人 想象 凡人 图书馆 内容 时代 见面 大赛 身体 衣服 宿舍 嘉宾 女人 总会 公众 风景 学会 陌生 兴趣 基本 学历 精神 成都 先生 好友 校友 习惯 作品 教室 艺术 思想 小学 男朋友 线下 联系 社群 武汉 家人 信息 模样 礼物 世间 长大 味道 陌生人 广州 父亲 朋友圈 印象 机会 女性 体重 空间 妹子 玫瑰 记忆 婚姻 人们 重庆 热情 杭州 计划 情况 读者 男孩 西安 小伙伴 励志 会员 少女 火车 体验 深圳 幻想 人物 陪伴 情绪 人家 意义 室友 大学生 国家 女孩子 山东 状态 程序员 天空 链接 思维 标准

可以看出确实提供了更为丰富的信息。原本想以文章内容为语料,用gensim训练word2vec看看上述词语的词向量分布情况,但没成功,只能后续再去好好搞搞。


百度云AI-中文词向量

不过找中文词向量的实例与配图时,看到了百度云AI的自然语言处理技术的API文档,于是免费注册后,直接调用词向量表示接口获取相应中文的词向量。

# pip install baidu-aip
from aip import AipNlp

""" 你的 APPID AK SK """
APP_ID = '你的 APP_ID'
API_KEY = '你的 API_KEY'
SECRET_KEY = '你的 SECRET_KEY'
client = AipNlp(APP_ID, API_KEY, SECRET_KEY)

word = "张飞"
""" 调用词向量表示 """
data = client.wordEmbedding(word);
w
print(data)

其中每个词语均被表示为1024维的向量(维度是不是有点高?之前看到的都是几百维的),再用t-SNE可视化高维词向量数据。先来看看降维至2维时的效果,大部分都分布在一起,没有想象中语义相关、相似的词语聚集在一起,不太相关的分散较远的效果,可能是百度云AI训练word2vec所用的语料不够相关所致?


word2vec t-SNE 2D

降至3维,依旧效果不佳,“哥哥”、“姐姐”两个词分散的较远,也是有些摸不着头脑,但发现“哥哥”--“女人”与“男人”--“姐姐”这两组距离上似乎较为接近......不可描述、不可描述......


word2vec t-SNE 3D.JPG

2.3 LDA主题模型

接下来我们看看所有文章都涉及了哪些主题,由于共有2700余篇文章,一篇篇查看是不太可行的,这就需要用到主题模型了。每篇文章(文档)都可以看成由若干主题组成,每个术语或单词可以分配给某个主题。

LDA(Latent Dirichlet Allocation)是一种文档主题生成模型,包含词、主题和文档三层结构。

主题模型

由于背后数学原理较为复杂,此处略过(其实是我也不会),感兴趣的可自行阅读:LDA数学八卦

先用词袋模型提取语料库中高频的单词,再用gensim进行LDA建模后,然后打印10个主题,每个主题前6个单词。看到结果时有些懵逼,不知道什么情况,每个主题基本都重复了。这里先顺带说下,虽然LDA名为主题模型,但每个主题并非真的就是“娱乐”、“体育”、“经济”等一般意义上的主题、话题,而且主题个数并不知晓,需要具体案例具体测试:

0.005*"简书" + 0.004*"喜欢" + 0.004*"一个" + 0.003*"文章" + 0.003*"没有" + 0.002*"生活"
0.015*"一个" + 0.011*"喜欢" + 0.007*"没有" + 0.005*"朋友" + 0.005*"知道" + 0.005*"现在"
0.009*"一个" + 0.005*"一起" + 0.005*"喜欢" + 0.004*"很多" + 0.004*"知道" + 0.003*"生活"
0.006*"一个" + 0.006*"喜欢" + 0.004*"没有" + 0.004*"知道" + 0.004*"觉得" + 0.003*"一起"
0.014*"喜欢" + 0.012*"一个" + 0.005*"知道" + 0.004*"没有" + 0.004*"希望" + 0.004*"一起"
0.014*"一个" + 0.012*"喜欢" + 0.011*"没有" + 0.007*"知道" + 0.006*"一起" + 0.004*"觉得"
0.029*"喜欢" + 0.010*"一个" + 0.007*"一起" + 0.006*"没有" + 0.005*"希望" + 0.005*"简书"
0.011*"一个" + 0.008*"脱单" + 0.007*"没有" + 0.006*"凡人" + 0.005*"喜欢" + 0.005*"知道"
0.006*"一个" + 0.006*"喜欢" + 0.005*"没有" + 0.003*"觉得" + 0.003*"希望" + 0.003*"一起"
0.009*"一个" + 0.009*"树洞" + 0.008*"投稿" + 0.008*"喜欢" + 0.008*"没有" + 0.007*"知道"

之后在LDA建模时加了个参数passes=15,再打印10个主题,各前6词语,效果有所改进:

0.007*"小贤有" + 0.001*"岳父" + 0.001*"咚咚" + 0.001*"梧桐" + 0.001*"大冬" + 0.001*"敲门砖"
0.028*"喜欢" + 0.012*"一个" + 0.011*"简书" + 0.009*"文章" + 0.007*"朋友" + 0.007*"没有"
0.018*"一个" + 0.012*"喜欢" + 0.008*"没有" + 0.007*"知道" + 0.007*"一起" + 0.006*"生活"
0.012*"脱单" + 0.011*"喜欢" + 0.008*"凡人" + 0.008*"一个" + 0.005*"工作" + 0.005*"生活"
0.008*"程序员" + 0.006*"打一" + 0.002*"技术" + 0.002*"骗子" + 0.002*"向云" + 0.002*"婚姻"
0.013*"活动" + 0.008*"交友" + 0.006*"专题" + 0.006*"简书" + 0.005*"作者" + 0.004*"时间"
0.006*"兔子" + 0.005*"先生" + 0.005*"亲爱" + 0.003*"回答" + 0.003*"小贱" + 0.002*"十分"
0.008*"老师" + 0.004*"同学" + 0.003*"学校" + 0.003*"一个" + 0.002*"旅行" + 0.002*"飘飘"
0.008*"一起" + 0.007*"没有" + 0.007*"一个" + 0.006*"喜欢" + 0.005*"同学" + 0.005*"校园"
0.013*"树洞" + 0.013*"投稿" + 0.010*"一个" + 0.010*"知道" + 0.010*"没有" + 0.009*"简书"

再是将词袋模型换成Tf-Idf模型,即不仅给单个文档中出现频率高的词语高权重,并且给在诸多文档中都常出现的词语以低权重。同样LDA建模后打印10个主题,前6词语,可以看到效果还是蜜汁尴尬,后续还需改进:

0.001*"婆婆" + 0.000*"树洞" + 0.000*"投稿" + 0.000*"打一" + 0.000*"欢欢" + 0.000*"作者"
0.002*"树洞" + 0.001*"投稿" + 0.001*"匿名" + 0.001*"账号" + 0.001*"场地" + 0.001*"来源于"
0.001*"树洞" + 0.001*"喜欢" + 0.001*"投稿" + 0.000*"一起" + 0.000*"大学" + 0.000*"没有"
0.000*"学校" + 0.000*"喜欢" + 0.000*"简书" + 0.000*"没有" + 0.000*"朋友" + 0.000*"投稿"
0.001*"喜欢" + 0.000*"比较" + 0.000*"希望" + 0.000*"简书" + 0.000*"公司" + 0.000*"朋友"
0.001*"树洞" + 0.001*"投稿" + 0.000*"匿名" + 0.000*"账号" + 0.000*"场地" + 0.000*"来源于"
0.001*"校友" + 0.001*"凡人" + 0.001*"校园" + 0.000*"脱单" + 0.000*"喜欢" + 0.000*"活动"
0.000*"孩子" + 0.000*"喜欢" + 0.000*"知道" + 0.000*"没有" + 0.000*"工作" + 0.000*"文字"
0.001*"树洞" + 0.001*"投稿" + 0.000*"喜欢" + 0.000*"烦恼" + 0.000*"一起" + 0.000*"倾诉"
0.001*"喜欢" + 0.001*"一起" + 0.001*"希望" + 0.001*"生活" + 0.001*"觉得" + 0.001*"知道"

2.4 人脸检测与颜值打分

接下来就是高潮部分了。在“简书交友”专题里,不少人都贴了照片,甚至有自拍照,因此,我从文章开头csv的数据里取出其中文章链接一栏,并对所有照片进行爬取并md5去重后,共计拿到9887张照片,共6.96GB。


照片一览

但这么多照片如何较好的浏览和查看呢,先是用上回图像检索(一):因缘际会与前瞻(又没填坑,惭愧)的技术,即用预训练的深度学习之图像识别模型提取1000余张照片的特征,再降维及可视化。虽然没有将相似照片聚集到一起,但也不失为可视化海量照片的一种方式,又或者可以拼接成照片墙,后续识别出人脸后就这样弄了。

1000张照片可视化

之后就是如何自动从这近万张照片中识别出人脸并筛选出颜值较高的小哥哥小姐姐了?

以前就留意过这方面的文章,原本想根据Python 爬虫 + 人脸检测 —— 知乎高颜值图片抓取一文实现下。但最近Python 抖音机器人,论如何在抖音上找到漂亮小姐姐?一文实在有些火,而且原作者提供了注册后的ID、KEY等参数,免去了自己注册的麻烦,于是在小小修改后直接用了起来,一些颜值打分的逻辑判断没修改,略有毛病,但大体能用。人脸识别并进行颜值打分,头像剪裁后统一存到一个文件夹,效果如下(侵删):

人脸识别、打分、剪裁

再是拼凑些照片墙(更多照片墙作品见于:
用python的PIL库轻松拼接一百张照片)看看,所有这些简友都是大概曾有交友意向的,除却一些乱入的表情包和名人外,差不多也是“简书简友”专题的人群画像了。

请在wifi或流量充足情况下查看(侵删)。至于这些人都是谁,都出现在哪篇文章中,为了不造成不必要的骚扰,自然是不可能告诉你们的:

人脸照片墙-1
人脸照片墙-2
人脸照片墙-3
人脸照片墙-4
人脸照片墙-5

三、收摊与小结

本文没有涉及太多代码,算是“纯享版”吧。要是有人感兴趣,后续会把对应代码放上来,来个“代码版/完整版”,不过考虑到贴到文章里既麻烦又冗长,可能会以jupyter notebook等格式丢到github。

标题提及“乱炖”数据,也是一开始就打算用到许多知道的技术,无论文本挖掘,还是图像处理,乱炖完的结果不知道大家看完后如何评价?

在本项目中也学到了些代码小trick,还是挺好玩的。文章不足之处有:挖掘的信息有些散乱,不成体系;Word2vec、LDA主题模型等部分还需要接着研究下,没有用NLP对文章中命名实体比如城市,职业等进行挖掘,后续可以试下;pandas还需要在练手和实战中熟练起来。此外想到海量照片可以用什么python库做成gif或小视频,方便自己或他人速览。

本文算是填了一开头讲到私信里的坑,不过上回图像检索的系列文章又没有动静了。但,这大概就是人生吧,逃......

PS:欢迎关注公众号:牛衣古柳(ID:Deserts-X),以及欢迎加QQ群:Python交友娱乐会所(613176398)哈。娱乐会所,没有嫩模。

Web note ad 1