我敢说你永远不会再使用tf-idf

朱莉娅·席尔格(Julia Silge)是天体物理学家,R大师和美丽图表的制造者,她是一位数据科学家,从任何角度来看,它们似乎都是舒适快乐的猫,他们团结了存在的最美好的祝福。 并且生活在这个世界上几乎没有什么让她烦恼或烦恼的。

我向你保证,亲爱的读者,让这样的灵魂烦恼不会令人感到高兴。 但是,我怀疑TF-IDF先生向她(和她,他!)展示的所有款待和友善对可怜的茱莉亚有危险。 如果她不注意的话,我担心她可能会被要求永远沉下去。 因为尽管她认为TF-IDF先生的陪伴非常愉快,但我确信这场比赛很少推荐。

乌夫,好吧,这很累。 我回到自己的声音,而不是尝试简·奥斯丁的。 你好 这篇文章对从事文本分析的人们可能有用,也许对于简·奥斯丁的粉丝们来说很有趣,他们想知道哪本小说是简·奥斯丁在她最接近奥斯丁的那一本书,以及她的先驱者/同时代人与她的风格最相似。

老实说,整个文章的主要对象是:茱莉亚·席尔格(Julia Silge),我很欣赏他的作品。她和戴维·罗宾逊(David Robinson)最近在一本有关文本挖掘的书中放了许多有用的R代码和解释。 这篇文章基本上是我和我交换的一些推文的后续。

如果您喜欢这里和/或Julia和David的书中的内容,您可能还想使用我在食物评论中探索的方法来检查Jason Kessler的github和Dan Jurafsky等人的东西。

您可能还想看看Mark Liberman上奥巴马最喜欢的国情咨文。 正如他指出的那样,本博客中使用替代R的加权对数奇数法旨在:

考虑到X和Y均从同一词汇表中进行随机选择的零假设,考虑到我们计数中可能存在的抽样误差,折衷差异(可能只是偶然的情况)以及增强真正出乎意料的差异。

乔丹·安德鲁·卡特的简·奥斯丁的这张有趣图片

数据

由于我对Jane Austen风格的表达方式感兴趣,因此我需要找到一个比较集。 因此,我抓住了奥斯汀的同时代人或影响者的众多作家的古腾堡计划书(请肯定推荐我错过的人!)。

塞缪尔·理查森(Samuel Richardson)(1689–1761),劳伦斯·斯特恩(Laurence Sterne)(1713–1768),夏洛特·伦诺克斯(Charlotte Lennox)(1730–1804),奥洛达·伊马卡诺(Olodah Equiano)(1745–1797),夏洛特·史密斯(Charlotte Smith)(1749–1806),范妮·伯尼(Fanny Burney)(1752-1840),伊丽莎白·因克巴尔德(Elizabeth Inchbald) (1753-1821年),玛丽·罗宾逊(1757–1800年),安·沃德·拉德克利夫(Ann Ward Radcliffe)(1764–1823年),玛丽亚·埃奇沃思(1768–1849年),阿米莉亚·奥佩(1769年至1853年),沃尔特·斯科特(1771年至1832年),玛丽·布鲁顿( 1778–1818年),苏珊·费里尔(Susan Ferrier)(1782-1854年),凯瑟琳·克劳(Catherine Crowe)(1803–1876年),黛娜·玛丽亚·穆洛克·克拉克(Dinah Maria Mulock Craik)(1826–1887年)和布拉德登(1835–1915年)。

如果您想挑逗奥斯丁中的错字,请确保提供指向您15岁时撰写的手稿的链接

作为参考,奥斯丁居住于1775年至1817年。 她于1811年首次出版《 理智与情感》 。 为了它的价值,我包括了她的一些少年和信件。 最有趣的是从15岁那年开始,她被称为(保留拼写错误!) Love and Freindship

带有R代码的逐个播放

首先让我们加载267,219行数据(来自18位作者的126幅不同的作品-尽管您可以用第二个数字来质疑,因为例如Dinah Maria Mulock Craik的作品《一生难忘被视为多部作品(第1-3卷) )。此代码还解决了以下问题:Fanny Burney在数据框中显示为“ Fanny Burney”和“-Fanny Burney”。

  setwd(“ wherever_you_have_all_your_text_files”) 
 文件名<-list.files(路径=“。”,模式= NULL,所有文件= FALSE,完整。names= FALSE,递归= FALSE,ignore.case = FALSE) 
  read_text_filename <-函数(文件名){ 
ret <-read.delim(文件名,sep =“〜”,header = F)
ret $ Source <-文件名#EDIT
退回
}
 图书馆(plyr) 
  df <-ldply(文件名,read_text_filename) 
 图书馆(tidyr) 
  df <-separate(data = df,col = Source,into = c(“ Title”,“ Author”),sep =“-”) 
  df $ Author <-gsub(“。txt”,“”,df $ Author) 
  df $ Author <-gsub(“-”,“”,df $ Author) 

