那些年开过的挖掘机,走过的挖掘机之路


就所谓算法而言,个人认为,同事说的很对:
所谓算法,并不是说那些复杂的数学模型才是算法,哪怕是你写的一个简单的计算公式,只要能够解决现有业务的痛点,有了自己的模型思路,它就是一个算法,只是它可能不够通用,只能解决特定业务需求而已。

 

在大规模的数据前提下,其实很多复杂的算法过程,反而效果没有这么好,或者说,我们会想方设法去简化其过程。

 

举个简单栗子:假设有一批大规模数据集,就以近千万篇博文为例。如果提供一篇博文,让你去查询与其相似度最高的top N,那我们的通常思路是什么?通常的做法是计算这篇博文与其他博文的相似度,至于相似度的计算方法就很多了,最简单的就是计算其向量夹角,根据向量夹角判定相似程度。OK,就算你用最简单的计算过程,你试想一下,运算近千万次需要多久?或许,有的人说,俺使用hadoop,利用分布式的计算能力来完成这个任务,但如果实际操作起来,你就会发现这是一个多么蛋疼的事情。

 

再举一个简单栗子(好吧,多吃点栗子):比如SVM,这是一种难以收敛的算法,在大数据的前提下,有些人希望使用它,但又希望使用更多的数据来训练模型,毕竟手里数据量太大,很多人还是希望使用尽量多的数据训练的,以达到模型更准确的目的。但是,随着训练数据量的增大,像SVM这种难以收敛的算法,其耗费的计算资源还是很巨大的。

 

(1)最早接触的应该是贝叶斯的分类了

 

贝叶斯算是分类算法中最简单的算法了,初学挖掘机算法的人十有八九第一个爱上的绝对是它。其实,贝叶斯的原理真的很简单,就是依据统计学的最大概率原理。这么简单,但是就是尼玛这么好用,多年依然屹立不倒。

 

训练过程就缺乏可陈了,基本上贝叶斯的都这样,由于是文本,所以一套流程下来,分词,去停词,作为最基本的知识点向量,然后就计算模型概率了。不过比较有趣的是,分类过程是放在Storm里头做的,相当于这是一个实时的分类业务。

 

(2)说到了文本,自然少不了分词算法了

 

其实说到分词算法,反倒没啥可说的。如今互联网上各种开源的分词工具,都已经做的很好了,效果也差不了多少,想进一步改进的话也够呛。至于说深入到分词算法的内部,涉及上下文法分析,隐含马尔科夫模型等东西,如果是个人出于兴趣去研究,那我没话说;如果是小公司,花费人力物力去优化分词效果,我只能说他们闲着蛋疼;如果是大公司,人家金多任性也是可以理解的。

 

所以,至今来说,个人对于分词方面的东西,也仅限于初步了解分词算法的衍变,内部大概涉及的算法,以及几种分词工具的使用。其实,在文本挖掘方面,仅仅针对于文本的分词是不够的,因为我们使用分词拆分出来的单词,往往很多跟业务都是没有关系的,通常做法是,建立对应业务字典,至于字典的建立,当然也是需要分词的,再进行进一步的加工,甚至可能会加上一些人工的工作。

 

(3)下一个就是实时热点分析了

 

我也不知道这算不算是算法,说到实时,自然跟Storm又有关系了(好吧,我承认我是搞这个之后开始接触数据的)。说到实时热点,可能大伙儿都摸不着头脑,举个简单栗子就明了了。

玩hadoop的童鞋都知道WordCount这个经典栗子,MapReduce在Map到Reduce的过程中,自动将相同的Key通过类似hash的方法聚合到一起了,所以,统计单词这个需求通过MR来做是辣么的简单。

 

那Storm的实时WordCount呢?好吧,这也是一个能够记录到实时技术领域史书上的经典案例(好吧,其实它就是一个Storm的HelloWorld)。Storm虽然没有类似MR那种自动Hash的功能,不过它也提供了一种数据分组流策略,也能达到类似的效果,并且它不像MR那样是批量的,它是实时的、流式的,也就是说你能动态的获取到当前变换的单词词频。

 

实时热点分析,如果我们把热点映射成单词,那我们是不是就可以实时的获取到当前Top N的热点了。这个方向可是有很大的研究价值的,实时地掌握了用户的热点导向,我们就可以动态的调整业务策略,从而衍生更大的数据价值。

 

不过,总体来说,这个数据模型更多依靠的是Storm这个实时工具的本身功能,模型设计上的东西反倒是少了。至于说算不算是算法模型,就跟前面所说的那样,看个人看法吧,你说是就是了~~

 

(4)国内很成熟的一种建模——推荐

 

就目前在国内做数据挖掘的来说,可能分类与推荐是做的最多的两种方向。分类就不多说了,就比如刚才所说的贝叶斯,简直就是分类中的鼻祖算法了。

 

可能一说到推荐算法,有人脑海里立马就闪现出关联规则、协同过滤、余弦相似性等这些词。这是没错的,但我要说的不是这个。其实个人想说的是推荐就两个方向:基于用户,基于内容。

 

