Mahout--(一)数据承载

mahout API英文解释:https://builds.apache.org/job/Mahout-Quality/javadoc/

推荐数据的处理是大规模的,在集群环境下一次要处理的数据可能是数GB,所以Mahout针对推荐数据进行了优化。

Preference

在Mahout中,用户的喜好被抽象为一个Preference。包括了userId,itemId和偏好值(user对item的偏好)。Preference是一个接口,它有一个通用的实现是GenericPreference。


Preference

但由于用户的喜好数据是大规模的,我们一般会选择把它放入集合或者数组。可是由于Java的对象的内存消耗机制,在大数据量下使用Collection<Preference>和Preference[]是很低效的。

为什么呢?

在Java中,一个对象占用的字节数 = 主要的8字节 + 基本数据类型所占的字节 + 对象引用所占的字节

(1)先说这主要的8字节

在JVM中,每一个对象(数组除外)都有一个头。这个头有两个字,第一个字存储对象的一些标志位信息。如:锁标志位、经历了几次gc等信息;第二个字节是一个引用,指向这个类的信息。

JVM为这两个字留了8个字节的空间。

这样一来的话。new Object()就占用了8个字节。那怕它是个空对象

(2) 基本类型所占用的字节数

byte/boolean 1bytes

char/short 2bytes

int/float 4bytes

double/long 8bytes

(3)对象引用所占用的字节数

reference 4bytes

注:实际中,有数据成员的话,要把数据成员按基本类型和对象引用分开统计。基本类型按(2)进行累加。然后对齐到8个倍数;对象引用按每一个4字节进行累加,然后对齐到8的倍数。

class test {

Integer i;

long l;

byte b;

}

占 8(基本) + 16(数据成员——基本类型:8 + 1。对齐到8) + 8(数据成员——对象引用Integer。4。对齐到8) = 32字节

如此一来的话。一个GenericPreference的对象就须要占用28个字节,userId(8bytes) + itemId(8bytes) + preference(4bytes) + 主要的8bytes = 28。假设我们使用了Collection<Preference>和Preference[]。就会浪费非常多这主要的8字节。设想假设我们的数据量是上GB或是上TB,这种开销是非常难承受的。

为此Mahout封装了一个PreferenceArray,用于保存一组用户喜好数据,为了优化性能,Mahout给出了两个实现类:GenericUserPreferenceArray和GenericItemPreferenceArray,分别依照用户和物品本身对用户偏好进行组装,这样就能够压缩用户ID或者物品ID的空间。


PreferenceArray

GenericUserPreferenceArray

我们看到,GenericUserPreferenceArray包括了一个userId,一个itemId的数组long[],一个用户的喜好评分数据float[]。而不是一个Preference对象的集合。它仅仅有较少的对象须要被创建和gc的检查。

用《Mahout in action》一书中的原话“mahout has alreadly reinvented an ‘array of Java objects‘”——"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类似于一个缓存区。它有一个“maximum size”的概念,当我们加入一个新元素的时候。假设超过了这个size,那些使用不频繁的元素就会被移除。

FastByIDMap和FastIDSet在存储方面的改进很显著。FastIDSet的每一个元素平均占14字节,而HashSet而须要84字节;FastByIDMap的每一个entry占28字节,而HashMap则须要84字节。

DataModel

Mahout推荐引擎实际接受的输入是DataModel。它是对用户喜好数据的压缩表示。DataModel的详细实现支持从随意类型的数据源抽取用户喜好信息。能够非常easy的返回输入的喜好数据中关联到一个物品的用户ID列表和count计数。以及输入数据中全部用户和物品的数量。详细实现包含内存版的GenericDataModel,支持文件读取的FileDataModel和支持数据库读取的JDBCDataModel。


DataModel

