@YELP NLP

YELP NLP (文本信息提取)

为了做研究,进了Yelp这个大坑。自己选的题,哭着也得搞出来… 感觉边写代码边记录下心得体会、下一步的构想等等有的没的,是个很好的整理思路的过程。所以我接下来会长篇累牍地写自己在做这个项目的过程中所遇到的问题和可能的解决方法。
挑来挑去,还是觉得CSDN的写博界面最友好,所以就在这里扎根啦。
哦!我的NLP! I am coming!

写在前面

我从Yelp 上收集了一些用户评论,现在希望从这些评论中提取出我想要的信息,特别是与用户的位置和社会网络相关的信息。目前,我设想的是训练一个分类模型,输入用户评论,输出0-1变量,告诉我这个评论中是否有我想要的信息。如果有的话,当然我可以继续深入下去,最终从模型中提取出这些信息。但是我现在想先从最简单的情况入手,只要模型能够告诉我输入项里是否存在我感兴趣的信息即可。目前,我还不知道具体怎么定义信息存在或不存在。我有的只是一个大致的想法。我知道我想要最终找到的句子是下面两类:

  • 关于位置的:
  1. This place is close to my place/home/apartment/work.
  2. I live close by. I live close by.
  3. This is a local restaurant. This is a local restaurant.
  • 关于社会网络的:
  1. I came with people from my work.
  2. I came to celebrate my birthday with my family. I came to celebrate my birthday with my family.
  3. This place was recommended by my boss/coworker. This place was recommended by my boss/coworker.

简单点说,我希望判断用户提交的评论中是否包含这样的信息,让我能够据此推测出他的住址/工作地址或社交情况。有可能这可以简化成一个关键词提取问题,但是我初步想了一下,感觉只是判断关键词是否存在似乎太简单了一点,模型的准确度可能很低,不过如果我最终想做一个分类模型的话,这无疑可以作为其中一个特征传进去。在关键词的选择上,我可能也需要多考虑一下。因为我的直觉告诉我,像apartment, home, work, coworker这样的关键词可能是比local, live, close等要更relevant一点。名词似乎更重要,但是只有这些名词也不行,因为我还需要知道这些名词的使用情景,只是告诉我他家的情况并不够,我希望他告诉我的是,他家住在附近,所以word embedding无疑是有必要的。但是more than embedding of any word, 也许我需要赋予我所关注的那些关键词的embedding更多的权重?我还需要再想一下细节,但是问题的关键应该就是关键词定位,并确定它们的使用情景。我之前有想过,用语言模型的方法来formalize使用情景,但是我看了相关文献,感觉也许embedding的想法更容易实现、效果也可能更好一些,毕竟网上已经有成型的实现embedding的工具了,而具体要定义什么样的语言模型、怎么定义,我还需要自己去摸索。后一种方式感觉吃力不讨好,工作量大不说,还存在不确定性,不知道效果怎么样。

我现在关注的虽然有两组信息,但是其实只要做出来其中一组的分类模型,第二组就会很容易了。我决定从位置信息入手,集中精力建一个能够work的位置分类模型。

建这个模型碰到的第一个问题是,到底是以句子为单位还是以整个评论文本为单位。其实我关注的应该是句子,但是如果要建以句子为单位的模型的话,我就需要有一个非常快的sentence tokenizer。而我初步试验了一下spaCy,它的performance完全跟不上我的需求。因为这个package里面附属了太多其他的东西,虽然我一把文本传进它的nlp model,就可以得到一个sentence list, 但是它同时也返给我很多其他我暂时不想要的东西,这些附属的功能现在看来就成了一个累赘,不必要的占用了资源。
事实上,我刚刚做了一下试验,估算了一下如果要用spacy给我所有的文本断句的话,需要大概10,000秒, 也就是166分钟,大概3个小时。这个时间倒也不是完全不能接受,但是转念一想,我现在还只有大概30万的用户评论。30万就已经需要这么久了,可以预见,如果我以后扩大样本量的话,光断句这个最basic的步骤就要花天长地久那么久,实在不合理。

所以我需要迅速的figure out 怎么能又快又好的实现断句功能。遇到这个瓶颈,是我之前没想到的。真正的战役还没开始,已然如临大敌了…

STEP 1.1: SENTENCE TOKENIZATION — Choosing the right tool

首先,我需要看一下除了spaCy之外,还有没有其他现成的performance 与 speed兼具的工具。简单google了一下,发现可用的python包有如下几个:

  1. spacy
  2. nltk
  3. coreNLP
  4. sentence-splitter 1.4

接下来我需要比较这几个包在sentence tokenization 方面的表现。

