Hivemall官方文檔翻譯-(第一部分:目錄)

1. 簡介

  Apache Hivemall是機器學習算法(machine learning algorithms)和多功能數據分析函數(versatile data analytics functions)的集合,它經過Apache Hive UDF / UDAF / UDTF接口提供了一些易於使用的機器學習算法。Hivemall 最初由Treasure Data 開發的,並於2016年9月捐獻給 Apache 軟件基金會,進入了Apache 孵化器。java

Apache Hivemall提供了各類功能包括:迴歸(regression)、分類(classification)、推薦(recommendation)異常檢測(anomaly detection)、k-最近鄰(k-nearest neighbor)以及特徵工程(feature engineering)。同時它還支持最早進的機器學習算法,如軟信度加權(Soft Confidence Weighted)、權重向量的自適應正則化(Adaptive Regularization of Weight Vectors)、因式分解機(Factorization Machines)和AdaDelta。mysql

1.1. 架構

Apache Hivemall 設計主要是運行在Apache Hive之上,可是還支持在Apache Pig 和 Apache Spark 上運行。因此咱們也能夠把它當作是一個跨平臺的機器學習類庫。咱們能夠經過Apache Hive構建預測模型而後在Apache Spark/Pig上使用;反之也是能夠的。
架構以下所示:
Hivemall架構git

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文件中。github

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:sql

  • Apache Spark
  • Apache Pig
  • Apache Hive on Docker for testing

2.1.4. 源代碼編譯

方法以下:shell

$ 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及以後的更新版本在生命週期中支持類持久函數。apache

Permanent functions在你經過Hiveserver使用Hive時候,或者避免每次session都要安裝hivemall的時,是很是有用的。數組

  1. 將hivemall的jar包放入HDFS
  2. 建立permanent functions
  3. 確認函數

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使用一種不常見的數據格式相似於LIBSVMVowpal 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爲例:

  1. 在Map階段放大訓練數據,在Reduce階段進行清洗
  2. 在每一個Map任務中放大和清洗訓練數據
  3. 結論

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變體中。
result

3.2.2. 在每一個Map任務中放大和清洗訓練數據

爲了處理大量的訓練數據,Hivemall提供了rand_amplifyUDTF,能夠在Map任務中隨機清洗輸入的行。 當填寫由${shufflebuffersize}指定的本地緩衝區時,rand_amplifyUDTF以隨機順序輸出行。

使用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;

訓練查詢執行以下所示:

result
map-local的乘法和清洗在合併階段沒有瓶頸,而且在單個MapReduce做業中查詢的效率是比較高的。

result
這個例子中使用 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;
相關文章
相關標籤/搜索