GenericDataModel是DataModel的内存版实现。适用于在内存中构造推荐数据。它仅仅仅是作为推荐引擎的输入接受用户的喜好数据,保存着一个依照用户ID和物品ID进行散列的PreferenceArray,而PreferenceArray中相应保存着这个用户ID或者物品ID的全部用户喜好数据。


GenericDataModel

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里面叫做“boolean preference”。 之所以会有这类喜好,是由于用户和物品的关联要么存在,要么不存在,记住仅仅是表示关联关系存不存在,不代表喜欢和不喜欢。实际上一条“boolean preference”可有三个状态:喜欢、不喜欢、没有不论什么关系。

在喜好数据中有大量的噪音数据的情况下,这样的特殊的喜好评定方式是有意义的。 同一时候Mahout为“boolean preference”提供了一个内存版的DataModel——GenericBooleanPrefDataModel


GenericBooleanPrefDataModel

能够看到,GenericBooleanPrefDataModel没有对喜好值进行存储。仅仅仅仅存储了关联的userId和itemId。注意和GenericDataModel的区别。GenericBooleanPrefDataModel採用了FastIDSet。仅仅有关联的Id,没有喜好值。

因此它的一些方法(继承自DataModel的)如getItemIDsForUser()有更好的运行速度。而getPreferencesFromUser()的运行速度会更差,由于GenericBooleanPrefDataModel本来就没存储喜好值。它默认用户对物品的喜好值都是1.0

@Override

public Float getPreferenceValue(long userID, long itemID) throws NoSuchUserException {

FastIDSet itemIDs = preferenceFromUsers.get(userID);

if (itemIDs == null) {

throw new NoSuchUserException(userID);

}

if (itemIDs.contains(itemID)) {

return 1.0f;

}

return null;

}

提问:

在mahout框架下,我现阶段学习到的是仅仅实用户对某些物品进行评分了,才干对这个用户进行推荐。可是假设用户刚登陆,没有其它的操作,如何进行推荐呀(我知道在mahout有个匿名用户的推荐方式)?可是,用户已经输入了他的一些兴趣爱好了。如何依据这些兴趣爱好对用户进行推荐呀。

还有,就是新增加的物品。仅仅有这些物品的一些属性,没有不论什么人对它进行评分,怎样依据属性将它推荐给用户呢?

还有我有一些好友了。如何依据好友的喜欢的物品进行推荐给我呀,在评分表中不是仅仅要用户id。物品id,和偏好。如何在当中区分出好友来呢?????

回答:

首先纠正你问题中的一点错误,Mahout
中有一个 Preference 的特殊实现 —— BooleanPreference(“布尔喜好值”)。通过这个特殊的 Preference 实现,Mahout 将不会关注用户对物品的详细评分。而仅仅是关注用户和物品之间有没有某种关联(比方点击、购买等),所以你的问题中提到的即使用户没有对物品进行评分。Mahout 也能够完毕对用户的推荐。

对于你的问题,我发现主要是疑惑怎样利用 Mahout 去解决推荐时的冷启动,包含用户冷启动(新用户)和物品冷启动(新物品)。这应该说是每个推荐系统都会面临着的问题,因此推荐系统的研究者们想出了非常多的解决方式,只是非常抱歉,Mahout 中对于冷启动问题并没有专门的实现。原因非常easy,眼下的 Mahout
仅仅是一个机器学习算法库(框架),它不是一个推荐系统或推荐引擎。只是。我们还是能够利用 Mahout 中提供的一些算法帮助我们解决冷启动。