就目前而言,我实际上并不关心作品,只关心作者。 因此,我将简化数据框,使其仅是作者和文本:

  df <-df [,c(3,1)] 

现在,我想获得二元组(两个词的短语)。 我喜欢二元组而不是二元组,因为它提供了更多的上下文和语法-但有缺点(尤其是您的数据较少)。 您可以在此处阅读有关双字母组和否定的更多信息,也可以在此处添加双字母组(但对三字组了解不多)来提高准确性。

您也可以采用相反的方式(如Monroe等人所做的那样)并使用词干。 这会将像这样的东西变成“猫”。 它将helpfulhelpinghelpedhelpshelp变成“ help”。 它将Sense&Sensibility变成sens and sens

实际上,当我在SMS短信或Cher的tweet上进行此类工作时,我使用自己的特殊标记器,以便可以完全提取表情符号,表情符号和标点符号。 (标记化只是“您如何拆分’单词’-并非所有语言都使用空格,甚至不是英语,您是否希望将一串五个表情符号视为一件事或五件事?”)但是,基本上,我想这件事应该用于现代文本标记化的方法已经接近CMU的计算语言学家的工作。

好的,还有一点要注意的是,我将保留大写字母,主要是因为我们以后希望能够过滤出专有名称。

 图书馆(dplyr) 
 图书馆(tidytext) 
  df_bis % 
unnest_tokens(bigram,V1,token =“ ngrams”,n = 2,to_lower = F)
  df_bis_more % 
计数(作者,美术字)
  df_bis_more % 
bind_tf_idf(bigram,Author,n)
  df_bis_more <-df_bis_more [order(-df_bis_more $ tf_idf),] 

通过这种方法,我们看到总体上tf-idf得分最高的是“叔叔托比”(劳伦斯·斯特恩,使用了835次),伊丽莎白·英巴尔德的“伍德利小姐”和“埃尔姆伍德勋爵”(分别为461次和421次)。 简·奥斯丁的最高双亲是“奈特利先生”,“达西先生”和“克劳福德小姐”(奥斯丁分别写下了269、244和215次)。 我没有报告实际的tf-idf分数,因为它们……对于数字而言毫无意义。 (这是针对他们的另一个标记。)

但是这些结果似乎是正确的。 具有唯一名称的主要字符不应该放在首位吗? 一个问题是,这些都是关于参考的,以至于它们在风格上非常无趣。 也许我们能看到的一件事是,奥斯丁在她的著作中很少有上议院,只有:8位“巴伯恩勋爵”,9位“圣勋爵”,4位“拉文肖勋爵”(!!!)和“斯宾塞勋爵”。 而且,如果您好奇三个“哦主”和九个“如何”主。

TF-IDF的替代品

好吧,现在让我们做些不同的事情。 我们将使用信息不充分的Dirichlet事前计算加权对数奇数比(请参见Monroe等)。 我认为“无信息的先验”在这里有点用词不当,但它体现了我们只是将所有这些作者相互比较的事实。 如果我们只是像简·奥斯丁那样互相对着书本进行分析,那么我们可以将范妮·伯尼(Fanny Burney)以及其他所有书本用作“信息性”书目,因为这样可以更深入地了解背景。 我们可以使用大量现代网络语言,但这是不对的。 要点是,您将从与您正在研究的人/文本相关的更大样本中汲取经验。

  termfreq <-aggregate(列表(TF = df_bis_more $ n),列表(bigram = df_bis_more $ bigram),FUN =总和) 
  df2 <-合并(df_bis_more,termfreq,by =“ bigram”) 
  df2 $ DFnotthem <-df2 $ TF-df2 $ n 
  df2 $ sum <-sum(df2 $ n) 
  authortermfreq <-aggregate(df_bis_more $ n,by = list(Author = df_bis_more $ Author),FUN = sum) 
  df2 <-merge(df2,authortermfreq,by =“ Author”) 
  df2 $ xnotthem <-df2 $ sum-df2 $ x 
  df2 $ l1them <-(df2 $ n + df2 $ TF)/((df2 $ sum + df2 $ x)-(df2 $ n + df2 $ TF)) 
  df2 $ l2notthem <-(df2 $ DFnotthem + df2 $ TF)/((df2 $ sum + df2 $ xnotthem)-(df2 $ DFnotthem + df2 $ TF)) 
  df2 $ sigmasqrd <-1 /(df2 $ n + df2 $ TF)+ 1 /(df2 $ DFnotthem + df2 $ TF) 
  df2 $ sqrt <-sqrt(df2 $ sigmasqrd) 
  df2 $ logodds <-(log(df2 $ l1them)-log(df2 $ l2notthem))/ df2 $ sqrt 