我们需要注意两点,我们推荐的对象是用户,或者说是类似用户这种有动作行为的实体;而推荐的东西则就是内容,他没有动作行为,但是他有不同的属性,或者用更砖业说法描述就是他必然有知识点。

基于用户推荐,我们看重的不是内容这个实体,而是用户本身的行为,我们认为用户的行为必然隐含着一些信息,比如,人的兴趣导向,那么既然你有了相关的行为,那么我按照你的行为去给你推荐一些东西,这总是有一定道理的。

 

基于内容的推荐,我们的侧重点则是内容,这就跟用户的历史行为无关了。我们潜意识的认为,既然你会看这个内容,那么跟这个内容有关系的内容,你是不是也感兴趣呢?或许这样说有失偏颇,但是大体方向是对的。

 

至于之前说的那些关联规则也好,协同过滤也好,余弦相似性也好,其实就是研究知识点与知识点之间关系所建立的模型.针对于基于内容推荐,其知识点就是内容之中的各种属性,比如影片推荐,其知识点可能就是各种评论数据、点播数据、顶踩数据、影片类型、演员、导演以及其中的一些情感分析等等;又比如博文,其知识点可能就是一个个带权的词,至于这个词就涉及到词的抽取了,再说到词的权重,可能就会涉及到TFIDF模型、LDA模型了。

 

而针对基于用户,其知识点最直接的体现就是用户的行为了,就是用户与内容之间的关系,不过深究下去,又会发现,其实跟内容的知识点也紧密联系,只不过这可能不止一个内容实体,而是多个内容实体的集合。

 

(5)文本单词的加权模型

 

前面正好提到了TFIDF以及LDA模型,所以顺带也就讲讲文本单词相关的加权模型吧。

 

说到文本挖掘,可能大部分人都熟悉TFIDF模型,既然涉及到了,那就简单的说一说。我们知道,文本的知识点就是一个个的单词,虽然都是单词,但也总有哪个词重要程度高一点,哪些词重要程度会低一点吧。

 

或许有人会说,出现多的词就重要。没错,那就是词频,简单的来想,这种思路并没有错,并且,早期的文本挖掘模型就是这么做的。当然,效果肯定是一般般的。因为那些经常出现的词往往都是一些没用的常用词,对文章的作用并不大。

 

直到TFIDF模型的出现,才根本性地解决了文本挖掘知识点建模的问题。如何判断一个词的重要程度,或者专业点的说法就是判断其对文章的贡献度?TFIDF通过词的词频来加大词在文章中的权重,然后通过其在多个文章中的文档频率来降低其在文章中的权重。说白了就是降低了那些公共词的权重,把真正贡献度大的词给暴露出来。这基本就是TFIDF的基本思路了,至于词频权重怎么加大,文档频的权重怎么降低,这就涉及到具体的模型公式了,根据不同的需求进行调整就OK了。

 

关于文章知识点主题建模的另外一种很重要的模型,那就是LDA模型了。它是一种比较通用的文章主题模型,它通过概率学原理,说白了就是贝叶斯,建立起知识点(也就是词),主题和文章的三层关系结构。词到主题有一个概率矩阵,主题到文章也有一个概率矩阵的映射关系。

 

好吧,LDA不能再说下去了,再说下去就露馅了。因为,俺也不是很懂啊。对于LDA,虽然部门内部有在使用,但是我没有做过具体的模型,只是和同事讨论过它,或者更确切的说向同事请教过它的一些原理以及一些设计思路。

 

(6)相似度计算

 

相似度计算,比如文本的相似度计算。它是一个很基础的建模,很多地方就用的到它,比如刚才我们说到的推荐,其内部关联的时候,有时候就会涉及到计算实体间的相似度。

 

关于文本的相似度,其实方法有很多。通常会涉及到TFIDF模型,拿到文本的知识点,也就是带权的词,然后通过这些带权的词去做一些相似度的计算。

比如,余弦相似模型,就是计算两个文本的余弦夹角,其向量自然就是那些带权的词了;又比如,各种算距离的方法,最著名的欧式距离,其向量也依然是这些词。还有很多诸如最长公共子串、最长公共子序列之类的模型,个人就不是很清楚了。

总之,方法很多,也都不是很复杂,原理都很像。至于哪个合适,就得看具体的业务场景了。

(7)文本主题程度——信息熵

曾经和同事尝试对数百万的博文进行领域划分,把技术博文划分成不同的领域,比如大数据领域、移动互联网领域、安全领域等等,其实说白了还是分类。

 

一开始我们使用贝叶斯进行分类,效果还行,不过最终还是使用SVM去建模了。这都不是重点,重点是我们想对划分到某一领域下的技术博文进行领域程度判断。

 

我们想了很多办法,尝试建立了数据模型,但效果都不是很理想,最终回归到了一个最本质的方法,那就是使用文本的信息熵去尝试描述程度,最终结果还是不错。这又让我再一次想到同事说过的那句话:简单的东西不一定不好用!

 

