00:00
我们看一下这里的这个t fidf的算法示例,首先呃,很简单,第一步是不是还是先引入引入依赖啊,这里要用到的依赖那派,呃,然后还有一个pandas pandas,这就是我们到时候可能画一个表格,把数据列出来好看一点对不对?呃,它里边有data frame,然后接下来的这一步,大家看我是不是先应该去考察数据啊,我现在有数据对吧?这里我就简单定义了,所以大家看我这个就不算教程,只能是说算是一个事例吧,我这里定义了。一个字符串,大家想这是不是就相当于是一个文档啊,尽管是非常简单非常简化的一个文档,呃,这也算一个文档,对不对啊?定义一个dock a,一个do b,大家看一下这两个文档,如果让大家体验关键字的话,大家会觉得A的关键字是什么?B的关键字是什么?这个猫坐在我的床上对吧?然后这狗是坐在我的膝盖上。
01:00
那肯定你A说的是猫对不对,B说的是狗,对吧?所以诶,这个猫是关键词,这个狗是关键词,还有什么吗?关键啊,大家觉得这个我是关键字是吧?呃,对,如果要是说有更多的文档的话,或许我也是一个关键词,但是其实直观上来看的话,我我的这种词其实很常见,对吧?应该很多文档里面都有,对于这两个文档而言,是不是它都有啊,都有的词你是不是就不应该叫做关键词啊,所以大家可能还会想到,对,是不是他坐在哪儿这个词不一样,或许这是这两个文档它关键点不一样的地方,对不对?诶,所以我们直观想的话,就是这一个猫,一个狗,一个在床上,一个在膝盖上,这个可能会不一样。好,接下来我们看看这个用t fidf怎么样能把这个关键词提取出来,呃,那首先有了这个,这是一个字符串。文文本的这个原始内容对不对,我们先做一些,呃,数据的处理,怎么样处理呢?这里会有一个叫做bow,就是bag of word,就是磁带,磁的带子,对吧,有一个这样的一个模型,它是什么模型呢?其实也很简单,就是把一个文档里边的词先全一个一个摘出来,对吧?因为我们这是一个就是完整的一个字符串,你直接这么去分析的话,肯定没法分析,是不是先得做分词啊,哎,所以是把它先分词分出来,怎么分呢?呃,这个就是其实是字符串的一个处理了,我们是不是可以split。
02:38
对吧?Split用什么去分割,对空格分割得到就可以了,同样得到B的一个磁带模型,Do b split空格啊,这个我们看一眼,Boa现在是什么样子啊,现在得到的是不是就是这样的一个列表啊,一个例子的对不对?那就是里边的每一个元素,就是在这个文档里边出现的所有的词。
03:08
那大家会想到,那到时候我们统计词频的时候,是不是有它就可以啊,啊,那这里边我们还要做一个操作,做一个什么操作呢?我们希望构建一个完整的词库,呃,这里边做一个操作啊。这个词库大家会想到一个word set,对吧?那怎么去贡建这样的词库,是不是就是把A和B里边所有的词合在一起就是完整的库啊,啊,相当于我们这个,呃,所有的出现过的词,那所有出现过的词我们到时候可能都需要去做统计,统计它出现多少次,然后在哪些文档里面出现过,对不对?哎,这些词都是要的啊,那大家会看到我是不是把它转成一个set会比较好处理一些啊,大家看一下这里的操作啊,我可以把这个Bo a,它本身是一个list,是不是可以转成set啊,两个set我希望他们做一个什么啊,我是不是还应该去重啊,大家想一想对吧?所以我用set set集合,它有一个方法可以去除,怎么样去重两个。
04:20
两个这个集合怎么样就可以把它们的元素合在一起,而且可以去除加哦,大家直观的想是加对吧?呃,那对于这个集合来说,它的家其实就应该是。大家之前没讲过是吧,是不是这个union就是相当于要求一个。并集对不对,把它两个集合并在一起之后的结果是不是就是所有的元素,然后还去过去过虫的,因为set里面元素本来就去虫,对不对,所以我们调一个它这个union方法啊,那当然了,里边我们要把这个Bo b传进去。好,呃,那么我们这里再看一眼这个what set是什么吧,大家看这里边是不是就得到的是我们所有的词啊,而且去了虫对不对?好,这是基本的一个处理,接下来第二步,第二步我们就要去统计了,对吧,我们进行呃词数统计。
05:33
呃,这一步其实很好想,大家会想到我是不是需要,就是便利一下A和B2个文档,然后把它们里边到底出现过哪些词,呃,相当于是做一个word count,对不对?呃,相当于就是这样的一个做法,那我这里边用一个字典吧,用一个统计字典来保存文档啊,就是词。
06:05
出现的次数。那所以我们这里可以有一个word dict a,它首先初始化一下,初始化我们是不是应该把它初始化成一个dict,用什么来初始化呢?那它里边的K我们就都用这个词库里边的K好了,对吧?然后后面它的value是不是就是它的数量啊,哎,这个就比较简单,好,那么我们把它from kids,这是不是代表从一个从一个列表或者从一个集合里边创建一个字典,把这些,呃,这个集合本身的值是作为我们这里的key来创建的,对不对?好,那么这里的from key word的set,然后后面是零,是不是就是所有的都是零啊,那大家会想到B是不是也是一样创建一开始初始化都是零,是不是都可以啊,我们统计磁平的话,它如果不出现的最后还是零,是不是就可以了,哎,这个还是比较简单的。
07:11
呃,大家如果希望看到的话,我们看一眼verdict a得到的是不是这样一个东西啊啊,这是一个这样的一个字典类型,大家可以认为就是Java里面的map对不对?呃,得到这样的一个哈希map,好,那接下来我们要做这个词频的统计了,便利文档统计词数,所以当然想到是不是一个for啊。For,大家会想到是不是每一个Bo a里边出现的word,我们Bo a对不对?这里拿到的每一个word是不是都要去把它对应的这个word count的这个字典里边要去加上一啊,哎,其实就是这样的一个过程,所以我们直接worddict a,它的key是不是就是当前的word,我们要把它加等于一,对不对?出现一个,我们就遍历的时候出现一个加一个对不对?同样我们可以把B也做一个这样的操作,Word in Bo be。
08:26
把它对应的统计出来对吧?呃,这其实就是这样的一个过程,呃,大家可能会想到,那最后得到的这一个word a应该又长一个什么样子呢?大家是不是看到A里边,那就是所有出现过的词刚好都只出现了一次,所以是不是就得到结果都是一啊,然后没有出现的在B里边的那两个词对应就是零对不对?哎,这个就看的很明显,那我们如果想要再把它这个看的更清楚一点的话,我们可以用这个pandas下面data frame把它做一个转换,Data frame,呃,这里边可以输入一个这样的列表,那么大家看这样一个data frame是不是看得更清楚一些啊,我们就用它里边字典的K作为这里边的这个,呃,就是我们整个的这个列名对不对,Column名字,然后它里边的这个数据,那就是对应的每一个的这个统计出来的词词的数量啊,就是这个过程,好,那接下来已经有了这个数量了。
09:42
啊,我这里是分成了两步,其实我们也可以一步做的啊,接下来我们是不是计算计算TF啊磁瓶啊,好,那么这个磁瓶是怎么算的,大家还记得吗?呃,这里我们定义一个方法吧,因为我们到时候还是有一个测试的函数掉进去,对吧?我们这里定义一个compute TF这样的一个函数,那大家可以想到这个计算磁瓶应该传入什么。
10:14
词瓶是不是得把词和对应的文档是不是都得传进去啊?那这里边我们计算词频干脆就是把一组词全传进去吧,那那大家可以想到我们传什么,是不是可以传前面已经统计出来的这一个Di的字典啊,这是word count对不对?我们把这个word count直接传进去就可以,所以我们把word dict传进来,另外还是不是应该传这个Bo啊,Bo相当于是我们那个分词之后的磁带,就是相当于原始文档了,对不对,把文档要传进去,好,那么接下来大家看里边的计算过程,我们可以用一个还是用一个字典对象啊。
11:02
字典对象记录所有的TF,对不对?好,TF,首先我们初始化就给一个空空的字典吧。接下来。大家记得我们在统计的过程当中,是不是还需要知道这个?我们这个文档里边的所有的词数啊,哎,那个总词数还要知道,那我们这里记录一个啊,叫n Bo count,它等于什么,是不是就是求一个lengths啊,把文档这个传进来,它的lengths就是总词数对不对?然后每一个词出现的数量是不是都已经在这个what count这个字典里边存着存着了,然后我们是不是可以把所有的词对应的那个TF全全算出来啊。是不是啊,最后就存到这样一个字典里边来,好记录TF多写一句啊,把所有的词对应在文档里的。
12:15
TF都算出来,好,这就不是一个词对一个文档的这个词平了,所有词对这个文档的词平对不对,我们最后存到一个这个呃,Di里边,那当然了,大家会想到接下来是不是还是一个for循环啊。循环我们要遍历什么呢?是不是要把这个word count字典里边的每一个那个词词数要拿出来,每一个词数除以这个n count是不是就是我们最后要的那个词瓶啊,啊,这个其实很简单啊,那我们要拿的应该是一个word和它的一个count,这是不是我们存在那个字典里面的key和value啊,好in,那么大家会想到我这里边拿就是word dict.items对吧?
13:06
好。那么拿到的这个word最后是不是要存到TF这个字典里面去啊,这个字典里边它的K是不是还是这个word,那么它对应的值应该是什么呢?对,是这里的count数除以。对,是不是上面的定义的这个N啊,这就是我们的那个总词数,哎,这就是它对应的这个词平,那最后是不是直接return这个TF,这个是不是就可以了,好,这就是我们这个计算词平的一个过程,那呃,我们完了之后就直接来测调用它测试一下吧,大家会想到我现在是不是针对每一个文档去做这个呃计算啊。首先得到一个t FA compute TF里边要传的是不是就是它的word count字典,还有它本身的那个文档啊,啊,这就是所有的词的词词数,还有这个总的词数都有了,对不对?其实我们也可以在外面把这个总次数算出来,然后直接传进去就可以,对不对?呃,传一个N也是可以的,我们这里是把这两个传进去了啊,大家会想到同样是不是还可以有一个TFB的计算啊,啊,不是TFBOYS啊好,大家看一下我们把这个算出来之后应该是长什么样子呢?诶大家看现在就不是简简单单的一了,对不对?所以一共是不是有六个词啊,这这个文档里面,所以其实就是每一个1/6嘛,啊,这个是不是很简单啊,所以词瓶这个非常简单,就已经把它统计出来了。
14:58
好,那接下来我们关键是这个逆文档频率可能会比较复杂一点,对吧,计算逆文档频率IDF。
15:14
呃,大家想一下,这个东西我们应该怎么去计算呢?还是类似的,我定义一个函数吧,这个叫compute IDF,这里边需要传入什么样的这个参数呢?大家首先会想到这里边其实是跟每个文档文档是不是没关系了,他是要统计一个词在所有的文档里边出现了几次,对吧,出现在哪几个,出现在几个文档里面,所以我们是不是应该要首先输入词,那词的话,我们这里还是把所有的那个那个word count传进去,是不是就把所有的词都能统计了,我们还是用一个字典去保存,那最后我们是不是应该把所有的文档也应该传进去啊,诶,那这里边其实大家可以把这个Bo做一个列表传进去,或者也可以大家想一下。
16:09
本身我们这个word count这个。字典里边它是不是就包含了所有文档里边出现过哪个词的这个信息啊。它尽管记录的是一个world count,但其实你只要出现过是不是world count就应该大于大,大于零它就出现过对不对,那是不是根据这个很方便就可以统计出来啊,那我们是不是就不需要再去从这个原始的文档里边一个一个再去遍历了,只要根据这个K去查,只要大于它的次数大于大于零,就说明在这个文档里面出现过,对不对啊,就应该给它记上好,所以这里我们直接传入的是一个worddicct的一个list。那大家想到what Di list,是不是相当于就是把所有的文档的那个world com都传进去了,是不是所有文档的信息就都有了呀?
17:06
但是不是能想到这样的一个一个过程,所以这个就稍稍微简单一点,为什么我们要传这个word count list呢?因为它里边是字典嘛,查询是不是特别方便,我们根据每一个那个词直接就把它可直接就查到它的value了。好,接下来我们看一下这个,呃,想法还是用一个字典来保存吧,用一个字典对象。保存,呃,IDF结果是不是每个词的每个词作为作为K对不对,然后存储的那个Y是不是就应该是它最后的那个IDF啊,IDF值对不对?好,那么我们还是先定义一个IDF,之前我们是这个直接把它初始化成空,我们这里边因为之后需要去取用里边的一些参数,那我们还是把它初始化成零吧,怎么样初始化成零呢?From kids对吧?
18:15
前面我们已经有过类似的做法,我是不是可以从worddic list里边大家想到worddic list这里边我们的两个这个world count字典前面我们定义成是不是它的这个K都一样啊,哎,所以现在我们要去拿它里边的这个值作为K,是不是我随便拿一个就应该是一样的这个K啊,好,所以我的这里的word也全部都用这个K啊,初始值零对不对,初始值为零,初始值为零。这相当于大家会想到我,这相当于是创建了一个字典,这个字典里边它的K是不是就是所有的词。
19:03
所有的词,然后对应的那个值就是要保存它的IDF那个逆文档频率,对不对啊,这就是我们想要做的一件事情,那这个因为我们的这一个呃,逆文档频率跟它是A文档还是B文档没关系,所以我们直接把它统计出来是不是就可以了?好,接下来呃,大家会想到我是不是应该还得统计一下总文档数量啊,我我们在那个公式里边大家回忆一下啊,还有个什么来着?是不是要的是一个N是总文档数量,另外还有一个是出现了这个词的文档数量,对不对?哎,那总文档数量我们是不是可以应该用一个N啊对,N来表示,那大家想到是不是这个what count list的长度是不是也就是总文档的数量啊对,因为我们是一个文档对应一个word com字典吧,Word list。
20:03
当然大家想到这里边还要计算这个,另外是不是还要有一个log啊,那这个log我们可能又要引入一个东西啊,引入ma这个包对不对,好。接下来大家会想到我是不是就需要去遍历这个world countt字典里边的每一个元素了?好,首先我是应该word Di list,这本来是一个list对吧?那我首先是要把它里边的这个每一个字典要拿出来,我们传进来的应该就是what what,呃,What count a和B对不对两个字点,我们首先遍历这两个字点,然后我们要遍历的是。字典中的每个词汇,那是不是又一重循环啊,要遍历每个K了,对吧?我们这里边拿出来的是word和count,跟上面统计词平的时候应该一样,In,诶,In啊,Worddict。
21:21
It,这样是不是就可以便利它里边所有的k value啊,然后接下来大家注意我们是要怎么统计呢。是不是只要对应的这个count大于零,我们是不是就得算它在一个文档当中出现过一次啊,我们现在相当于要算这个,算这个ni对不对,对吧,我们要算这个爱好,那接下来这里啊统计ni。那我们这里边if if什么是不是要countt,如果大于零的话,我们就算它这个是不是要加一啊,这里边我们没有单独定义统计出来,但是我们可以利用一个什么东西,我们这个idfic是不是直接可以利用起来啊?
22:18
大家会想到在最后的这个表达式里边,我们算出来的IDF,这是这样一个表达式,一开始是不是我直接认为这个是是这个IDF也可以把它存进去啊。先把它存成爱对不对,好好,那么我这里边写一句啊,就是先把I增加一存入到。呃,就是我们的idficct里边,那当然了,我们就是IDF dictt对应的word是不是就要加等于一啊,哦,大家会想到,就当我们这里的两重循环遍历完成之后,这个IDF dict里边是不是就统计出来了,所有word对应的那个值是它对应的这个ni啊,出现在几个文档里面对不对?
23:23
那我们现在是不是得到就是所有的na啊,好,所以上面那个已经得到所有词汇I对应的。现在是不是我们现在。根据公式把它替换成为最后的IDF值对不对,IDF值这是这是我们要做的事情,那同样大家会想到需要去遍历一下了,遍历一个word,然后大家会想到啊,里边是不是应该有一个ni啊,啊,当然这个ni大家只要知道意思就可以啊,我这里边写一个ni in IDF Di items对不对?之前的这一个分辨历it里边是不是,我们其实只是要拿到它的P啊,只要判断它那个count大于大于零,我们要从里面拿出来,这是从worddicctt,就是word count那个字典里面拿的对不对?现在我们是不是就直接把。
24:50
刚才存出来的那个ni全存到idfd的这个子点里了,我们是不是把对应的那个值ni替换改成算出来的IDF就可以了,大家看一下这个怎么算IDF word还是这个值对不对?它应该等于什么?按照公式是不是首先是一个log啊,math.log啊,当然ma里边应该log个十啊,我们默认是这个常用对数里边是不是一个除法,上边是不是N加一,这是N是总文导数是不是在这里啊,所以这里是加一,下边是不是就是ni加一啊,所以我们这里边就是ni加一,大家看看是不是这样的一个计算过程啊,这就是带公式把我们得到这一个,呃。
25:50
IDF值,然后替换写到这个里面,最后返回的就是IDF,对不对?好,那这里大家可以想到这个返回的idficct,其实呃,应该就是我们是不是所有词的if都已经统计出来了,对吧?就跟文档没关系的一个状态啊,那我们再来测试一下ID叫IDF词吧,是不是就等于compute IDF?
26:25
我们传入的应该是word countt字典的列表,对不对?那所以这里要传进来的是一个列表,里边是worddict a和word b,是不是这样就可以了?好,那么大家看一眼。呃,我们这里边把这个IDF打印出来看一眼,大家看这是得到的一个。IDF的一个表达,那大家看到在这个IDF里边是不是onset the man my这些词汇它就全是零啊,为什么是零大家知道吗?它是不是因为所有的文档里边都出现了这些词啊,所以是不是ni跟N相等了,那这一除里边是几里边是1LOG1是不是零啊?诶,所以那大家就会想到,如果这是它在所有文档里面出现的话,逆文档频率一乘,是不是它就变成零了,所以它就完全不重要对吧?完全不关键啊,这就是这样的一个过程,当然了,最后还有一步,第几步了,第五步最后计算t fidf,对吧?
27:54
好,那么这里边我们当然就是可以定义一个compute t fidf,这里面我们要传什么呢?是不是就把每一个文档的词频统计TF传进来,然后把IDF传进来,是不是直接就可以算了呀?啊,当然我们这里边还可以去,还是按照这个字典的这种方式去定义的话,那就t fidf定义一个字典,空字典,我们是不是for每一个word的和呃,Ttf值对吧,我们这个TF不要重新。
28:35
定义了,我们叫TFY6吧,因TF里边大家会想到这个里边的每一个值是不是除以它,呃,不是除以乘以对应的IDF,这个得到的这个词的逆文档频率就是我们对应最后的那个结果啊,哎,所以其实就是这么简单的一个计算方式,那我们就t fidf对应的这个词word等于什么呢?是不是等于它的TF value乘以IDF里边找到的这个IDF值啊,大家看是不是就是这样就找出来了。
29:20
我们保存成字典,就是这样方便,我们根据这个word就全可以把它拿出来,这个实现还是比较简单的啊,最后我们return一下t fidf,好,那当然了,这里我们可以算一下t fid FA等于compute t fidf,我们传什么呢?是不是TFA和IDF?大家会想到每个是不是都传IDF啊,因为IDF跟这个TT就是每一个文档是不是没关系,它是逆文档频率只跟词有关,所以每次我们都传它,好,那当然了,下边可以把这个B对应的t fidf也计算出来。
30:07
好,那呃,最后大家如果想看一下的话,我们可以用一个pandas里边this frame把它包装一下,对不对,这个包装的时候做一个列表,TIDFATFIDFB,大家看一眼,这就是我们最后算出来的,在两个文档里边每个词汇他给出的这个。关键程度吧,对吧,或者说他到底哪些词是关键词,通过这一个权重,通过这个值是不是一目了然,我们算出来第一个文档里边是不是这个猫和这个bed在床上,这是两个关键词啊,别的词汇是不是全是零。然后在第二个文档里面对应就是dog和这个膝盖,这两个是关键词,别的全是零。
31:02
呃,这就是我们整个这个t fidf的一个实现过程。
我来说两句