这给了我们要与tf-idf进行比较的主要内容,但让我们做其他一些事情。

  df2 $ perc <-df2 $ n / df2 $ TF 
 图书馆(plyr) 
  numauthors <-ddply(df2,'bigram',function(x)c(numauthors = nrow(x))) 
  df2 <-merge(df2,numauthors,by =“ bigram”) 
  df2 <-df2 [order(-df2 $ tf_idf),] 
  df2 $ ranktfidf <-seq.int(nrow(df2)) 
  df2 <-df2 [order(-df2 $ logodds),] 
  df2 $ ranklogodds <-seq.int(nrow(df2)) 
  df2 $ rankdiffabsv <-abs(df2 $ ranktfidf-df2 $ ranklogodds) 

好的,首先要注意的是,tf-idf将对数赔率的前两位排在超低位置。 这些是“说”和“的”,这是沃尔特·斯科特(Walter Scott)经常使用的东西(分别为5824次和32468次)。 这些二元组的对数奇数得分非常高。 他们是极端的苏格兰人(“其中的一个”和“外面的”;“所说的女士”,“所说的国王”,“所说的页面” 当然是最好的,在修道院中被使用过89次) ,“称子”。

使用tf-idf进行文体分析的问题之一是,如果每个人都使用tf-idf,即使某些人比其他人使用它们的次数更多,他们也会得到0分。 这是因为“ tf-idf”中的“ idf”用于反文档频率。 作为英语阅读者/演讲者,您将不会惊讶所有18位作者都使用“ of the”和“ said the”。 反向文档频率的计算方法是:文档总数(=作者,因此18)的自然对数除以使用该短语的文档(作者)数(在这种情况下,每个人都使用它,因此又是18)。 18/18的自然对数=自然对数(1)=0。因此,将tf * 0 = 0乘以。 这样做的基本原理是正确的-tf-idf通常用于查找搜索词,老实说,如果出现在任何地方,它都不是一个很好的搜索词。

但是,您和我俩都知道有些人说/写其他人都做的话……只是更多。 就像沃尔特·斯科特(Walter Scott)。 在我看来,这是对数赔率的巨大优势。 并且它可以帮助您区分这些作者。 因此,在tf-idf中,简·奥斯丁(Jane Austen)的和也是“ 0”,但在对数奇数中,这些值分别为-6.1和-6.6。 就是说,对数赔率可以帮助我们发现,尽管Jane Austen使用了这些词(的表示为 25倍,的表示为 3699),但与其他作者相比,这些单词的数量远远少于我们的预期。 我不会问的一个问题是,奥斯丁是否拒绝让角色不带名字说话(例如,她可能更喜欢“说道林神父”而不是“说神父”)。 当然,您可以说是维吉兰特人的斗篷 ,但也许奥斯丁会更喜欢维吉兰特人的斗篷 。 或者,也许有一些更明确的文章是奥斯汀不喜欢的。

两种方法的最高值大多是专有名词。 因此,让我们做一个快速过滤器来查找不包含任何大写字母的双字母组。 当您比较排名时,以下是最上面的小写短语,至少相隔50个点。 您认为其中哪个更适合您?

  • 她的姑姑,将军的每件事,都非常亲切,她必须在那里非常不同地倾向于某种东西
  • 不,要,非常,她可以,不,应该,不可以,必须,不知道

我不确定自己是否有偏好。 但这将显示出对数赔率的优势:在这种情况下,我可以说您选择的任何一个列表都充满了高对数赔率。 当您添加或减少文本时,短语的对数奇数会发生变化,但是只要它们高于1.96,这都表示为Austen-y。 您拥有的证据越少,加权对数奇数将减少的越多。 很难比较或理解Tf-idf值-您必须相对于语料库了解它们。 因此,对数奇数的另一个好处是人类可读性。

