Mahout.docx
- 文档编号:3326928
- 上传时间:2022-11-21
- 格式:DOCX
- 页数:21
- 大小:338.14KB
Mahout.docx
《Mahout.docx》由会员分享,可在线阅读,更多相关《Mahout.docx(21页珍藏版)》请在冰豆网上搜索。
Mahout
认识Mahout
ApacheMahout是ApacheSoftwareFoundation(ASF)旗下的一个开源项目,提供一些可扩展的机器学习领域经典算法的实现,旨在帮助开发人员更加方便快捷地创建智能应用程序,并且,在Mahout的最近版本中还加入了对ApacheHadoop的支持,使这些算法可以更高效的运行在云计算环境中。
Mahout源码目录说明
mahout项目是由多个子项目组成的,各子项目分别位于源码的不同目录下,下面对mahout的组成进行介绍:
1、mahout-core:
核心程序模块,位于/core目录下;
2、mahout-math:
在核心程序中使用的一些数据通用计算模块,位于/math目录下;
3、mahout-utils:
在核心程序中使用的一些通用的工具性模块,位于/utils目录下;
上述三个部分是程序的主题,存储所有mahout项目的源码。
另外,mahout提供了样例程序,分别在taste-web和examples目录下:
4、taste-web:
利用mahout推荐算法而建立的基于WEB的个性化推荐系统demo;
5、examples:
对mahout中各种机器学习算法的应用程序;
6、bin:
bin目录下只有一个名为mahout的文件,是一个shell脚本文件,用于在hadoop平台的命令行下调用mahout中的程序;
在buildtools、eclipse和distribution目录下,有mahout相关的配置文件
7、buildtools目录下是用于核心程序构建的配置文件,以mahout-buildtools的模块名称在mahout的pom.xml文件中进行说明;
8、eclipse下的xml文件是对利用eclipse开发mahout的配置说明;
9、distribution目录下有两个配置文件:
bin.xml和src.xml,进行mahout安装时的一些配置信息。
(在开发的时候一般很少对这个目录下的文件进行修改,所以不用太关注,知道大体什么意思就ok)
另外,在mahout的下载地址下可以看到有个文件夹与mahout处于同一级别,它是mahout项目的分支项目—mahout-collections,用于实现了核心程序中使用的集合类操作,该模块独立于mahout进行开发,是对标准jdk中关于集合类的修改,使其可以适应数据密集型项目的开发。
在Mahout实现的机器学习算法见下表:
算法类
算法名
中文名
分类算法
LogisticRegression
逻辑回归
Bayesian
贝叶斯
SVM
支持向量机
Perceptron
感知器算法
NeuralNetwork
神经网络
RandomForests
随机森林
RestrictedBoltzmannMachines
有限波尔兹曼机
聚类算法
CanopyClustering
Canopy聚类
K-meansClustering
K均值算法
FuzzyK-means
模糊K均值
ExpectationMaximization
EM聚类(期望最大化聚类)
MeanShiftClustering
均值漂移聚类
HierarchicalClustering
层次聚类
DirichletProcessClustering
狄里克雷过程聚类
LatentDirichletAllocation
LDA聚类
SpectralClustering
谱聚类
关联规则挖掘
ParallelFPGrowthAlgorithm
并行FPGrowth算法
回归
LocallyWeightedLinearRegression
局部加权线性回归
降维/维约简
SingularValueDecomposition
奇异值分解
PrincipalComponentsAnalysis
主成分分析
IndependentComponentAnalysis
独立成分分析
GaussianDiscriminativeAnalysis
高斯判别分析
进化算法
并行化了Watchmaker框架
推荐/协同过滤
Non-distributedrecommenders
Taste(UserCF,ItemCF,SlopeOne)
DistributedRecommenders
ItemCF
向量相似度计算
RowSimilarityJob
计算列间相似度
VectorDistanceJob
计算向量间距离
非Map-Reduce算法
HiddenMarkovModels
隐马尔科夫模型
集合方法扩展
Collections
扩展了java的Collections类
Mahout最大的优点就是基于hadoop实现,把很多以前运行于单机上的算法,转化为了MapReduce模式,这样大大提升了算法可处理的数据量和处理性能。
(一)Mahout下个性化推荐引擎Taste介绍
Taste是 ApacheMahout 提供的一个个性化推荐引擎的高效实现,该引擎基于java实现,可扩展性强,同时在mahout中对一些推荐算法进行了MapReduce编程模式转化,从而可以利用hadoop的分布式架构,提高推荐算法的性能。
在Mahout0.5版本中的Taste, 实现了多种推荐算法,其中有最基本的基于用户的和基于内容的推荐算法,也有比较高效的SlopeOne算法,以及处于研究阶段的基于SVD和线性插值的算法,同时Taste还提供了扩展接口,用于定制化开发基于内容或基于模型的个性化推荐算法。
Taste 不仅仅适用于 Java 应用程序,还可以作为内部服务器的一个组件以 HTTP 和 WebService 的形式向外界提供推荐的逻辑。
Taste 的设计使它能满足企业对推荐引擎在性能、灵活性和可扩展性等方面的要求。
下图展示了构成Taste的核心组件:
从上图可见,Taste由以下几个主要组件组成:
DataModel:
DataModel是用户喜好信息的抽象接口,它的具体实现支持从指定类型的数据源抽取用户喜好信息。
在Mahout0.5中,Taste 提供JDBCDataModel 和 FileDataModel两种类的实现,分别支持从数据库和文件文件系统中读取用户的喜好信息。
对于数据库的读取支持,在Mahout0.5中只提供了对MySQL和PostgreSQL的支持,如果数据存储在其他数据库,或者是把数据导入到这两个数据库中,或者是自行编程实现相应的类。
UserSimilarit和ItemSimilarity:
前者用于定义两个用户间的相似度,后者用于定义两个项目之间的相似度。
Mahout支持大部分驻留的相似度或相关度计算方法,针对不同的数据源,需要合理选择相似度计算方法。
UserNeighborhood:
在基于用户的推荐方法中,推荐的内容是基于找到与当前用户喜好相似的“邻居用户”的方式产生的,该组件就是用来定义与目标用户相邻的“邻居用户”。
所以,该组件只有在基于用户的推荐算法中才会被使用。
Recommender:
Recommender是推荐引擎的抽象接口,Taste 中的核心组件。
利用该组件就可以为指定用户生成项目推荐列表。
(二)Mahout之
(一)数据承载
推荐数据的处理是大规模的,在集群环境下一次要处理的数据可能是数GB,所以Mahout针对推荐数据进行了优化。
Preference
在Mahout中,用户的喜好被抽象为一个Preference,包含了userId,itemId和偏好值(user对item的偏好)。
Preference是一个接口,它有一个通用的实现是GenericPreference。
因为用户的喜好数据是大规模的,我们通常会选择把它放入集合或者数组。
同时,由于Java的对象的内存消耗机制,在大数据量下使用Collection
为什么呢?
在Java中,一个对象占用的字节数=基本的8字节+基本数据类型所占的字节+对象引用所占的字节
(1)先说这基本的8字节
在JVM中,每个对象(数组除外)都有一个头,这个头有两个字,第一个字存储对象的一些标志位信息,如:
锁标志位、经历了几次gc等信息;第二个字节是一个引用,指向这个类的信息。
JVM为这两个字留了8个字节的空间。
这样一来的话,newObject()就占用了8个字节,那怕它是个空对象
(2)基本类型所占用的字节数
byte/boolean 1bytes
char/short 2bytes
int/float 4byte
double/long 8bytes
(3)对象引用所占用的字节数
reference 4bytes
注:
实际中,有数据成员的话,要把数据成员按基本类型和对象引用分开统计。
基本类型按
(2)进行累加,然后对齐到8个倍数;对象引用按每个4字节进行累加,然后对齐到8的倍数。
classtest{
Integeri;
longl;
byteb;
}
占8(基本)+16(数据成员——基本类型:
8+1,对齐到8)+8(数据成员——对象引用Integer,4,对齐到8)=32字节
如此一来的话,一个GenericPreference的对象就需要占用28个字节,userId(8bytes)+itemId(8bytes)+preference(4bytes)+基本的8bytes=28。
如果我们使用了Collection
设想如果我们的数据量是上GB或是上TB,这样的开销是很难承受的。
为此Mahout封装了一个PreferenceArray,用于表示喜好数据的集合
我们看到,GenericUserPreferenceArray包含了一个userId,一个itemId的数组long[],一个用户的喜好评分数据float[]。
而不是一个Preference对象的集合。
下面我们做个比较,分别创建一个PreferenceArray和Preference数组
在size为5,但只包含一条喜好数据的情况下:
PreferenceArray需要20Bytes(userId8bytes+preference4bytes+itemId8bytes),而Preference[]需要48字节(基本8bytes+一个Preference对象28bytes+4个空的引用4×312Bytes)。
如果在有多条喜好数据的情况下,PreferenceArray中将只有一个itemId,这样它所占用的8Bytes微乎其微。
所以PreferenceArray用它特殊的实现节省了4倍内存。
用《Mahoutinaction》一书中的原话“mahouthasalreadlyreinventedan'arrayofJavaobjects'”——"mahout已经重新改造了Java对象数组"。
PreferenceArray和它的具体实现减少的内存开销远远比它的的复杂性有价值,它减少了近75%的内存开销(相对于Java的集合和对象数组)
除了PreferenceArray,Mahout中还大量使用了像Map和Set这些非常典型的数据结构,但是Mahout没有直接使用像HashMap和TreeSet这些常用的Java集合实现,取而代之的是专门为Mahout推荐的需要实现了两个API,FastByIDMap和FastIDSet,之所以专门封装了这两个数据结构,主要目的是为了减少内存的开销,提升性能。
它们之间主要有以下区别:
∙和HashMap一样,FastByIDMap也是基于hash的。
不过FastByIDMap使用的是线性探测来解决hash冲突,而不是分割链;
∙FastByIDMap的key和值都是long类型,而不是Object,这是基于节省内存开销和改善性能所作的改良;
∙FastByIDMap类似于一个缓存区,它有一个“maximumsize”的概念,当我们添加一个新元素的时候,如果超过了这个size,那些使用不频繁的元素就会被移除。
FastByIDMap和FastIDSet在存储方面的改进非常显著。
FastIDSet的每个元素平均占14字节,而HashSet而需要84字节;FastByIDMap的每个entry占28字节,而HashMap则需要84字节。
DataModel
Mahout推荐引擎实际接受的输入是DataModel,它是对用户喜好数据的压缩表示。
DataModel的具体实现支持从任意类型的数据源抽取用户喜好信息,可以很容易的返回输入的喜好数据中关联到一个物品的用户ID列表和count计数,以及输入数据中所有用户和物品的数量。
具体实现包括内存版的GenericDataModel,支持文件读取的FileDataModel和支持数据库读取的JDBCDataModel。
GenericDataModel是DataModel的内存版实现。
适用于在内存中构造推荐数据,它仅只是作为推荐引擎的输入接受用户的喜好数据,保存着一个按照用户ID和物品ID进行散列的PreferenceArray,而PreferenceArray中对应保存着这个用户ID或者物品ID的所有用户喜好数据。
FileDataModel支持文件的读取,Mahout对文件的格式没有太多严格的要求,只要满足一下格式就OK:
∙每一行包含一个用户Id,物品Id,用户喜好
∙逗号隔开或者Tab隔开
∙*.zip和*.gz文件会自动解压缩(Mahout建议在数据量过大时采用压缩的数据存储)
FileDataModel从文件中读取数据,然后将数据以GenericDataModel的形式载入内存,具体可以查看FileDataModel中的buildModel方法。
JDBCDataModel支持对数据库的读取操作,Mahout提供了对MySQL的默认支持MySQLJDBCDataModel,它对用户喜好数据的存储有以下要求:
∙用户ID列需要是BIGINT而且非空
∙物品ID列需要是BIGINT而且非空
∙用户喜好值列需要是FLOAT
∙建议在用户ID和物品ID上建索引
有的时候,我们会忽略用户的喜好值,仅仅只关心用户和物品之间存不存在关联关系,这种关联关系在Mahout里面叫做“booleanpreference”。
之所以会有这类喜好,是因为用户和物品的关联要么存在,要么不存在,记住只是表示关联关系存不存在,不代表喜欢和不喜欢。
实际上一条“booleanpreference”可有三个状态:
喜欢、不喜欢、没有任何关系。
在喜好数据中有大量的噪音数据的情况下,这种特殊的喜好评定方式是有意义的。
同时Mahout为“booleanpreference”提供了一个内存版的DataModel——GenericBooleanPrefDataModel
可以看到,GenericBooleanPrefDataModel没有对喜好值进行存储,仅仅只存储了关联的userId和itemId,注意和GenericDataModel的差别,GenericBooleanPrefDataModel采用了FastIDSet,只有关联的Id,没有喜好值。
因此它的一些方法(继承自DataModel的)如getItemIDsForUser()有更好的执行速度,而getPreferencesFromUser()的执行速度会更差,因为GenericBooleanPrefDataModel本来就没存储喜好值,它默认用户对物品的喜好值都是1.0
@Override
publicFloatgetPreferenceValue(longuserID,longitemID)throwsNoSuchUserException{
FastIDSetitemIDs=preferenceFromUsers.get(userID);
if(itemIDs==null){
thrownewNoSuchUserException(userID);
}
if(itemIDs.contains(itemID)){
return1.0f;
}
returnnull;
}
(三)Mahout之协同过滤推荐
协同过滤——CollaborativeFiltering
协同过滤简单来说就是根据目标用户的行为特征,为他发现一个兴趣相投、拥有共同经验的群体,然后根据群体的喜好来为目标用户过滤可能感兴趣的内容。
协同过滤推荐—— CollaborativeFilteringRecommend
协同过滤推荐是基于一组喜好相同的用户进行推荐。
它是基于这样的一种假设:
为一用户找到他真正感兴趣的内容的最好方法是首先找到与此用户有相似喜好的其他用户,然后将他们所喜好的内容推荐给用户。
这与现实生活中的“口碑传播(word-of-mouth)”颇为类似。
协同过滤推荐分为三类:
∙基于用户的推荐(User-basedRecommendation)
∙基于项目的推荐(Item-basedRecommendation)
∙基于模型的推荐(Model-basedRecommendation)
基于用户的协同过滤推荐——UserCF
原理:
基于用户对物品的喜好找到相似邻居用户,然后将邻居用户喜欢的物品推荐给目标用户
上图示意出UserCF的基本原理,假设用户A喜欢物品A和物品C,用户B喜欢物品B,用户C喜欢物品A、物品C和物品D;从这些用户的历史喜好信息中,我们可以发现用户A和用户C的口味和偏好是比较类似的,同时用户C还喜欢物品D,那么我们可以推断用户A可能也喜欢物品D,因此可以将物品D推荐给用户A。
实现:
将一个用户对所有物品的偏好作为一个向量(Vector)来计算用户之间的相似度,找到K-邻居后,根据邻居的相似度权重以及他们对物品的喜好,为目标用户生成一个排序的物品列表作为推荐,列表里面都是目标用户为涉及的物品。
基于物品的协同过滤推荐——ItemCF
原理:
基于用户对物品的喜好找到相似的物品,然后根据用户的历史喜好,推荐相似的物品给目标用户。
与UserCF类似,只是关注的视角变成了Item。
假设用户A喜欢物品A和物品C,用户B喜欢物品A、物品B和物品C,用户C喜欢物品A,从这些用户的历史喜好可以分析出物品A和物品C是比较类似的,喜欢物品A的人都喜欢物品C,基于这个数据可以推断用户C很有可能也喜欢物品C,所以系统会将物品C推荐给用户C。
实现:
将所有用户对某一个物品的喜好作为一个向量来计算物品之间的相似度,得到物品的相似物品后,根据用户历史的喜好预测目标用户还没有涉及的物品,计算得到一个排序的物品列表作为推荐。
相似度的计算——SimilarityMetricsComputing
关于相似度的计算,现有的几种基本方法都是基于向量(Vector)的,其实也就是计算两个向量的距离,距离越近相似度越大。
在推荐的场景中,在用户-物品偏好的二维矩阵中,我们可以将一个用户对所有物品的偏好作为一个向量来计算用户之间的相似度,或者将所有用户对某个物品的偏好作为一个向量来计算物品之间的相似度。
下面我们详细介绍几种常用的相似度计算方法:
∙欧几里德距离(EuclideanDistance)
最初用于计算欧几里德空间中两个点的距离,假设x,y是n维空间的两个点,它们之间的欧几里德距离是:
可以看出,当n=2时,欧几里德距离就是平面上两个点的距离。
当用欧几里德距离表示相似度,一般采用以下公式进行转换:
距离越小,相似度越大
∙皮尔森相关系数(PearsonCorrelationCoefficient)
皮尔森相关系数一般用于计算两个定距变量间联系的紧密程度,它的取值在[-1,+1]之间。
∙Cosine相似度(CosineSimilarity)
Cosine相似度被广泛应用于计算文档数据的相似度:
相似邻居的计算
邻居就是上文说到的“兴趣相投、拥有共同经验的群体”,在协同过滤中,邻居的计算对于推荐数据的生成是至关重要的,常用的划分邻居的方法有两类:
∙固定数量的邻居:
K-neighborhoods或者Fix-sizeneighborhoods
用“最近”的K个用户或物品最为邻居。
如下图中的A,假设要计算点1的5-邻居,那么根据点之间的距离,我们取最近的5个点,分别是点2,点3,点4,点7和点5。
但很明显我们可以看出,这种方法对于孤立点的计算效果不好,因为要取固定个数的邻居,当它附近没有足够多比较相似的点,就被迫取一些不太相似的点作为邻居,这样就影响了邻居相似的程度,比如图1中,点1和点5其实并不是很相似。
∙基于相似度门槛的邻居:
Threshold-basedneighborhoods
与计算固定数量的邻居的原则不同,基于相似度门槛的邻居计算是对邻居的远近进行最大值的限制,落在以当前点为中心,距离为K的区域中的所有点都作为当前点的邻居,这种方法计算得到的邻居个数不确定,但相似度不会出现较大的误差。
如下图中的B,从点1出发,计算相似度在K内的邻居,得到点2,点3,点4和点7,这种方法计算出的邻居的相似度程度比前一种优,尤其是对孤立点的处理。
Threshold-basedneighborhoods要表现的就是“宁缺勿滥”,在数据稀疏的情况下效果是非常明显的。
Mahout对这两类邻居的计算给出了自己的实现,分别是NearestNUserNeighborhood和ThresholdUserNeighborhood,从名字就可以看出它们的对应关系
(四)Mahout之(三)相似性度量
UserCF和ItemCF都依赖于相似度的计算,因为只有通过衡量用户之间或物品之间的相似度,才能找到用户的“邻居”,才能完成推荐。
上文简单的介绍了相似性的计算,但不完全,下面就对常用的相似度计算方法进行详细的介绍:
1.基于皮尔森相关性的相似度——Pearsoncorrelation-basedsimilarity
皮尔森相关系数反应了两个变量之间的线性相关程度,它的取值在[-1,1]之间。
当两个变量的线性关系增强时,相关系数趋于1.基于皮尔森相关性的相似度——Pearsoncorrelation-basedsimilarity
皮尔森相关系数反应了两个变量之间的线性相关程度,它的取值在[-1,1]之间。
当两个变量的线性关系增强时,相关系数趋于1或-1;当一个变量增大,另一个变量也增大时,表明它们之间是正相关的,相关系数大于0;如果一个变量增大,另一个变量却减小,表明它们之间是负相关的,相关系数小于0;如果相关系数等于0,表明它们之间不存在线性相关关系。
用数学公式表示,皮尔森相关系数等于两个变量的协方差除于两个变量的标准差。
协方差(Covariance):
在概率论和统计学中用于衡量两个变
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Mahout