苹果企业社会责任报告的情感分析
R 中的情感分析简介
你曾经想了解一份报告试图传达的语言或语气的类型吗?
有数百万的报告、文章、网站、书籍等。这个过程允许用户更快地理解焦点的主要主题,而不需要深入文本。
从本教程开始,您需要具备使用 R Studio 的初级/中级工作知识。如果你没有访问我的其他帖子来了解更多—R 中的文本分析
文件
访问苹果(或任何其他网站)获取其 2019 企业社会责任 (CSR)报告。我更喜欢阅读文本格式的数据。
下面是我为准备加载到 R Studio 中的文件所做的工作。
- 全选—突出显示文档中的所有内容
- 复制和粘贴—将整个报告粘贴到您计算机上的文本文件应用程序中。(Windows —记事本和 Macs 文本编辑器)
- 将文件保存到您的工作目录中,或者记住您的文件位置。
如果你在这一步遇到困难,请下载我的apple . txt文件。
图书馆
library(textreadr)
library(tidytext)
library(stopwords)
library(dplyr)
在文件中读取
如果你没有把你的工作目录设置到和你的 Apple.txt 文件相同的位置,那么你需要粘贴完整的路径。如果您已经设置了工作目录,下面是代码。
apple <- read_document(file="apple.txt")
设置数据框架
我们需要采取三个步骤来准备好数据帧。
- 将我们加载的文件转换成数据帧
- 将列名重命名为“text”(这将有助于我们以后的工作更轻松)
- 将数据帧转换成字符,这样我们就可以使用文本分析
**#setup the dataframe** apple_df <- as.data.frame(apple)**#rename column to text** colnames(apple_df) <- c("text")**#convert column type to character** ap_df <- data.frame(lapply(apple_df, as.character), stringsAsFactors=FALSE)
前 15 排。
情感库
现在我们已经准备好要分析的文本,我们可以使用任何 3 R 库。我们将使用 get _ opinions 函数来获得洞察力。
AFINN
来自芬恩·厄普·尼尔森,bing
出自刘兵和合作者,以及nrc
赛义夫穆罕默德和彼得特尼。
要使用情感函数,我们需要对单词进行标记,同时过滤掉停用词。
标记化是将每个单词分离出来的过程,使每个单词成为一个独立的点用于分析。例如,使用标记化,句子“棕色狐狸跳了”,将是“the”、“brown”、“fox”和“jumped”
停用词将过滤掉报告中任何不必要的词,例如,“我”、“我”、“the”等。
阿芬
[AFINN](https://www.tidytextmining.com/sentiment.html)
词典给单词打分在-5 到 5 之间,负分表示负面情绪,正面评分表示正面情绪。
afinn_ap <- ap_df %>%
unnest_tokens(word, text) %>% **#tokenizing the dataframe**
anti_join(stop_words) %>% **#filtering out the top words**
inner_join(get_sentiments("afinn")) %>% **#getting the sentiment**
count(word, value, sort=T) **#sorting for most frequent words**
基于字数的前 10 个单词
堆
[bing](https://www.tidytextmining.com/sentiment.html)
词典以二元方式将单词分为积极和消极两类。按照同样的结构,我们可以得到对 bing 库的看法。
bing_ap <- ap_df %>%
unnest_tokens(word, text) %>%
anti_join(stop_words) %>%
inner_join(get_sentiments("**bing**")) %>%
count(word, **sentiment**, sort=T)
请注意我们的代码中有两件事发生了变化。第一个是加载了“bing”库。另一个变化是单词代替了值*** (Afinn 代码)。这是因为这两个图书馆以不同的方式标注他们的情感。***
必应最常用的 10 个词
我们可以看到 Bing 和 Afinn 的结果几乎相同。
(美国)全国科学研究委员会(National Research Council)
现在,我最喜欢的图书馆——NRC。[nrc](https://www.tidytextmining.com/sentiment.html)
词典以二元方式(“是”/“否”)将单词分为积极、消极、愤怒、期待、厌恶、恐惧、快乐、悲伤、惊讶和信任等类别。
同样,我们可以看到与前面的库类似的结构。
*nrc_ap <- ap_df %>%
unnest_tokens(word, text) %>%
anti_join(stop_words) %>%
inner_join(get_sentiments("**nrc**"))%>%
count(word, sentiment, sort=T)*
NRC 图书馆中出现频率最高的单词
有趣的是看 R 怎么把同一个词分成不同的情感类别。我们把资源*这个词归类为喜悦、积极、信任。*
后续步骤
既然我们有了从报告中获取情感值的基本想法,现在我们可以使用文本分析为更高级的技术做准备了。我将发布一个后续教程,深入研究 r 中的 wordcloud 分析。
辅导的
如果你想更多地练习 R 中的文本分析,可以看看我的其他帖子。
资源
社交媒体上低资源语言的情感分析
进入真正的语言混乱的 NLP 之旅
最近,社交媒体风暴席卷了整个世界,它赋予了每个连接到互联网的人在地球上任何时间任何地点公开表达意见的特权。由此产生的互联网上流行的有意见的文本为数据科学研究和行业提供了一个挖掘这些数据进行情感分析的机会,这是一种快速人工方法,用于衡量大众对产品、新闻、事件和政策的意见,其中每条文本都会自动分类为积极、消极或中立。
然而,将单词分类为情感类别的复杂性因语言而异。它极大地依赖于语言资源的可用性和语言的自然稀疏性。例如,丰富的数字词典、语料库和带标签的数据集很好地推进了英语情感分析科学,但对于资源较少的语言,如阿拉伯方言口语,即我博士研究的更广泛领域,则没有那么好或那么快。
词汇稀疏性
稀疏性是一种语言中单词的词汇数量,属于一种语言的单词的形式数量越多,该语言的稀疏性就越高:
稀疏度= ∑单词 x 形式【单词】
在英语中,屈折形式享受、享受、和衍生形式享受可以很容易地与积极情感词享受对应起来。对于形态丰富的语言来说,词形变化不仅限于时态和数,还包括主语、宾语、代词、阴蒂和性别。一个简单的例子是阿拉伯语中的爱حبّt11】一词;它可以屈折为我爱你(男性)* احبكَ 、我爱你(女性) احبكِ 、我爱你(复数) احبكم 、我们爱他们 احببناهم 、我们将爱你(复数) سنحبكم 在这条战线上达到 100 多个屈折。另一方面,源自一个词的词汇由前缀、中缀、后缀和音调符号组成,例如情感 محبة ,亲昵 تحابب ,合意 محبب ,优选 مستحب ,友好 متحاب ,有利 محبذ 所有都源自同一个词爱。*
背景来自 myfreetextures
“交一个在友谊中诚实的朋友,因为友谊的真诚在一个诚实的朋友身上”——未知。(所有名词都源于صدق 诚实)。
阿拉伯语的派生词法与三个字面量的单词非常和谐,只是太复杂了,无法通过词干分析器、词尾分析器或分词器进行分类。例如,单词استنكار 否认的行为可以映射成 11 个不同意思的单词:استنارانارسترستارسارسكركرتنكتنكرنكرنار。
如果没有一致的正字法,一种形态丰富的语言的词汇稀疏性会变得非常大,在这种情况下,一个单词的每种形式都可能有不同的拼写。拼写不一致对于纯口语的语言来说是常见的,这样,如果转录,就没有标准的拼写可以遵循,结果每个人在文本中以不同的方式表达他们的舌头。方言阿拉伯语就是这种情况,这是一种对4 . 2 亿本地人的每个地区来说都是深奥的阿拉伯语口语。不同地区的不同阿拉伯方言在词汇选择、解释、词法、发音和语速方面都有所不同,而且由于英语、法语、西班牙语、意大利语和土耳其语等外语在该地区历史上的影响,外来词也有所不同。
让-巴蒂斯特·希莱尔,耶尼·卡米伊和 i̇stanbul 港,18 世纪晚期
阿拉比齐
在大约 30 年前数字通信兴起之前,方言阿拉伯语一直被认为是一种口语语言,当时一种新的阿拉伯语变体 Arabizi 诞生了,Arabizi 是 Araby 和 Englizi 的组合,是我博士研究的主要重点。Arabizi 是一个非常非正式的拉丁脚本口语方言阿拉伯语转录。更不用说方言阿拉伯语在拼写上自然缺乏共识,阿拉伯人开始试探性地用一种不同语言的文字来映射他们的音素。这进一步扩大了正字法的不一致性,因为:
- 一个单词是根据它的发音来转录的,因此同一个单词的不同发音会有不同的转录:例如,在阳性 wordخير fine 中的一个字母元音音素ي /yā/发音为/y/KHāyr 或/eh/ kher,因此常见的是同一个单词既有 khayr 又有 kher 的转录。
- 关于如何转录不同的元音音素,没有一致的正字法。同一个单词的读音 khāyr 或 kher 可以被转录为 *kher、kheir、khair、kheyr、khayr、*或者甚至省略掉大部分或全部元音字母 khyr 。
- 在如何转录不同的辅音音素方面几乎没有一致性,例如在口腔的后舌音区发音的喉音حḥā’、خ·卡瓦、ع ᶜayn、غ·盖恩和喉塞音ء·哈姆扎。例如,来自同一个 wordخير khāyr 的خ Khā’在某些地区在某种程度上被标准化为复合字母 kh 或数字 5 甚至 7 '。这立即使 wordخير Khāyr 的拼写法数量增加了三倍。
因此,简单三字基 wordخير Khāyr 可能的正字法有: kher,kheir,khair,kheyr,khayr,khyr,5er,5eir,5air,5eyr,5yr,7’er,7’eir,7’air,7’eyr,7’ayr,7’yr。
现在很明显,词汇稀疏度的大小等于每个单词的屈折变化的数量乘以其可能的正字法的数量。
稀疏度= ∑单词 x(形态学 x 正投影)形式【单词】
代码转换
最后,词汇稀疏性以代码转换为顶点,将阿拉伯语与其他拉丁脚本语言混合,主要是英语或法语。几个地区的阿拉伯青年在说话时不断地在阿拉伯语和法语或英语之间转换;因为阿拉伯语是口语的转录,所以在他们的文本中看到这一点并不奇怪。在阿尔及利亚、摩洛哥和 Tunisia⁴,阿拉伯语和法语的混合很正常,在 Lebanon⁵和 Egypt⁶.,阿拉伯语和英语的混合也很正常语码转换可能发生在各部分使用不同语言的对话中,每个分句都使用不同语言的句子中,或者是断断续续使用语码转换词的句子中。这可以从黎巴嫩的一份《脸书邮报》中得到证明:
脸书会话中的语码转换
这种语码转换意味着阿拉伯语不是一种独立的语言,而是与其他语言紧密相连的。因此,为阿拉伯人解决自然语言处理(NLP)任务的努力,尤其是情感分析,需要与阿拉伯本地人在社交文本中使用的英语或法语单词和短语相集成。这就造成了两种语言之间的重叠,对词语歧义的另一个挑战,如诱饵 (بيت家)、该死( ضمن 投保或包含)、罚款( فيني I-can)、杀死( كل 凡)、或疯狂( انساني 人道)。
因此,词汇稀疏性变成了:
稀疏度= ∑单词 x(形态学 x 正投影)形式[单词] +(英语和法语)单词
为了弄清楚这能达到多大,我们需要先解决我的一个博士研究问题:
如何将阿拉伯语情感词与其屈折变体和正字法变体进行映射?
单词匹配
别忘了,阿拉伯语资源极其匮乏,我们没有起点,尤其是黎凡特方言。我们创建了带标签的数据集,并训练了一个语言识别器,从语码转换的脸书数据中汇编了一个包含 100 万条评论的阿拉伯语语料库。
我们在脸书语料库上训练了单词嵌入,由此语料库中的每个单词都被神经网络架构作为实数值向量投影到新的阿拉比齐嵌入空间中。然后,我们将余弦向量相似度与基于规则的方法相结合,从该嵌入空间中发现输入情感词的屈折形式及其拼写变体。
图片由作者使用神经网络背景
我们发现几乎每一个我们输入的情感词都有屈折和正字法形式,但令我们惊讶的是,有些词达到了 1K 多种形式!如字 i7tiram احترام 尊敬:
1,069 个表单匹配积极情感阿拉伯语单词 i7tiram(尊重)
情感分析
一个词的 1K+形式对情感分析意味着什么?
情感分析的基本技术是无监督和有监督的 approaches⁷,称为基于词典和机器学习的方法。
在基于词典的方法中,在预定义的正面和负面单词列表或具有情感得分的单词列表中搜索输入文本中的每个单词,凭直觉判断句子中正面或负面单词的数量决定了该句子的情感。这在很大程度上是正确的,但是它对缺乏情感词的肯定句或否定句无效,例如在讽刺或多词表达中。
在一种更智能的方法中,机器学习,一种算法通过从训练数据中学习来学习将输入文本分类为正面、负面或中性,这些训练数据是由人类注释者预先标记为正面、负面或中性的句子。为算法提供的训练数据越多,它在学习哪些模式、单词或单词共现导致正确的情感类别方面就变得越好。这种方法在对缺乏情感词的句子进行分类时应该表现得更好,但是创建大型数据集在时间和价格方面都非常昂贵。
非常大的词汇稀疏性挑战了这两种技术:
我们怎样才能创建一个包含所有形式的情感词汇的词典呢?另一方面,有标签的数据集应该有多大才能覆盖所有形式的情感词?
预计到这两种方法面临的挑战的复杂性,我决定尽可能自动地为 Arabizi 归纳出形态上和拼写上丰富的情感词典。我们在项目-rbz 上发布这项工作的成果出版物和资源。
音译
尽管阿拉伯语是用拉丁字母书写的,但它毕竟是阿拉伯语,所以为什么我要把它当作一种新的语言,并赋予它感情;我们就不能把它音译成阿拉伯文字吗?
作者图片
首先,这种非正统的转录产生了严重的单词歧义。因为阿拉伯语有短元音和长元音音位,以及轻声和重读辅音音位,所以一个阿拉伯语单词很容易与两个或更多的阿拉伯语单词混淆。
短元音是音调符号,长元音是元音字母ا و ي / ā、σ(或 wā)和 yā(或ī)/,为此,单词 غابة ghābeh 森林与长元音 ā 会与黎凡特方言阿拉伯语中的否定词غبي·加贝愚蠢与短元音 a 混淆。由于没有长短元音之分,两者都可以转录为 ghabeh。
至于轻声和重读辅音音素对应词,ذ د ك س ت和ظ ض ق ص ط是两个不同的字母组,分别代表轻声和重读字母 *th、d、k、s、*和 t 。阿拉伯语单词 dareb 可能是否定的ضربḍarb(强调)击中或物理打击或درب darb(软 d) 路径或路线的转录。
因此,映射到两个或更多阿拉伯字母的元音字母和拉丁辅音字母的拼写不一致会影响音译,从而为大多数阿拉伯语单词提供了几种可能性。音译在线进行,逐字逐句,用户在输入每个阿拉伯语单词后,从可能的音译列表中手动选择他们想要的阿拉伯语单词。 Yamli 以此闻名:
Yamli 阿拉伯音译
其次,Arabizi 是方言阿拉伯语的转录,而不是现代标准阿拉伯语(MSA ),其中的单词选择和表达因地区而异。因此,开发一个适合所有人的音译方法而不去迎合每一种方言是幼稚的。这是谷歌对整个文本进行自动化音译的努力,我们测试了一条来自黎巴嫩的积极的阿拉伯语推文:da5l Jame lik w hadam tik/oh-my(表情)你的美丽和你的幽默(女性)。
2019 年谷歌翻译;2020 年,它给出了:走进你的句子,摧毁你
在这种情况下,与将其音译为错误的阿拉伯语单词并试图在之后对其进行分类相比,包含屈折的积极单词 jamelik (your-beauty) 和*hadam tik(your-hum)*的阿拉伯语情感词典将更好地将该句子分类为积极的。
第三,出于情感分析的目的,方言阿拉伯语是资源贫乏的:把一种资源贫乏的语言的文字转换成另一种文字有什么意义?
原图: Benhance 画廊,我所想我所说的 Ghonemi
结论
简而言之,我通过我的研究了解到,充分吸收一种语言带来的挑战,并在处理任务之前评估所需 NLP 任务的可用或所需资源是至关重要的。
虽然阿拉伯语包含了太多的挑战,但不一致的拼写和拉丁化并不是新现象。例如,爪哇方言和 Alsatian⁸语是启发式转录的;希腊语、波斯语、印地语、孟加拉语、乌尔都语、泰卢固语和泰米尔语也被转录成拉丁文字,称为希腊语、芬利语、 Hinglish、Binglish …
我希望我对这篇文章中详细描述的 Arabizi 的词汇挑战的理解能够对社交媒体上低资源语言的情感分析的复杂性有所启发,并激励 NLP 社区探索为其他高稀疏性语言提供资源的类似方法。
[1] Baly,Ramy 等人,“情感树库和形态学丰富的递归深度模型,用于有效的阿拉伯语情感分析。” *ACM 亚洲和低资源语言信息处理汇刊(TALLIP)*16.4(2017):1–21。
[2]法尔哈、易卜拉欣·阿布和瓦利德·马格迪。" Mazajak:一个在线阿拉伯情感分析器."第四届阿拉伯语自然语言处理研讨会会议录。2019.
[3]穆罕默德·阿里·亚甘。"“Arabizi”:阿拉伯俚语的一种当代风格."设计问题24.2(2008):39–52。
[4] Seddah,Djamé等人,“建立一个用户生成内容的北非阿拉伯语树库:应对地狱”计算语言学协会第 58 届年会论文集。2020.
[5]沙利文,娜塔莉。写阿拉伯语:在推特上用罗马化的黎巴嫩阿拉伯语拼写变体。Diss。2017.
[6]马里亚姆·阿布莱兹。"拉丁化的阿拉伯语和双语能力的联系."兰卡斯特大学语言学研究生会议语言教学。英国兰卡斯特。第三卷。2009.
[7]张,雷,,刘兵.“用于情感分析的深度学习:一项调查.” Wiley 跨学科评论:数据挖掘与知识发现 8.4 (2018): e1253。
[8]米勒、爱丽丝和卡伦堡。"文本语料库和新书写语言的挑战."第一届资源不足语言口语技术(SLTU)和资源不足语言协作与计算(CCURL)联合研讨会会议录。2020.
希望你喜欢这篇文章,我有时会在推特上发一些关于资源匮乏的自然语言处理的东西: @TahaTobaili
不到 50 行 Python 代码中的情感分析
神经网络并不总是答案……
照片由 pixabay 上的 Free-Photos-242387 拍摄
自然语言处理(NLP)可能是一个难以理解的话题。NLP 涵盖了大量不同的学科和建模技术,从主题分析到机器翻译和语音识别到语音合成。情感分析包含在 NLP 系列中,是对一段文本中表达的情感进行量化的过程。通常,情感是根据文本的积极或消极程度来评估的。
最先进的情感分析技术通常涉及循环神经网络,如长期短期记忆模型(LSTMs)或计算成本高昂的 BERT 嵌入,大量的优秀材料已被写入如何创建和训练这些。然而,也许你不需要复杂的建模或大量的代码来实现有竞争力的性能。
那么,我们如何着手创建自己的情感分析模型呢?
数据
这里使用的数据可以在 Kaggle 上找到,包括训练集中的 27,481 条带标签的推文和测试集中的 3,534 条推文。因此,让我们继续使用每个数据科学家最好的朋友熊猫来加载数据:
import pandas as pdtraining_df = pd.read_csv("train.csv")
training_df.head()
让我们对测试集做同样的事情:
test_df = pd.read_csv("train.csv")
test_df.head()
注意,测试集没有selected_text
列。因此,让我们确保我们所做的任何数据清理都适用于训练集和测试集的text
列。
数据处理
为了简单起见,我们不想在清理方面做得太多,但我们可以做一些简单的事情来帮助任何模型识别情绪。数据清理过程如下:
- 删除推文中的所有超链接
- 替换常见的缩写
- 删除标点符号(分词器为我们做了这件事)
在我们清理的同时,我们还可以将情感标签映射到整数,并从同一个函数返回它们。
import reCONTRACTIONS_DICT = {"can`t":"can not",
"won`t":"will not",
"don`t":"do not",
"aren`t":"are not",
"i`d":"i would",
"couldn`t": "could not",
"shouldn`t": "should not",
"wouldn`t": "would not",
"isn`t": "is not",
"it`s": "it is",
"didn`t": "did not",
"weren`t": "were not",
"mustn`t": "must not",
}def prepare_data(df:pd.DataFrame) -> pd.DataFrame:
df["text"] = df["text"] \
.apply(lambda x: re.split('http:\/\/.*', str(x))[0]) \
.str.lower() \
.apply(lambda x: replace_words(x,contractions_dict))
df["label"] = df["sentiment"].map(
{"neutral": 1, "negative":0, "positive":2 }
)
return df.text.values, df.label.valuesdef replace_words(string:str, dictionary:dict):
for k, v in dictionary.items():
string = string.replace(k, v)
return stringtrain_tweets, train_labels = prepare_data(train_df)
test_tweets, test_labels = prepare_data(test_df)
句子分词器:
现在我们需要将每条 tweet 标记成一个固定长度的向量——特别是一个嵌入了的 TFIFD。为了实现这一点,我们可以使用 Keras 的内置Tokenizer()
,适合训练数据。
from keras.preprocessing.text import Tokenizertokenizer = Tokenizer()
tokenizer.fit(train_tweets)train_tokenized = tokenizer.texts_to_matrix(
train_tweets,
mode='tfidf'
)test_tokenized = tokenizer.texts_to_matrix(
test_tweets,
mode='tfidf'
)
系统模型化
接下来,我们需要选择我们的模型。当谈到情感分析时,世界是你的牡蛎,然而为了长话短说,我们求助于每个数据科学家的第二好朋友, sk-learn 的随机森林分类器:
from sklearn.ensemble import RandomForestClassifierforest = RandomForestClassifier(
n_estimators=500,
min_samples_leaf=2,
oob_score=True,
n_jobs=-1,
)
forest.fit(train_tokenized,train_labels)print(f"Train score: {forest.score(train_tokenized,train_labels)}")
print(f"OOB score: {forest.oob_score_}")
选择n_estimators
和num_samples_leaf
时进行了少量的超参数调整,以尝试最大化分数,同时避免过度拟合。这给了我们 0.77 的训练得分和 0.69 的出袋得分(关于出袋得分的更多信息,这篇文章很好地解释了这一点,但是 TL;DR 是随机森林的验证分数的代理)。
现在,让我们来看看测试集上的性能:
print("Test score: {forest.score(test_tokenized,test_labels)"}
这个值为 0.69,所以到目前为止,我们进展顺利!
混淆矩阵
sk-learn 可以轻松获取分类器和测试数据来生成混淆矩阵,显示测试集的性能,如下所示:
from sklearn.metrics import plot_confusion_matrixplot_confusion_matrix(
forest,
test_encoded_docs,
test_labels,
display_labels=["Negative","Neutral","Positive"],
normalize='true'
)
正如混淆矩阵所显示的,到目前为止,当谈到我们卑微的随机森林时,一切都很好。
这告诉我们很多关于我们所犯错误的类型。大多数错误发生在预测积极和中性情绪以及消极和中性情绪之间的差异时,在错误的大格局中,这并不是最糟糕的。然而值得庆幸的是,我们很少混淆积极情绪和消极情绪,反之亦然。
我们与 VADER 相比如何?
VADER 是一个“基于规则的情绪分析工具,专门针对社交媒体表达的情绪”。但是,对我们来说重要的是,这是一个现成的模型,可以用作基准。
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzeranalyzer = SentimentIntensityAnalyzer()
vs=[]
for sentence in test_tweets:
vs.append(analyzer.polarity_scores(sentence)["compound"])vader_scores = []
for v in vs:
if v < -0.5:
score = 0
elif v < 0.5:
score = 1
else:
score = 2
vader_scores.append(score)
给定阈值 0.5,VADER 在中性情绪类上实现了大致相同的真阳性率,但在积极和消极情绪类上的表现都比我们的模型差——很高兴知道训练我们自己的模型是值得的!
那么我们在这里学到了什么?
情绪分析并不像看起来那么神秘。当然,如果我们增加模型的复杂性,改进数据清理和使用更复杂的嵌入,我们可以做得更好,我们仍然能够实现合理的性能,而不需要任何东西。当你考虑到当前 Kaggle 竞赛的领先者得了 0.73 分,而我们用不到 50 行代码就达到了 0.69 分,我很高兴把它留在那里…
情感分析:朴素贝叶斯算法介绍
来源:stocksnap.io
数据集:https://www . ka ggle . com/c/情操分析电影评论/数据
本教程假设读者对贝叶斯定理和文本分析完全无知。你只需要按照教程和一切都解释了一个新鲜的人工智能/毫升。如果你是专业用户,希望快速修改概念**,你可以访问** 我的 github 库**(Senti _ analysis . ipynb)**上的代码。
对于任何类型的数据科学项目,您需要做的第一件事就是加载数据并使用它。我更喜欢(也是我认识的大多数数据科学家)用二手熊猫来下载数据(图 1)。给定数据以为单位。tsv 格式(制表符分隔变量)。我已经把它转换成。csv 使用 excel,同时可以使用*。tsv 格式也是。当我加载数据时,我遇到了一个小问题,因为在一些行中使用了特殊字符(大约 4 行包含/、分隔符和反斜杠)。在加载数据之前,我必须手动删除这些字符。
图 1:加载数据
我强烈建议新用户使用基本的熊猫指令来玩游戏。您可以使用:dataset.info()来获得不同列的汇总,如果任何列包含任何带有 NAN 数据的行(如果是,那么有多少?).请使用 dataset.head()、dataset.tail()、dataset.describe()、dataset[' C o l u m n N a m e ′ ] e . t . c 来深入了解数据集。例如 ( 图 2 ) 使用数据集。 ColumnName'] e.t.c 来深入了解数据集。例如(图 2)使用数据集。 ColumnName′]e.t.c来深入了解数据集。例如(图2)使用数据集。ColumnName.value_counts()给出每种情绪的计数(设 0 为一星评价,4 为五星评价)。从这里我们可以猜测,平均来说这部电影似乎是一部三星级电影。
图 2:基本 pandas 命令的使用
为了进一步进行情感分析,我们需要进行文本分类。我们可以用“词袋(BOW)”模型进行分析。用外行人的话来说,BOW 模型将文本转换成数字形式,然后可以在算法中用于分析。
具体来说,BOW 模型用于文本数据中的特征提取。它返回一个包含所有单词和每个单词重复次数的向量。它被称为 BOW,因为它只关心一个单词重复的次数,而不是单词的顺序。让我们举一个例子来更好地理解它(假设每个文档只包含一个句子):
文件 1:瑞士是一个美丽的国家。文档 2:印度是一个拥有聪明的 IT 专业人士的国家。美国是一个充满机遇的国家。
下表称为文档术语矩阵(DTM)。
———————
| Words->Swzld 是一个聪明的 IT 教授美丽的国家印度美国 opport
| Doc 1 Vector->1 1 1 1 1 0 0 0 0 0 0
Doc 2 Vector->0 1 1 0 1 1 1 1 1 1 1 1 1 1 1 0 0
| Doc 3 Vector->0 1 1 0 1 0 1 0 1 0 1 1 1
|累计->1 3 1 3 1 2 1 1 1 1 1 1 1 1 1 1 1
———————
上图所示型号为 monogram 型号。 如果一次取两个单词(例如:瑞士是一个美丽的国家……),那么它被称为双字母模型,同样地,一次取 N 个单词,它将是 N 字母模型。较高克数的模型往往比 monogram 模型效果更好。
每个文档中的内容越长,每个向量的长度就越长(将包含许多零)。如果文档太大,文档向量将是稀疏向量。稀疏向量需要大量内存来存储,并且由于长度的原因,即使是计算也会变得很慢。为了减少稀疏向量的长度,可以使用诸如词干化、词汇化、转换成小写或忽略停用词等技术
现在,我们将使用 sci-kit-learn 的 CountVectorizer 模块生成 DTM(图 3)。要阅读更多关于 CountVectorizer 的参数,您可以访问 这里 。如上所述,我们将使用:
- tokenizer =覆盖字符串记号化步骤,我们从 NLTK 的 Regex 记号化器生成记号化器(缺省情况下:None)
- lowercase = True(不需要使用,因为默认情况下设置为 True)
- stop_words = 'english '(默认情况下不使用,为了改善结果,我们可以提供一个自定义的停用词列表)
- ngram_range = (1,1)(默认情况下,将使用 its (1,1),即严格的单字母组合,(2,2)仅使用双字母组合,而(1,2)两者都使用)
图 3:使用计数矢量器准备“单词包”
我们现在将分割数据用于训练和测试,以检查我们的模型表现如何(图 3)。此外,我们将随机化数据,以防我们的数据首先包括所有积极的,然后是所有消极的或其他类型的偏见。我们将使用:scikit_learn 的train _ test _ split()来拆分 text_count(其中包含我们的 X)和 dataset[‘情绪’](其中包含 Y)。
图 4:使用 train_test_split 将数据分为训练和测试数据集。
现在我们有了训练和测试数据。我们应该开始分析了。我们的分析(和大多数 ML 分析一样)将分为 5 个步骤(记住它们的一个助记法是 DC-FEM 记住哥伦比亚特区消防和紧急医疗服务):
- 定义模型
- 编译模型
- 拟合模型
- 评估模型
- 用模型做预测
1.定义模型
我们将使用 朴素贝叶斯【NB】分类器之一来定义模型。具体来说,我们将使用 多项式分类器 。作为一个 ML 的新生,你可以使用 sklearn 这里 给出的备忘单来决定用于特定问题的最佳模型。它告诉我们使用 NB 分类器。让我们绕道了解更多关于 NB 模式的信息。
朴素贝叶斯模型
该模型应用贝叶斯定理,并天真地假设不同特征之间没有关系。根据贝叶斯定理:
后验=可能性*命题/证据
或者
P(A|B) = P(B|A) * P(A)/P(B)
举个例子:在一副扑克牌中,选择一张牌。假定一张牌是一张脸牌,那么这张牌成为皇后的概率是多少?
这个可以用贝叶斯定理解决。
P(皇后给脸牌)= P(皇后|脸)
P(给脸皇后)= P(脸|皇后)= 1
P(皇后)= 4/52 = 1/13 P(脸)= 3/13 从贝叶斯定理:
P(皇后|脸)= P(脸|皇后)P(皇后)/P(脸)= 1/3
对于具有多个变量的输入:
P(y|x1,x2,… xn) = P(x1,x2,… xn|y)* P(y)/P(x1,x2,…xn)
使用朴素贝叶斯我们假设 x1,x2 … xn 相互独立,即:
P(x1,x2,…xn | y)= P(x1 | y)* P(x2 | y)…* P(xn | y)
P(Xi)分布中的假设例如,假设高斯分布将产生高斯朴素贝叶斯(GNB),或者多项式分布将产生多项式朴素贝叶斯(MNB)。
朴素贝叶斯模型特别适用于文本分类和垃圾邮件过滤。使用 NB 算法的优点是:
- 需要少量的训练数据来学习参数
- 与复杂的模型相比,可以相对快速地进行训练
NB 算法的主要缺点是:
- 这是一个不错的分类器,但却是一个糟糕的估计器
- 它适用于离散值,但不适用于连续值(不能用于回归)
NB 算法的困境
关于 NB 算法的一个具有挑战性的问题是:尽管 NB 算法中的条件独立性假设在现实生活中几乎不成立,但是 NB 算法作为分类器是如何工作得如此之好的呢?我不会在这里讨论解决方案,而是将您引向包含解决方案的资源( 这里 )。简而言之,答案在于依赖性的分布,而不是依赖性,不知何故,由于分布,依赖性的影响抵消了。
NB 分类的损失函数
NB 分类使用零一损失函数。在此函数中,错误=错误分类的数量。这里,误差函数不考虑概率估计的准确性,假设具有最高概率的类被正确预测。比如说有 A 和 B 两个类,给了不同的属性(x1,x2,… xn)。P(A |所有属性)= 0.95,P(B |所有属性)=0.05,但是 NB 可能估计 P(A |所有属性)= 0.7,P(B |所有属性)= 0.3。这里虽然估计得远不准确,但分类是正确的。
让我们回到我们的分析。定义和编译模型的前两步简化为从 sklearn 中识别和导入模型(正如 sklearn 给出的预编译模型)。
2.编译模型
因为我们使用 sklearn 的模块和类,我们只需要导入预编译的类。Sklearn 在这里 给出了所有 职业的信息。
图 5:从 sklearn 库中导入多项式朴素贝叶斯模型
3.拟合模型
在这一步中,我们在多项式 b 中生成模型拟合数据集。为了寻找拟合模型时可以传递的参数,建议查看正在使用的模块的 sklearn 网页。对于 MNB 可以在这里勾选。
图 6:在多项式朴素贝叶斯中拟合数据。
4.评估模型
这里我们量化我们模型的质量。我们使用 sklearn 库中的 度量 模块来评估预测(图 7)。
图 7:使用 sklearn 的度量来评估模型
调整模型
我们观察到我们的模型的准确率超过 60%。我们现在可以利用我们的模型来增加它的准确性。
尝试不同的 n-grams
详情见图 8(二元模型)和图 9(三元模型)。
图 8:文本矢量化的二元模型。
图 9:文本矢量化的三元模型。
尝试不同的朴素贝叶斯算法
参考图 10(补码 NB)、图 11(高斯 NB)、图 12(伯努利 NB)。
图 10:使用互补朴素贝叶斯模型进行情感分析
图 11:使用高斯朴素贝叶斯模型进行情感分析
图 12:使用伯努利朴素贝叶斯模型进行情感分析
提高准确性
我们已经尝试使用不同的 n-grams 和不同的朴素贝叶斯模型,但最高准确率徘徊在 60%左右。为了改进我们的模型,让我们尝试改变方式,创建弓。目前,我们用 CountVectorizer 创建了 BOW,它计算文本中单词的出现次数。一个词出现的次数越多,它对分类就变得越重要。
术语频率-逆文档频率
**让我们使用 TF-IDF,它考虑了术语频率和逆文档频率的乘积。术语频率是一个术语在文档中出现的频率。假设一个术语在一个文档中出现了“f”次,带有“d”个单词。
词频= f/d
IDF 为‘逆文档频率’。如果一个语料库包含 N 个文档,而我们感兴趣的术语只出现在 D 个文档中,那么 IDF 是:
IDF = log(N/D) TF-IDF 是术语频率和逆文档频率的乘积。 **TF-IDF 显示了一个词在语料库中的稀有度。如果一个词很少见,那么它可能是某个特定情感/信息的标志性词汇。
图 13:使用中的 TfidfVectorizer
尝试非贝叶斯算法
即使是 Tfidf 矢量器(即创建不同的弓)也无助于提高模型的准确性。除了朴素贝叶斯算法,我们还可以选择随机梯度下降分类器或线性支持向量分类器。众所周知,这两种方法都能很好地处理文本数据分类。让我们试着用这些:
图 14:尝试不同的文本分类算法
推理
我们观察到,使用 TF-IDF 创建的 BOW 的线性支持向量分类器给出了最好的结果,准确率达到 63.88%。虽然准确性仍然很低,但仍需要对模型进行改进,以给出更好的结果。
祝贺大家完成教程。您应该已经了解了如何使用不同的分类器,以及朴素贝叶斯定理和与之相关的不同算法。我已经分享了一个关于建立和评估模型(DC-FEM)的广泛策略。还讨论了与朴素贝叶斯算法相关的挑战。我们讨论了“单词包”(BOW)模型以及使用 CountVectorizer 和 TfidfVetorizer 创建 BOW 的两种不同方式。
建议读数:
在我的 github 库访问完整代码。
从零开始展开朴素贝叶斯
基于监督学习的书籍情感分析
用 Python 和 scikit 分析一本书的情感的简单教程——学习
在本教程中,我将解释如何通过基于支持向量机(SVM)的监督学习技术来计算一本书的情感。
本教程计算圣奥古斯丁忏悔录的情感分析,可以从古腾堡项目页面下载。这部杰作分为 13 本书(章)。我们将每本书存储在不同的文件中,名为 number.text(例如 1.txt 和 2.txt)。每个文件的每一行只包含一个句子。
jupyter 笔记本可以从我的 Github 资源库下载:https://github.com/alod83/papers/tree/master/aiucd2021
一本书的情感分析的类似实验可以在下面的链接找到:https://towards data science . com/perspective-analysis-of-a-book-through-unsupervised-learning-df 876563 dd1b。在这种情况下,我解释了如何利用无监督学习技术来执行情感分析。
入门指南
监督学习需要一些带注释的文本来训练模型。因此,第一步包括读取注释文件并将其存储到数据帧中。注释文件包含每个句子的相关分数,该分数是正数、负数或空值。
import pandas as pddf = pd.read_csv('sources/annotations.csv')
df
我们可以计算一些关于注释的统计数据,比如正面、负面和中性分数的数量,以及注释的总数。我们可以使用应用于数据帧的count()
方法。
df.count()
df[df['score'] > 0].count()
df[df['score'] < 0].count()
df[df['score'] == 0].count()
准备训练集和测试集
为了计算每个句子的情感,我们将利用监督学习技术,该技术利用二进制分类模型。该模型将一个句子作为输入,根据句子是否被正面评价,返回 1 或 0。因为我们的模型是二进制的,所以我们必须删除所有带有中性分数的注释。
import numpy as np
# Remove any 'neutral' ratings equal to 0
df = df[df['score'] != 0]
现在我们可以向 dataframe 添加一列,称为Positively Rated
,包含 1 或 0,这取决于一个正的或负的分数。我们使用where()
方法为数据帧的这个新列分配适当的值。
df['Positively Rated'] = np.where(df['score'] > 0, 1, 0)
计算情绪
我们定义一个辅助函数,称为calculate_indexes()
,它接收监督学习模型(将在后面描述)和CountVectorizer
向量作为输入,如后面所述。
在该函数中,我们通过open()
函数打开对应于每本书的文件,我们通过函数file.readlines()
读取所有行,并通过将predict()
函数应用于模型来计算每一行的分数。
那么,我们可以定义三个指数来计算一本书的情绪:正面情绪指数(pi)、负面情绪指数(ni)和中性情绪指数(nui)。一本书的圆周率对应于一本书中的肯定句的数量除以该书的总句子数量。同样,我们可以计算一本书的 ni 和 nui。
def calculte_indexes(model,vect):
pos_index = []
neg_index = []
neutral_index = []
all_text = ""
for book in range(1,14):
file = open('sources/' + str(book) + '.txt')
lines = file.readlines()
pos = 0
neg = 0
for line in lines:
score = model.predict(vect.transform([line]))
if score == 1:
pos += 1
else:
neg += 1
all_text += ' ' + line.lower()
n = len(lines)
pos_index.append(pos / n)
neg_index.append(neg / n)
return pos_index,neg_index
现在我们可以训练算法了。我们定义了两种不同的情况:第一种情况我们不考虑 ngrams,第二种情况我们考虑。我们定义了一个名为train_algorithm()
的函数,可以通过指定 ngrams 的用法来调用它。
在函数中,我们首先通过名为train_test_split()
的scikit-learn
函数将数据集分为训练集和测试集两部分。训练集将用于训练算法,测试集将用于测试算法的性能。
X_train, X_test, y_train, y_test = train_test_split(df['sentence'],
df['Positively Rated'], random_state=0)
然后,我们构建标记计数矩阵,即包含每个句子哪些标记可用的矩阵。这可以通过类CountVectorizer
来完成,该类接收要考虑的 ngrams 数量作为输入。在本教程中,只考虑两个 ngrams。我们只考虑最小文档频率等于 5 的标记。
vect = CountVectorizer(min_df=5).fit(X_train)
然后我们可以构建模型:我们使用包含在scikit-learn
中的LinearSVC()
类,并用训练集model.fit(X_train_vectorized, y_train)
训练它。
model = LinearSVC()
model.fit(X_train_vectorized, y_train)
最后,我们通过预测测试集的输出并将结果与测试集中包含的真实输出进行比较来测试算法的性能。作为指标,我们测量 AUC,但我们也可以计算其他指标。
predictions = model.predict(vect.transform(X_test))
print('AUC: ', roc_auc_score(y_test, predictions))
一旦训练好模型,我们就可以通过calculte_indexes()
函数来计算指标。最后,我们绘制结果。
这里是功能train_algorithm()
的全部代码。
from sklearn.model_selection import train_test_split
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.svm import LinearSVC
from sklearn.metrics import roc_auc_score
import matplotlib.pyplot as pltdef train_algorithm(df, ngrams=False):
# Split data into training and test sets
X_train, X_test, y_train, y_test = train_test_split(df['sentence'],
df['Positively Rated'],
random_state=0)
# Fit the CountVectorizer to the training data
vect = CountVectorizer(min_df=5).fit(X_train)
if ngrams:
# Fit the CountVectorizer to the training data specifiying a minimum
# document frequency of 5 and extracting 1-grams and 2-grams
vect = CountVectorizer(min_df=5, ngram_range=(1,2)).fit(X_train)
print('NGRAMS')
else:
print('WITHOUT N-GRAMS')
# transform the documents in the training data to a document-term matrix
X_train_vectorized = vect.transform(X_train)
# Train the model
model = LinearSVC()
model.fit(X_train_vectorized, y_train)
# Predict the transformed test documents
predictions = model.predict(vect.transform(X_test))print('AUC: ', roc_auc_score(y_test, predictions))
pos_index, neg_index = calculte_indexes(model,vect)
X = np.arange(1,14)
plt.plot(X,pos_index,'-.',label='pos')
plt.plot(X,neg_index, '--',label='neg')
#plt.plot(X,neutral_index,'-',label='neu')
plt.legend()
plt.xticks(X)
plt.xlabel('Libri')
plt.ylabel('Indici')
plt.grid()
if ngrams:
plt.savefig('plots/svm-ngram-bsi.png')
else:
plt.savefig('plots/svm-1gram-bsi.png')
plt.show()
进行实验
现在我们可以在启用和禁用 ngrams 的情况下运行实验。
train_algorithm(df, ngrams=False)
train_algorithm(df, ngrams=True)
没有 n-grams 的实验
用 n-grams 做实验
吸取的教训
在本教程中,我向你展示了如何通过监督学习技术来计算一本书每一章的情感:
- 监督学习需要一些训练集,即一些手动标注的数据。因此,在开始玩模型之前,您应该做注释数据的(小)部分这一枯燥的任务。训练集越大,算法的性能越好;
- 要计算一个句子的情感,你应该使用一个(二进制)分类算法,比如支持向量机(SVM)。scikit-learn 库提供了许多分类算法;
- 一旦选择了模型,就可以用训练集对其进行训练;
- 别忘了测试模型的性能:)
基于无监督学习的书籍情感分析
用 Python 分析一本书情感的简单教程
入门指南
在本教程中,我将向您展示如何通过基于 AFINN 词典的无监督学习(UL)技术,对包含在书中的文本进行情感分析。本教程利用了仅适用于英语和丹麦语的afinn
Python 包。如果你的文本被写成不同的语言,你可以先翻译成英文,然后使用afinn
包。
这个笔记本应用了情绪分析圣奥古斯丁忏悔,可以从古腾堡项目页面下载。这部杰作分为 13 本书(或 13 章)。我们将每本书存储在不同的文件中,名为 number.text(例如 1.txt 和 2.txt)。每个文件的每一行只包含一个句子。
你可以从我的 Github 库下载代码:https://github.com/alod83/papers/tree/master/aiucd2021
首先从afinn
包中导入Afinn
类。
from afinn import Afinn
然后通过指定使用的语言创建一个新的Afinn
对象。
afinn = Afinn(language=’en’)
计算情绪
使用 Afinn 给出的分数来计算情感
afinn
对象包含一个名为score()
的方法,该方法接收一个句子作为输入,并返回一个分数作为输出。分数可以是正的、负的或中性的。我们计算一本书的分数,只需简单地将该书所有句子的分数相加。我们定义了三个变量> pos、neg 和 neutral,分别存储一本书所有句子的所有正面、负面和中性得分的总和。
首先,我们定义三个索引,它们将在后面使用。
pos_index = []
neg_index = []
neutral_index = []
我们通过open()
函数打开对应于每本书的文件,我们通过file.readlines()
函数读取所有行,并为每一行计算分数。
那么,我们可以定义三个指数来计算一本书的情绪:正面情绪指数(pi)、负面情绪指数(ni)和中性情绪指数(nui)。一本书的圆周率对应于一本书中的肯定句的数量除以该书的总句子数量。同样,我们可以计算一本书的 ni 和 nui。
for book in range(1,14):
file = open('sources/' + str(book) + '.txt')
lines = file.readlines()
pos = 0
neg = 0
neutral = 0
for line in lines:
score = int(afinn.score(line))
if score > 0:
pos += 1
elif score < 0:
neg += 1
else:
neutral += 1
n = len(lines)
pos_index.append(pos / n)
neg_index.append(neg / n)
neutral_index.append(neutral / n)
绘图结果
以图形方式显示结果
最后,我们可以通过使用matplotlib
包来绘制结果。
import matplotlib.pyplot as plt
import numpy as npX = np.arange(1,14)
plt.plot(X,pos_index,'-.',label='pos')
plt.plot(X,neg_index, '--',label='neg')
plt.plot(X,neutral_index,'-',label='neu')
plt.legend()
plt.xticks(X)
plt.xlabel('Libri')
plt.ylabel('Indici')
plt.grid()
plt.savefig('plots/afinn-bsi.png')
plt.show()
吸取的教训
在本教程中,我向您展示了一个简单的策略来计算包含在一本书中的文本的情感。这可以通过 Python 提供的afinn
包来实现。您可以遵循以下步骤:
- 把书的正文分成几章,然后把每一章存放在一个单独的文件里
- 把每一章的所有句子分成不同的行
- 通过
Afinn
类提供的score()
方法分别计算每个句子的分数 - 计算每个章节的正面情感指数、负面情感指数和中性情感指数
- 绘图结果。
如果想应用监督学习技术进行情感分析,可以继续关注:)。
基于朴素贝叶斯的微博情感分析
每秒发布数百万条推文。它帮助我们了解公众对特定事件的反应。为了获得推文的情感,我们可以使用朴素贝叶斯分类算法,这只是贝叶斯规则的应用。
贝叶斯规则
贝叶斯规则仅仅是描述一个事件发生的概率,而这个概率是建立在与它相关的另一个事件发生的先验知识之上的。
那么假设事件 B 已经发生,事件 A 发生的概率为
假设事件 A 已经发生,事件 B 发生的概率是
使用这两个方程,我们可以将它们统一改写为
让我们看看推文,以及我们如何从推文中提取特征
我们将有两个推特语料库,正面和负面推特。
正面推文:“我很开心,因为我在学习 NLP”,“我很开心,不难过。”
负面推文:“我很难过,我没有学习 NLP”,“我很难过,不开心。”
预处理
我们需要对数据进行预处理,这样可以节省大量内存,减少计算过程。
- 小写:我们将所有的文本转换成小写。这样,像学习和学习这样的词就可以理解为同一个词
- 删除标点符号、网址、名称:我们将删除标点符号、网址、名称或标签,因为它们对推文的情感分析没有帮助。
- 去除停用词:像“The”、“is”这样的停用词对情感没有帮助。因此,这些词必须删除。
- 词干:像“take”、“taking”这样的词被视为相同的词,并转换为基本词,这里是“take”。这样可以节省大量内存和时间。
概率方法:
为了获得单词的概率统计,我们将创建一个这些单词的字典,并统计每个单词在正面和负面推文中的出现次数。
让我们看看这些单词计数如何有助于找到这两个类的单词的概率。这里,单词“I”出现了三次,并且阳性语料库中的唯一单词总数是 13。因此,假设推文是正面的,单词“I”出现的概率将是
freq 表示一个词出现的频率,class: {pos,neg}
对我们词汇表中的所有单词都这样做,我们会得到这样一个表格:
在朴素贝叶斯中,我们将发现每个词是如何对情感做出贡献的,这可以通过正类和负类的词的出现概率的比率来计算。我们来举个例子;我们可以看到,‘sad’这个词出现的概率更多的是针对否定类而不是肯定类。因此,我们将通过公式找到每个单词的这些概率的比率:
这个比率被称为似然性,其值介于(0,∞)之间。趋向于零的值表示与在负面推特中发生的概率相比,它在正面推特中发生的概率非常低,而趋向于无穷大的比值表示与在正面推特中发生的概率相比,它在负面推特中发生的概率非常低。换句话说,比值高意味着积极。此外,比率值 1 表示名称是中性的。
拉普拉斯平滑
有些单词可能只在某个特定的班级出现过。没有出现在否定类别中的单词将具有概率 0,这使得比率不确定。所以,我们将使用拉普拉斯平滑技术来追踪这种情况。让我们看看应用拉普拉斯平滑后等式是如何变化的:
通过在分子中添加“1 ”,使概率不为零。这个因子叫做α因子,在(0,1)之间;具体来说,当我们将该α因子设置为 1 时,平滑被称为拉普拉斯平滑。同样,概率之和将保持为 1。
在我们的示例中,唯一单词的数量是 8,因此 V= 8。
拉普拉斯平滑后,概率表将看起来像这样:
朴素贝叶斯:
为了估计一条推文的情绪,我们将取推文中出现的每个词的概率比的乘积。请注意,不在我们的词汇表中的单词将不起作用,并将被视为中性的。在我们的应用程序中,朴素贝叶斯的等式如下:
m =一条推文中的字数,w =一条推文中的字数
由于数据可能不平衡,并可能导致特定类别的有偏差的结果,因此我们将上面的等式乘以一个先验因子,该因子是正面推文的概率与负面推文的概率之比。
朴素贝叶斯的完全方程
因为我们取所有这些比率的乘积,我们可能会得到一个太大或太小而无法存储在我们的设备上的数字,所以这里出现了对数似然的概念。我们在朴素贝叶斯方程上取对数。
取似然方程的对数后,标度将改变如下:
让我们看一个例子。推特:“我很高兴,因为我在学习。
这是我们推文的总体对数可能性。
因此,推文的总体对数似然值大于零,这意味着推文是正面的。
缺点:
- 朴素贝叶斯算法假设单词相互独立。
- 语料库中的相对频率:有时人们会屏蔽可能具有攻击性的特定类型的推文,等等。这导致了数据的不平衡
- 词序:通过改变词序,情感可能会改变,但是使用朴素贝叶斯,我们不会遇到这种情况。
- 删除标点符号:记得在数据预处理中,我们删除了标点符号,这可能会改变推文的情绪。这里有一个例子:‘我敬爱的祖母:(’
结论:
朴素贝叶斯是一种简单而强大的算法,知道了数据就可以相应地对数据进行预处理。朴素贝叶斯算法也用于社会的许多方面,如垃圾邮件分类、贷款审批等。
一段时间内(1958 年至 2019 年)所有 Billboard 热门 100 首歌曲的情感分析
流行音乐歌词平均每年多得 1.3%的负面!
马里乌斯·马萨拉尔在 Unsplash 上的照片
我是老派灵魂乐和说唱音乐的粉丝。我还是一名数据科学家,专攻自然语言处理(NLP)和自然语言理解(NLU)。在听音乐的时候,我发现自己在想,为什么旧学校的音乐似乎比现代音乐更积极、更有益健康。
在我看来,我听的大多数老校魂歌曲都是关于爱情和舞蹈的,而且它们通常含有相对较少的亵渎性语言。他们似乎更快乐,总体上也更积极。与此同时,我听的大多数当代说唱歌曲对亵渎性语言的使用要慷慨得多,而且总体上看起来更加愤怒和消极。我想知道这是否真的是普遍的情况。作为一名数据科学家,我为了满足自己的好奇心,对数据进行了深入研究。
我决定对过去几十年的代表性音乐样本进行情感分析,看看音乐是否变得越来越消极。我想知道随着时间的推移,流行音乐歌词中使用的语言的积极性得分是否有显著变化。
数据
我决定用 Billboard Hot 100 作为代表样本。Billboard Hot 100 是美国追踪一周前 100 首最流行歌曲的标准图表。我使用了一个数据集,包含了从 1958 年 8 月 2 日到 2019 年 6 月 22 日的所有 Billboard Hot 100 条目。
在获得 Billboard Hot 100 数据集后,我使用 LyricsGenius API 客户端抓取了 genius.com 上所有条目的歌词。我成功地为 26138 首独特的歌曲搜集了歌词。我对歌词进行了情感分析,以下是我的结果:
结果
- 平均而言,进入 Billboard Hot 100 的歌词倾向于接近中性。数据集中所有歌词的平均情感极性是 0.125。其中-1 完全为负,1 完全为正。
- 2019 年记录了最多的负面歌词,1979 年记录了最多的正面歌词。
- 2019 年的歌词比 1979 年的歌词负面 4 倍。
- 平均而言,在 1958 年至 2019 年期间,歌词情绪每年比 多 1.3%。
5.1958 年歌词热门关键词包括:【“喜欢”、“来了”、“渺小”、“曼宁”、“知道”、“跳喜欢”、“好”、“时间”】
6.2019 年歌词热门关键词包括:[“喜欢”、“耶”、“黑鬼”、“婊子”、“小婊子”、“爱”、“需要”、“操”]
分析
在这里,我详细说明了我得到结果的步骤。
-
**安装和导入库:**我使用了一些流行的 Python 模块进行文本处理。我还用 LyricsGenius 刮过 genius.com。
-
API 认证:在使用 LyricsGenius 包之前,我注册了一个 Genius 客户端访问令牌。
3.下载 Billboard Hot 100 数据集:我从数据世界获得 Billboard Hot 100 数据集。
4.定义函数:我为这个项目写了四个函数。
a.一个从 genius 中抓取歌词的功能。
b.一个获取歌词情感的函数。
c.一个处理所有文本预处理的函数。
d.一个函数,以获取歌词中的关键词。
5.把所有的东西放在一起:在导入包和数据,然后定义函数之后,我把函数应用到数据上,得到我的结果。
结论
这是什么意思?这一分析表明,流行音乐歌词可能越来越消极。然而,从这项分析中不清楚的是,这是否反映了社会趋势。作为一个社会,我们变得越来越消极了吗?根据我们创造和消费的文化艺术品,我们能对人类状况做出多少假设?这些是我在分析中没有探讨的问题。然而,这些问题很有趣,可以作为后续研究的基础。
如果您有兴趣自己探索这些数据,或者有兴趣查看我关于这个项目的 Jupyter 笔记本,请随意查看项目 GitHub 资源库。
动物穿越评论的情感分析
在对星谷的狂热之后,我想我再也不会回到任何需要耕种/囤积/捕鱼/采矿的游戏中去了。但是我在这里:自从我 3 月 22 日买了《动物穿越:新视野》(ACNH)以来,总共花了 100 个小时,这比 BotW 还多小时。说真的,ACNH 不是一个我认为我会喜欢的游戏:没有什么太令人兴奋的,只是一堆研磨。但它很可爱,而且它来得正是时候,让我(和许多人)在保持社交距离的同时与朋友联系。Polygon 上有一篇关于这种游戏中的研磨元素如何提供一定程度的放松和舒适的文章。因此,自 3 月 20 日发布以来,ACNH 的销量直线上升就不足为奇了,谷歌对 ACNH 的搜索量也是如此。
谷歌搜索对动物穿越和任天堂 Switch 的兴趣
该图还显示,对 ACNH 的兴趣增加也增加了对任天堂 Switch 的兴趣。而且,任天堂 Switch 现在几乎在所有地方都卖光了,包括在 T2。新闻报道 ACNH 打破了任天堂 Switch 冠军在日本的销售记录。亚马逊上的 ACNH 纸质版的价格也几乎翻了一番。我大胆的推断是,任天堂 Switch 销量的增加和 ACNH 销量的增加是正相关的。
似乎 ACNH 很受玩家欢迎。然而,当我在一些游戏网站上查看评论时,如 GameSpot 和 Metacritic,平均用户评分分别为 6.4 和 5.2/10,尽管该网站的官方评级为 9/10。那么,为什么玩家对这款游戏的评价比官方评测人员差呢?我对用户评分感到惊讶(我会给 7/10,比神奇宝贝剑与盾更好),我很好奇用户对 ACNH 的看法。
所以,我做了一个快速的情感分析(因为我刚刚从克里斯·毛雷尔教授本周的文本分析课上学到了它)。我首先使用 Python 上的beautiful soup从 Metacritic 中删除评审数据。然后,在使用 r 进行情感分析之前,我对 CSV 文件进行了一点格式化。我比较了来自词典包的几个词典,并决定 Hu-Liu、Jockers-Rinker 和 NRC 词典最适合我在分析元评论时使用,因为它们在情感评分方面具有一致性。
用户评论的平均情感分数
平均情绪得分
由三个词典生成的平均情感得分表明,用户评论通常不太正面(0 为中性,1 为正面)。然而,在最近的评论中有一个越来越积极的趋势。评论中不太积极的情绪得分并不令人惊讶,因为在 3450 个用户评级中,几乎有 50%是负面的。高度正面的评论可以被高度负面的评论抵消,从而得到相对中性的分数。
用户评论中的正面词和负面词
那么,这些 Metacritic 用户在评论中谈论的是什么呢?我整理了由胡-刘和 Jockers-Rinker 词典(未显示)生成的消极和积极词汇的列表,并根据它们的频率制作了词云。
否定词云
我猜人们不喜欢这个游戏中的资本主义思想,并把汤姆·努克描述成独裁者,而我们(玩家)是他的奴隶(支付我们的住房贷款)。限制”是最常出现的负面词汇。我推断这种频繁发生是由于用户抱怨每个控制台一个岛的限制(也许?). '“失望”出现,表明由于炒作,这些用户的期望很高。
正词云
这个正面词云以“好玩”为最常出现的正面词。像“享受”、“享受”和“享受”这样的词经常出现,足以推断一些用户确实喜欢这个游戏。
这两个字云恰恰说明了喜欢游戏的人对游戏的趣味性和创意元素赞不绝口,认为这个游戏很神奇(等等。).他们非常喜欢这个游戏,因此给予了积极的评价和很高的评分。那些不喜欢游戏的人给了很低的分数(读“0”),并在他们的评论中使用更严厉的词语,如“独裁者”、“奴隶”、“失望”。这些恰恰说明 ACNH 是一个收到两极分化意见的游戏。
用户评论中的情感
词语及其与情感的关联
我还用 NRC 的词典研究了与这些评论相关的情绪。尽管用户最常使用与信任相关的词,但像“系统”、“账户”和“系列”这样的词并不能表达用户对游戏的态度。像“长”、“等待”和“开始”这样的期待词在这里也没有太多意义。表示快乐的单词似乎也出现得更频繁。悲伤、厌恶、愤怒和恐惧是在这个评论集中检测到的负面情绪。他们最有可能与那些评价低的评论联系在一起。
情感-词词云
出于好奇,我做了这个分析。似乎 Metacritic 用户对 ACNH 的意见两极分化,如中性情绪得分、正面和负面词云以及网站上的评级百分比所示。但这种感性的分析并没有讲述 ACNH 评论的全部故事。我意识到这个分析的局限性,尤其是关于情感的分析。Metacritic 用户也不能很好地代表 ACNH 玩家,因为它只是为数不多的游戏评论网站之一。YouTube 可能是另一个平台,玩家可以在这里谈论游戏并分享他们的经历。
德里推特的情感分析
演职员表:莎拉·库菲斯,Unsplash
估计推文中的正面/负面分数
数据是一个比许多人认为的更广泛的术语。它不仅包含 Excel 文件或等效的结构化表格数据,还包含文本文件、音频文件、图片等非结构化数据。考虑到所有数据格式的详尽列表,可以很好地认识到结构化数据只是冰山一角。尤其是文本数据,可以在大多数主题中找到。
本文旨在使用关键词和特定位置的技术从 Twitter 上抓取推文。此外,我还将展示可以用来评估一条 tweet 的情绪的软件包。我感谢 Twitter 社区允许我们访问这些数据。使用的编程语言是 Python 3.3,使用的 IDE 是 Spyder 3.3.3。
检索推文
Python 提供了一些有趣的包来从 Twitter 中抓取 tweets。GetOldTweets3 就是这样一个包(我觉得它很方便,因为它很灵活)。
#Importing the Packages
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import GetOldTweets3 as got#Setting the Parameters
text_query = 'coronavirus'
location = 'Delhi'
tweetCriteria = got.manager.TweetCriteria()
.setQuerySearch(text_query).setNear(location)
.setSince("2020-03-01").setUntil("2020-05-05")#Creating a list of all tweets
tweets = got.manager.TweetManager.getTweets(tweetCriteria)#Creating list of chosen tweet data
text_tweets = [[tweet.text] for tweet in tweets]
text_date = [[tweet.date] for tweet in tweets]tweets = pd.DataFrame(list(zip(text_date, text_tweets)),
columns = ['Date', 'Tweet'])
在导入基本的和必需的包之后,我们首先设置服务于我们目的的基本参数。这些参数包括:
setQuerySearch :一条推文应该包含的关键词或短语。
setNear :推文的参考位置。
setSince :需要抓取推文的日期。
set until:tweets 需要被抓取的日期。
出于这个分析的目的,我将参考位置设置为德里,将文本查询设置为冠状病毒(因为这是人们目前在推特上谈论的主要内容)。开始日期设定为2020–03–01(2020 年 3 月 1 日)至2020–05–05(2020 年 5 月 5 日)。这是两个月多一点。
运行时间主要取决于 tweets 被抓取的数量和互联网速度。
一旦 tweet 被抓取,就会创建一个带有单独的日期和 tweet 列的数据框。该数据集包含 37,135 条推文和 2 列(日期和推文)。
In [2]: tweets.shape
Out[2]: (37135, 2)
清理推文以供进一步分析
Tweets 预清理
一旦创建了基本的数据框架,清理推文以供进一步分析就变得非常重要。这包括删除不必要的括号、撇号、用户名等。
#Cleaning the Tweetsfrom nltk.corpus import stopwords
date = []
tweet = []
words = set(nltk.corpus.words.words())
for i in range(0,len(tweets)):
date.append(tweets.iloc[i,0])
string = tweets.iloc[i,1]
string = re.sub(r”http\S+”, “”, string) #Removes Hyperlink
string = re.sub(‘@[^\s]+’,’’,string) #Removes Usernames
string = re.sub(‘#[^\s]+’,’’,string) #Removes Hashtags
tweet.append(string.strip(“[“).strip(“]”))new_tweet = pd.DataFrame(list(zip(date, tweet)), columns = [‘Date’, ‘Tweet’])
上面几行代码删除了特殊字符和短语,如标签、超链接、用户名和括号。最后,我们得到一个相对干净的数据框架。
清理后的推文
寻找推文的情感分数
Python 提供了多个包来评估文本的情感。在这个实例中使用的包是Vader perspection。更多关于这个包的信息可以在找到。
#Checking the Polarity
from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
sent = SentimentIntensityAnalyzer()
sentiment_dict = []
for i in range(0,len(new_tweet)):
sentiment_dict.append(sent.polarity_scores(new_tweet.iloc[i,1]))positive = []
neutral = []
negative = []
compound = []
for item in sentiment_dict:
positive.append(item[‘pos’])
neutral.append(item[‘neu’])
negative.append(item[‘neg’])
compound.append(item[‘compound’])sentiment_df = pd.DataFrame(list(zip(positive, neutral, negative, compound)), columns = [‘Positive’, ‘Neutral’, ‘Negative’, ‘Compound’])
new_tweet[‘Positive’] = sentiment_df[‘Positive’]
new_tweet[‘Negative’] = sentiment_df[‘Negative’]
new_tweet[‘Neutral’] = sentiment_df[‘Neutral’]
new_tweet[‘Compound’] = sentiment_df[‘Compound’]
Vader perspection以字典的形式返回输出,包含 4 个键( pos,neu,neg,compound )。 pos、neu 和 neg 的值介于 0 和 1 之间,0 表示不具有该词的任何特征,1 表示很可能是正面、负面或中性评论。最后一项复合表示根据 pos、neu 和 neg 得分计算的范围(-1,1)内的最终得分。
运行代码,我们得到以下输出:
情感得分
让我们讨论上面输出中的一些实例。
索引 11 上的推文:推文是用印地语写的。因此,该算法无法为其分配任何情感,并且默认给出完美的中性分数。
指数 4 上的推文:空白推文被分配一个完美的中性分数。
索引 12 上的推文:用英语写的印地语推文也被分配为中性。
有许多推文是用印地语写的,因为参考地点是德里。反击的一个方法是删除所有中立的推文。这符合逻辑,因为我们主要关注的是正面和负面的推文。
#Removing all the neutral comments
wf_tweet = new_tweet.loc[new_tweet[‘Neutral’] != 1].reset_index()
wf_tweet = wf_tweet.drop(‘index’, axis = 1)
最终输出
我们现在已经给所有的推文分配了情感分数。具有负复合值的推文描绘负面情绪,而具有正复合值的推文描绘正面情绪。
我们现在可以将复合值分为正值和负值。
输出
结论
我们有一个如上给出的最终输出。可以对数据框进行进一步分析,以挖掘信息,从而有趣地洞察德里(印度)民众对冠状病毒的看法。日期列可以证明是一个重要的属性,也可以看出人们的态度/情绪是如何随时间变化的。根据情绪得分,人们还可以发现哪些标签在负面和正面的推文中使用最多。然而,这种分析超出了本文的范围。
感谢您的阅读。我真诚地希望它对你有所帮助,我一如既往地欢迎讨论和建设性的反馈。
给我发邮件:icy.algorithms@gmail.com
你可以在领英上找到我。
编者按: 走向数据科学 是一份以数据科学和机器学习研究为主的中型刊物。我们不是健康专家或流行病学家,本文的观点不应被解释为专业建议。想了解更多关于疫情冠状病毒的信息,可以点击 这里 。
使用 Python 和情感分析探索和可视化您的 LinkedIn 网络
希望优化您的 LinkedIn 个人资料?为什么不让数据为你服务呢?
动机
如果你是 LinkedIn 的用户,你有没有想过你的社交网络中的人群?如果你正在努力拓展你在数据科学领域的人脉,你的人脉中的大多数人都在数据科学相关领域工作吗?
你的留言呢?它们是否大多是积极的,关于与你兴趣相关的话题?
作为 LinkedIn 上的一名活跃用户,我有超过 500 个联系,我对我的网络中的人的统计数据以及我在过去两年中收到的消息感到好奇。
分析 LinkedIn 数据有什么好处?好吧,如果你正在为工作机会优化你的 LinkedIn 档案,为什么不使用可用的数据作为你的工具呢?
在本文中,我将结合可视化和自然语言处理来分析我的网络和消息。读完这篇文章后,你应该能够分析自己的 LinkedIn 数据,并从中获得见解!
数据
我没花太多力气就拿到了数据,因为你可以直接从 LinkedIn 上下载。这里的是你可以怎么做的。
具体来说,我导入了消息和连接数据。
我将使用 Datapane 嵌入来自每个库的可视化,这是一个用于发布和共享 Python 报告的 Python 框架和 API。如果您想为我下面的任何一个图或表格留下评论,请随时点击左上角的“查看完整报告”留下您的评论,我会尽快回复您!
这里是这篇文章的笔记本,这样你就可以跟随文章并可视化你自己的数据!
网络
连接的日期
从导入开始并检查数据
在上表中,我只展示了我最近的 10 个关系作为例子。Connected On
表示我与那个人联系的日期。我将把该列转换成日期-时间并用 Plotly 可视化
我每天的新连接数都有一个峰值,特别是 2020 年 1 月到 2020 年 7 月,是我在 LinkedIn 上最活跃的时期。
公司
我网络中的人在哪些组织工作?我可以用这样的条形图:
但是在这种情况下,也许 treemap 在可视化公司方面做得更好?
树形图将分层数据显示为一组嵌套矩形。每个组由一个矩形表示,矩形的面积与其值成比例。
有了树形图,比较一家公司与其他公司的相关比例就更容易了!看起来我的网络中有很大一部分人来自拜耳作物科学。第二大百分比来自我的大学。
位置
哇!没想到会看到这么多数据科学家。我人际网络中最常见的职位是我的人际网络目标群体,这很好。
有些人的头衔可能以“数据科学家”开头,但头衔中也有更多的词。找出所有以“数据科学家”开头的职位
>>> network.Position.str.startswith('Data Scientist').sum()
268
消息
是时候分析消息了!在过去两年的 3895 封邮件中,我可以发现哪些隐藏的事实?
这些数据中有一些有趣的栏目。既然我们对消息的内容感兴趣,那就让我们更深入地挖掘一下。
语言检测
除了英语,我的一些信息是越南语,一些是其他语言(我不知道它们是什么意思)。由于我只想分析英文消息,所以我将使用来自 spacy_langdetect 的 LanguageDetector 从其余消息中提取英文消息。
例如,我将检查文本“这是英语测试”是否被检测为英语文本
{'language': 'en', 'score': 0.9999987378584019}
This is an english text. {'language': 'en', 'score': 0.999998324978528}
99%认为是英语考试。让我们用越南语文本再试一次
{'language': 'vi', 'score': 0.9999995883738908}
Đây là Tiếng Việt {'language': 'vi', 'score': 0.9999981449655853}
而且被检测出是越南人!现在让我们用它来表达整个信息
厉害!现在我们所有的信息都是英文的。
命名实体
命名实体是一个现实世界的对象,如人、地点、组织、产品等…比如,巴拉克·奥巴马是人名还是地名?纽约是一个地点还是一个组织?
有很多方法可以检测命名实体,但是 SpaCy 是我喜欢的工具。让我们用这条消息来测试一下:
"This is amazing Tran, it's wonderful you could experience that part of Mexico. Yes, I was born in Guadalajara, and lived in Morelia when I was a kid. I visited Guanajuato just a couple of times. What is even better, I have been living in Japan and Singapore for many years, and about 6 months in Hà Nội. I was amazed about the tons of similarities between Vietnam and Mexico "
[(Tran, 'ORG'),
(Mexico, 'GPE'),
(Guadalajara, 'GPE'),
(Morelia, 'GPE'),
(Guanajuato, 'PERSON'),
(Japan, 'GPE'),
(Singapore, 'GPE'),
(many years, 'DATE'),
(about 6 months, 'DATE'),
(Hà Nội, 'ORG'),
(tons, 'QUANTITY'),
(Vietnam, 'GPE'),
(Mexico, 'GPE')]
ORG
是组织,GPE
是地缘政治实体,PERSON
是人名,DATE
是日期实体,QUANTITY
是数量实体。
displacy.serve(message1, style=’ent’)
我们甚至可以想象句子中的命名实体
其中一些分类不正确,如 Tran(人名)或 Guanajuato(地点),但大多数都是正确的!让我们找到所有消息的命名实体
我的消息中的大多数命名实体都是个人实体!这看起来像是我们在消息中获得了许多个人实体,但是我们也应该小心模型的正确性。虽然大部分分类正确,但也有部分不正确。
最常见的单词
我的 LinkedIn 留言里最常见的词是什么?
从一些基本的数据处理开始
清理完文本后,让我们想象一下我们得到了什么
这些大词是我们希望从 LinkedIn 信息中看到的词。我们也知道我的谈话是真的进入数据。相当酷!
情感分析
我的 LinkedIn 消息的情绪是什么?我猜大部分都是正面的,但是有多少百分比呢?因为我没有可用的训练数据集,所以我使用预训练数据集。来自 NLTK 的 SentimentIntensityAnalyzer 是一个完美的工具。
{'neg': 0.0, 'neu': 0.323, 'pos': 0.677, 'compound': 0.6369}
SentimentIntensityAnalyzer 分析中性、消极和积极的百分比。Compound
是百分比组合的最终结果。因此,我们可以创建基于复合的情感分析功能
使用此函数预测样本文本的情感
>>> predict_sentiment
('Negative', 62.9)>>> predict_sentiment('It is super useful')
('Positive', 77.3)>>> predict_sentiment('It is just okay')
('Positive', 38.8)
这似乎工作得很好!如果对你的文本不起作用,在这里找到提取情绪的其他方法。
现在我们可以将这一点应用到我们所有的信息中
正如所料,大多数信息都是积极的。我不记得什么时候我的信息是负面的。有哪些负面信息,哪些词让它们变得负面?
让我们看看一些消极的词汇,并把它们形象化
>>> sample = list(sentiment_df[sentiment_df['Sentiment'] == 'Negative'].Message)[2]
>>> sample'lots code gets shipped w technical debt'
因为词债是负的!
正面词的指标有哪些?我们拿一个肯定句的例子来找出答案
“高兴”这个词使句子更加积极!
结论
恭喜你!您刚刚学习了如何使用自然语言处理来分析您自己的 LinkedIn 数据或者类似的文本数据。我们不知道数据中隐藏着什么,直到我们努力去发现它。分析你自己的数据,你会对你所看到的感到惊讶,并且学到一些有用的东西!
如果你有任何问题,请给我留言!你可以在这篇报道的文章中找到所有的图表!
想要根据您的 LinkedIn 数据生成您自己的报告?这篇文章的笔记本可以在这里找到。一定要在笔记本的目录下添加 CSV 文件,准备好分析!
我喜欢写一些基本的数据科学概念,并尝试不同的算法和数据科学工具。你可以在 LinkedIn 和 T2 Twitter 上与我联系。
星这个回购如果你想检查我写的所有文章的代码。在 Medium 上关注我,了解我的最新数据科学文章,例如:
[## 用 Python 模块 Newspaper 和 NLTK 查找文章中的常用词
使用 newspaper3k 和 NLTK 从报纸中提取信息和发现见解的分步指南
towardsdatascience.com](/find-common-words-in-article-with-python-module-newspaper-and-nltk-8c7d6c75733) [## 如何用 Python 对 Tweets 进行标记
我们应该选择 TweetTokenizers 还是其他 4 种常见的 Tokenizers?
towardsdatascience.com](/an-introduction-to-tweettokenizer-for-processing-tweets-9879389f8fe7) [## PyTorch 是什么?
想想 Numpy,但是有强大的 GPU 加速
towardsdatascience.com](/what-is-pytorch-a84e4559f0e3) [## 自然语言处理中的卷积神经网络
什么是卷积神经网络,如何利用它进行情感分析?
towardsdatascience.com](/convolutional-neural-network-in-natural-language-processing-96d67f91275c) [## 我收集了超过 1k 的顶级机器学习 Github 配置文件,这就是我的发现
从 Github 上的顶级机器学习档案中获得见解
towardsdatascience.com](/i-scraped-more-than-1k-top-machine-learning-github-profiles-and-this-is-what-i-found-1ab4fb0c0474)
基于拥抱脸管道特征的政治演讲情感分析
在评估政治演讲时,你更相信谁——人类专家还是算法?2020 年 2 月至 6 月期间,在新加坡对新冠肺炎的演讲进行了测试,得出了一些有趣的结果。
选举季节让我们许多人充满恐惧。但这也是一个很好的机会,可以用一个实际的用例来测试一些新的 NLP 特性。
最近几周,我一直在试验拥抱脸(Hugging Face)的 HF 管道功能,看看如何轻松快速地使用它们来分析/总结新加坡的政治演讲。这篇文章将概述我对上述演讲进行短期和长期情绪分析的尝试,这些演讲在 2020 年 2 月至 6 月之间发表,具有 HF 的管道特征。
我发现结果相当令人印象深刻,尽管只是使用默认模型,没有对本地数据进行额外的微调。随着美国和新加坡等国家的选举即将到来,测试这些基于变形金刚的模型在不同政治环境下的表现还有进一步的空间。
回购、数据和警告
这篇文章的 Github repo 包含一个笔记本和生成这篇文章中的一些图表所需的数据,以及 Plotly 图表和 CSV 结果表的样本。如果您希望一次生成多个演讲的结果,可以很容易地调整代码。
这些数据包括来自新加坡政府和总理办公室网站的六份官方演讲记录。这些演讲的重点是政府应对新冠肺炎挑战的计划,并将为即将到来的大选提供更广泛的辩论框架。为了更公平地评估情绪,一些过长的文本被分成了更小的段落,但绝大多数演讲都是以原始形式进行分析的。
更严格的情感分析应用需要使用特定领域的数据对模型进行微调,尤其是在涉及医学或法律问题等专业主题的情况下。然而,在这篇文章中,我使用 HF 管道进行“开箱即用”的情感分析,这意味着结果是基于默认蒸馏模型(更具体地说:蒸馏-基础-未装箱-微调-SST-2-英语)。HF 的网站上有一个与情感分析和文本分类任务兼容的其他模型的列表,如果你想进一步实验的话。
分析一篇演讲的情感
感谢 HF 的优秀员工,pipeline API 处理了复杂编码方面的繁重工作。在简单的文本预处理(分成段落)和清理之后,执行情感分析只需要几行代码。
管道生成情感标签以及分数。通过将标签和分数提取到一个单独的数据框中,我们可以轻松地检查结果,并查看模型可能出现错误的地方:
对我来说,更棘手的任务是找到一种可视化和注释结果的好方法。为了清晰和易于使用,我最终选定了一个组合 Plotly 和谷歌幻灯片。请随意切换到您选择的可视化库。
这是来自数据集中第一个语音的情感分析的样本结果:
HF 的情绪分析管道对这次演讲的 33 个段落中的 23 个段落进行了积极的评估。
一眼看去,你就能知道说话者在积极或消极的领域停留了多长时间。在这种情况下,我们可以看到新加坡总理李显龙如何平衡新冠肺炎经济影响的严峻警告与政府计划帮助新加坡人应对失业的保证。他还以积极的方式结束了 6 月 7 日的演讲,将全国人民团结在一个共同的挑战周围。
分析一组演讲的情绪
如果我们将一系列的“情绪结构”图表组合在一起,我们可以很快了解来自同一机构的发言者是否在以不同的语气传递一致的信息,或者每个人是否在唱不同的调子。你也可以用这个来观察一个主题的情绪是如何随着时间而变化的。
下图以 10 次演讲为例,展示了新加坡政治领导人在 2 月至 6 月期间,在预期的民意调查之前,是如何改变他们在新冠肺炎问题上的讲话语气的。如果你比较左右两边的专栏,你会注意到整体情绪(对新冠肺炎)有明显的转变,从 2 月到 4 月底以消极为主,到 6 月份变得更加积极:
这一结果并不令人惊讶,因为在政府于 5 月份成功控制疫情之前,新加坡 4 月份的疫情明显恶化。随着选举的临近,高层政治领导人显然需要转向一种新的沟通策略——和语气——他们在 6 月份就这么做了。
2 月和 4 月下旬的讲话不包括在回购中,但可以在上述两个政府网站的链接中找到。
我认为这可以用来分析,比如说,川普在新冠肺炎疫情爆发初期和后期的语调变化。我也很想在拜登和特朗普的辩论中验证这一点。
算法出错的地方
这篇文章中的演讲分析结果可以从这里下载快速浏览。看看你是否同意算法的评估。
当然也有错误。下面的图表显示,在分析新加坡国家发展部长王冠逸的新冠肺炎 6 月 9 日在 T4 的演讲时,Distilbert 模型至少在两个方面出现了错误:
该算法错误地将他演讲中讨论新加坡新的测试和接触者追踪能力的一部分贴上了负面标签,而这一部分本应被视为中性或积极的。在演讲接近尾声时,它再次出错,错误地将一段赞扬商界贡献的段落标为负面。
在其他地方,这种算法可能会被对一种可怕情况的模糊而笼统的描述所“击败”,比如新加坡内阁资政张志勇·何岸 6 月 11 日演讲的第二段:
上一段中的语言大大低估了新冠肺炎造成的破坏的程度和严重性,有趣的是,算法将其标记为积极的。人类分析师会得出相反的结论。
结束注释+进一步工作
一个显而易见的改进是用一个关于新加坡政治和/或新冠肺炎的定制数据集对模型进行微调。然而,这个任务看起来并不简单(至少对我来说),找到一个相关的和标记的训练数据集并不容易。
我也很有兴趣看看 HF 的 pipeline 的结果如何与其他已知的情感分析方法相比较。
但总的来说,尽管这种方法有明显的局限性,我还是对 HF 管道的结果印象深刻。显然,围绕演讲的情绪不仅仅取决于所用的词语,还取决于演讲者的演讲和举止。
一个完整的基于人工智能的演讲情感分析应该理想地结合使用计算机视觉和音频取证,以更好地理解演讲者的面部表情和说话声音如何增加演讲的整体情感。但是这超出了本文的范围。
同时,如果您发现了错误或者用这种方法做了一些有趣的事情,请告诉我。在以下时间 Ping 我:
推特:蔡振鸿
领英:www.linkedin.com/in/chuachinhon
基于 Python 的社交媒体情感分析
用于对社交媒体文本中的情感进行分类的 Python 工具的初学者友好概述。我讨论了我使用不同工具的经历,并提供了一些建议,帮助您开始自己的 Python 情感分析之旅!
T. Selin Erkan 在 Unsplash 上的照片
在古罗马,公共话语发生在城市中心的广场上。人们聚集在一起交流思想,讨论与社会相关的话题。如今,这种公共话语已经转移到 Reddit 等网站的数字论坛、Twitter 的微博平台和其他社交媒体上。也许作为一名研究人员,你很好奇人们对某个特定话题的看法,或者作为一名分析师,你希望研究贵公司最近营销活动的效果。用情感分析监控社交媒体是衡量公众意见的好方法。幸运的是,使用 Python 有许多选择,我将讨论我已经试验过的方法和工具,以及我对这种体验的想法。
在我的学习之旅中,我从最简单的选项 TextBlob 开始,通过 Pytorch 和 Tensorflow 逐步使用 transformers 进行深度学习。如果您是 Python 和情绪分析的初学者,不要担心,下一节将提供背景知识。否则,请随意跳到下面的图表,查看 Python 自然语言处理(NLP)领域的可视化概述。
情感分析简介
情感分析是 NLP 的一部分;文本可以通过情感(有时称为极性)进行分类,可以是粗粒度的,也可以是细粒度的。粗略情感分析可以是二元(正面或负面)分类,或者是包括中性的 3 分等级。而 5 分制是精细分析,代表高度积极、积极、中立、消极和高度消极。早期的分析依赖于基于规则的方法,如 Python 库 TextBlob 和 NLTK-VADER 所使用的方法,这两种方法在初学者中很受欢迎。大多数机器学习(ML)方法都是基于特征的,并且涉及浅度或深度学习。浅层方法包括在单层神经网络中使用分类算法,而 NLP 的深度学习需要神经网络中的多层。这些层中的一层(第一个隐藏层)将是一个嵌入层,它包含上下文信息。
对神经网络的详细解释超出了本文的范围,但是对于我们的目的来说,过于简化就足够了:神经网络是一组算法,它们以模拟人脑中神经元网络的方式来学习关于数据的关系。为了更深入地探究神经网络背后的迷人理论,我建议这篇介绍性文章。
我注意到的一个共同的主题是,一种方法越善于从上下文中捕捉细微差别,情感分类的准确性就越高。有几种技术可以以捕捉上下文的方式编码或嵌入文本,以获得更高的准确性。因此,嵌入层对于深度学习模型的成功是不可或缺的。今天,深度学习正在以令人兴奋的速度推进 NLP 领域。深度学习的前沿是 transformers ,预训练的语言模型可能有数十亿个参数,它们是开源的,可以用于最先进的准确度分数。我创建了下面的图表来展示可用于情感分析的 Python 库和 ML 框架,但是不要感到不知所措,有几个选项可供初学者使用。
可用于情感分析的 Python 库和机器学习框架。图片作者。
基于规则的 Python 库
TextBlob 很受欢迎,因为它使用简单,如果您是 Python 新手,这是一个很好的起点。我的一个早期项目涉及用 TextBlob 计算的极性和主观性分数的数据可视化。下面的代码片段显示了对从 Twitter 实时流出的 tweets 的 TextBlob 的简单实现,完整代码请查看我的要点。
虽然使用 TextBlob 很容易,但不幸的是它不是很准确,因为自然语言,尤其是社交媒体语言,很复杂,并且基于规则的方法会忽略上下文的细微差别。 NLTK-VADER 是一个专门为处理社交媒体文本而开发的 NLP 包。我建议,如果你正在处理 tweets,并且正在为 TextBlob 寻找一个比较点,那就去看看吧。
TextBlob 示例,完整的要点和实时 Twitter 流可用。
基于特征方法的机器学习
我意识到,如果我想要更高的准确性,我需要使用机器学习;语境化是关键。我从传统的浅层学习方法开始,如单层神经网络中使用的逻辑回归和支持向量机算法。除了比深度学习需要更少的工作之外,其优势还在于从原始数据中自动提取特征,只需很少或不需要预处理。我使用 NLP 软件包 spaCy 和 ML 软件包 scikit-learn 来运行简单的实验。我受到了一篇博文的启发,作者使用这两个包来检测社会评论中的侮辱,以识别欺凌者。对于细粒度的情感分类,机器学习(基于特征)比基于规则的方法有优势,这篇优秀的帖子在 5 级斯坦福情感树库(SST-5)数据集上比较了基于规则的方法和基于特征的方法的准确性。
深度学习:嵌入和变形金刚
深度学习和单词嵌入进一步提高了情感分析的准确度。2013 年,谷歌创建了 Word2Vec 嵌入算法,它与手套算法一起仍然是最受欢迎的两种单词嵌入方法。要进行实际演练,请查看的这篇文章,作者在文章中使用嵌入式技术创建了一个图书推荐系统。传统上,对于深度学习分类,单词嵌入将被用作递归或卷积神经网络的一部分。然而,这些网络需要很长时间来训练,因为递归和卷积很难并行化。注意力机制提高了这些网络的准确性,然后在 2017 年,transformer 架构引入了一种使用注意力机制的方法,没有递归或卷积。因此,在过去几年中,NLP 在深度学习方面的最大发展无疑是变形金刚的出现。
Python 深度学习库
当我开始研究深度学习时,我依靠 Reddit 的建议选择了一个 Python 框架作为起点。对初学者的最大建议是 Python 库, Keras ,它是一个功能 API。我发现它非常容易理解,特别是因为它建立在 Tensorflow 框架之上,具有足够的抽象性,细节不会变得令人不知所措,并且足够简单,初学者可以通过玩代码来学习。仅仅因为 Keras 简化了深度学习,这并不意味着它不具备以复杂的方式处理复杂问题的能力。在必要时,用 Tensorflow 工具来增加 Keras 相对容易,以便在较低的抽象层次上调整细节,因此 Keras 是深度学习战场上的有力竞争者。在下面的代码片段中,我试图从预训练的语言模型中构建一个分类器,同时尝试使用多样本丢失和分层 k 折叠交叉验证,所有这些都可以使用 Keras 实现。
多辍学模型的 Keras 代码片段,带有分层 k-fold 交叉验证的抽样。
我对变形金刚的介绍是可爱命名的 Python 库,拥抱变形金刚。这个库使得将变形金刚与主要的机器学习框架、 TensorFlow 和 Pytorch 一起使用变得简单,并且提供他们自己的hugging faceTrainer来微调他们提供的预训练模型的分类。最受欢迎的 transformer BERT 是一个在巨大语料库上预先训练的语言模型;基本模型有 1.1 亿个参数,大型模型有 3.4 亿个参数。对于情感分类,BERT 必须在下游分类任务中使用带有情感标签的数据集进行微调。这被称为迁移学习,它利用预先训练的模型权重的力量,允许在微调过程中迁移上下文嵌入的细微差别。还有其他几个变压器,如罗伯塔,阿尔伯特和伊莱克特拉,仅举几例。除了非常容易使用之外, Huggingface 还有很好的文档,如果你有兴趣探索其他模型的话,链接于此。此外,由于在 CPU 上进行微调需要时间,我建议利用 Colab 笔记本,这将允许你在谷歌的云 GPU 上免费运行实验(有每月速率限制),以加快训练时间。
哪个机器学习框架适合你?
我可以根据我的经验提供我对我更喜欢哪个机器学习框架的看法,但我的建议是至少尝试一次。OG 框架 Tensorflow 是一个优秀的 ML 框架,但是在我的 NLP transformers 实验中,我主要使用的是 Pytorch 框架(富于表现力、非常快速、完全控制)或 HF Trainer(直接、快速、简单)。我对 Pytorch 的偏爱是因为它允许在设计和修补实验时进行控制——而且它比 Keras 更快。如果你喜欢面向对象编程胜过函数式编程,我建议你使用 Pytorch 框架,因为它的代码使用了类,因此简洁明了。在下面使用 Pytorch 的代码片段中,我创建了一个分类器类,并使用构造函数从该类创建一个对象,然后由该类的 forward pass 方法执行。
使用 Huggingface 预训练模型的 BERT py torch 实现片段。
需要额外的代码来运行向后传递,并使用优化器来计算损失和更新权重。 Pytorch 的代码明显比 Keras 所需的代码长。如果你喜欢快速编写代码,而不是详细说明每一个训练步骤,那么 Keras 是你更好的选择。然而,如果你想了解训练中发生的一切, Pytorch 让这成为可能。要获得带示例的 Pytorch 的分步指南,请查看这篇介绍性帖子。对于一个使用 Pytorch 的很酷的项目,我推荐维尼林·瓦尔科夫的这个很棒的教程,他向你展示了如何使用 BERT 和hugging face transformers和 Pytorch ,然后用 FASTAPI 部署那个模型。
希望这篇文章能让你明白从哪里开始用 Python 进行情感分析,以及随着你的进步你有什么选择。就我个人而言,我期待了解更多关于 NLP 的最新进展,这样我就可以更好地利用现有的令人惊叹的 Python 工具。
纽约巨人队 2020 年选秀的情感分析
图片来源于NorthJersey.com 的克里斯·佩多塔——今日美国网
体育分析
对巨人队选秀权的球迷情绪的深入观察
对于纽约巨人队的球迷来说,过去 10 年左右的选秀之夜传递了各种各样的情感。有高潮也有低谷。根据选秀之夜的反应和在球场上的表现,前台已经确定了几个人选,最著名的是小奥黛尔·贝克汉姆和萨昆·巴克利。不幸的是,对于每一个 Saquon 或 Odell,都有一些 Ereck Flowers 或 Eli Apples 加入其中。
不久前,球迷对 NFL 选秀的反应主要是通过现场球队球迷的嘘声或欢呼声来衡量的。然而,在当今世界,球迷们迅速涌向 Twitter 或 Reddit 等社交媒体网站,让人们听到他们对球队未来发展方向的看法。我开始通过 Python 使用网络抓取和情感分析来捕捉这种反应。
我决定收集 Reddit 的评论,而不是 Twitter,因为在我看来,Reddit 用户的反应往往比 Twitter 上常见的“烧掉它”人群更合理。本文将介绍通过情感分析获取、探索和分析数据的过程。我的目标是足够详细,读者可以为他们自己喜欢的 NFL 球队复制这一分析。
我将使用 Python 和 Jupyter Notebook 作为 IDE 来进行这个分析。下面列出了使用的包和依赖项。
获取数据
一旦包被导入,第一步是获得实际的 Reddit 评论数据。幸运的是,PRAW 包(Python Reddit API Wrapper)让这个任务变得简单了。
要打开一个连接,登录 Reddit,然后跟随这个链接。接下来,点击下面截图左下角显示的“创建另一个应用程序”按钮。
然后填写申请表。填写您的姓名,选择一个脚本,并添加您计划如何使用从 API 提取的数据的简短描述。对于重定向 URL,请始终输入“http//localhost:8080”。
现在已经创建了应用程序,返回到 Jupyter 笔记本,并使用 praw.Reddit 创建一个到 Reddit 的连接。client_id 是一个 14 个字符的字符串,它将出现在上面访问的 Reddit 应用程序页面上您的姓名和“个人使用脚本”下。你可以在创建 app 后找到“client_secret”,它是一个 27 个字符串。其余的字段非常简单明了,包括输入 Reddit 帐户信息。
一旦连接建立,您将能够访问 PRAW 提供的所有强大功能。出于我的目的,我只需要从 Reddit 访问标题、时间戳和评论数据。然而,你还可以获得更多的特性,比如文章正文、投票数和评论数。
为了访问我正在寻找的信息,我从 NYGiants subreddit 中的最后 750 个帖子中提取了帖子 id。这样,我确信我会涵盖 4 月 23 日至 25 日发生的整个 NFL 草案。
在访问了 post ids 之后,我编写了一个嵌套的 for 循环来捕获我正在寻找的信息。首先,我遍历每个 id,从相关帖子中提取评论。然后我循环浏览每一条评论,找出它们的标题和日期。Praw 文档提供了可以从 Reddit 帖子中提取的提交对象的详尽列表。
结果数据帧
争论数据
上面的数据框提供了必要的数据来捕捉今年选秀期间纽约巨人队球迷的时代精神。运行这个循环需要相当长的时间,所以我复制了一份数据,并将其写入一个 CSV 文件,以便以后访问。我还过滤了数据,以便它只包含从 4 月 23 日开始到 4 月 25 日午夜结束的 Reddit 评论,以确保我只查看 NFL 选秀日。顺便提一下:我已经养成了从数据帧的一部分复制数据的习惯。这个习惯确保我不会遇到任何来自熊猫的复制警告的场景。
然而,我不想只是全面地探索草案评论,所以我还为巨人的每个顶级选秀(前 4 轮)创建了一个特定的草案名称。为了实现这个目标,我使用了一个正则表达式来查找包含每个选秀名称的 Reddit 帖子标题。我将正则表达式设置为选择每个草稿的名字或姓氏,而忽略字母大小写。当然还有更彻底的表达方式可以使用,但我觉得这种方法抓住了绝大多数的评论。仅安德鲁·托马斯一人就在 3 天内发表了 972 条评论。不出所料,球员被选中的时间越晚,他们从巨人队球迷那里得到的评论就越少。
可视化数据
现在数据准备好了,我可以研究数据,看看它显示了什么。我最喜欢的一种可视化文本数据的方式是单词云的形式。我认为这是一种有趣而简单的方式来理解纽约巨人队球迷对选秀的看法。
要生成单词云,您需要安装软件包并编写一个函数来生成图像。通过调用 WordCloud 函数,您可以轻松地定制单词云的不同方面,如最大字数、字体大小和配色方案。包含一个停用词列表是非常重要的,这样你的词云就不会被诸如 I、and、am 等填充词所占据。向海王星实验室人工智能大声喊出来,获得如何生成单词云的精彩教程。
戴夫·盖特勒曼在 2020 年 NFL 选秀中以第四顺位选中了安德鲁·托马斯,这多少有些出人意料。然而,许多球迷(包括我自己)对这个选择感到高兴,因为它有助于巩固过去几年来糟糕透顶的进攻线。下面是一个单词云,描述了巨人队球迷对安德鲁·托马斯的选择的感受。作为参考,在其他单词的上下文中较大的单词比其他单词包含在更多的 Reddit 帖子中。有几个词会立即出现,比如“棒极了”,这可能代表了许多发帖人对该作品质量的看法。“加强”和“铲球”对我来说也很突出,显然是关于修复纽约巨人队进攻线的上述问题。
安德鲁·托马斯词云
单词云并不是一种分析文本的复杂方法,但它确实提供了一种快速查看数据集中哪些单词最常见的方法。为了简洁起见,我不会包括其他选秀状元的词云。但是,如果您感兴趣,一旦编写了函数,代码很容易被其他玩家复制。
基本情感分析
情感分析使用自然语言处理(NLP)来确定一串文本是否具有正面、中性或负面的含义。这是快速解决我正在试图解决的问题的完美工具…巨人队的球迷对 2020 年 NFL 选秀有什么感觉?
我将使用一个名为 TextBlob 的包来完成这项任务。通过 TextBlob 运行情感分析将返回两个值,一个极性得分和一个主观性得分。极性分值的范围从-1 到 1,适用于字符串中的每个单词。肯定暗示的单词得分为 1,而否定暗示的单词标记为-1。串中这些分数的平均值产生最终的极性分数。主观性得分的范围是从 0 到 1,简单地衡量一个字符串的主观程度。例如,句子“我午餐吃了一份鸡肉三明治”的主观性得分较低,因为这是事实,因此没有解释的余地。在本文中,我将更多地关注极性得分。 TextBlob 网站有更多与其情感分析功能相关的信息。
下面的函数允许我将极性得分应用到每个球员的数据框中的每个评论。使用这个函数,我将一个字符串放入一个 TextBlob 中,然后删除停止的单词,最后计算剩余单词的极性得分。有必要删除停用词,以免夸大中性评论的数量。
一旦创建了“polarity_score”函数,就可以很容易地将它应用于每个球员的数据框,以计算每个评论的情绪。
在我分析的这一点上,我意识到我想要容易地分析每个玩家对彼此的情绪。所以我运行了几行代码,将每个玩家组合到一个数据框中。首先,我添加了一个名为“Player”的特性来识别评论是针对哪个玩家的。接下来,我将每个球员添加到一个名为“draft_class”的数据帧中。
现在,我可以轻松地比较 2020 年每个选秀权的球迷情绪了。为了完成这个任务,我决定使用 Plotly express ,因为它能够交付交互式可视化。这对于关注数据的特定部分以及悬停在数据点上查看特定值非常有用。
import plotly.express as px
我决定首先探索巨人的前四个选秀权的极性得分的分布。为了做到这一点,我创建了一个直方图,每个玩家都有不同的分布。Plotly express 还允许用户轻松调整直方图仓的数量、图表颜色和图表/轴标签,如下面的代码所示。下面的缩写循环删除了图表右侧自动生成的球员姓名的文本标签。我觉得包括这些标签是多余的,因为图例也是可用的。
注意:我为这篇文章中没有直接嵌入的可视化图形道歉。Embed.ly,支持媒体嵌入的技术遇到了一些技术问题。
[## 巨人选秀的极性得分分布| Bkmurphy 制作的直方图| Plotly
Bkmurphy 的“巨人选秀极性得分分布”交互图和数据是一个直方图,显示…
chart-studio.plotly.com](https://chart-studio.plotly.com/~bkmurphy/1.embed)
数据显示,所有 2020 年巨人队的选择都遵循类似的极性得分分布。对每个球员的大部分评论都围绕着一个中性的内涵。不过我们也看到 2020 选秀班正面评价明显多于负面。这可能预示着一些事情。首先,这可能意味着巨人的粉丝群对选秀的整体方向感到满意,对前台的工作感到满意。我认为这将是一个有点合理的结论,考虑到许多球迷希望看到今年选秀中的进攻线和防守。或者,这可能意味着球迷们正在合理化,选择的球员是最好的,有助于巨人未来的改善。
在查看了极性得分分布后,我对了解每个玩家正面、中立或负面评论的百分比很感兴趣。我很快编写了一个函数,将大于 0 的值分类为“正”,如果值等于 0 则为“中性”,如果小于 0 则为“负”。
然后,我将这个函数应用于每个玩家数据框的极性得分,为情绪创建一个新列。生成的数据框如下图所示。
每个草图拾取的最终数据框
此时,我可以操纵数据来显示每个玩家的每种情绪类型的百分比。我决定将数据可视化在一个堆积条形图中。这样做需要对上面显示的数据框进行一些额外的数据操作。对于每个玩家,我创建了一个新的数据框,通过将每个情感类型的值计数除以数据长度来实现。然后,我必须组合这些数据框,并将值放入数据透视表中,以正确格式化堆积条形图的数据。生成的数据透视表如下所示。
情感价值数据透视表
这个数据透视表提供了一种在交互式条形图中可视化结果的方式。我选择不包含开发数据透视表的代码,因为它有些冗长。如果有人感兴趣,我很乐意与大家分享本文之外的代码。
[## 纽约巨人 2020 选秀阶级情绪| Bkmurphy 制作的堆积条形图| plotly
Bkmurphy 的“纽约巨人队 2020 选秀阶层情绪”互动图和数据是一个堆积条形图,显示…
chart-studio.plotly.com](https://chart-studio.plotly.com/~bkmurphy/13.embed)
快速浏览一下 2020 年选秀班的情绪可以发现,大约 55%与安德鲁·托马斯有关的评论都有积极的内涵。相反,约 14%的评论对选择他持负面看法。再次,这支持了巨人队的球迷对安德鲁·托马斯作为第一轮选秀权感到满意的想法。
大多数选秀权都和安德鲁·托马斯有相似的正面/负面评论比例。我确实注意到负面评论的比例在高轮选秀中显著增加。这让我很惊讶,因为我预计中性评论的数量会增加,因为球迷不太可能熟悉后面几轮的球员。我怀疑负面评论的增加是因为许多球迷在选秀中更倾向于选择某个球员。也许他们认为这个球员是偷来的,认为巨人不选他是疯了。当巨人不选择这个球员时,我认为球迷更有可能消极地看待最终的选秀权。当然,这更多的是个人偏见的反映,而不是对真正的巨人选秀权的损害。
结论
好了,现在您应该能够通过从 Reddit API 中提取评论来运行完整的情感分析。情感分析是一种快速了解人们对某个特定话题的感受的方法。
虽然我将这个过程应用于 NFL 草案评论,但这个过程在许多不同的应用程序中是可重复的。例如,一家企业可以收集 Twitter 或 Reddit 上的评论来了解客户的声音,或者《星球大战》等电影系列的粉丝可以分析粉丝对最新电影发行的感受。可能性是广泛的,并为一些创造性的项目留下了很大的空间。
我希望这个教程是有用的。如果你有任何问题,评论,建设性的批评,或其他想法,请随时在下面的评论中告诉我!
基于深度学习的优步和奥拉情感分析
了解印度出租车服务客户的需求
肖院长在 Unsplash 上的照片
本文介绍了我们使用深度学习来了解优步和 Ola 在印度各地的出租车服务的研究。
要点
- 我们的工作针对不同人群的日常交通方式,以及他们对服务提供商的期望。
- 目前在印度最受欢迎的两家出租车服务是优步和 Ola,拥有大量生活方式不同的用户。
- 如今,Twitter 正处于数据高峰期,每天有数百万人发推文,目前优步和奥拉在 Twitter 上的粉丝分别为 315.2K 和 244.9K。
- 用于理解人们情绪的深度学习算法是卷积神经网络。
- 我们评估情绪类别的模型,例如积极和消极,以找出它相对于用例产生的准确性。
介绍
Twitter 情绪分析用于发现推文背后人们的情绪或情感。通过推文分析个人/客户的评论,这有助于公司进一步了解客户对公司提供的产品或服务的评论。自从 Twitter 情感分析开始以来,从客户的角度提取、量化和理解他们产品的价值对公司来说是非常有益的。虽然 Twitter 情绪分析可以在任何领域进行,但选择的领域是优步和奥拉出租车服务公司。选择优步和奥拉的原因是因为可以从出租车用户那里收集到大量的数据。这可以在以后用于提取推文,以了解客户对服务是否满意&他们面临什么问题。
研究人员已经对 3000 条推文进行了情感分析,在提取这些推文后,必须清除它们中的停用词、超链接和空格。我们想到使用的方法是深度学习,以更敏锐地理解它如何对优步和奥拉的 Twitter 情绪分析产生影响。对于我们的数据集,使用的算法是深度前馈神经网络(DFF)和卷积神经网络(CNN)。这两种算法都属于深度神经网络(DNN)的范畴。清理完 tweets 后,首先使用的技术是 Google Word2Vec。Google Word2Vec 是一种训练文本中词汇的高级方法。它训练词汇,使其尽可能接近单词的意思。各种参数是感知器的权重乘法、各种激活函数、用于优化输出和损失函数的优化器。精度是基于损失函数计算的。该函数用于计算训练和测试数据之间的损失,从而使我们了解深度学习算法如何影响优步和奥拉的推特情感分析。
资料组
使用 API 从 Twitter 获得用于情感分类的数据集。
CSV 格式的 Excel 表格
需要记住的重要一点是,可以从文本(用户的推文)中获得情感分类的相关信息。
情感分类涉及的步骤
获得所需用例有不同的步骤,它们是
情感分析的步骤
情感分析包括 7 个步骤,分别是:
1.文本输入
数据是从优步和 Ola 收集的,并牢记用例的相关参数。
2.标记化
符号化是从整体中提取有意义的数据的过程。
3.停止单词过滤
停用词是应该被过滤的常用词。
4.否定处理
否定处理决定了不同类型否定的否定范围。
5.词干
词干是一种压缩不同单词形式的方法。
6.分类
用于情感分析的分类算法,将在其中创建模型。
7.情感类
情感类别分为正面和负面,或者对于不同的用例可以有所不同。
词云生成
词云只不过是在特定文本中出现次数较多的词的可视化表示。单词越大,出现的次数越多,反之亦然。
词云让我们正确理解一个特定的词是如何与用例相关联的。
优步的文字云生成
优步的圆形文字云—作者图片
Ola 的词云生成
Ola 的圆形单词云—作者图片
算法
使用深度学习来理解情感的算法有
非深度前馈神经网络
单层神经网络—图片由作者提供
深度前馈神经网络
多层神经网络—作者图片
卷积神经网络(CNN)
一维卷积神经网络—图片由作者提供
谷歌 Word2Vec
Google Word2vec 是一种更好的训练文本理解不同单词之间词汇的方法。NLP 使用不同的词汇表进行改进,因为 word2vec 是两层的,包含不同的单词和单词之间的相似性,这有助于特定文本以更好的方式理解含义。关于网格的 google word2vec 的表示如下所示。
Google Word2Vec 展示——作者图片
深度学习用于尽可能最好地理解 Word2Vec。
实验
这项研究的实验部分由通过执行迭代获得的各种测试和结果组成。情感分析涉及的步骤有:
使用 TwitterAPI 从 Twitter 收集数据
CSV 文件包含两个数据集的 3000 条推文
获取每条推文的情感评分
将推文分为正面&负面
正面== 1 &负面== 0
生成单词词汇
将数据划分为 2400 个训练&测试
谷歌 Word2Vec 地图
越接近的点越相似——作者图片
特征数量与推文数据集——按作者分类的图片
用于优化网络的公式
感知器的权重乘法感知器具有一个输入,该输入具有一些输入值,并被传递到具有一些分配的权重的节点,该权重被加上偏差并被传递到激活函数。每个感知器的公式如下所示。
带输入和偏差的广义权重乘法—作者图片
激活函数权重相乘得到的值&加上偏置赋予激活函数,有不同的激活函数,本文使用的两个是 ReLu & Sigmoid 激活函数。
ReLU 激活功能—作者图片
Sigmoid 激活功能—图片由作者提供
优化输出的优化器优化器用于通过各种迭代来优化值,有不同数量的优化器可供使用。用于 DNN 的优化器是 Adadelta。Adagrad optimizer 的缺乏是由于分母值的增加导致了学习率的增加,为了克服这种影响,使用了 Adadelta。
Adadelta 优化器—作者图片
损失函数用于处理输出损失的损失函数是
二元交叉熵损失函数。使用二进制是因为输出分别为 0 & 1。
二元交叉熵损失函数—作者图片
为分类创建的模型
非深度神经网络
单层神经网络
在不同的时间间隔上训练非深度神经网络,以了解这如何影响大多数数据集的准确性。该模型分别针对优步和奥拉的数据集进行了训练。
单层神经网络获得的精度和损失
NDNN 的训练和验证准确性/损失
【NDNN 的 500 个数据集区间的精度
增加 500 条推文的数据集
该表具有以百分比表示的准确度,并且可以观察到,对于 500 个数据集,生成的准确度对于优步是 87.00 %,对于 Ola 是 70.00 %。Ola 从基本数据集得到的准确性相对较低,因此它为 3000 个数据集生成了最高的 81.88 %。优步数据集的平均准确率为 92.99 %,Ola 的平均准确率为 75.18 %,比优步低 17.81 %。
深度神经网络
多层神经网络
深度前馈神经网络也在超参数优化的帮助下使用,以了解各个模型需要多少个隐藏层。用于深度学习模型的隐藏层的数量是 2-隐藏层,所有其他参数保持不变。与批量大小为 50 的非深度神经网络相比,该模型中使用的时期也是 20。
多层神经网络获得的精度以及损失
DNN 的培训和验证准确性/损失
DNN 500 个数据集区间的精度
增加 500 条推文的数据集
可以观察到,优步数据集的基本精度为 88.00 %,奥拉数据集的基本精度为 71.00 %,优步数据集的最高精度为 96.33 %,奥拉数据集的最高精度为 82.05%,与模型的 1 层相比,精度没有显著提高。与非深度学习神经网络相比,优步数据集增加了 0.16 %,Ola 数据集增加了 0.17 %。
卷积神经网络
卷积神经网络
有一个维数为 300 和字数为 2200 的 1-嵌入层,它连接到 128 个内核大小为 3,4,5 的滤波器,并且使用的激活函数是 ReLu。Max Pooling 还用于从格网中获取最大值,这些值通过激活函数 Sigmoid 传递到输出层。
从卷积神经网络获得的精度以及损失
CNN 的培训和验证准确性/损失
CNN 500 个数据集区间的精度
增加 500 条推文的数据集
可以观察到,为优步数据集生成的最小准确度是 91.00 %,而 Ola 数据集是 65.00 %,这优于非深度神经网络和深度神经网络的准确度。优步和奥拉数据集的最大准确率分别为 96.00 %和 80.37 %,与其他两个模型的准确率接近。优步数据集的平均准确率为 93.59 %,而 Ola 数据集的平均准确率为 74.42 %。
结论
这些数据在深度学习算法的帮助下进行训练,以更深入的方式理解情绪。Google word2vec 用于生成词汇,并使数据集中的词与相似的词得到正确的理解。所有三个模型都计算了精确度。为优步数据集生成最佳精度的模型是具有两个隐藏层的深度神经网络。超参数优化提供了使用两个隐藏层的选择,这反过来最适合优步推文。类似地,为 Ola 数据集生成最佳准确度的模型是具有两个隐藏层的相同深度神经网络。据观察,与优步相比,Ola 推文的准确性并不是那么好,因为提取的推文有许多格式不正确的文本,尽管清理工作已经完成,但仍无法产生预期的准确性。还观察到 CNN 模型在 DNA 方面是温和的,这是有疑问的。卷积神经网络在图像处理方面更为人所知,但也用于理解它在文本分析中的表现。
参考
[1]去,亚历克,黄蕾,和 Richa Bhayani。“推特情绪分析。”熵 17 (2009): 252。
[2] Sharma、Anuj 和 Shubhamoy Dey。"情感分析的特征选择和机器学习技术的比较研究."2012 年 ACM 应用计算研究会议录。2012.
[3]金,尹。"用于句子分类的卷积神经网络."arXiv 预印本 arXiv:1408.5882 (2014)。
[4]塞弗林、阿利亚克塞和亚历山德罗·莫斯奇蒂。"用深度卷积神经网络进行推特情感分析."第 38 届国际 ACM SIGIR 信息检索研究与发展会议录。2015.
[5]王、博、。"基于方面的情感分析的深度学习."斯坦福大学报告(2015)。
在你走之前
研究论文:https://ieeexplore.ieee.org/document/9215429
代号:【https://github.com/yashindulkar/Uber-Deep-Learning
代号:【https://github.com/yashindulkar/Ola-Deep-Learning
亚马逊美食评论的情感分析:从 EDA 到部署
在 Unsplash 上由 Ayesha Firdaus 拍摄的照片
Amazon.com 公司是一家总部位于华盛顿州西雅图市的美国跨国科技公司。亚马逊专注于电子商务、云计算、数字流媒体和人工智能。由于他们在电子商务平台上实力雄厚,他们的评论系统可能会被卖家或客户滥用,他们会撰写虚假评论来换取激励。手动检查每一篇评论并标注其观点是昂贵的。因此,更好的方法是依靠机器学习/深度学习模型。在本案例研究中,我们将关注亚马逊上的 美食评论数据集 ,该数据集可在 Kaggle 上获得。
注意:本文不是对我们问题的代码解释。相反,我将解释我使用的方法。你可以从 这里 看我的代码。
关于数据集
该数据集由亚马逊超过 10 年的美食评论组成,包括截至 2012 年 10 月的 568,454 条评论。评论包括评级、产品和用户信息以及纯文本评论。它还包括所有其他亚马逊类别的评论。
我们有以下栏目:
- 产品 Id:产品的唯一标识符
- 用户 Id:用户的唯一标识符
- 配置文件名称:用户的配置文件名称
- 有用性分子:认为评论有用的用户数量
- 有用性分母:表示他们认为评论是否有用的用户数量
- 分数:评分在 1 到 5 之间
- 时间:时间戳
- 摘要:审查摘要
- 文本:评论
目标
给出一个评价,确定该评价是正面的(评分为 4 或 5)还是负面的(评分为 1 或 2)。
如何确定一个点评是正面还是负面?
我们可以使用分数/评级。评分为 4 或 5 可视为正面评价。评级为 1 或 2 可被视为负面评级。评级为 3 的审查被认为是中性的,此类审查在我们的分析中被忽略。这是一种确定评论极性(积极/消极)的近似和代理方式。
探索性数据分析
基本预处理
作为基本数据清理的一步,我们首先检查任何丢失的值。幸运的是,我们没有任何缺失值。接下来,我们将检查重复条目。经过分析,我们发现对于不同的产品,同一用户在同一时间给出了相同的评论。实际上这没有意义。所以我们将只保留第一个,删除其他重复的。
重复条目的示例:
数据
现在我们的数据点减少到 69%左右。
分析评论趋势
回顾趋势
- 从 2001 年到 2006 年,审查的次数是一致的。但之后,评论的数量开始增加。在这些评论中,许多评论的五星评级都很高。也许这是未经核实的帐户,以虚假评论不适当地提升卖家。另一个原因可能是由于用户帐户数量的增加。
分析目标变量
如前所述,我们将所有高于等级 3 的数据点指定为正类,低于等级 3 的数据点指定为负类。我们将忽略其余的要点。
目标
**观察:**很明显,我们的分类数据集不平衡。所以我们不能选择准确性作为衡量标准。所以这里我们将使用 AUC(ROC 曲线下面积)
为什么不平衡数据集的准确性不行?
考虑这样一个场景,我们有一个不平衡的数据集。例如,考虑信用卡欺诈检测的情况,其中 98%的点数为非欺诈(1),其余 2%的点数为欺诈(1)。在这种情况下,即使我们预测所有的点都是非欺诈的,我们也将获得 98%的准确性。但事实并非如此。所以我们不能用准确性作为衡量标准。
什么是 AUC ROC?
AUC 是 ROC 曲线下的面积。它告诉我们这个模型在多大程度上能够区分不同的类。AUC 越高,模型预测 0 为 0 和 1 为 1 的能力越强。用 TPR 对 FPR 绘制 ROC 曲线,其中 TPR 在 y 轴上,FPR 在 x 轴上。
分析用户行为
用户行为
- 在分析了用户带来的产品数量后,我们知道大多数用户都只带了一种产品。
- 另一件要注意的事情是,有用性分母应该总是大于分子,因为有用性分子是认为评论有用的用户数量,而有用性分母是表示他们认为评论是否有用的用户数量。有一些数据点违背了这一点。所以我们去掉这些点。
在我们的预处理之后,数据从 568454 减少到 364162。也就是说,大约 64%的数据仍然存在。现在让我们进入我们的重要部分。正在处理审阅数据。
预处理文本数据
在我们进一步分析和建立预测模型之前,文本数据需要一些预处理。因此,在预处理阶段,我们按以下顺序执行以下操作
- 从移除 Html 标签开始。
- 删除任何标点符号或有限的一组特殊字符,如、或。或者#!等等。
- 检查单词是否由英文字母组成,并且不是字母数字
- 将单词转换成小写
- 最后,删除停用词
列车测试分离
一旦我们完成预处理,我们将把数据分成训练和测试。我们将在根据时间对数据排序后进行拆分,因为时间的变化会影响评论。
向量化文本数据
之后,我应用了 bow 矢量化、tfidf 矢量化、average word2vec 和 tfidf word2vec 技术来描述我们的文本,并将它们保存为单独的矢量。由于对大量数据进行矢量化是很昂贵的,所以我计算了一次并存储起来,这样我就不想一次又一次地重新计算了。
注意:我对单词包和 tfidf 使用了一种单字方法。在 word2vec 的情况下,我训练了模型,而不是使用预先训练好的权重。对于 bow/tfidf,您总是可以尝试使用 n-gram 方法,并且可以在 word2vec 的情况下使用预先训练的嵌入。
您应该始终尝试根据训练数据来拟合您的模型,并根据测试数据来转换它。不要试图在测试数据上安装矢量器,因为这会导致数据泄漏问题。
TSNE 可视化
代表 t 分布随机邻居嵌入的 TSNE 是最流行的降维技术之一。它主要用于较低维度的可视化。在进入机器学习模型之前,我试图在更低的维度上可视化它。
TSNE
我在 TSNE 遵循的步骤:
- 保持困惑不变,我在不同的迭代中运行 TSNE,找到了最稳定的迭代。
- 现在保持迭代不变,我在不同的困惑下运行 TSNE,以获得更好的结果。
- 一旦我得到了稳定的结果,用同样的参数再次运行 TSNE。
但是我发现 TSNE 不能很好地分离低维的点。
注:我用随机的 20000 分(平均等级分布)试了试 TSNE。大量数据点可能会改善结果
机器学习方法
朴素贝叶斯
如果我们有一个基线模型来评估,在机器学习中总是更好。我们将从创建一个朴素贝叶斯模型开始。对于朴素贝叶斯模型,我们将拆分数据进行训练、cv 和测试,因为我们使用的是手动交叉验证。最后,我们在 bow 特征和 tfidf 特征上尝试了多项式朴素贝叶斯。在超参数调优之后,我们以下面的结果结束。
朴素贝叶斯
我们可以看到,在这两种情况下,模型都有点过度拟合。别担心,我们也会尝试其他算法。
逻辑回归
由于算法很快,我很容易在 12gb 内存的机器上训练。在这种情况下,我只将数据分为训练和测试,因为 grid search cv 进行内部交叉验证。最后,我对 bow 特性、tfidf 特性、平均 word2vec 特性和 tfidf word2vec 特性进行了超参数调优。
逻辑回归
尽管 bow 和 tfidf 特征在测试数据上给出了更高的 AUC,但是模型稍微有些过度拟合。平均 word2vec 特征使模型更一般化,在测试数据上 AUC 为 91.09。
avg-word2vec 上的性能指标逻辑回归
支持向量机
接下来,我尝试了 SVM 算法。我尝试了线性 SVM 和 SVM 径向基函数。SVM 在处理高维数据时表现良好。具有平均 word2vec 特征的线性 SVM 产生了更一般化的模型。
SVM
平均 word2vec 上的性能指标线性 SVM
决策树
尽管我们已经知道这种数据很容易在决策树上过度拟合,但我只是尝试了一下,看看它在基于树的模型上表现如何。
在超参数调优之后,我得到了下面的结果。我们可以看到,与逻辑回归、朴素贝叶斯和 SVM 相比,模型过拟合,决策树的性能较低。我们可以通过使用像成本复杂性修剪这样的后期修剪技术在一定程度上克服这个问题,或者我们可以在它上面使用一些集成模型。在这里,我决定使用像 random forest 和 XGboost 这样的集合模型,并检查性能。
决策树
随机森林
对于随机森林,我们可以看到测试的 AUC 增加了。但是,大多数模型还是有点过度拟合。
随机森林
XG-Boost
Xg-boost 的表现也与随机森林相似。大多数模型都过拟合。
xgboost
在尝试了几种机器学习方法后,我们可以看到逻辑回归和线性 SVM 平均 word2vec 特征给出了一个更一般化的模型。
不要止步于此!!!
序列模型呢。事实证明,它们能很好地处理文本数据。接下来,我们将尝试使用深度学习方法来解决问题,看看结果是否有所改善。
深度学习方法
基本上,如果我们使用序列模型来解决这个问题,文本预处理会有一些不同。
- 初始预处理与我们之前所做的相同。我们将删除标点符号,特殊字符,停用词等,我们也将每个单词转换成小写。
- 接下来,我们将使用另一种方法,而不是直接对数据进行矢量化。首先,我们通过编码将文本数据转换成有序的。也就是说,对于语料库中的每个独特的单词,我们将分配一个号码,如果单词重复,号码就会重复。
例如,“这是真正美味的食物,非常棒”的顺序是“25,12,20,50,11,17,25,12,109”,而“这是糟糕的食物”的顺序是“25,12,78,11”
- 最后,我们将把每个序列填充到相同的长度。
填料
标绘后,序列的长度,我发现大部分评论的序列长度≤225。所以我把序列的最大长度取为 225。如果序列长度> 225,我们将按顺序取最后 225 个数字,如果长度< 225,我们用零填充初始点。
我们的模型由一个具有预训练权重的嵌入层、一个 LSTM 层和多个密集层组成。我们尝试了 LSTM 和密集层的不同组合以及不同的漏失。我们使用手套向量进行预训练嵌入。我认为这在一定程度上对我们 AUC 分数的提高起到了重要作用。最后,我们用两个 LSTM 层和两个密集层得到了更好的结果,并且丢失率为 0.2。我们的架构如下所示:
体系结构
我们的模型在第二个纪元中很容易就收敛了。我们得到了约 94.8%的验证 AUC,这是我们得到的一般化模型的最高 AUC。
有一个 LSTM 层
有两层 LSTM
我们的一些实验结果如下:
LSTM 结果
就这样,我成功地训练了一个模型。这里来了一个有趣的问题。但是怎么用呢?放心吧!我还将解释我如何使用 flask 部署模型。
使用 Flask 的模型部署
这是大家错过的最精彩的部分。如何部署我们刚刚创建的模型?我选择 Flask,因为它是一个基于 python 的微型 web 框架。由于我来自一个非 web 开发人员的背景,Flask 相对来说比较容易使用。
现在,我们将通过预测文本“食物有好味道”的情感来测试我们的应用程序。我们将通过创建如下请求来测试它
试验码
我们的应用程序将输出给定文本成为相应类的概率和类名。在这里,我们的文本被预测为概率约为 94%的正类。
在外
你可以玩我的 Github 项目的全部代码。
改善范围:
- 尽管如此,我们目前的模式还有很大的改进空间。为了训练机器学习模型,我从来没有使用过完整的数据集。你可以试试。它可能有助于克服我们的 ml 模型的过度拟合问题。
- 我只对我们的深度学习模型使用了预训练单词嵌入,而没有对机器学习模型使用。所以你可以尝试使用预训练嵌入,就像手套或 word2vec 与机器学习模型一样。
参考文献
亚马逊评论的情感分析
来源:archwiz, via: Shutterstock
更好地理解数据是数据分析的关键步骤之一。在这项研究中,我将分析亚马逊的评论。这些评论是非结构化的。换句话说,这篇文章没有条理。然而,情感分析通过自动标记帮助我们理解所有这些非结构化文本。情感分析帮助我们以高效且经济的方式处理大量数据。
这项研究是更大研究的一部分。为了检查特征提取和数据清洗部分(上一步),可以检查 [我的上一篇帖子](http://Before making predictions based on machine learning models, we need to understand the data better. The reviews are unstructured. In other words, the text is unorganized. Sentiment analysis, however, helps us make sense of all this unstructured text by automatically tagging it. Sentiment analysis helps us to process huge amounts of data in an efficient and cost-effective way. That’s why, sentiment analysis was applied in on the text data.) 。你可以在这里 找到这项研究的所有 Python 代码 。在这项研究中,我将:
- 简要介绍情感分析的理论背景
- 执行情感分析
- 为每个步骤提供 python 代码。
什么是 NLTK?
为了执行情感分析,我们将使用 Python 的 NLTK 包。Christopher Manning 说:“NLTK 有点像 NLP 的瑞士军刀,意思是它对任何事情都不太好。但是它有很多基本的工具。”对于访问 Wordnet,这是一个简单的解决方案。
什么是 Wordnet?
T21 是由普林斯顿大学开发的一个大型英语词汇数据库。名词、动词、形容词和副词被分成认知同义词组(同义词组),每个同义词组表达一个不同的概念。同素集通过概念语义和词汇关系相互联系(Fellbaum,1998)。换句话说,Wordnet 可以被描述为在线词库。它告诉你词义和词义之间的关系。Wordnet 最初创建于 1985 年,目前仍在改进中。
Wordnet 可通过以下方式获得:
import nltk
nltk.download('wordnet')
在这项研究中,我们将使用两个主要的情感分类器:
1.极性
2.主观性
Python 的 TextBlob 包是一种执行情感分析的便捷方式。当计算单个单词的情感时,TextBlob 取整个文本的平均值。对于同音异义词,Textblob 不与不同的含义进行协商。换句话说,只考虑单词在整个文本中最常见的意思。为了制作所有这些模型,Textblob 使用 WordNet 数据库。
极性
极性是浮动的,在[-1,1]的范围内,其中 1 表示肯定的陈述,而-1 表示否定的陈述。图 1 显示了评论中极性得分的分布。大多数评论都是在积极的一面(图 1)。
# Create quick lambda functions to find the polarity of each review# Terminal / Anaconda Navigator: conda install -c conda-forge textblobfrom textblob import TextBlobdf['Text']= df['Text'].astype(str) #Make sure about the correct data typepol = lambda x: TextBlob(x).sentiment.polarity
df['polarity'] = df['Text'].apply(pol) # depending on the size of your data, this step may take some time.import matplotlib.pyplot as plt
import seaborn as snsnum_bins = 50
plt.figure(figsize=(10,6))
n, bins, patches = plt.hist(df.polarity, num_bins, facecolor='blue', alpha=0.5)
plt.xlabel('Polarity')
plt.ylabel('Number of Reviews')
plt.title('Histogram of Polarity Score')
plt.show();
图 1:评论极性分数的分布
在图 2 中,可以观察到,与差评相比,好评(好评=1)具有更高的极性。另一方面,好的评论也有更高数量的负极性评论。这是一个不平衡的数据,好评的数量高于差评。因此,在这一类别中看到更多的极端值并不奇怪。
plt.figure(figsize=(10,6))
sns.boxenplot(x=’Good_reviews’, y=’polarity’, data=df)
plt.show();
图 2:关于好或坏评论的极性分布的箱线图。
正如我们从这个方框图中看到的,
- 我们有一些极性很低(非常负面)的好评
- 一些负面评价具有很高的极性(正面陈述)
让我们来看看其中的一些:
df.loc[(df.polarity == 1 & (df.Good_reviews == 0))].Text.head(10).tolist()
表 1: 极性为 1(最正面)的评论,好评为 0(差评)
当检查表 1 时,可以看到一些评论实际上是正面的,但不知何故得到了不好的评论分数。请记住,这些都是极端的案例评论,看到他们的评级没有太大意义也就不足为奇了。
**标点符号 vs 极性:**从图 3 可以看出,标点符号的值低时,极性较高。对此的一个可能的解释是,更加注意标点符号的人在他们的产品评价中更倾向于平衡。尽管有异常值,平均极性得分几乎是一条线,在 0.25 左右。该信息与图 1 一致。我们还可以看到,在极性的两个方向上都存在极端情况(图 3)
plt.figure(figsize=(15,8))
df3= df.loc[df.upper <= 50]
sns.boxenplot(x='upper', y='polarity', data=df3)
plt.xlabel('Punctuation', fontsize=13)
plt.ylabel('Polarity Score', fontsize=13)
plt.title('Punctuation vs Polarity Plot', fontsize=15)
plt.show();
图 3:标点符号的数量和极性得分
乐于助人与极性:图 4 呈现了好评类别中乐于助人与极性之间的关系。有一些有趣的异常值。例如,一些评论的极性最低(最负面),但评级很好(好评论为 1),有用性超过 3。这个组合是一个有争议的案例。当我们更仔细地看这些案例时,我们可以看到这些评论没有对购买使用负面的词语(表 2)。那些否定的表达是为了和其他购买进行比较。目前,NLP 方法在处理这种单词用法方面做得不太好。
plt.figure(figsize=(12,6))
df_sub= df.loc[df.HelpfulnessNumerator <=30]
sns.boxenplot(x='HelpfulnessNumerator', y='polarity', hue='Good_reviews', data=df_sub)plt.xlabel('Helpfulness Numerator', fontsize=13)
plt.ylabel('Polarity Score', fontsize=13)
plt.title('Helpfulness Numerator vs Polarity', fontsize=15)
plt.show();
图 4:好评类别中的有用性和极性
表 2
主观性
主观性用于单个句子,以确定一个句子是否表达观点。就主观性而言,世界上的文本信息可以大致分为两大类:事实和观点。主观句通常指的是个人观点、情感或判断,而客观句指的是事实信息。事实是关于实体、事件和属性的客观表达。观点通常是描述人们对实体、事件及其属性的情绪、评价或感觉的主观表达(刘,2010)。
在情感分析中,主观性也是一个位于[0,1]范围内的浮点数。当接近 0 时,更多的是关于事实。当主观性增加时,它接近于一种意见。在数据集中,评论的主观性分数的分布类似于正态分布(图 5)。当我们检查主观性、极性、和好评特征之间的关系时,我们可以看到主观性和极性显示出漏斗模式(图 6)。还可以观察到,主观性评分低的评论在极性上也是中性评论。
对于创建主观性评分:
sub = lambda x: TextBlob(x).sentiment.subjectivity
df['subjectivity'] = df['Text'].apply(sub)
df.sample(10)
检查主观性分数的分布:
# Density Plot and Histogram of subjectivity
plt.figure(figsize=(10,5))
sns.distplot(df['subjectivity'], hist=True, kde=True,
bins=int(30), color = 'darkblue',
hist_kws={'edgecolor':'black'},
kde_kws={'linewidth': 4})plt.xlim([-0.001,1.001])
plt.xlabel('Subjectivity', fontsize=13)
plt.ylabel('Frequency', fontsize=13)plt.title('Distribution of Subjectivity Score', fontsize=15)
图 5:亚马逊评论中主观性分数的分布
plt.figure(figsize=(10,6))
sns.scatterplot(x='polarity', y='subjectivity', hue="Good_reviews", data=df)
plt.xlabel('Polarity', fontsize=13)
plt.ylabel('Subjectivity', fontsize=13)
plt.title('Polarity vs Subjectivity', fontsize=15)
plt.show();
图 6:主观和极性得分调整到好评类别
图 7 展示了极性和主观性如何受到评论评级的影响(好的评论特征)。在阅读这个图时,我们需要记住 y 轴在一个非常小的范围内。我们可以看到,两组之间的平均主观性得分差异可以忽略不计。(你可以在 我的 GitHub repo 上找到这个剧情的代码)
图 7:评论评级的极性和主观性得分的平均值
审查极端评论
为了更好地理解我们的数据,我们需要从不同的角度来检查它。有一些评论可以被认为是一个极端的案例。例如,表 3 给出了 10 条评论,它们具有最高的极性(最积极的情绪),但是“好评”值为 0,并且是最主观的(意见)。这些推文很难被情感分析算法评分。毫不奇怪,他们的得分最高(极性=1)。
df.loc[(df["Good_reviews"] == 0) & (df.polarity == 1 ) & (df.subjectivity ==1), "Text"].head(10).tolist()
表 3
为了理解数据是如何形成的以及情感分析是如何工作的,让我们用不同的标准来检查更多的评论(表 4 和表 5)。
df.loc[(df["Good_reviews"] == 1) & (df.polarity == 1 ) & (df.subjectivity ==1), "Text"].sample(5).tolist()
表 4
df.loc[(df["Good_reviews"] == 1) & (df.polarity == -1 ) & (df.subjectivity ==1), "Text"].sample(5).tolist()
表 5
总之,通过这项研究,我试图通过将情感分析应用于亚马逊评论数据来展示它是如何工作的。在接下来的研究中,我将通过一步一步的解释来展示如何使用潜在狄利克雷分配(LDA)进行主题分析。
开心分析!
*特别感谢我的朋友 Tabitha Stickel 校对这篇文章。
我的情感分析进一步内容推荐:
- 赵雅丽:【https://youtu.be/xvqsFTUsOmc?t=4125】
- 计算极性和主观性:https://planspace.org/20150607-textblob_sentiment/
参考文献:
费尔鲍姆,C. (1998 年)。WordNet:一个电子词汇数据库。布拉德福图书公司。吉邦,欧克斯,m .&贝洛特,P. (2016 年 6 月)。从表情符号到情感分析。
刘,学士(2010)。情感分析和主观性。自然语言处理手册, 2 (2010),627–666。