在tf-idf的全部18位作者中,前10,000个术语中,log-odds同意其中应有8607个词的排名很高(对数几率大于1.5)。 它只认为排名靠前的tf-idf项目中有两个是愚蠢的(即负对数奇数)。 甚至这些只是微弱的负面因素: De Courcy对Jane Austen而言为-0.47对数,而对Catherine Crowe而言则为-0.033对数。 老实说,我认为这不会使Monroe等人的方法更好。 但是在接下来的几节中,我将展示一些扩展,您可能可以弄清楚如何使用tf-idf,但并不那么简单。

带我去奥斯丁峰

简·奥斯丁(Jane Austen)超过1.5的对数为932个。 我们可以拿她的小说来数一看。 我们将它们乘以“百万分之二”来对其进行归一化。 例如, 艾玛在这部小说中总共164,267个二元组中有80种“非常”的用法。 如果艾玛(Emma)是一本更长的书—一百万个双语法例—我们希望会有487个“非常”的书。 这只是让我们比较不同长度的作品。 我们将这个值乘以所有作者集中为奥斯丁计算的对数奇数。 “非常非常”非常适合澳大利亚人:其对数奇数得分是7.06。 最后,我们总结每项工作。 我们已经控制了长度,并为更多的奥斯曼语词组赋予了更大的权重。 所以我们只需要比较总和。

事实证明,简·奥斯丁在她出版的第三本小说《 艾玛》(Emma)中是她最大的奥斯丁主义者。 这是她按奥丁尼亚式排列的书。 这是确切的顺序,但是有一些自然的切入点,因此我将它们分为三组(在每个子弹束中,奥氏体分数是有序的,但是接近):

  • 艾玛(1816),理智与情感(1811),傲慢与偏见(1813)
  • 曼斯菲尔德公园(1814),诺桑杰尔修道院(诺曼底修道院,1​​818年出版),精选来信(1796–1816)
  • 说服力(推测出版,1818年),苏珊夫人(少年时期,约1793年至1795年),爱与友谊(少年时期,约1790年)

也许您想要的段落是《奥斯丁小说》中的《奥斯丁》? 在这里,用粗体表示的是澳式转折:

唯一 想做的就是使前景完全令Emma满意-在弗兰克·丘吉尔(Frank Churchill)留在Surry的允许期限内, 将球固定一天。 因为,尽管韦斯顿先生有信心,但她不能认为丘吉尔夫妇不可能允许侄子在他两周之后的一天里生活 如此不可能。 但这被认为是不可行的。 准备工作必须花些时间,在进入第三个星期之前, 任何事情都无法妥善准备,几天之内, 他们必须计划,进行并希望不确定性存在风险,在她看来 ,风险很大,徒劳无功。

最常见的奥斯丁短语是:

是的,我感到内this,因为我从R切换到Tableau来制作此图形。 我用紫色把我认为很有趣的东西放了起来–奥斯丁有一些确定性,还有其他存在性

我个人中其他一些最喜欢的奥斯丁短语包括爱,等于,什么,非常漂亮,非常和agree ,乐于助人以及每一个方面

作者的反风格

我喜欢看到别人不说什么的能力。 当前的计算仅报告实际使用双字母组的作者的对数为负。 填写值的一种方法是找到丢失的行。 例如,范妮·伯尼(Fanny Burney)的奈特利(Knightley)先生代币为零-让我们为她和其他所有人(包括奥斯丁)加一个。

我们可以使用一些R代码来执行此操作,但是坦率地说,填写所有这些二元组所需的时间比我想要的要长。 因此,我将继续说,我只关心至少一位作者的对数奇数已经高于1.5或低于-1.5的术语。 (如果您更科学,则可能要使用1.96作为截止值。)

  topbottom  1.4999) 
  justbis <-as.data.frame(唯一(topbottom $ bigram)) 
  df3 <-subset(df2,bigram%in%justbis $`unique(topbottom $ bigram)`) 
 图书馆(plyr) 
  df3filled 已完成%(作者,bigram,fill = list(n = 0)) 
  df3 <-df3filled [,c(1:3)] 
  df3 $ n <-df3 $ n + 1 

该子集将df2数据帧减少到所有行的13%。 然后再次将其填充五倍。