对于新用户。(1)假设是一个注冊用户而且已经登录。但没有发生不论什么用户行为(比方评论、分享、收藏、购买),那么我们能够拿他的注冊信息,依据他的性别、年龄、所在地等信息进行推荐,也就是基于人口统计特征的推荐(Demographic-based)。(2)假设是一个注冊用户但没有登录,那么我们能够通过 cookie
去识别用户,这个时候 cookie 和 userId 有同等的功效。解决的办法也就和(1)类似了。顺便罗嗦几句,一个成熟的推荐系统可以做到在用户未登录的情况下也能进行推荐,这就告诉我们。标识用户的除了 userId,还有 cookie,所以可以在记录用户喜好的表里添加一列用来存储用户的 cookie。这个视实际情况而定(对于 SNS 站点。如微博须要登录才干使用,不存在此类问题。可是对于淘宝就存在此问题);(3)对于未注冊的新訪客。由于没有人口统计信息,所以一般通过一些热卖推荐、随机推荐引导用户浏览、点击、收藏、注冊,让用户在站点上发生一些有价值的行为,然后再依据这些行为进行推荐。

对于新物品,仅仅要有物品的属性,那怕没有不论什么人对它进行评分,也是能够进行推荐的,方法就是依据物品的属性去推荐,也就是基于内容的推荐(Content-based)。通过物品的属性去计算物品之间的相关度。举个样例。如果新增加的物品是一本刚出版的《HBase: The Definitive Guide》,没有不论什么用户对它进行过评分或购买,如果这个时候有一个用户对《Hadoop
in Action》有了非常高的评分。那么我们就能够把《HBase: The Definitive Guide》推荐给这个用户,由于这两本书用着共同的属性和特点:计算机、分布式、大数据 ...

那么怎样利用 Mahout 帮忙解决新用户和新物品的冷启动问题呢?一个简单的方法是聚类。对于新用户,我们依据他们的人口统计信息去聚类。把用户划分成一个一个的簇;新物品也是一样的,能够利用物品的属性。假设没有属性。能够对物品的介绍和描写叙述进行分词,抽取出物品的属性和关键词描写叙述,然后依据属性和关键词去聚类,把物品划分成一个一个的簇。Mahout
中对聚类有专门的实现,能够关注我后面的日记和博文。

你的最后一个问题,怎样依据好友的喜好进行推荐?说直接点,也就是怎样利用社交数据进行推荐?随着 SNS 的流行,这样的推荐方法也逐渐被重视,推荐的方法也非常easy:从社交站点获取用户的好友列表。然后在目标站点中搜索好友列表中每个好友喜欢的物品。然后推荐给用户。

通经常使用户的好友列表是来源于外部的 SNS 站点。最普遍的就是通过开放的
API 授权后获取(微博、QQ空间都是这样),而用户的喜好 userId、itemId、preference 存储在目标站点的 MySQL 或者缓存中。须要做的仅仅仅是 查找、过滤、排序 那么简单。

推荐的书籍和资料:《Mahout in Action》、《推荐系统实践》。ReSysChina

学习mahout,可是苦于网上资源太少,太零散,只是这边博文讲得比較清楚和细致:网址:http://www.douban.com/note/204399134/

时间: 2024-11-20 23:41:06

Mahout--(一)数据承载的相关文章

Mahout之数据承载

转载自:https://www.douban.com/note/204399134/ 推荐数据的处理是大规模的,在集群环境下一次要处理的数据可能是数GB,所以Mahout针对推荐数据进行了优化. Preference 在Mahout中,用户的喜好被抽象为一个Preference,包含了userId,itemId和偏好值(user对item的偏好).Preference是一个接口,它有一个通用的实现是GenericPreference. Preference 但因为用户的喜好数据是大规模的,我们通

如何来合理解决电商系统数据承载过大的问题呢?

原文地址:http://whosmall.com/?post=431 初创企业在发展过程中,一般不会遇到类似问题,但是随着业务量的增加,特别是电商系统,由于每日的订单数量过多,导致数据库的承载量过大,更换服务器的成本很大,所以如何来合理解决电商系统数据承载过大的问题呢? 1.从初始阶段,这应该是属于系统架构师应该考虑进去的事情,所以这项工作应该由架构师来完成: 2.如果没有合理的架构,那么在需要解决这个问题的时候,可以通过数据库分库,分表.切片的方式来进行.(再次强调这是个技术问题,产品不背锅)

