算法逃兵的数据挖掘知识总结

作为转做工程的算法逃兵,趁着之前所学还没忘光,以课程cs246为纲整理一下之前所学过的一点数据挖掘知识。 当然本文不会详细的介绍每一部分的知识,更多的是作为一个小的知识框架。

分布式计算

因为我现在主要做这个,所以这一章节写得稍微细一点,后面就应该没这么多了。为处理大规模数据,需要增加硬件配置。可以选择纵向扩展,即增加cpu核数、增加单机内存等,也可以选择横向扩展,即增加性能一般、甚至廉价的机器的数量,通常实际应用场景为数据密集型,因此选择后者,也称为分布式计算。原因包括但不仅限于以下几点(具体可以看设计数据密集型应用第一章部分):

  • 可靠性。在实际生产环境中,故障是常态,出现在包括硬件、软件、人为操作等多方面。分布式多机的环境可以有效地在线处理多类故障,避免数据丢失、重复运算等问题。
  • 可扩展性。数据量往往不是一成不变的,若机器性能不足,则会影响数据处理的效果;若机器性能过剩,则又会造成资源浪费。横向扩展可以在负载增加的时候动态的增加机器数量。
  • 可维护性。如状态监控、数据迁移、流程控制、程序更新等。

提到分布式计算,首先不得不了解的就是Google家的三篇经典:GFS、MapReduce、BigTable,分别对应了分布式存储模型、分布式计算模型、分布式数据库模型,其中GFS(可以参考一下之前的博客,虽然现在看起来写的巨烂,但是作为稍微了解一下GFS还是可以的)和BigTable与数据挖掘关系不大,更多的是分布式工程上的问题,这里主要介绍MapReduce。
MapReduce是一种分布式批处理的计算框架,顾名思义,它是以一种类似于函数式编程中的map和reduce操作的方式,将整个数据处理的计算过程分为两个部分。其中map操作会每次提取一条记录,从中提取出一对键值对,reduce操作会将收集到的所有相同key的value放在一起,汇总得到一个键值对。
在这里插入图片描述
举一个MapReduce论文中的例子,用这个计算模型来统计单词出现次数。首先将原输入文件分为多个分块,分给每个用于map操作的机器,比如机器A拿到“i eat an apple”,那么经过map操作就会得到[i,1],[eat,1],[an,1],[apple,1]这样的键值对。在所有用于map的机器处理完之后,有一个shuffle的过程,这里shuffle并不是它字面意义上的打乱,而是根据各条记录的key进行排序,然后每个用于reduce的机器会分到它要处理的key,将对应的key值的map完的记录拉过去进行汇总,得到类似于[i,15],[apple,3]这样的结果。
在这里插入图片描述
MapReduce是一个将计算过程进行抽象的计算框架,使得原本复杂的计算过程在将各个任务分离后,每台机器仅需处理自己有限的任务即可,其更多精妙的地方在于其工程实现,这里不加赘述。有以下几点需要注意:

  • MapReduce依托于GFS,每次为降低网络传输造成的耗时,会在map阶段开始前将各机器所需记录文件copy至每台机器本地,处理后的结果也存至本地,然后再copy至reducer处,因此IO耗时是一个不可忽略的问题;
  • 待所有map操作均完成后,才开始进行shuffle&reduce;
  • 在MapReduce框架下处理数据,使用者仅需自己定义好数据格式后,编写map和reduce函数即可;
  • 分布式MapReduce的模式具有很好的容错性,比如在某台机器崩掉后,可以迅速补充另一台机器重新开始它的任务;
  • MapReduce后得到的结果的key是有序的,但每个key内的value是无序的,若要value也有序则需要二次排序(可以自行查阅一下这是什么);
  • 需要注意一下数据倾斜问题。比如实际处理中,某个key的数据量特别大,则在其他reducer都任务完成后,处理该key的reducer还在继续。数据倾斜是MapReduce中一个十分常见的问题,可以通过例如事先进行抽样找到热键,然后将热键任务分散至多个reducer上等方法处理。