在速度方面:

我利用batch_size = 500, num_batch = 5的小样本试验,估算不同程序完成对现有全部数据(342970条reviews)进行断句所需要的时间。以下是估算时间的均值和方差。

Table 1. Estimated Processing Time

mean(估算时间) std(估算时间)
spaCy 9281.36s 433.35
NLTK 74.56s 15.69
coreNLP 2329.33s 521.74
sentence_splitter 1.4 395.54s 10.72

可以看到,最快的是NLTK,最慢的是spaCy. sentence_splitter和coreNLP属于中等。但是我估计NLTK的效果应该很差,因为我稍微追踪了一下断句数就发现,NLTK生成的句子数量明显少于spaCy。

在质量方面:断句量

这是我比较断句质量的其中一个指标 – 给定文本,不同包进行断句处理后,生成的句子数量。多数情况下,断句量大的效果更好,但也不绝对。很多时候,断句的难点就在于需要选择性地跳过某些形似断句点的地方,比如称呼和缩写 — Dr. Chen, M.D., U.S.A。这些短语中存在句点,但它并不是句子的终结,而只是一种表示省略的方式。如果错误的把它们当成句点,就会把本属于同一句的两个部分拆开。这种情况下,断句量会与断句效果成反比。
但是,这个问题算是断句问题中的经典难题了,大部分现有的模型都能够很好的规避它。在当前这个发展阶段,断句错误更多的集中在处理不规则的网络文本时,文本中可能出现一些奇奇怪怪的句点,甚至没有标点符号。人们在网络上打字,一方面比较随意,另外一方面也可能受手机键盘的影响,经常会省略标点符合,以空格代替。这种情况下,如何进行断句,是一个新问题。也正是由于这个问题的出现,我才特别关注断句量,因为不正确的断句模型会严重低估句子数量。从我所做的实验来看,这也正是很多现有工具的局限所在。

我所做的实验室,给定1000条reviews和任意两个断句模型A和B,计算有多大可能模型A给出的断句量会大于模型B,反之亦然。我现在先不管正确的断句结果应该是怎么样的,或者说哪个模型给出的判断更合理,这些都需要我们根据不同文本进行详细的分析。我现在只想知道,有没有哪个模型会系统性地断出更多或者更少的句子。对于这个比较问题,我对两个变量感兴趣。首先,我想知道,有多大可能,两个模型给出的断句量正好相等。一般来说,断句量相等就意味着断句结果一致,虽然也不总是如此。这是一个简化的假设。另外一方面,我也想知道,在那些不相等的情况下,哪个模型更有可能得到更多的断句。

Table 2. Count of Sentences: A Comparative Case

spaCy NLTK coreNLP sentence splitter
spaCy (>) # 290/322 265/288 315/315
NLTK (>) 32/322 # 46/92 117/133
coreNLP (>) 23/288 46/92 # 103/113
sentence splitter (>) 0/315 16/133 10/113 #

最终的结果以二维矩阵的形式来展示。每一行中各格都有两个数字,前一个数字表示在1000次实验中,该格对应的行模型断句量大于该格对应的列模型所给出的断句量这一情况所出现的次数,后一个数字则表示这两个模型给出断句量不相等的次数。
从这个表,我们可以看出,在不同模型的两两对比中,有两个特征特别明显:

  1. spaCy断出的句子系统性地多于其他模型;
  2. 在NLTK, coreNLP 和 sentence_splitter之间,NLTK和coreNLP的断句情况高度一致,而二者的句子数量也显著多于sentence_splitter.

因此,从断句量的角度来看:
spaCy>NLTK≈coreNLP>sentence_splitterspaCy > NLTK \approx coreNLP > sentence\_splitterspaCy>NLTKcoreNLP>sentence_splitter

之前说过,断句量只是一个粗略的指标,要想直接比较不同模型的断句质量,我们还必须直接审视断句结果,检查其中是否存在不合理断句的情况。

在质量方面:句子本身

由于这一步比较花时间,我只选择性地比较两个模型的结果。我不再考虑sentence splitter, 因为这个程序不光表现不够好,在运行的时候还存在bug. 考虑到NLTK和coreNLP的结果高度一致,而NLTK显著快于coreNLP,所以在这二者之间,我选择了NLTK。

我所做的实验是:给定50条reviews,手动检查spaCy 和 NLTK 给出不同断句数的情况。

在这50条中,两个模型断句数不同的有17条。
一看具体的断句情况就能发现,之所以spaCy的断句量会显著高于其他模型,是因为它更偏向于shorter sentences。当句子出现可断可不断的时候,spaCy一般都会选择断,比如