为了节省空间,我将重做以上所有操作,以获取约164k唯一二元组子集的新对数奇数分数,至少一个作者对此有强烈的偏爱。 如果仔细观察,您会知道新数字将忽略一堆“无趣”的二元组。 我内心的完美主义者讨厌我没有使用所有数据,但是我的直觉是,减少计算时间不会有太大不同。 我尚未证明这是真的,请随时与我矛盾。 (我经常劝说人们不要删除“停用词”……在这里,我基本上是说“不要使用预定的停用词,因为您并不真正知道它们是否重要,但请继续忽略您有一些停用词打电话的基础……无聊”。

作者拥有的单词越多,对他们而言,不要使用在其他人中很流行的短语就越重要。 因此,对于Jane Austen来说,这n + 1表明以下短语-她从未使用过-考虑到其他人使用它们的频率,这是最令人惊讶的:

  • 上帝需要死亡,你有,你是我,我没有

必须需要”一词尤其与玛丽·伊丽莎白·布拉德登(Mary Elizabeth Braddon)联系在一起,但是沃尔特·斯科特(Walter Scott)也经常使用它,塞缪尔·理查森(Samuel Richardson),夏洛特·伦诺克斯(Charlotte Lennox),范妮·伯尼(Fanny Burney)都使用了20次以上。

Olaudah Equiano的自传包括奴隶制的恐怖,但与他的同时代人相比,语法上的否定性(例如“不要”,“不要”)少得令人惊讶

同时, 我不是 Braddonesque,Edgeworthian和Burneyish。 这是绝对的非奥斯丁。 唯一使用较少我不使用的作者是Olaudah Equiano,他从不使用它。 请注意,“ 不” (不收缩)是非常奥氏体的, “不”也是如此。 Olaudah Equiano也不使用not 。 我不确定他和否定怎么回事,但这可能值得研究。

哪个作者最喜欢Jane Austen(不是Jane Austen)?

我们的新数据框使我们能够计算出与其他人最相似的人。 我要声明的是,我并不真正在意某个作者在75%的时间中使用的字词,还是在此极端数据帧中出现在总字词频率的最低四分位数中的字词(“限制为39英寸,请记住这不是确切数字,因为我们为每个不使用术语的作者增加了+1)。

  highspecificterms  0.75 | TF <40) 
  highhighspecificterms <-as.data.frame(unique(highlyspecificterms $ bigram)) 
  df3reduced <-subset(df3,!(df3 $ bigram%in%highspecificterms $`unique(highlyspecificterms $ bigram)`))) 
  df3forcor <-df3reduced [,c(1,2,16)] 
  df3forcor <-spread(df3forcor,Author,logodds,fill = NA) 
  df3forcor.cor = cor(df3forcor [,-1],method =“ spearman”)^ 2 
  df3forcor.dist = dist(df3forcor.cor) 
  df3forcor.clust = hclust(df3forcor.dist) 
 情节(df3forcor.clust) 

在这里,我们看到Fanny Burney和Jane Austen看起来是最相似的。 而且您会注意到,出于某种原因,我不知道古腾堡计划将一位名字叫“伊丽莎白”的作者称为“夫人”。 Inchbald”。

我醒来看起来很好。

这当然是有道理的-范妮·伯尼(Fanny Burney)是一位工作广为人知且对简·奥斯丁(Jane Austen)有影响力的人。 我还没有研究过将它们结合在一起的七巧板(对不起……还不够长吗?!)也就是说,他们俩都在小说中使用了书信形式(其中有些小说是一个人物在写的信)到另一个字符)。

两者之间最著名的联系是伯尼小说的结局, 塞西莉亚可能是简·奥斯丁获得她最著名作品的标题的地方(封顶在古腾堡计划中,btw)。

莱斯特博士说:“整个不幸的生意都是PRIDE和PREJUDICE的结果。 您的叔叔迪安(Dean)以他的任意意志开始了它,仿佛他自己的一项法令可以制止自然路线! 借着的名字, 似乎有能力维持生计,这个男性分支的家庭已经灭绝了。 您的父亲莫蒂默(Mortimer)先生也保持同样的自我偏好,喜欢用喜欢的声音逗他的耳朵挠the,而对儿子与一个富有而应得的妻子的坚定幸福感到满意。 但是,请记住这一点; 如果对PRIDE和PREJUDICE来说,您应该为自己的痛苦而苦恼,那么善与恶之间的平衡是如此美妙,以至于对PRIDE和PREJUDICE来说,您也应该对他们予以解约:就我可以对Delvile先生说的,无论是推理还是恳求,我都说过-我所能建议的,我所建议的所有男人都想听到的,-被完全扔掉了,直到我向他指出他自己的耻辱,因为在这些卑鄙的住宿中im妇daughter

难道不是一个很棒的词吗? “包围在墙壁中” –其中的“壁画”与您在“壁画”中看到的根相同。

现在,如果您能原谅我,我突然需要阅读埃德加·爱伦·坡的书。