Apache mahout 源码阅读笔记--DataModel之FileDataModel

要做推荐,用户行为数据是基础. 用户行为数据有哪些字段呢? mahout的DataModel支持,用户ID,ItemID是必须的,偏好值(用户对当前Item的评分),时间戳 这四个字段 {@code userID,itemID[,preference[,timestamp]]} mahout数据源支持从文件.DB中读取. 从FileDataModle.java的注释来看,还是做了不少工作的. 1)原文件更新后一定的时间段,才会reload 2)支持增量更新(不用每次都重新copy所有数据) 3)

大数据与传统数据

小编说:在这个人人都说大数据的时代,许多人对大数据的印象只是停留在仰望的阶段,其实大数据没人们说得那么神奇.玄乎或者是无所不能,今天我们就以传统数据作为比对,看看大数据究竟有什么特点让其处于时代的浪潮之巅. 本文选自<从1开始--数据分析师成长之路>. 大数据与传统数据相比的主要特点可以概括为:数据量"大".数据类型"复杂".数据价值"无限".  数据量大十分好理解,以前我们存储数据使用的单位是 KB,一个Excel表格也就几十到几百

Mahout机器学习平台之聚类算法详细剖析(含实例分析)

第一部分: 学习Mahout必须要知道的资料查找技能: 学会查官方帮助文档: 解压用于安装文件(mahout-distribution-0.6.tar.gz),找到如下位置,我将该文件解压到win7的G盘mahout文件夹下,路径如下所示: G:\mahout\mahout-distribution-0.6\docs 学会查源代码的注释文档: 方案一:用maven创建一个mahout的开发环境(我用的是win7,eclipse作为集成开发环境,之后在Maven Dependencies中找到相应

Struts2 In Action笔记_页面到动作的数据流入和流出

因为回答百度知道的一个问题,仔细查看了<Struts2 In Action>,深入细致的看了 “数据转移OGNL 和 构建视图-标签”,很多东西才恍然大悟. 一直觉得国外写的书很浮,不具有操作性,但其实,Coding多了,才发现国外的书写的深刻.清晰.能传道解惑. 一.主要收获 1. Struts2 框架的数据流入和流出 使用 Struts2 标签时,所有非字符串属性都被当作 OGNL表达式进行解析. 使用  %{expression} 语法可以强制将字符串属性当作 OGNL表达式解析. 2.

Mahout学习路线图-张丹老师

前言 Mahout是Hadoop家族中与众不同的一个成员,是基于一个Hadoop的机器学习和数据挖掘的分布式计算框架.Mahout是一个跨学科产品,同时也是我认为Hadoop家族中,最有竞争力,最难掌握,最值得学习的一个项目之一. Mahout为数据分析人员,解决了大数据的门槛:为算法工程师,提供基础的算法库:为Hadoop开发人员,提供了数据建模的标准:为运维人员,打通了和Hadoop连接. Mahout就是训象人,在Hadoop上创造新的智慧! 目录 Mahout介绍 Mahout学习路线图

大数据系列文章汇总 - 更新到15篇

转自:http://blog.csdn.net/matthewei6/article/details/50615816 大数据(一) - hadoop生态系统及版本演化大数据(二) - HDFS大数据(三) - YARN大数据(四) - MapReduce大数据(五) - HBase大数据(六) - ZooKeeper大数据(七) - Flume大数据(八) - Sqoop大数据(九) - Hive大数据(十) - Pig大数据(十一) - Mahout大数据(十二) - Oozie大数据(十三

JFinal数据映射生成工具

//第一次学习Jfinal框架,挺方便的,就是这个ActiveRecordPlugin有点头疼,  //是不是失去了将数据库对象化的操作了,怪自己懒,写一个算是数据库映射吧..(大虾莫笑) 1. [代码][Java]代码      ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47