原句是:

HORRIBLE … incredibly HORRIBLE .

spaCy就把它断成了两句,而NLTK则把它当成一句。

更明显的一个例子是:

worst service ever!!! the pizzas took 2 hrs to deliver and when i called the girl over the phone told me thats it was on its way but that it was taking long because of the rain but i live a block away … she was really rude and literally told me " can u just fucking wait" and hang up on me … they just dont give a fuck … and the delivery guy had the guts to ask why i didnt tip him … sticking with pizza hut

这个句子中没有句号,只有省略号,所以NLTK完全没有断句,而spaCy则断成了5句。

  1. worst service ever!!!
  2. the pizzas took 2 hrs to deliver and when i called the girl over the phone told me thats it was on its way but that it was taking long
    because of the rain
  3. but i live a block away …
  4. she was really rude and literally told me " can u just fucking wait" and hang up on me …
  5. they just dont give a fuck … and the delivery guy had the guts to ask why i didnt tip him … sticking with pizza hut

这个例子非常重要,因为我们在段落中发现了表示位置的句子,“but i live a block away…"。

这正是我想在成千上万的reviews中找到的关键性信息,而显然只有spaCy把它单独分割出来了。这样单独成句的好处是:

  1. 在后续的建模过程中,我们能够更容易的定位出关键句和关键词;
  2. 更重要的是,在短小精悍的句子中,关键性的信息能够更容易的被分类模型pick up. 如果传入模型的是NLTK给出的一整个段落,那么相关关键词的出现对分类结果的影响就会被冲淡。当然我们可以在后续的建模过程中考虑到这一点,人为地提高关键词的权重,或者为false positives设定更高的loss function,但是总的来说,肯定是在不改变句意的情况下,句子越短做出的判断越准确的。

找到这个重要例子之后,我决定再拿它在sentence_splitter上试验一下。sentence_splitter的断句结果与NLTK一样,没有能够成功的断句。

这让我决定,目前还是用spaCy来断句。之后如果出现了performance太差的问题,再模仿spaCy,单独训练自己的sentence splitter。

这样一来,我预计需要花三个小时,将所有的reviews都断成sentences,另存为sentences.txt,之后才能进行正式的实验部分。这个断句程序写起来非常容易,但是我需要特别考虑如何更好地实现sentences与reviews之间的对应。给定一个sentence, 我如何能够迅速的确定,它来自哪一条review?


Note:

我在测试sentence_splitter的时候,发现这个包和spaCy有冲突。在同一个程序中调用这两个包中的函数,sentence_splitter会返回“_regex_core.error: unterminated character set at position 91”。这个问题,github有另外一个用户已经反映过了,不过好像并没有得到开发者的回答。[link]

为了解决这个问题,我不得不在测试的过程中将基于sentence_splitter的处理单独拎出来,通过文本在不同的程序之间传递结果。非常坑… 最后写了两个程序: “splitter_time_estimate.py”里包含了估算时间和单独处理sentence_splitter的函数,“splitter_sentence_length.py”里包含了基于其他几个模型比较断句量的函数。

写在最后:

虽然走了一大圈,比较了各种工具,最后还是决定用spaCy来断句,但我并不觉得之前做的这些工作是毫无意义的。这些工作让我更加确定了,断句模型在处理网络文本时的难题在哪里,这为我在未来开发自己的断句模型提供了新思路。也许最大的挑战不是像教材所说的,判断不同的标点符号是否标识着一个句子的结束,而是要在完全没有标点的情况下仍然能够正确地断句。这有点像是文言文了,文本本身没有句点,但是我们仍然可以人为地加入一些句点,让文本结构和逻辑更明确。解决了这个问题之后,我们能得到的将不仅仅是一个断句模型,更是一个加减标点模型。在网络空间中,保证标点的正确使用,不正是一个重要的挑战吗?特别是在使用手机的时候,从字母表键盘跳转到标点符号键盘再跳回来,本身就非常不方便。如果有一个程序,可以自动地给文本加标点,在手机上打字的用户体验就会更好。这也会提高语音识别文本的可读性。当然,很多现有的程序已经能够做到这一点了,比如输入法,到了恰当的地方都会自动推荐标点符号,但是准确度如何,就不好说了。至少,到目前为止,我还没有在NLP的文献中看到有任何论文明确地讨论过这个问题的。不过,也可能是我见识浅薄吧…

Anyway, STEP 1.1 正式告一段落。
下一步是,SENTENCE TOKENIZATION WITH spaCy。

