1. 简介
Apache Hivemall是机器学习算法(machine learning algorithms)和多功能数据分析函数(versatile data analytics functions)的集合,它通过Apache Hive UDF / UDAF / UDTF接口提供了一些易于使用的机器学习算法。Hivemall 最初由Treasure Data 开发的,并于2016年9月捐献给 Apache 软件基金会,进入了Apache 孵化器。
Apache Hivemall提供了各种功能包括:回归(regression)、分类(classification)、推荐(recommendation)异常检测(anomaly detection)、k-最近邻(k-nearest neighbor)以及特征工程(feature engineering)。同时它还支持最先进的机器学习算法,如软信度加权(Soft Confidence Weighted)、权重向量的自适应正则化(Adaptive Regularization of Weight Vectors)、因式分解机(Factorization Machines)和AdaDelta。
1.1. 架构
Apache Hivemall 设计主要是运行在Apache Hive之上,但是还支持在Apache Pig 和 Apache Spark 上运行。所以我们也可以把它当做是一个跨平台的机器学习类库。我们可以通过Apache Hive构建预测模型然后在Apache Spark/Pig上使用;反之也是可以的。
架构如下所示:
2. 开始运行
2.1. 安装
2.1.1. 前置条件
- Hadoop v2.4.0 or later
- Hive v0.13 or later
- Java 7 or later
- hivemall-core-xxx-with-dependencies.jar
- define-all.hive
2.1.2. 安装
将下面两行配置添加到$HOME/.hiverc
文件中。
add jar /home/myui/tmp/hivemall-core-xxx-with-dependencies.jar;
source /home/myui/tmp/define-all.hive;
这样在每次启动一个Hive session
时,都会自动载入Hivemall所有的功能。除了添加配置之外,也可以每次都运行下面的命令行。
$ hive
add jar /tmp/hivemall-core-xxx-with-dependencies.jar;
source /tmp/define-all.hive;
2.1.3. 其他选择
你也可以在以下的平台上运行Hivemall:
- Apache Spark
- Apache Pig
- Apache Hive on Docker for testing
2.1.4. 源代码编译
方法如下:
$ git clone https://github.com/apache/incubator-hivemall.git
$ cd incubator-hivemall
$ bin/build.sh
这时,你可以在目录./target
中发现hivemall的jars文件。
2.2. 作为类持久函数(permanent functions)安装
Hive v0.13及之后的更新版本在生命周期中支持类持久函数。
Permanent functions
在你通过Hiveserver
使用Hive时候,或者避免每次session都要安装hivemall的时,是非常有用的。
- 将hivemall的jar包放入HDFS
- 创建
permanent functions
- 确认函数
2.2.1. 将hivemall的jar包放入HDFS
首先将hivemall的jar包放入HDFS,如下:
hadoop fs -mkdir -p /apps/hivemall
hadoop fs -put hivemall-with-dependencies.jar /apps/hivemall
2.2.2. 创建permanent functions
以下是一个辅助的步骤来定义hivemall数据库的功能,而不是默认数据库。
CREATE DATABASE IF NOT EXISTS hivemall;
USE hivemall;
然后使用 define-all-as-permanent.hive
创建 permanent functions
,一哥DDL脚本定义永久UDFS。
set hivevar:hivemall_jar=hdfs:///apps/hivemall/hivemall-with-dependencies.jar;
source /tmp/define-all-as-permanent.hive;
2.2.3. 确认函数
在命令行输入:
show functions "hivemall.*";
会显示
> hivemall.adadelta
> hivemall.adagrad
2.3. 输入格式
接下来介绍在Hivemall的训练数据的输入格式,在这里将会使用EBNF(扩展的巴科斯范式)注解来描述这种格式。
2.3.1. 分类的输入格式
Hivemall的分类器需要2到3个参数:特征值、标签和选项。训练方法的前两个参数表示的是训练示例。在统计学上,特征值和标签分别被称为解释变量和响应变量。
2.3.2. 特征值格式(分类和回归)
在回归和分类之间的特征值的格式是相同的。Hivemall对于特征值的类型的列可以是ARRAY<INT|BIGINT|TEXT>
等多种类型。Hivemall使用一种不常见的数据格式类似于LIBSVM
和Vowpal Wabbit
。
在一个数组中,每个特征值的格式如下:
feature ::= <index>:<weight> or <index>
每个索引的元素或者权重的数据格式如下:
index ::= <INT | BIGINT | TEXT>
weight ::= <FLOAT>
索引通常从1开始的整数类型(INT/BIGINT)。下面是一个特征值的示例:
10:3.4 123:0.5 34567:0.231
注意:稍后将会提到,索引"0"将会作为虚拟变量保存。
除了数字之外,你也可以使用TEXT
值作为一个索引。比如:你可以使用array("height:1.5", "length:2.0")做为特征值。
"height:1.5" "length:2.0"
2.3.3. 定量和分类变量
定量变量必须有一个索引的目录。
Hivemall(v0.3.1之后)提供add_feature_index
函数,这个函数很方便的将索引添加到定量变量。
select add_feature_index(array(3,4.0,5)) from dual;
输出结果:
["1:3.0","2:4.0","3:5.0"]
你可以对每个特征值忽略指定权重,比如分类变量如下:
feature :: = <index>
2.3.4. Bias/Dummy变量
注意:"0"倍保存为偏差变量(在统计学称为虚拟变量)。
Hivemall中addBias
函数追加"0:1.0"作为特征值数组中的一个元素。
2.3.5. 特征值哈希化
Hivemall通过mhash function
支持特征值的哈希化。
在默认的设置中,mhash
函数接受一个文本格式的特征值,然后生成一个范围在1到224=16777216的哈希数。
在特征值维数比较大的时候,特征值哈希化是非常有用的。当预测模型比较大,会超出内存限制或者发生内存溢出的时候,可以考虑使用mhash function
。
一般情况下,当特征值为数少于16777216的时候,是没有必要使用mhash
的。如果特征值的索引是非常大的文本,使用大量的内存空间,考虑使用mhash
函数如下:
-- feature is v0.3.2 or before
concat(mhash(extract_feature("xxxxxxx-yyyyyy-weight:55.3")), ":", extract_weight("xxxxxxx-yyyyyy-weight:55.3"))
-- feature is v0.3.2-1 or later
feature(mhash(extract_feature("xxxxxxx-yyyyyy-weight:55.3")), extract_weight("xxxxxxx-yyyyyy-weight:55.3"))
输出
43352:55.3
2.3.6. 二分分类器的标签格式
标签必须是一个INT
类型的列,并且值是1或-1,如下所示:
<label> ::= 1 | -1
或者,也可以使用以下的格式,使用1代表正数,0代表负数:
<label> ::= 1 | -1
2.3.7. 多类分类器的标签格式
标签可以使用任意的元类型,如下:
<label> ::= <primitive type>
往往,标签列的类型是INT,BIGINT或TEXT
2.3.8. 回归的输入格式
在回归算法里,响应/预测变量是一个真实的数字。
在Hivemall v0.3之前,值接受FLOAT类型作为目标值:
<target> ::=<FLOAT>
你需要显示的将一个double值转换成float:
CAST(target as FLOAT)
另一方面,v0.3版本之后,可以接受多种兼容的格式:
<target> ::= <FLOAT | DOUBLE | INT | TINYINT | SMALLINT| BIGINT >
2.3.9. 逻辑回归的目标
逻辑回归实际上是一个二分分类方案,虽然它可以产生正的的训练样本的概率。
一个训练集输入的目标值必须在0.0到1.0,更明确一点就是0.0或1.0。
2.3.10. 帮助函数
-- hivemall v0.3.2 and before
select concat("weight",":",55.0);
-- hivemall v0.3.2-1 and later
select feature("weight", 55.0);
weight:55.0
select extract_feature("weight:55.0"), extract_weight("weight:55.0");
weight | 55.0
-- hivemall v0.4.0 and later
select feature_index(array("10:0.2","7:0.3","9"));
[10,7,9]
select
convert_label(-1), convert_label(1), convert_label(0.0f), convert_label(1.0f)
from
dual;
0.0f | 1.0f | -1 | 1
2.3.11. 量化特征
`array<string> quantitative_features(array<string> featureNames, ...) 是一个helper函数来创建稀疏表中的数量特征。
select quantitative_features(array("apple","value"),1,120.3);
["apple:1.0","value:120.3"]
2.3.12. 分类特征
array<string> categorical_features(array<string> featureNames, ...)
是一个helper函数,要从表中创建稀疏分类特征。
select categorical_features(
array("is_cat","is_dog","is_lion","is_pengin","species"),
1, 0, 1.0, true, "dog"
);
["is_cat#1","is_dog#0","is_lion#1.0","is_pengin#true","species#dog"]
2.3.13. 准备训练数据表
select
rowid() as rowid,
concat_array(
array("bias:1.0"),
categorical_features(
array("id", "name"),
id, name
),
quantitative_features(
array("height", "weight"),
height, weight
)
) as features,
click_or_not as label
from
table;
3. 几点有效的Hivemall建议
3.1. 显式使用addBias()会有更好的预测结果
训练者学习以下形式的函数$f(x)= y$或权重$W$,以预测其中x是特征向量的标签。$y=f(x)=Wx$
如果没有偏差条款(bias caluse)(或正则化处理),由于$f(x)$与原点(0,0)交叉,所以f(x)不能处理成超平面分割(1,1)和(2,2)。
使用偏差条款b,训练者学习以下函数$f(x)=Wx+b$之后,预测模型会考虑到数据集中存在的偏差,预测到超平面并不一定与原点相交。
Hivemall的addBias()
向特征向量添加偏差。 要使用一个偏差条款,需要在训练和测试的数据集中使用addBias()
。例如:偏值b是默认值为0(v3版本之前为"-1")的特征。
注意:偏差是所有训练和测试集中表现出来的特征。
3.1.1. 数据集中添加偏差变量
create table e2006tfidf_test_exploded as
select
rowid,
target,
split(feature,":")[0] as feature,
cast(split(feature,":")[1] as float) as value
-- extract_feature(feature) as feature, -- hivemall v0.3.1 or later
-- extract_weight(feature) as value -- hivemall v0.3.1 or later
from
e2006tfidf_test LATERAL VIEW explode(addBias(features)) t AS feature;
3.1.2. 训练集中添加偏差变量
create table e2006tfidf_test_exploded as
select
rowid,
target,
split(feature,":")[0] as feature,
cast(split(feature,":")[1] as float) as value
-- extract_feature(feature) as feature, -- hivemall v0.3.1 or later
-- extract_weight(feature) as value -- hivemall v0.3.1 or later
from
e2006tfidf_test LATERAL VIEW explode(addBias(features)) t AS feature;
3.2. 使用rand_amplify()
会有更好的预测结果
本节介绍了对提高预测分数有用的放大技术。
迭代算法在机器学习中是必不可少的(例如,随机梯度下降)以获得良好的预测模型。但是因为每个MapReduce作业的输入和输出都通过HDFS,所以MapReduce不适用于迭代算法。
在这节中,将会描述Hivemall如何处理这种问题,下面以KDD Cup 2012
,Track 2 Task
为例:
- 在Map阶段放大训练数据,在Reduce阶段进行清洗
- 在每个Map任务中放大和清洗训练数据
- 结论
3.2.1. 在Map阶段放大训练数据,在Reduce阶段进行清洗
Hivemall提供放大UDTF来枚举机器学习中的迭代效果,无需几个MapReduce步骤。
放大(amplify)功能为每行返回多行,其中第一个参数${xtimes}
是乘法因子。
在下面的例子中,乘法因子设置为3。
set hivevar:xtimes=3;
create or replace view training_x3
as
select
*
from (
select
amplify(${xtimes}, *) as (rowid, label, features)
from
training_orcfile
) t
CLUSTER BY rand();
在上面的示例中,CLUSTER BY
子句使用分配密钥的随机密钥将Map的输出分配给reducer,并且reducer的输入记录是随机清洗的。
记录和随机清洗的乘法与迭代具有相似的效果。 因此,我们建议用户使用放大视图进行训练,具体如下:
create table lr_model_x3
as
select
feature,
cast(avg(weight) as float) as weight
from
(select
logress(features,label) as (feature,weight)
from
training_x3
) t
group by feature;
上述两个MapReduce的查询过程如下所示:
在本示例中,使用trainning_x3
函数而不是简单训练表,这样得到了更高和更好的AUC(0.746214)。
amplify()
中的一个问题是,在第1阶段的清洗(复制)和合并阶段可能会成为瓶颈。 当训练表比较大,涉及100个Map任务时,合并运算操作需要通过(外部)合并排序来合并至少100个文件!
注意:实际瓶颈不是M/R迭代,而是清洗训练实例。没有清洗的迭代(如Spark示例中)交导致非常慢的收敛,并导致需要更多的迭代。 但是,清洗的过程是避免不了的,即使在迭代MapReduce变体中。
3.2.2. 在每个Map任务中放大和清洗训练数据
为了处理大量的训练数据,Hivemall提供了rand_amplify
UDTF,可以在Map任务中随机清洗输入的行。 当填写由${shufflebuffersize}
指定的本地缓冲区时,rand_amplify
UDTF以随机顺序输出行。
使用rand_amplify()
,training_x3的视图定义如下:
set hivevar:shufflebuffersize=1000;
create or replace view training_x3
as
select
rand_amplify(${xtimes}, ${shufflebuffersize}, *) as (rowid, label, features)
from
training_orcfile;
训练查询执行如下所示:
map-local的乘法和清洗在合并阶段没有瓶颈,并且在单个MapReduce作业中查询的效率是比较高的。
这个例子中使用 rand_amplify
得到了更好的AUC(0.743392)
3.2.3. 结论
我们建议用户使用amplify()
进行小型训练输入,并使用rand_amplify()
进行大型训练输入,以在合理的训练时间内获得更好的准确性。
方法 | 消耗时间 (sec) | AUC |
---|---|---|
Plain | 89.718 | 0.734805 |
amplifier+clustered by | 479.855 | 0.746214 |
rand_amplifier | 116.424 | 0.743392 |
3.3. RDBMS实时预测
Apache Hivemall提供了一个在Apache Hive上构建预测模型的批量学习方案。 学习过程本身是一个批处理过程,但是可以通过对事务关系DBMS进行预测来实现在线/实时预测。
在本节将介绍如何使用关系DBMS运行实时预测,我们假设您已经运行了a9a二进制分类任务。
3.3.1. 前置条件
- Mysql
将mysql-connector-java.jar
放到$SQOOP_HOME/lib
路径。 - Sqoop
Sqoop 1.4.5不支持Hadoop v2.6.0。 因此,您需要为Hadoop 2.6构建软件包。 为此,您需要编辑build.xml和ivy.xml,如此补丁(https://gist.github.com/myui/...所示。
3.3.2. 在Mysql上准备模型表
create database a9a;
use a9a;
create user sqoop identified by 'sqoop';
grant all privileges on a9a.* to 'sqoop'@'%' identified by 'sqoop';
flush privileges;
create table a9a_model1 (
feature int,
weight double
);
不要忘记编辑MySQL配置文件(/etc/mysql/my.cnf)中可以从Hadoop主站和从站节点访问的bind_address。
3.3.3. Hive导出表到MySQL
使用Sqoop检查MySQL服务器的连接。
export MYSQL_HOST=dm01
export HADOOP_HOME=/opt/hadoop
export HADOOP_CONF_DIR=${HADOOP_HOME}/etc/hadoop/
export HADOOP_COMMON_HOME=${HADOOP_HOME}
bin/sqoop list-tables --connect jdbc:mysql://${MYSQL_HOST}/a9a --username sqoop --password sqoop
因为Sqoop无法读取Hive表,所以需要创建TSV表。
create table a9a_model1_tsv
ROW FORMAT DELIMITED
FIELDS TERMINATED BY "\t"
LINES TERMINATED BY "\n"
STORED AS TEXTFILE
AS
select * from a9a_model1;
检查'a9a_model1_tsv'的位置如下:
desc extended a9a_model1_tsv;
> location:hdfs://dm01:9000/user/hive/warehouse/a9a.db/a9a_model1_tsv
bin/sqoop export \
--connect jdbc:mysql://${MYSQL_HOST}/a9a \
--username sqoop --password sqoop \
--table a9a_model1 \
--export-dir /user/hive/warehouse/a9a.db/a9a_model1_tsv \
--input-fields-terminated-by '\t' --input-lines-terminated-by '\n' \
--batch
导出成功完成后,您可以在MySQL的模型表中找到条目。
mysql> select * from a9a_model1 limit 3;
+---------+---------------------+
| feature | weight |
+---------+---------------------+
| 0 | -0.5761121511459351 |
| 1 | -1.5259535312652588 |
| 10 | 0.21053194999694824 |
+---------+---------------------+
3 rows in set (0.00 sec)
我们建议创建一个模型表索引,以提高在线预测中的查寻效率。
CREATE UNIQUE INDEX a9a_model1_feature_index on a9a_model1 (feature);
-- USING BTREE;
3.3.4. 将测试数据从Hadoop导出到MySQL(可选步骤)
在将要导出的Hive中准备一个测试数据表。
create table a9atest_exploded_tsv
ROW FORMAT DELIMITED
FIELDS TERMINATED BY "\t"
LINES TERMINATED BY "\n"
STORED AS TEXTFILE
AS
select
rowid,
-- label,
extract_feature(feature) as feature,
extract_weight(feature) as value
from
a9atest LATERAL VIEW explode(addBias(features)) t AS feature;
desc extended a9atest_exploded_tsv;
> location:hdfs://dm01:9000/user/hive/warehouse/a9a.db/a9atest_exploded_tsv,
准备一个测试表,从Hadoop的导入数据。
use a9a;
create table a9atest_exploded (
rowid bigint,
feature int,
value double
);
然后,运行Sqoop将数据从HDFS导出到MySQL。
export MYSQL_HOST=dm01
bin/sqoop export \
--connect jdbc:mysql://${MYSQL_HOST}/a9a \
--username sqoop --password sqoop \
--table a9atest_exploded \
--export-dir /user/hive/warehouse/a9a.db/a9atest_exploded_tsv \
--input-fields-terminated-by '\t' --input-lines-terminated-by '\n' \
--batch
为rowid列添加一个索引以提高rowid的选择。
CREATE INDEX a9atest_exploded_rowid_index on a9atest_exploded (rowid) USING BTREE;
导出成功完成后,您可以在MySQL的测试表中找到条目。
mysql> select * from a9atest_exploded limit 10;
+-------+---------+-------+
| rowid | feature | value |
+-------+---------+-------+
| 12427 | 67 | 1 |
| 12427 | 73 | 1 |
| 12427 | 74 | 1 |
| 12427 | 76 | 1 |
| 12427 | 82 | 1 |
| 12427 | 83 | 1 |
| 12427 | 0 | 1 |
| 12428 | 5 | 1 |
| 12428 | 7 | 1 |
| 12428 | 16 | 1 |
+-------+---------+-------+
10 rows in set (0.00 sec)
3.3.5. 通过MySQL在线/实时预测
定义用于逻辑回归预测的S形函数如下:
DROP FUNCTION IF EXISTS sigmoid;
DELIMITER //
CREATE FUNCTION sigmoid(x DOUBLE)
RETURNS DOUBLE
LANGUAGE SQL
BEGIN
RETURN 1.0 / (1.0 + EXP(-x));
END;
//
DELIMITER ;
我们在这里假设对具有(0,1,10)的“特征”进行预测,并且它们中的每一个是分类特征(即权重为1.0)。然后,您可以通过逻辑回归获得概率如下:
select
sigmoid(sum(m.weight)) as prob
from
a9a_model1 m
where
m.feature in (0,1,10);
+--------------------+
| prob |
+--------------------+
| 0.1310696931351625 |
+--------------------+
1 row in set (0.00 sec)
类似于Hive的方式,您可以运行预测如下:
select
sigmoid(sum(t.value * m.weight)) as prob,
if(sigmoid(sum(t.value * m.weight)) > 0.5, 1.0, 0.0) as predicted
from
a9atest_exploded t LEFT OUTER JOIN
a9a_model1 m ON (t.feature = m.feature)
where
t.rowid = 12427; -- prediction on a particular id
也可以使用SQL视图来测试上述查询中的目标“t”。
+---------------------+-----------+
| prob | predicted |
+---------------------+-----------+
| 0.05595205126313402 | 0.0 |
+---------------------+-----------+
1 row in set (0.00 sec)
3.4. 综合学习稳定预测
这个例子说明了如何在Hivemall中运行集体学习。
3.4.1. UDF准备
delete jar /home/myui/tmp/hivemall.jar;
add jar /home/myui/tmp/hivemall.jar;
source /home/myui/tmp/define-all.hive;
3.4.2. [情况1]模式集合/混合
3.4.2.1. 训练
SET hive.exec.parallel=true;
SET hive.exec.parallel.thread.number=8;
SET mapred.reduce.tasks=4;
drop table news20mc_ensemble_model1;
create table news20mc_ensemble_model1 as
select
label,
-- cast(feature as int) as feature, -- hivemall v0.1
argmin_kld(feature, covar) as feature, -- hivemall v0.2 or later
voted_avg(weight) as weight
from
(select
-- train_multiclass_cw(addBias(features),label) as (label,feature,weight) -- hivemall v0.1
train_multiclass_cw(addBias(features),label) as (label,feature,weight,covar) -- hivemall v0.2 or later
from
news20mc_train_x3
union all
select
-- train_multiclass_arow(addBias(features),label) as (label,feature,weight) -- hivemall v0.1
train_multiclass_arow(addBias(features),label) as (label,feature,weight,covar) -- hivemall v0.2 or later
from
news20mc_train_x3
union all
select
-- train_multiclass_scw(addBias(features),label) as (label,feature,weight) -- hivemall v0.1
train_multiclass_scw(addBias(features),label) as (label,feature,weight,covar) -- hivemall v0.2 or later
from
news20mc_train_x3
) t
group by label, feature;
-- reset to the default
SET hive.exec.parallel=false;
SET mapred.reduce.tasks=-1;
3.4.2.2. 预测
create or replace view news20mc_ensemble_predict1
as
select
rowid,
m.col0 as score,
m.col1 as label
from (
select
rowid,
maxrow(score, label) as m
from (
select
t.rowid,
m.label,
sum(m.weight * t.value) as score
from
news20mc_test_exploded t LEFT OUTER JOIN
news20mc_ensemble_model1 m ON (t.feature = m.feature)
group by
t.rowid, m.label
) t1
group by rowid
) t2;
3.4.2.3. 评测
create or replace view news20mc_ensemble_submit1 as
select
t.label as actual,
pd.label as predicted
from
news20mc_test t JOIN news20mc_ensemble_predict1 pd
on (t.rowid = pd.rowid);
select count(1)/3993 from news20mc_ensemble_submit1
where actual == predicted;
0.8494866015527173
3.4.2.4. 清理
drop table news20mc_ensemble_model1;
drop view news20mc_ensemble_predict1;
drop view news20mc_ensemble_submit1;
不幸的是,在这种情况下,很多都会失败。
算法 | 准确性 |
---|---|
一排 | 0.8474830954169797 |
SCW2 | 0.8482344102178813 |
合奏(模型) | 0.8494866015527173 |
CW | 0.850488354620586 |
3.4.3. [情况2]预测合奏
3.4.3.1. 预测
create or replace view news20mc_pred_ensemble_predict1
as
select
rowid,
m.col1 as label
from (
select
rowid,
maxrow(cnt, label) as m
from (
select
rowid,
label,
count(1) as cnt
from (
select * from news20mc_arow_predict1
union all
select * from news20mc_scw2_predict1
union all
select * from news20mc_cw_predict1
) t1
group by rowid, label
) t2
group by rowid
) t3;
3.4.3.2. 评测
create or replace view news20mc_pred_ensemble_submit1 as
select
t.label as actual,
pd.label as predicted
from
news20mc_test t JOIN news20mc_pred_ensemble_predict1 pd
on (t.rowid = pd.rowid);
select count(1)/3993 from news20mc_pred_ensemble_submit1
where actual == predicted;
0.8499874780866516
不幸的是,在这种情况下,很多也都会失败。
算法 | 准确性 |
---|---|
一排 | 0.8474830954169797 |
SCW2 | 0.8482344102178813 |
合奏(模型) | 0.8494866015527173 |
集合(预测) | 0.8499874780866516 |
CW | 0.850488354620586 |
3.5. 混合模型更好的预测收敛(MIX服务器)
在本页中,我们将介绍如何在Hivemall上使用模型混合。模型混合对于训练分类器的更好的预测性能和更快的收敛是有用的。您可以在此(http://www.slideshare.net/myu...中找到MIX协议的内部设计的简要说明。
3.5.1. 前置条件
- Hivemall V0.3或更高版本
我们建议使用快速网络集群混合。
3.5.2. 运行混合服务器
首先,将以下文件放在可从Hadoop worker节点访问的服务器上
- target/hivemall-mixserv.jar
- bin/run_mixserv.sh
注意:hivemall-mixserv.jar内容比较大,因此仅用于混合服务器。
# run a Mix Server
./run_mixserv.sh
在这个例子中,我们假设Mix服务器在host01,host03和host03上运行。 Mix服务器使用的默认端口是11212,端口可以通过run_mixserv.sh的“-port”选项进行配置。
我们建议使用多个MIX服务器来获得更好的MIX吞吐量(3-5个或更多的足够用于正常的群集大小)。 Hivemall的MIX协议通过添加MIX服务器节点可以水平扩展。
3.5.3. 通过Hivemall使用Mix协议
在hive中安装Hivemall。
确保使用hivemall-with-dependencies.jar进行安装。该jar包含最小要求的jar包(netty,jsr305),用于在Hive上运行Hivemall。
现在,我们解释如何使用混合使用KDD2010a数据集的例子。
在Hivemall上启用mixing很简单,如下:
use kdd2010;
create table kdd10a_pa1_model1 as
select
feature,
cast(voted_avg(weight) as float) as weight
from
(select
train_pa1(addBias(features),label,"-mix host01,host02,host03") as (feature,weight)
from
kdd10a_train_x3
) t
group by feature;
你仅需要做的只是添加“-mix”训练选项,如上面的查询所示。
3.5.4. 混合模式的影响
根据我的经验,MIX将32节点簇上的KDD2010a PA1训练的预测精度从0.844835019263103(w/o混合)提高到0.8678096499719774(w/mix)。
使用MIX协议的开销几乎可以忽略不计,因为使用异步非阻塞I/O有效地处理MIX通信。此外,由于混合的收敛速度更快,因此在某些设置下可以提高训练时间。
3.6. 在Amazon Elastic MapReduce上运行Hivemall
………暂无………
4. 常用的Hive/Hadoop提示
4.1. 为每行添加rowid
4.1.1. 在Hivemall提供ROWID生成器
可以使用ROWID()
函数来生成Hivemall(V0.2或更高版本)的独特的rowid。
select
rowid() as rowid, -- returns ${task_id}-${sequence_number} as string
*
from
xxx;
此外,Hivemall在V0.5-RC.1或更高版本开始支持ROWNUM()
。
select
rownum() as rowid, -- returns sprintf(`%d%04d`,sequence,taskId) as long
*
from
xxx;
4.1.2. 使用SQL其他ROWID生成方案
CREATE TABLE xxx
AS
SELECT
regexp_replace(reflect('java.util.UUID','randomUUID'), '-', '') as rowid,
*
FROM
..;
生成rowid的另一个方式是使用row_number()
。但是,对于大型数据集,因为在单个reducer上执行rowid生成,所以查询执行将变得很慢,。
CREATE TABLE xxx
AS
select
row_number() over () as rowid,
*
from a9atest;
4.2. Hivemall的Hadoop调优
4.2.1. 前置条件
请按照下面的指导进行Hadoop调优:
http://hadoopbook.com/
http://www.slideshare.net/clo...
4.2.2. mapper的配置
当训练操作在mapper上运行时(例如,当使用rand_amplify()
)时,mapper配置对于hivemall很重要。
mapreduce.map.java.opts="-Xmx2048m -XX:+PrintGCDetails" (YARN)
mapred.map.child.java.opts="-Xmx2048m -XX:+PrintGCDetails" (MR v1)
mapreduce.task.io.sort.mb=1024 (YARN)
io.sort.mb=1024 (MR v1)
在上述情况下,Hivemall最多可以使用1024MB。
mapreduce.map.java.opts - mapreduce.task.io.sort.mb = 2048MB - 1024MB = 1024MB
此外,其他Hadoop组件也会占用内存空间。 Hivemall可以使用大约1024MB*0.5左右。我们建议至少为映射器设置-Xmx2048m。
所以尽可能的将mapreduce.map.java.opts - mapreduce.task.io.sort.mb
设置为最大。
4.2.3. Reducer端的配置
当训练操作在Reducer端运行时(例如,当使用amplify()
)时,Reducer端的配置对于hivemall很重要。
mapreduce.reduce.java.opts="-Xmx2048m -XX:+PrintGCDetails" (YARN)
mapred.reduce.child.java.opts="-Xmx2048m -XX:+PrintGCDetails" (MR v1)
mapreduce.reduce.shuffle.input.buffer.percent=0.6 (YARN)
mapred.reduce.shuffle.input.buffer.percent=0.6 (MR v1)
-- mapreduce.reduce.input.buffer.percent=0.2 (YARN)
-- mapred.job.reduce.input.buffer.percent=0.2 (MR v1)
在上述情况下,Hivemall最多可以使用820MB。
mapreduce.reduce.java.opts (1 - mapreduce.reduce.input.buffer.percent) = 2048 (1 - 0.6) ≈ 820 MB
此外,其他Hadoop组件也会占用内存空间。 Hivemall可以使用大约820MB*0.5左右。我们建议至少为映射器设置-Xmx2048m。
所以尽可能的将mapreduce.reduce.java.opts * (1 - mapreduce.reduce.input.buffer.percent)
设置为最大。
4.2.4. 预估Hivemall消耗内存的公式
对于密集模型,Hivemall中消耗的内存如下:
feature_dimensions (2^24 by the default) * 4 bytes (float) * 2 (iff covariance is calculated) * 1.2 (heuristics)
2^24 4 bytes 2 * 1.2 ≈ 161MB
使用了SpaceEfficientDenseModel
之后,公式变化如下:
feature_dimensions (assume here 2^25) * 2 bytes (short) * 2 (iff covariance is calculated) * 1.2 (heuristics)
2^25 2 bytes 2 * 1.2 ≈ 161MB
4.2.5. Hive的执行引擎
推荐使用Apache Tez
作为Hivemall查询的Hive执行引擎
set mapreduce.framework.name=yarn-tez;
set hive.execution.engine=tez;
也可以通过配置以下设置使用普通的旧MapReduce:
set mapreduce.framework.name=yarn;
set hive.execution.engine=mr;
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。