从上面内容可以看到,MapReduce可以有效地解决大数据量下批处理的一些问题,通过分布式的方式进行可靠、高速的数据处理。但是仍然存在比如中间IO耗时、不利于迭代运算等问题,详细来讲MapReduce在map和reduce中间需要进行存储到硬盘和从硬盘中加载两个IO操作,增加了处理的耗时,时效上不如纯粹in-memory的操作。虽然可以通过将问题分解为map和reduce两个简单独立的过程进行处理,但是对于复杂的处理过程则需要写多个map和reduce过程,因此不适用于复杂的计算模式。针对这些问题,Spark提出了有效地解决方案。
Spark是一种流处理的in-memory的计算框架,它以一种计算图(DAG)的方式构建计算模型,图中每一个节点是一个算子,具有比MapReduce更丰富的计算模式。Spark以一种叫做弹性分布式数据集(RDD)的方式进行数据存储,RDD一旦创立不可改变,只可以通过某个算子得到新的RDD或者提取得到value。
Spark中的算子可以分为两类,一类叫Transformations,可以将RDD转化为另一个RDD,一类叫Actions,可以从RDD中提取得到value。具体可以参考cs246的这个tutorial。对于Spark我也用的不多,这里总结一下我了解到的几个点:

  • Spark的api非常丰富,可以对单纯的对RDD进行操作,也可以用Spark SQL对DataFrame即一种类似于数据表格的数据格式进行操作,或者进行Graph处理;
  • 相对于别的流处理框架,Spark具有丰富的机器学习工具包;
  • 流处理是一种有别于批处理计算的模式,除Spark外Flink也是一种使用广泛的流处理框架,尤其是在阿里的推广之下Flink在各大公司得到广泛的应用(阿里nb)。一个比较明显的比较是Flink是一种真正意义上的流处理框架,对于流数据处理具有更高的性能,但是在解决机器学习相关的问题时Spark具有更大的优势。
  • Spark支持多种语言如Java、Scala、Python等,可以选择装一个自己熟悉的如PySpark进行练手,语法大致相同,重要的是学会用Spark这一框架的api去解决问题的思路而不是语法;
  • 可以尝试用Spark做一些小数据集上的练手作业,比如统计网站日志中最活跃、出现频率最高的N个用户、商品,或者比如用MovieLens数据集做一个简单的基于协同过滤的打分估计(我只做过这个,很简单的)。

关联算法

关联算法和那个经典的啤酒尿布故事有关,即沃尔玛发现啤酒和尿布放在相邻的货架上销量会增加,因为一般出来买尿布的都是年轻的爸爸,顺便会为自己买啤酒。也就是说关联算法处理的每条记录是一个多个物品的集合,从中发掘哪些物品一起出现的频率比较高。其实这类问题和协同过滤这种推荐算法有些类似,但也不太一样。课程讲义中给出了商品/购物车、单词/文档、药品/病人这样的例子,即发掘物品之间共同出现的概率而非完全是物品之间的相似程度。课程中主要讲了A-Priori算法和改进的PCY算法,由于我没做过这个所以这里就不讲了,可以自行百度或者看讲义

局部敏感哈希