信息熵描述的是一个实体的信息量,通俗一点说就是它能够描述一个实体的信息混乱程度。在某一个领域内,知识点都是相似的,都是那些TFIDF权重的词,因此,是不是可以认为,一个文本其信息熵越小,其主题越集中越明显,信息的混乱度越低,反过来说,有些文本主题很杂乱,可能包含了多种领域的一些东西,其领域的程度就会降低。

最起码表面上,这种说法是行得通的,并且实际的效果还不错。

 

(8)用户画像

 

用户画像这个方向可能是近两年比较火的方向了。近年来,各大互联网公司,各大IT企业,都有意识的开始从传统的推荐到个性化推荐的道路衍变,有些可能做的深一些,有些可能浅一些。

 

商业价值的核心是用户,这自然不用多说。那么如何结合用户进行推荐呢,那就是用户的属性,那关键是用户的属性也不是一开始就有的,我们所有的只是少量用户的固有属性以及用户的各种行为记录。我们连用户是啥子里情况都不清楚,推个毛啊!

 

所以,我们需要了解用户,于是对用户进行用户画像分析就很有必要了,其实就是把用户标签化,把用户标记成一个个属性标签,这样,我们就知道每一个用户大概是什么情况了。一些商业行为,也就有了目的性。

 

至于说如何对用户的每一个画像属性进行填充,这就看具体的情况了。简单的,用几个简单模型抽取到一些信息填充进去;复杂的,使用复杂的算法,通过一些复杂的转换,给用户打上标签。

 

(9)文章热度计算

 

给你一大坨文章,你如何判断哪篇文章比较热,哪篇文章比较矬,换个说法就是,我进入一个文章列表页,你能给我提供一个热文章的排序列表吗?

 

可能大部分的思路都很直接,拿到文章能够体现热度的属性,比如点击率、评论情感分析、文章的顶踩情况,弄个简单加权计算模型,咔咔就出来了。

 

本质上这没错,简单的模型在实际的情况中不一定不好使,部分属性也的确能够体现出一篇文章的热度,通过加权计算的方式也是对的,具体的权重就需要看具体情况了。

 

但如果这么做的话,实际上会出现什么情况?今天我来了,看见了这个热度推荐列表,明天我来了,还是看到这个列表,后天我来了,依然是这个列表。

 

尼玛,这是啥情况,咋天天都是这个破列表,你要我看几遍?!不错,这就是现实情况,造成的结果就是,越热的文章越来越热,越冷的文章越冷,永远的沉底了,而热的文章永远在前头。

 

如何解决这个问题?我们把时间也加入参考,我们要把老文章通过降权的方式,把他人为的沉下去,让新文章有出头的机会。这就是说,需要我们把创建时间也加入权重中,并且随着时间推移,衰减其热度权重,这样,就不会出现热的一直热,冷的一直冷了。至于衰减的曲线,就需要看具体业务了。

 

这样就能解决根本问题了吗?如果文章本身信息量就不够呢,比如,本身大部分就是新文章,没有顶踩,没有评论,甚至连点击曝光都很少,那用之前的模型就行不通了。

 

那是不是就无解了呢?方法还是有的,比如,我们寻找到一个相似的站点,他也提供了类似最热文章推荐的功能,并且效果还很不错。那么,我们是不是就可以借助它的热度呢?我们通过计算文章相似度的方法,复刻出一个最热列表出来,如果站点性质相似,用户性质相似,文章质量不错,相似度计算够准确,相信这个热度列表的效果也是会不错滴(这方法太猥琐了~~)。

 

(10)Google的PageRank

 

首先,别误会,我真心没有写过这个模型,我也没有条件去写这个模型。

 

认识它了解它,缘自于跟几个老同学合伙搞网站(酷抉网)。既然搞网站吧,作为IT人猿,一些基本的SEO的技术还是需要了解的。于是,我了解到:想要增大网站的权重,外链是不可缺少的。

 

我跟我几个老同学说,你们去做外链吧,就是逮住网站就放咱网站的链接。他们问到:一个网站放的链接越多越好吗?放的网站越多越好吗?啥网站放比较好?这都不是重点,关键是他们问:为毛啊?

 

把我问的那个是哑口无言啊,于是我一怒之下就去研究PageRank了。PageRank具体的推演过程我就不说了(况且凭借我这半吊子的水平也不一定能说清楚),其核心思想有几个:当一个网页被引用的次数越多时,其权重越大;当一个网页的权重越大时,其引用的网页权重也随之增大;当一个网页引用的次数越多时,它引用的网页给它带来的权重越低。

 

当我们反复迭代路上过程时,我们会发现某个网页的的排名基本就固定了,这就是PageRank的基本思路。当然也有个问题需要解决,比如,初始网页如何给定其初始权重,高计算迭代过程如何简化其计算过程等等。这些问题,在Google的实际操作中,都做了比较好的优化。