不幸的人各有不幸吗?文本分析流浪汉乞讨标语牌后发现的套路(附代码)

简介:


流浪者惯用一张手写标语牌来表达自己,我们对数百名纽约街头流浪者手中的标语做了文本分析,想看看他们希望传达的声音。


纽约的无家可归者普遍使用两种乞讨方式:一种是在十字路口的角落或地铁站与站之间的车厢里反复唠叨他们的困境,这种方式在要到一点小钱的同时也会招致周围游客的厌恶。另一种方式是举一个纸质标语牌,在上面写上他们要说的话。


标语牌显然更具优势。因为相比于口头表述,文字扫一眼更快,增减更灵活并允许他人自由选择看或不看。不幸的是,我们大多数人路过乞讨者时都会选择忽视那些标语牌。这种行为是最方便的,也是最现实的。毕竟在纽约有超过6万名乞讨者,关注他们每一个似乎不是很现实。


所以,假设你平时并没有注意这些标语牌,你觉得他们一般都写了些什么?

 

上图:在谷歌上输入词条“纽约无家可归者的标牌”后给出的搜索结果

 

弄明白纽约无家可归者标语牌上

文字内容的第1步

 

事实上,搜集和转录这些数据就够写一篇博客了,这里只做一些概括性的描述。首先在google、推特和Instagram (一個免费提供在线图片及影片分享的社交应用)上搜索“New York City homeless sign”或类似的词条,你会得到几百张来自新闻报道、社交媒体的贴文和个人摄影的可用照片。


但是这些标语牌往往难以转录。因为这些照片一般质量较差,没有聚焦,或是拍摄角度太偏。即使一个标语牌的文字完全清晰可见,也会存在一些其他问题。如乞讨者可能会使用一些特殊(经常是错误)的拼写、标点符号、换行符和手写字体。有时他们所表达的信息并非简单一句话,而是几乎没有任何线索连接成句的各种想法。

 

#nychomeless#homeless#heraldsquare

上图:例举纽约无家可归者写的一句有语病的句子


些标语可能有凌乱、想法模糊的特点,这些会造成转录困难。


我们可以使用一些修正标准来规整文本内容,以方便进一步描述和分析,例如纠正一些简单的书写错误和使用完整拼写代替符号表述(“4” 换成 “for”, “+” 换成 “and”)。我们再使用R语言提供的文本挖掘包忽略掉大小写、换行符和其他标点符号之间的不一致,最终得到标准化的数据。


汇集了244条标语用于文本分析

流浪者们的声音