局部敏感哈希(LSH)主要解决的问题是在大数据下寻找相似个体。我们知道KNN这样的朴素的寻找最为相似的K个个体的算法,即根据自定义的距离计算公式,如欧氏距离、汉明距离等,逐个计算目标个体与所有数据集中个体的距离,从中选择前K小的个体作为最为相似的个体,假如目标个体有M个,数据集规模N,则时间复杂度为O(kMN),或者使用kd-tree进行存储,时间复杂度可以降低为O(kMlogN),这在大规模数据量下是十分惊人的,如搜图程序中相似图片的寻找、电商网站中相似商品的召回,因此需要通过其他方式来实现快速的检索相近个体。我们知道,传统的最近邻算法是基于空间进行划分,但是对于维度较高的使用场景,基于空间划分的算法性能下降,甚至不如线性搜索。
LSH是一种基于概率的高精确度的相似搜索算法,在可以牺牲一部分精确程度的前提下实现快速的检索。具体也没什么好讲的,把min hashing、分桶啊这些看懂就好,这里贴两篇讲得蛮不错的知乎的文章12。LSH感觉也没什么练手的必要,重要的还是知道有这么个场景下这么个算法,知道算法是通过什么途径解决了什么问题就好了。

聚类

聚类真的是数据挖掘中最为常见的几个问题之一了。k-means啦层次啦EM啦DBSCAN啦。对于聚类算法呢,首先要掌握每类算法是什么这是最基本的啦,当然大概率过几天后算法具体内容会忘记。所以,重要的还是要学会总结,比如聚类算法分为哪几类,像什么基于密度啦基于距离啦基于互连性。为什么要知道这些呢,因为你是要用算法啦解决问题的人,而不是命题作文或者背诵默写算法的人,所以你需要知道在什么场景下,应该用什么聚类算法去解决什么样的问题,该场景下是什么类型的噪声,目标个体是否有明确的分布,分布类型是什么,我们更加看重精确程度还是耗时。原理方面可以看一下这篇博客。还有一点就是,作为一个工程师,除了知道该去用什么方法解决问题外,还需要知道怎么用该方法解决问题,这些方法的部署复杂程度、耗时、占用内存情况如何。所以,重要的并非算法的详细原理,而是他们的特性,除非你想要用此发论文,那么到时候也大可以有的放矢,知道有这个方法可以有针对性地去检索这方面资料进行详细研究。比如我之前写的论文就用到了DBSCAN,为什么要用它,怎么在自己的场景下去适配、改进它,这又可以有一番工作了。

降维

这方面我所掌握的也就是那几本机器学习书上的一些老生常谈的算法,什么SVD啦PCA啦LDA啦,没有做过和这个有关系的实际问题,说不出什么有用的东西。具体可以自己搜一下哪些算法,各自解决的是什么类型的问题、有哪些优势。SVD嘛就是矩阵理论里面学的那个SVD,选择最高的k个奇异值对应的特征向量,可以用于像是图像压缩、推荐系统里面。这方面还是有一定的数学量的,有兴趣的话就推一下,不过反正以后也会忘哈哈哈哈哈。

推荐系统