YELP NLP 文本信息提取项目相关推荐

  1. YELP NLP 英文文本断句

    @关于Yelp NLP Project的介绍和问题设定 STEP 1.2: SENTENCE TOKENIZATION WITH spaCy 查了一些资料之后,我决定将reviews 和 senten ...

  2. nlp文本数据增强_如何使用Texthero为您的NLP项目准备基于文本的数据集

    nlp文本数据增强 Natural Language Processing (NLP) is one of the most important fields of study and researc ...

  3. nlp文本相似度_用几行代码在Python中搜索相似文本:一个NLP项目

    nlp文本相似度 自然语言处理 (Natural Language Processing) 什么是自然语言处理? (What is Natural Language Processing?) Natu ...

  4. 【NLP】GitHub 上有哪些有趣的关于 NLP 的Python项目?

    知乎上有人提问:GitHub 上有哪些有趣的关于 NLP 的Python项目? 先来说说什么是NLP? 自然语言处理(NLP)的重点是使计算机能够理解和处理人类语言.计算机擅长处理结构化数据,如电子表 ...

  5. NLP文本分类大杀器:PET范式

    作者 | 周俊贤 整理 | NewBeeNLP 之前我们分享了NLP文本分类 落地实战五大利器!,今天我们以两篇论文为例,来看看Pattern Exploiting Training(PET)范式,可 ...

  6. 学NLP不懂这个项目?快别去秋招了,你HOLD不住的!

    秋招马上来了!offer还会远吗! 事实上,时至7月,一大批AI招聘岗位已然强势来袭! 例如某大厂: 是的,你与秋招的距离已经越来越近, 那么你与算法offer的距离又是多远呢? 是不是真的可以&qu ...

  7. 斯坦福NLP名课带学详解 | CS224n 第15讲 - NLP文本生成任务(NLP通关指南·完结)

    作者:韩信子@ShowMeAI,路遥@ShowMeAI,奇异果@ShowMeAI 教程地址:https://www.showmeai.tech/tutorials/36 本文地址:https://ww ...

  8. NLP——语料库信息提取和处理方法

    NLP--语料库信息提取和处理方法 本文以搜狗新闻语料为例,记录文本语料的收集.读取.处理等一整套的方法,主要是为了排排坑. 文章目录 NLP--语料库信息提取和处理方法 前言 一.语料下载 二.文件 ...

  9. 直播实录|百度大脑EasyDL是如何帮助NLP文本提升标注效率的?又如何进行复杂文本分类的?

    百度大脑EasyDL是如何帮助NLP文本分类用户提升标注效率的?业界领先的文本分类智能标注产品效果如何?在百度产品经理夜巡的带领下,你将会学习到EasyDL专业版文本分类模型最新上线的智能标注功能的具 ...

最新文章

  1. 企业如何突破增长瓶颈?
  2. 26.使用ajaxSetup()方法设置全局Ajax默认选项
  3. ISA2004发布应用程序服务器
  4. vscode中调试react
  5. k8s控制器:DaemonSet
  6. C#LeetCode刷题-并查集
  7. 如何通过虚拟私有云保障服务安全【华为云分享】
  8. matplotlib绘制K线图
  9. java入学测试_算法历练之路——入学考试(JAVA)
  10. Web SCADA 电力接线图工控组态编辑器 1
  11. 最新!CVPR2020 最新论文下载!
  12. 14届数独-真题标准数独-Day 4-20220119
  13. 免费抽奖---PMP续证PDU | PMP知识地图.
  14. 影响职场升迁的小动作
  15. Java阿拉伯数字转换为大写数字
  16. 腾达路由器连接移动路由器,做WIFI信号延申
  17. 大数据开发工程师到底是干嘛的?日常做什么呢?
  18. 线上学习老师或者学习委员如何收集作业(进来的同志都体会到收作业的苦衷!尤其是学委!通过学习通方法)学委必须要会!
  19. 激活黑群晖Synology Active Backup for Business,黑群晖系统备份软件激活,亲测有效
  20. Word中的图片设置嵌入式之后显示不全问题

热门文章

  1. mysql case多个关键字 使用and 或者in()
  2. 在非洲运营互联网系统-系统研发历程(上)
  3. 深入理解计算机系统|Attack Lab
  4. S5PV210 WM8960音频驱动 学习
  5. 视频教程-基于深度学习的计算机视觉: 原理与实践 (下部)-计算机视觉
  6. 【问题集合】VDP2019虚拟现实设计平台常见问题集合
  7. 算法笔记_048:找零问题(Java)
  8. PDF转换成Word图文教程
  9. More Effective C++之类型转换
  10. gitlab 构建tag_Gitlab+Harbor+Jenkins pipeline实现利用tag部署docker容器