最后,我们汇集了244条标语用于文本分析(数据集链接:https://github.com/PerplexCity/Sign_From_Below/blob/master/transcribed_signs.csv)对于文本挖掘而言,244条文本的语料库相对来说较小。通常,《战争与和平》这样大块头的书或推特上百万条的文本才会以下面的方式进行分析。然而,我们还是找到了合理可信的规律。


幸福的人都是相似的,不幸的人则各有各的不幸。尽管如此,通过对这几百条标语进行筛选,我们还是可以发现,乞讨者想要通过标志牌说服他人所采用的几种固定套路:大部分情况下他们会把自己描述成更值得同情的对象,例如怀孕的母亲,退伍的军人,或抢劫受害者。有些人会尝试一些小聪明(我打赌你看了这句话会留下1美元),其他的则比较典型(我和老虎伍兹有一段绯闻,看看我现在的下场)。


通常他们会先一步回答你的疑惑。如:为什么他们没有家?(丈夫去世、没有保险、丢失一切、无家可归、你能帮帮我吗、上帝保佑你、感恩节快乐)。为什么他们不去其他地方?(需要一张车票、赚得35美元去新泽西州大西洋城、那里我有地方住并且有一个工作机会)。


虽然有很多奇闻轶事,但这是一个数据博客,所以我们需要数据来说明问题。


前25个出现频率最高的单词


上图:纽约无家可归者的标牌上使用频率最高的25个单词


如上述词频表所示,无家可归者的优先表述是寻求帮助(“help”)和表明自己无家可归(“homeless”),并始终保持礼貌(“please”)。


在文本挖掘中,像“and”或 “the”一类的常见词经常会被去掉,因为他们会稀释整个高频词汇表。有趣的是,在这个样本中这些词并没有被去掉,但竟也没有排到我们词频表的最前面。这说明两个问题:首先,无家可归者不太可能会去使用这些如此容易被预测到的词,可能是为了节省空间和提高浏览速度;其次,这也表明无家可归者使用“help” 和 “homeless”这些词的频率非常高,正如一般的文本使用“the”(4%)这类普遍的术语一样。


你可能会把上图的y轴看作是独立的一些单词,但是也可以把他们看作是一元语法(unigrams,比如大数据的unigram形式为:大/数/据),或者是N元语法(n-gram,语言学专业术语,表示n个单词组成的序列)的最简单形式。我们可以对二元词(bigram,两个单词组成的短语)的频率进行排序,如下:


【由于我们不能使用bigrams(双单词)的频率除以单词数量得到相对频率,所以x轴向左对齐表示绝对频率】


可以看到,第一个图表中一些单词的搭配在了上图中聚集到了一起。比如,“Please” 和“help”使用很频繁,它们联合在一起使用也很频繁,类似的还有“God” 和 “bless”。


需要注意到是,这种创建二元词(bigrams)、三元词(trigrams)和其他多元词的方式是根据原有文本来模拟产生新文本的基础。我们也可以尝试随机选择一些词来伪造一个自然的句子,通过这种方式得到的句子读起来跛脚可笑。但是如果你知道哪些序列是合理的,你就可以拼凑出短语和句子,就像拼火车一样。


一个简单的例子,假如你使用“please”作为开头,二元词(bigrams)频率表能预测下一个单词“help”,然后你可以连接到“thank,” “you,” “God,” 和 “bless”,即马尔可夫文本生成链,它是网络机器模仿人类写作的原理。


多元词(n-gram)的单词数越多,模拟的写作看起来就越接近于人类,因为你使用的基于真实文本的片段单元更长。下图是在无家可归者标语样本上使用trigrams生成短句的示例。其中一些结果看起来毫无意义,但其他的你能想象到或许是来自某个真实的标语:


上图:无家可归者标语模拟结果的截图


呃,这里我们使用这些标语生成假文本似乎玩笑开得有点过了,毕竟现在纽约及其他城市无家可归还是一个很严重的问题。我们的分析就到这里了。如果你对文本挖掘很感兴趣,并且想要进一步了解Andrey Kotov的这个项目或者其中使用的R语言知识,两者都提到了本文。你也可以查看博客使用的分析数据和程序,链接在文章的最后。


最后,如果你想要帮助这些无家可归的人,可以捐款给Bowery Mission,它为纽约的流浪者提供住所、食物和衣服。

原文发布时间为:2017-02-05

本文来自云栖社区合作伙伴“大数据文摘”,了解相关信息可以关注“BigDataDigest”微信公众号

相关文章
|
存储 缓存 算法
【OSTEP】分页: 快速地址转换(TLB) | TLB命中处理 | ASID 与页共享 | TLB替换策略: LRU策略与随机策略 | Culler定律
【OSTEP】分页: 快速地址转换(TLB) | TLB命中处理 | ASID 与页共享 | TLB替换策略: LRU策略与随机策略 | Culler定律
545 0
|
Linux 内存技术
U-BOOT小全(六):BootLoader源码(UBoot-Kernel 1)
U-BOOT小全(六):BootLoader源码(UBoot-Kernel 1)
240 0
|
24天前
|
人工智能 自然语言处理 数据可视化
2025年适合大型企业的BI产品及企业高效运用BI工具指南
本文将聚焦适合大型企业的BI产品选型,深入解析主流产品优势,并结合实践经验探讨企业如何用好BI工具,为各行业企业提供专业参考。
|
存储 供应链 分布式数据库
深入理解区块链技术:原理、应用与挑战
本文旨在探讨区块链技术的基本原理、主要应用及其面临的挑战。通过分析区块链的分布式账本技术、加密算法和共识机制,我们揭示了其如何在无需中心化权威的情况下确保数据的不可篡改性和透明性。此外,文章还讨论了区块链在金融、供应链管理、智能合约等领域的应用案例,并指出了当前区块链技术面临的可扩展性、隐私保护和法律监管等挑战。通过对这些内容的深入分析,我们希望为读者提供一个全面而深入的区块链技术概览。
1662 16
|
9月前
|
存储 弹性计算 安全
课时23:案例分享——钉钉
钉钉作为企业级产品,采用SaaS平台技术,依托阿里云的ECS、OSS等服务,实现快速部署与客户需求的高效适应。其数据存储于阿里云RDS中,确保安全性和可靠性,并通过高强度加密保障信息传输安全。阿里云的安全防护措施为钉钉提供了坚实后盾,使其能专注于优化和创新,提升用户体验。
308 0
|
前端开发 JavaScript Java
【SpringBoot系列】视图解析器的搭建与开发
【SpringBoot系列】视图解析器的搭建与开发
252 0
|
前端开发 JavaScript
JS-instanceof 的实现原理
`instanceof` 运算符在前端 JavaScript 中用于检测对象的原型链是否包含指定构造函数的 `prototype` 属性。它通过遍历对象的原型链来实现。每个对象都有一个内部链接 `[[Prototype]]` 指向其原型对象,当访问属性或方法时,JavaScript 引擎会沿着原型链查找。`instanceof` 的具体实现是通过比较对象的原型链中的原型与构造函数的 `prototype` 属性,直到找到匹配的原型或到达原型链的顶端。示例代码展示了如何使用 `instanceof` 检查对象的继承关系。此外,`instanceof` 可用于验证继承关系和类型检查,支持多态性。
|
安全 C++
利用信号量实现线程顺序执行
【8月更文挑战第25天】信号量是多线程编程中用于控制共享资源访问的关键同步机制,能有效保证线程按预设顺序执行。实现方法包括:引入相关头文件(如 C++ 中的 `<semaphore.h>`),创建信号量并通过 `sem_init` 设置初始值;在各线程函数中运用 `sem_post` 与 `sem_wait` 来传递执行权;最后,通过 `sem_destroy` 销毁信号量以释放资源。使用过程中需注意错误处理、确保线程安全及合理设定信号量初值,以维持程序稳定性和高效性。
209 1
|
自然语言处理 监控 自动驾驶
大模型在自然语言处理(NLP)、计算机视觉(CV)和多模态模型等领域应用最广
【7月更文挑战第26天】大模型在自然语言处理(NLP)、计算机视觉(CV)和多模态模型等领域应用最广
1142 11
|
存储 关系型数据库 MySQL
MySQL中利用存储过程实现循环批量建表
MySQL中利用存储过程实现循环批量建表
11413 1