emmmm推荐可以说是我在算法上花时间比较久的一个方向了,也读过一些书和论文,水过两个比赛,所以稍微多说一点。
推荐应该是所谓的算法工程师们发光发热最多的一个方面了,从基于内容推荐的头条、知乎,到YouTube、bilibili这些视频网站,再到淘宝、拼多多这些电商网站,核心算法无一不是推荐。最基础的推荐,就拿MovieLens这个数据集来讲,是每个用户对看过的电影的打分记录。所有人基本都不可能把所有电影都看过,因此所有人、所有物品有关的记录都是关于它自身的总集合的一个子集,我们需要做的是对它的补集进行预测,比如这个人假如看了这部电影他会打多少分,对于这个人一般在多少分以上的电影他才会去看,这个电影可以推荐给哪些人,哪些电影可以推荐给这个人等等。
首先我们可以讲一下上一章中讲过的SVD,也就是一种降维算法。我们可以把一个人看过的所有电影,他们的观感(如喜欢、不喜欢可以用1、0表示,打几分可以用1~5分表示等)作为这个用户的特征向量,或者把一个电影,所有看过这个电影的人的分数作为这个电影的特征向量。当然有几个问题,一个还是上面提到的,这个特征向量是不全的,也就是说有很大的噪声,因此不能直接拿来用,另一个就是用户量和影片量都是巨大的,必然不能直接拿来运算,因此需要从中提取有用的特征,SVD就是这样一个用于提取特征的算法。我们可以将用户、影片的打分情况这个表格看作一个矩阵,一个维度是用户id,一个维度是影片id,那么对于缺省值怎么处理呢?最简单的当然可以将每个用户或影片已有的记录的打分值取平均作为该用户、影片的缺省值,也有其他方法可以查一下,我忘记了嘿嘿。然后将该矩阵进行奇异值分解,从中选择k个的最高的奇异值对应的特征向量,就可以作为每个用户、影片的k维特征向量了。那么如何推荐呢,比如我们可以根据用户的特征向量计算用户之间相似程度,那么相似用户看过的电影是不是代表该用户很大概率也会喜欢呢?或者计算影片之间相似程度,该用户看过这个电影,是否也会喜欢它的相似影片呢。这两个就是最简单的UCF和ICF了。那么是否分数高推荐就一定好呢,比如有些影片看的人多,有些影片看的人少,或者有些人观影量大,有些人观影量小,就会造成计算的不平衡,我们可以通过一个人或者电影的已有记录数定义一个权重,在计算topK的时候加上这个权重进行计算。实际上市场中存在一个长尾理论,即大多数商品有关的记录数都是很少的,记录数很高的商品在所有商品中占少数,因此直方图分布呈长尾状。
在这里插入图片描述
作为一个推荐算法工程师,实际上应该将自己作为半个产品经理。如何去挖掘长尾数据、如何保证推荐的平衡性是一个重要问题。这方面推荐去看一下有关的书籍,比如项亮的《推荐系统实践》可以不用细读,尤其是其中的程序啦完全可以跳过,花几十分钟或者几小时速览一下推荐系统包括哪些方面就好了。
推荐系统相关的比赛应该是数据挖掘比赛中最多的,常见的比如点击率(CTR)和转化率(CVR)预测。这类问题实际上可以归为回归问题,算法模型方面就比较丰富了,如最早的Logistic Regression,到FM,到比赛中大放异彩的xgboost、lightgbm这类类似于GBDT的集成树模型,再到深度网络。那么,我们需要做什么呢?在几年前,大家或许用tensorflow写过一个deepfm这样的模型,背一下xgboost的论文,大概就会找到一份好的工作,但是现在这样肯定就是送了。你要做的不是去尝试各种花里胡哨的模型,首先最基础的几个模型是肯定要懂的,比如LR和GBDT类模型,要有用这些模型操作过数据的经验,而且模型中具体的细节肯定是要懂得。除此外,为什么要用这些模型,各有哪些优缺点,这个是比较关键的。实际工业场景下为什么用的还是LR,因为简单快速,因为模型的作用就是提取特征,只要特征提取的够好够详细,LR一样好用。实际工业场景的数据中有哪些问题,比方说数据清洗中怎么处理缺省值,有哪个方法是适用于所有场景都是最好的还是说不同情况下有不同的最好的处理方法呢,是设置为0还是null呢还是平均值呢还是单独一类呢,有些方法比如xgboost是怎么做到自动处理缺省值的呢。有哪些方法可以来观察数据分布呢,比如直方图、小提琴图?不同类型的数据该怎么处理呢,是把类比特征(categorical)转化为连续变量(continuous)还是把连续变量分段成类别特征呢,不同模型下选择哪种变量类型呢,是否要归一化、标准化?哪些模型不需要归一化?为什么不需要?这些都是面试常见的问题,也是实际处理问题中会遇到的。建议的方法就是找一个这两年的腾讯广告算法大赛或者阿里妈妈广告算法大赛的top选手的博客好好读一下,总结一下流程,然后自己找一个不大不小的数据量跑一下。各种花里胡哨的深度模型可以不必在意,比赛里最好用的就是lightgbm,关键是学习一下高手在拿到一份数据后,怎么清洗、转换、提取特征的。
另外,其他的阅读材料建议《美团机器学习实践》(这本书写的真的棒)、《百面机器学习》,还有一些知乎用户比如王喆的文章,都是写的很棒的。当然这些都是补充。
关于模型方面尤其是深度网络模型真的不想写了,一方面我是觉得没啥大用,另一方面我也没做过多少嘿嘿。

PageRank

这个是在《集体智慧编程》中有的,也比较好理解,就算是其中概率推导部分也不是很复杂。不过既然涉及到图这一模型了,其实有必要看一下数据结构中的图部分的。比如常见的图的存储方法有哪几种,分别适用于什么场景下。除了DFS、BFS这些必须吃透的算法外,常见的图有关的问题有必要了解一下,比如下面某一章的讲义12,但是不必深抠,因为平时也用不到,比如最小生成树、最短路径算法等。
有一个比较有意思的事情,其实可以结合一下前面的分布式计算框架,考虑一下分布式的pagerank怎么实现,因为实际问题中必然不会在单机上运行吧,毕竟这么大数据量。稍微扩充一下实际上可以放在简历上。

TrustRank &WebSpam

emmmm这个我就不懂了,也是Google的搜索排序有关的,可以看一下讲义然后和pagerank结合一下考虑怎么丰富那个项目。

大规模机器学习

看了一下这两章的的讲义,讲的主要是各种集成树模型和支持向量机(SVM)。集成树模型主要是随机森林、GBDT,包括GBDT引申的xgboost、lightgbm等。随机森林的概念很好懂,随便找本书或者博客读一下决策树和随机森林有关的章节就好,可以看一下《统计学习方法》,简明扼要。GBDT同样。xgboost是一个具有重要意义的模型(陈天奇真巨佬),建议好好读一下原论文,比如模型的整体思想,每棵树的构建,相对于原来的GBDT它从哪几个方面进行了哪些形式的优化。当然具体实现就不必了,直接conda/pip install就好,但是用还是要用一下的,可以结合上面讲到的比赛数据,比方说从很大的比赛数据中sample一块来跑一下试试看看效果。SVM是在深度学习兴起之前一度屠榜的模型,因为其数学证明严谨,而且可以通过各式核函数处理不同类型问题。数学问题说复杂也不复杂,就是用的最优化里面学到的对偶问题,kkt条件这些,记不住的话也不必重复花时间在上面,重要的是和你的项目有关的理论内容。

流式系统

感觉这个就和大数据相关性更大了。总结一下我遇到的几个常见的问题吧,最好总结记忆一下,挺死的知识点。

  • 大数据量下如何判断是否存在某条数据:布隆过滤器
  • 大数据量下统计频率最高的n个词:首先对词取hash,分到多个机器上,然后用hashtable/hashmap保存词出现次数,用小顶堆保存topk,最后将每台机器上的topk进行类似于归并排序的操作,选出全局的topk
  • 从一个无限长的数据流中采样出k个数据,并保证每个数据被采样到的概率相同:水塘采样法

emmmm算法有关的先想到这几个,其他的比如raft算法啦flink框架啦这样的工程有关的东西就不在这写了。从今年的情况来看,算法岗已经逐渐冷却,信息具有时效性,一窝涌向算法坑的临时转行的人注定只能接受神仙打架这一现实。但是这不代表算法不能做了,从身边offer收割机同学身上学到的是,首先要有项目,论文也罢比赛也罢自己写的轮子也罢,在具有一定规模的基础上,将它吃透,能给别人讲清楚怎么解决的问题,中间碰到了什么现象,怎么处理的。不是说必须要有顶会、有重大比赛top3,只要在自己的项目上面花时间准备了、题目做的不是太差,就肯定会有offer的。说到题目,这就是另一个重要的点了,先挖个坑等秋招彻底结束后补一下。

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值