HAWQ + MADlib 玩转数据挖掘之(二)——矩阵

原创 2017年07月19日 18:03:32
        矩阵是Madlib中数据的基本格式,通常是二维的。在Madlib中,数组的概念与向量类似,数组通常是一维的,是矩阵的一种特殊形式。

一、矩阵表示

        MADlib为矩阵提供了两种表示形式:稠密和稀疏。

1. 稠密

        矩阵被表示为一维数组的分布式集合,例如3x10的矩阵如下表:
 row_id |         row_vec
--------+-------------------------
   1    | {9,6,5,8,5,6,6,3,10,8}
   2    | {8,2,2,6,6,10,2,1,9,9}
   3    | {3,9,9,9,8,6,3,9,5,6}

2. 稀疏

        使用行列下标指示矩阵中每一个非零项,例如:
 row_id | col_id | value
--------+--------+-------
      1 |      1 |     9
      1 |      5 |     6
      1 |      6 |     6
      2 |      1 |     8
      3 |      1 |     3
      3 |      2 |     9
      4 |      7 |     0

        所有矩阵运算都以任一种表示形式工作。

二、矩阵运算

1. 数组运算

        Madlib的数组运算模块提供了一组用C和SQL实现的基本数组操作,是几种需要快速数组操作的机器学习算法的支持模块。数组运算函数支持以下数字类型:
  • SMALLINT
  • INTEGER
  • BIGINT
  • REAL
  • DOUBLE PRECISION(FLOAT8)
  • NUMERIC(内部被转化为FLOAT8,可能丢失精度)
        另外,array_unnest_2d_to_1d()函数还支持TEXT和VARCHAR数据类型。

(1)数组运算函数
        数组运算函数列表及功能描述如表1所示。

函数

描述

array_add()

两个数组相加,需要所有值非空,返回与输入相同的数据类型。

sum()

向量元素求和,需要所有值非空,返回与输入相同的数据类型。

array_sub()

两个数组相减,需要所有值非空,返回与输入相同的数据类型。

array_mult()

两个数组相乘,需要所有值非空,返回与输入相同的数据类型。

array_div()

两个数组相除,需要所有值非空,返回与输入相同的数据类型。

array_dot()

两个数组点积,需要所有值非空,返回与输入相同的数据类型。

array_contains()

检查一个数组是否包含另一个数组。如果右边数组中的每个非零元素都等于左边数组中相同下标的元素,函数返回TRUE。

array_max()

返回数组中的最大值,忽略空值,返回与输入相同的数据类型。

array_max_index()

返回数组中的最大值及其对应的下标,忽略空值,返回类型的格式为[max, index],其元素类型与输入类型相同。

array_min()

返回数组中的最小值,忽略空值,返回与输入相同的数据类型。

array_min_index()

返回数组中的最小值及其对应的下标,忽略空值,返回类型的格式为[min, index],其元素类型与输入类型相同。

array_sum()

返回数组中值的和,忽略空值,返回与输入相同的数据类型。

array_sum_big()

返回数组中值的和,忽略空值,返回FLOAT8类型。该函数的意思是当汇总值可能超出元素类型范围时,替换array_sum()。

array_abs_sum()

返回数组中绝对值的和,忽略空值,返回与输入相同的数据类型。

array_abs()

返回由数组元素的绝对值组成的新数组,需要所有值非空。

array_mean()

返回数组的均值,忽略空值。

array_stddev()

返回数组的标准差,忽略空值。

array_of_float()

该函数创建元素个数为参数值的FLOAT8数组,初始值为0.0。

array_of_bigint()

该函数创建元素个数为参数值的BIGINT数组,初始值为0。

array_fill()

该函数将数组每个元素设置为参数值。

array_filter()

该函数只保留输入数组中符合指定标量运算符的元素。要求是一维数组,并且所有值非空。返回与输入相同的数据类型。缺省时该函数移除所有0值。

array_scalar_mult()

该函数将一个数组作为输入,元素与第二个参数指定的标量值相乘,返回结果数组。需要所有值非空,返回与输入相同的数据类型。

array_scalar_add()

该函数将一个数组作为输入,元素与第二个参数指定的标量值相加,返回结果数组。需要所有值非空,返回与输入相同的数据类型。

array_sqrt()

返回由数组元素的平方根组成的数组,需要所有值非空。

array_pow()

该函数以数组和一个float8为输入,返回每个元素的乘幂(由第二个参数指定)组成的数组, 需要所有值非空。

array_square()

返回由数组元素的平方组成的数组,需要所有值非空。

normalize()

该函数规范化一个数组,使它的元素平方和为1。要求是一维数组,并且所有值非空。

表1

(2)数组运算示例
        建立一个数据表,包含两个整型数组列,并添加数据。
drop table if exists array_tbl;
create table array_tbl 
( id integer,
  array1 integer[],
  array2 integer[] 
);
  
insert into array_tbl values
( 1, '{1,2,3,4,5,6,7,8,9}', '{9,8,7,6,5,4,3,2,1}' ),
( 2, '{1,1,0,1,1,2,3,99,8}','{0,0,0,-5,4,1,1,7,6}' );

        查询array1列的最小值、最大值、均值和标准差。
select id, 
       madlib.array_min(array1), 
       madlib.array_max(array1),
       madlib.array_min_index(array1), 
       madlib.array_max_index(array1),
       madlib.array_mean(array1), 
       madlib.array_stddev(array1)
  from array_tbl;
        结果:
 id | array_min | array_max | array_min_index | array_max_index |    array_mean    |   array_stddev   
----+-----------+-----------+-----------------+-----------------+------------------+------------------
  1 |         1 |         9 | {1,1}           | {9,9}           |                5 | 2.73861278752583
  2 |         0 |        99 | {0,3}           | {99,8}          | 12.8888888888889 | 32.3784050118457
(2 rows)

        执行数组加减。
select id, 
       madlib.array_add(array1,array2),
       madlib.array_sub(array1,array2)
  from array_tbl;
        结果:
 id |          array_add           |        array_sub        
----+------------------------------+-------------------------
  1 | {10,10,10,10,10,10,10,10,10} | {-8,-6,-4,-2,0,2,4,6,8}
  2 | {1,1,0,-4,5,3,4,106,14}      | {1,1,0,6,-3,1,2,92,2}
(2 rows)

        执行数组乘除。不包含id=2的行,因为有除数为0,会报错ERROR:  division by zero is not allowed。
select id, 
       madlib.array_mult(array1,array2),
       madlib.array_div(array1,array2)
  from array_tbl
 where 0 != all(array2);
        结果:
 id |         array_mult         |      array_div      
----+----------------------------+---------------------
  1 | {9,16,21,24,25,24,21,16,9} | {0,0,0,0,1,1,2,4,9}
(1 row)

        计算数组的点积,并根据点积定义验证结果。
select id, 
       madlib.array_dot(array1, array2),
       madlib.array_sum(madlib.array_mult(array1,array2))
  from array_tbl;
        结果:
 id | array_dot | array_sum 
----+-----------+-----------
  1 |       165 |       165
  2 |       745 |       745
(2 rows)

        数组元素乘标量值3。
select id,
       array1, 
       madlib.array_scalar_mult(array1,3)
  from array_tbl;
        结果:
 id |        array1        |     array_scalar_mult     
----+----------------------+---------------------------
  1 | {1,2,3,4,5,6,7,8,9}  | {3,6,9,12,15,18,21,24,27}
  2 | {1,1,0,1,1,2,3,99,8} | {3,3,0,3,3,6,9,297,24}
(2 rows)

        构造一个包含9个元素的数组,每个元素值设置为1.3。
select madlib.array_fill(madlib.array_of_float(9), 1.3::float);
        结果:
              array_fill               
---------------------------------------
 {1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.3,1.3}
(1 row)

        将二维数组列展开为一维数组集合。array_unnest_2d_to_1d是madlib 1.11版本的新增的函数,用于将二维数组展开为一维数组。1.10版本并无次函数,但可以创建一个UDF实现。
create or replace function madlib.array_unnest_2d_to_1d(anyarray)
returns table(unnest_row_id int, unnest_result anyarray) as
$func$
select d1,array_agg(val)
  from (select $1[d1][d2] val,d1,d2
          from generate_series(array_lower($1,1), array_upper($1,1)) d1,
               generate_series(array_lower($1,2), array_upper($1,2)) d2
         order by d1,d2) t 
 group by d1
$func$ language sql immutable;
        之后就可以调用函数展开二维数组:
select id, (madlib.array_unnest_2d_to_1d(val)).*
  from (select 1::int as id, array[[1.3,2.0,3.2],[10.3,20.0,32.2]]::float8[][] as val
         union all
        select 2, array[[pi(),pi()/2],[2*pi(),pi()],[pi()/4,4*pi()]]::float8[][]) t
 order by 1,2;
        结果:
 id | unnest_row_id |            unnest_result             
----+---------------+--------------------------------------
  1 |             1 | {1.3,2,3.2}
  1 |             2 | {10.3,20,32.2}
  2 |             1 | {3.14159265358979,1.5707963267949}
  2 |             2 | {6.28318530717959,3.14159265358979}
  2 |             3 | {0.785398163397448,12.5663706143592}
(5 rows)
        如果调用函数时不用.*标记,函数将返回具有两个属性(行ID和对应的展开后一维数组)的复合记录类型。

2. 矩阵运算

        矩阵运算函数支持的数据类型包括SMALLINT、INTEGER、BIGINT、FLOAT8和NUMERIC(内部被转化为FLOAT8,可能丢失精度),

(1)矩阵运算函数分类
        可大致分成以下类型:
  • 表示函数:
—— 转化为稀疏矩阵
matrix_sparsify( matrix_in, in_args, matrix_out, out_args)
—— 转化为稠密矩阵
matrix_densify( matrix_in, in_args, matrix_out, out_args)
—— 获取矩阵的维度 
matrix_ndims( matrix_in, in_args )
  • 算数函数:
-- 矩阵转置
matrix_trans( matrix_in, in_args, matrix_out, out_args)
-- 矩阵相加
matrix_add( matrix_a, a_args, matrix_b, b_args, matrix_out, out_args)
-- 矩阵相减
matrix_sub( matrix_a, a_args, matrix_b, b_args, matrix_out, out_args)
-- 矩阵乘法
matrix_mult( matrix_a, a_args, matrix_b, b_args, matrix_out, out_args)
-- 数组元素依次相乘
matrix_elem_mult( matrix_a, a_args, matrix_b, b_args, matrix_out, out_args)
-- 标量乘矩阵
matrix_scalar_mult( matrix_in, in_args, scalar, matrix_out, out_args)
-- 向量乘矩阵
matrix_vec_mult( matrix_in, in_args, vector)
  • 提取函数:
-- 从行下标提取行
matrix_extract_row( matrix_in, in_args, index)
-- 从列下标提取列
matrix_extract_col( matrix_in, in_args, index)
-- 提取主对角线元素
matrix_extract_diag( matrix_in, in_args)
  • 规约函数(跨指定维度的聚合):
-- 获取维度最大值。如果fetch_index = True,返回对应的下标。
matrix_max( matrix_in, in_args, dim, matrix_out, fetch_index)
-- 获取维度最小值。如果fetch_index = True,返回对应的下标。
matrix_min( matrix_in, in_args, dim, matrix_out, fetch_index)
-- 获取维度的和
matrix_sum( matrix_in, in_args, dim)
-- 获取维度的均值
matrix_mean( matrix_in, in_args, dim)
-- 获取矩阵范数
matrix_norm( matrix_in, in_args, norm_type)
  • 创建函数:
-- 创建一个指定矩阵,用1初始化为给定的行列维度。
matrix_ones( row_dim, col_dim, matrix_out, out_args)
-- 创建一个指定矩阵,用0初始化为给定的行列维度。
matrix_zeros( row_dim, col_dim, matrix_out, out_args)
-- 创建正方形恒等矩阵
matrix_identity( dim, matrix_out, out_args)
-- 用给定对角元素初始化矩阵
matrix_diag( diag_elements, matrix_out, out_args)
-- 用从分布中采样的值初始化矩阵。支持普通、均匀、伯努利分布
matrix_random( distribution, row_dim, col_dim, in_args, matrix_out, out_args )
  • 分解函数:
-- 矩阵求逆
matrix_inverse( matrix_in, in_args, matrix_out, out_args)
-- 广义逆矩阵
matrix_pinv( matrix_in, in_args, matrix_out, out_args)
-- 矩阵特征提取
matrix_eigen( matrix_in, in_args, matrix_out, out_args)
-- Cholesky分解
matrix_cholesky( matrix_in, in_args, matrix_out_prefix, out_args)
-- QR分解
matrix_qr( matrix_in, in_args, matrix_out_prefix, out_args)
-- LU分解
matrix_lu( matrix_in, in_args, matrix_out_prefix, out_args)
-- 矩阵的核范数
matrix_nuclear_norm( matrix_in, in_args)
-- 矩阵的秩
matrix_rank( matrix_in, in_args)

        分解函数仅基于内存操作实现。单一节点的矩阵数据被用于分解计算。这种操作适合小型矩阵,因为计算不是分布到个多个节点的。


(2)稠密矩阵运算示例
        创建实例稠密矩阵表和数据。
drop table if exists mat_a;
create table mat_a (
        row_id integer,
        row_vec integer[]
);
insert into mat_a (row_id, row_vec) values (1, '{9,6,5,8,5,6,6,3,10,8}');
insert into mat_a (row_id, row_vec) values (2, '{8,2,2,6,6,10,2,1,9,9}');
insert into mat_a (row_id, row_vec) values (3, '{3,9,9,9,8,6,3,9,5,6}');
insert into mat_a (row_id, row_vec) values (4, '{6,4,2,2,2,7,8,8,0,7}');
insert into mat_a (row_id, row_vec) values (5, '{6,8,9,9,4,6,9,5,7,7}');
insert into mat_a (row_id, row_vec) values (6, '{4,10,7,3,9,5,9,2,3,4}');
insert into mat_a (row_id, row_vec) values (7, '{8,10,7,10,1,9,7,9,8,7}');
insert into mat_a (row_id, row_vec) values (8, '{7,4,5,6,2,8,1,1,4,8}');
insert into mat_a (row_id, row_vec) values (9, '{8,8,8,5,2,6,9,1,8,3}');
insert into mat_a (row_id, row_vec) values (10, '{4,6,3,2,6,4,1,2,3,8}');

drop table if exists mat_b;
create table mat_b (
    row_id integer,
    vector integer[]
);
insert into mat_b (row_id, vector) values (1, '{9,10,2,4,6,5,3,7,5,6}');
insert into mat_b (row_id, vector) values (2, '{5,3,5,2,8,6,9,7,7,6}');
insert into mat_b (row_id, vector) values (3, '{0,1,2,3,2,7,7,3,10,1}');
insert into mat_b (row_id, vector) values (4, '{2,9,0,4,3,6,8,6,3,4}');
insert into mat_b (row_id, vector) values (5, '{3,8,7,7,0,5,3,9,2,10}');
insert into mat_b (row_id, vector) values (6, '{5,3,1,7,6,3,5,3,6,4}');
insert into mat_b (row_id, vector) values (7, '{4,8,4,4,2,7,10,0,3,3}');
insert into mat_b (row_id, vector) values (8, '{4,6,0,1,3,1,6,6,9,8}');
insert into mat_b (row_id, vector) values (9, '{6,5,1,7,2,7,10,6,0,6}');
insert into mat_b (row_id, vector) values (10, '{1,4,4,4,8,5,2,8,5,5}');

        矩阵转置。
select madlib.matrix_trans('"mat_b"', 'row=row_id, val=vector','mat_r');
select * from mat_r order by row_id;
        结果:
 row_id |         vector          
--------+-------------------------
      1 | {9,5,0,2,3,5,4,4,6,1}
      2 | {10,3,1,9,8,3,8,6,5,4}
      3 | {2,5,2,0,7,1,4,0,1,4}
      4 | {4,2,3,4,7,7,4,1,7,4}
      5 | {6,8,2,3,0,6,2,3,2,8}
      6 | {5,6,7,6,5,3,7,1,7,5}
      7 | {3,9,7,8,3,5,10,6,10,2}
      8 | {7,7,3,6,9,3,0,6,6,8}
      9 | {5,7,10,3,2,6,3,9,0,5}
     10 | {6,6,1,4,10,4,3,8,6,5}
(10 rows)

        提取矩阵的主对角线。
select madlib.matrix_extract_diag('mat_b', 'row=row_id, val=vector');
        结果:
  matrix_extract_diag   
------------------------
 {9,3,2,4,0,3,10,6,0,5}
(1 row)

        矩阵相加。
drop table if exists mat_r;
select madlib.matrix_add('mat_a', 'row=row_id, val=row_vec',
                         'mat_b', 'row=row_id, val=vector',
                         'mat_r', 'val=vector, fmt=dense');
select * from mat_r order by row_id;
        结果:
 row_id |            vector             
--------+-------------------------------
      1 | {18,16,7,12,11,11,9,10,15,14}
      2 | {13,5,7,8,14,16,11,8,16,15}
      3 | {3,10,11,12,10,13,10,12,15,7}
      4 | {8,13,2,6,5,13,16,14,3,11}
      5 | {9,16,16,16,4,11,12,14,9,17}
      6 | {9,13,8,10,15,8,14,5,9,8}
      7 | {12,18,11,14,3,16,17,9,11,10}
      8 | {11,10,5,7,5,9,7,7,13,16}
      9 | {14,13,9,12,4,13,19,7,8,9}
     10 | {5,10,7,6,14,9,3,10,8,13}
(10 rows)

        矩阵相乘。
drop table if exists mat_r;
select madlib.matrix_mult('mat_a', 'row=row_id, val=row_vec',
                          'mat_b', 'row=row_id, val=vector, trans=true',
                          'mat_r');
select * from mat_r order by row_id;
        结果:
 row_id |                  row_vec                  
--------+-------------------------------------------
      1 | {380,373,251,283,341,303,302,309,323,281}
      2 | {318,318,222,221,269,259,236,249,264,248}
      3 | {382,366,216,300,397,276,277,270,313,338}
      4 | {275,284,154,244,279,183,226,215,295,204}
      5 | {381,392,258,319,394,298,342,302,360,300}
      6 | {321,333,189,276,278,232,300,236,281,250}
      7 | {443,411,282,365,456,318,360,338,406,330}
      8 | {267,240,150,186,270,194,210,184,233,193}
      9 | {322,328,234,264,291,245,317,253,291,219}
     10 | {246,221,109,173,222,164,167,185,181,189}
(10 rows)

        创建对角矩阵。
drop table if exists mat_r;
select madlib.matrix_diag(array[9,6,3,10],
                          'mat_r', 'row=row_id, col=col_id, val=val');
select * from mat_r order by row_id::bigint;
        结果:
 row_id | col_id | val 
--------+--------+-----
      1 |      1 |   9
      2 |      2 |   6
      3 |      3 |   3
      4 |      4 |  10
(4 rows)

        创建单位矩阵。
drop table if exists mat_r;
select madlib.matrix_identity(4, 'mat_r', 'row=row_id,col=col_id,val=val');
select * from mat_r order by row_id;
        结果:
 row_id | col_id | val 
--------+--------+-----
      1 |      1 |   1
      2 |      2 |   1
      3 |      3 |   1
      4 |      4 |   1
(4 rows)

        提取指定下标的行或列。
select madlib.matrix_extract_row('mat_a', 'row=row_id, val=row_vec', 2) as row,
       madlib.matrix_extract_col('mat_a', 'row=row_id, val=row_vec', 3) as col;
        结果:
          row           |          col          
------------------------+-----------------------
 {8,2,2,6,6,10,2,1,9,9} | {5,2,9,2,9,7,7,5,8,3}
(1 row)

        获取指定维度的最大最小值及其对应的下标。dim=2表示计算每一行的最大最小值,返回一个列向量。
drop table if exists mat_max_r;
drop table if exists mat_min_r;
select madlib.matrix_max('mat_a', 'row=row_id, val=row_vec', 2, 'mat_max_r', true),
       madlib.matrix_min('mat_a', 'row=row_id, val=row_vec', 2, 'mat_min_r', true);
select * from mat_max_r;
select * from mat_min_r;
        结果:
         index          |            max            
------------------------+---------------------------
 {9,6,2,7,3,2,2,6,7,10} | {10,10,9,8,9,10,10,8,9,8}
(1 row)

         index         |          min          
-----------------------+-----------------------
 {8,8,1,9,5,8,5,7,8,7} | {3,1,3,0,4,2,1,1,1,1}
(1 row)

        用稀疏格式初始化矩阵。
drop table if exists mat_r;
select madlib.matrix_zeros(5, 4, 'mat_r', 'row=row_id, col=col_id, val=entry');
select * from mat_r;
        结果:
 row_id | col_id | entry 
--------+--------+-------
      5 |      4 |     0
(1 row)

        用稠密格式初始化矩阵。
drop table if exists mat_r;
select madlib.matrix_zeros(5, 4, 'mat_r', 'fmt=dense');
select * from mat_r order by row;
        结果:
 row |    val    
-----+-----------
   1 | {0,0,0,0}
   2 | {0,0,0,0}
   3 | {0,0,0,0}
   4 | {0,0,0,0}
   5 | {0,0,0,0}
(5 rows)

        用1初始化矩阵。
drop table if exists mat_r;
select madlib.matrix_ones(5, 4, 'mat_r', 'row=row,col=col, val=val');
select * from mat_r order by row, col;
        结果:
 row | col | val 
-----+-----+-----
   1 |   1 |   1
   1 |   2 |   1
   1 |   3 |   1
   1 |   4 |   1
   2 |   1 |   1
   2 |   2 |   1
   2 |   3 |   1
   2 |   4 |   1
   3 |   1 |   1
   3 |   2 |   1
   3 |   3 |   1
   3 |   4 |   1
   4 |   1 |   1
   4 |   2 |   1
   4 |   3 |   1
   4 |   4 |   1
   5 |   1 |   1
   5 |   2 |   1
   5 |   3 |   1
   5 |   4 |   1
(20 rows)

        用1初始化稠密矩阵。
drop table if exists mat_r;
select madlib.matrix_ones(5, 4, 'mat_r', 'fmt=dense');
select * from mat_r order by row;
        结果:
 row |    val    
-----+-----------
   1 | {1,1,1,1}
   2 | {1,1,1,1}
   3 | {1,1,1,1}
   4 | {1,1,1,1}
   5 | {1,1,1,1}
(5 rows)

        两个矩阵元素相乘。
drop table if exists mat_r;
select madlib.matrix_elem_mult('mat_a', 'row=row_id, val=row_vec',
                               'mat_b', 'row=row_id, val=vector',
                               'mat_r', 'val=vector');
select * from mat_r order by row_id;
        结果:
 row_id |             vector              
--------+---------------------------------
      1 | {81,60,10,32,30,30,18,21,50,48}
      2 | {40,6,10,12,48,60,18,7,63,54}
      3 | {0,9,18,27,16,42,21,27,50,6}
      4 | {12,36,0,8,6,42,64,48,0,28}
      5 | {18,64,63,63,0,30,27,45,14,70}
      6 | {20,30,7,21,54,15,45,6,18,16}
      7 | {32,80,28,40,2,63,70,0,24,21}
      8 | {28,24,0,6,6,8,6,6,36,64}
      9 | {48,40,8,35,4,42,90,6,0,18}
     10 | {4,24,12,8,48,20,2,16,15,40}
(10 rows)

        按维度求和,本例中每行求和。
select madlib.matrix_sum('mat_a', 'row=row_id, val=row_vec', 2);
        结果:
           matrix_sum            
---------------------------------
 {66,55,67,46,70,56,76,46,58,39}
(1 row)

        获取维度均值。
select madlib.matrix_mean('mat_a', 'row=row_id, val=row_vec', 2);
        结果:
               matrix_mean               
-----------------------------------------
 {6.6,5.5,6.7,4.6,7,5.6,7.6,4.6,5.8,3.9}
(1 row)

        计算矩阵范数,本例求欧几里德范数。
select madlib.matrix_norm('mat_a', 'row=row_id, val=row_vec', '2');
        结果:
  matrix_norm  
---------------
 64.1014820421
(1 row)

        标量乘矩阵。
drop table if exists mat_r;
select madlib.matrix_scalar_mult('mat_a', 'row=row_id, val=row_vec', 3, 'mat_r');
select * from mat_r order by row_id;
        结果:
 row_id |             row_vec             
--------+---------------------------------
      1 | {27,18,15,24,15,18,18,9,30,24}
      2 | {24,6,6,18,18,30,6,3,27,27}
      3 | {9,27,27,27,24,18,9,27,15,18}
      4 | {18,12,6,6,6,21,24,24,0,21}
      5 | {18,24,27,27,12,18,27,15,21,21}
      6 | {12,30,21,9,27,15,27,6,9,12}
      7 | {24,30,21,30,3,27,21,27,24,21}
      8 | {21,12,15,18,6,24,3,3,12,24}
      9 | {24,24,24,15,6,18,27,3,24,9}
     10 | {12,18,9,6,18,12,3,6,9,24}
(10 rows)

        获取矩阵的行列维度数。
select madlib.matrix_ndims('"mat_a"', 'row=row_id, val=row_vec');
        结果:
 matrix_ndims 
--------------
 {10,10}
(1 row)

        向量乘矩阵。
select madlib.matrix_vec_mult('mat_a', 'row=row_id, val=row_vec', array[1,2,3,4,5,6,7,8,9,10]);
        结果:
              matrix_vec_mult              
-------------------------------------------
 {365,325,358,270,377,278,411,243,287,217}
(1 row)

        求逆矩阵。
drop table if exists mat_r;
select madlib.matrix_inverse('mat_a', 'row=row_id, val=row_vec', 'mat_r');
select row_vec from mat_r order by row_id;

        求广义逆矩阵。
drop table if exists mat_r;
select madlib.matrix_pinv('mat_a', 'row=row_id, val=row_vec', 'mat_r');
select row_vec from mat_r order by row_id;

        提取矩阵的特征值。
drop table if exists mat_r;
select madlib.matrix_eigen('mat_a', 'row=row_id, val=row_vec', 'mat_r');
select eigen_values from mat_r order by row_id;

        矩阵的Cholesky分解。
select madlib.matrix_cholesky('mat_a', 'row=row_id, val=row_vec', 'matrix_out_prefix');
select row_vec from matrix_out_prefix_p order by row_id;
select row_vec from matrix_out_prefix_l order by row_id;
select row_vec from matrix_out_prefix_d order by row_id;

        矩阵的QR分解。
select madlib.matrix_qr('mat_a', 'row=row_id, val=row_vec', 'matrix_out_prefix');
select row_vec from matrix_out_prefix_q order by row_id;
select row_vec from matrix_out_prefix_r order by row_id;

        矩阵的LU分解。
select madlib.matrix_lu('mat_a', 'row=row_id, val=row_vec', 'matrix_out_prefix');
select row_vec from matrix_out_prefix_l order by row_id;
select row_vec from matrix_out_prefix_u order by row_id;
select row_vec from matrix_out_prefix_p order by row_id;
select row_vec from matrix_out_prefix_q order by row_id;

        求矩阵的核范数。
select madlib.matrix_nuclear_norm('"mat_a"', 'row=row_id, val=row_vec');
        结果:
 matrix_nuclear_norm 
---------------------
       118.852685995
(1 row)

        求矩阵的秩。
select madlib.matrix_rank('mat_a', 'row=row_id, val=row_vec');
        结果:
 matrix_rank 
-------------
          10
(1 row)

(3)稀疏矩阵运算示例
        稠密矩阵转为稀疏矩阵。
drop table if exists mat_b_sparse;
select madlib.matrix_sparsify('mat_b', 'row=row_id, val=vector',
                              'mat_b_sparse', 'col=col_id, val=val');
select * from mat_b_sparse order by row_id, col_id;

        创建稀疏矩阵表及其数据。
drop table if exists mat_a_sparse;
create table mat_a_sparse (
    rownum integer,
    col_num integer,
    entry integer
);
insert into mat_a_sparse values (1, 1, 9);
insert into mat_a_sparse values (1, 2, 6);
insert into mat_a_sparse values (1, 7, 3);
insert into mat_a_sparse values (1, 8, 10);
insert into mat_a_sparse values (1, 9, 8);
insert into mat_a_sparse values (2, 1, 8);
insert into mat_a_sparse values (2, 2, 2);
insert into mat_a_sparse values (2, 3, 6);
insert into mat_a_sparse values (3, 5, 6);
insert into mat_a_sparse values (3, 6, 3);
insert into mat_a_sparse values (7, 1, 7);
insert into mat_a_sparse values (8, 2, 8);
insert into mat_a_sparse values (8, 3, 5);
insert into mat_a_sparse values (9, 1, 6);
insert into mat_a_sparse values (9, 2, 3);
insert into mat_a_sparse values (10, 10, 0);

        获取行列维度数。
select madlib.matrix_ndims('mat_a_sparse', 'row="rownum", val=entry');
        结果:
 matrix_ndims 
--------------
 {10,10}
(1 row)

        矩阵转置。
drop table if exists matrix_r_sparse;
select madlib.matrix_trans('mat_a_sparse', 'row=rownum, val=entry',
                           'matrix_r_sparse');
select rownum, col_num, entry from matrix_r_sparse order by col_num, rownum;
        结果:
 rownum | col_num | entry 
--------+---------+-------
      1 |       1 |     9
      2 |       1 |     6
      7 |       1 |     3
      8 |       1 |    10
      9 |       1 |     8
      1 |       2 |     8
      2 |       2 |     2
      3 |       2 |     6
      5 |       3 |     6
      6 |       3 |     3
      1 |       7 |     7
      2 |       8 |     8
      3 |       8 |     5
      1 |       9 |     6
      2 |       9 |     3
     10 |      10 |     0
(16 rows)

        获取矩阵的主对角线。
select madlib.matrix_extract_diag('mat_a_sparse', 'row=rownum, val=entry');
        结果:
  matrix_extract_diag  
-----------------------
 {9,2,0,0,0,0,0,0,0,0}
(1 row)

        添加两个稀疏矩阵,然后转换成稠密格式。
drop table if exists matrix_r_sparse;
drop table if exists matrix_r;
select madlib.matrix_add('mat_a_sparse', 'row=rownum, val=entry',
                         'mat_b_sparse', 'row=row_id, col=col_id, val=val',
                         'matrix_r_sparse', 'col=col_out');
select madlib.matrix_densify('matrix_r_sparse', 'row=rownum, col=col_out, val=entry',
                             'matrix_r');
select * from matrix_r order by rownum;
        结果:
 rownum |           entry           
--------+---------------------------
      1 | {18,16,2,4,6,5,6,17,13,6}
      2 | {13,5,11,2,8,6,9,7,7,6}
      3 | {0,1,2,3,8,10,7,3,10,1}
      4 | {2,9,0,4,3,6,8,6,3,4}
      5 | {3,8,7,7,0,5,3,9,2,10}
      6 | {5,3,1,7,6,3,5,3,6,4}
      7 | {11,8,4,4,2,7,10,0,3,3}
      8 | {4,14,5,1,3,1,6,6,9,8}
      9 | {12,8,1,7,2,7,10,6,0,6}
     10 | {1,4,4,4,8,5,2,8,5,5}
(10 rows)

        矩阵相乘。
drop table if exists matrix_r;
select madlib.matrix_mult('mat_a_sparse', 'row=rownum, col=col_num, val=entry',
                          'mat_b_sparse', 'row=row_id, col=col_id, val=val, trans=true',
                          'matrix_r');
select * from matrix_r order by rownum;
        结果:
 rownum |                   entry                   
--------+-------------------------------------------
      1 | {260,216,137,180,190,156,138,222,174,159}
      2 | {104,76,14,34,82,52,72,44,64,40}
      3 | {51,66,33,36,15,45,33,21,33,63}
      4 | {0,0,0,0,0,0,0,0,0,0}
      5 | {0,0,0,0,0,0,0,0,0,0}
      6 | {0,0,0,0,0,0,0,0,0,0}
      7 | {63,35,0,14,21,35,28,28,42,7}
      8 | {90,49,18,72,99,29,84,48,45,52}
      9 | {84,39,3,39,42,39,48,42,51,18}
     10 | {0,0,0,0,0,0,0,0,0,0}
(10 rows)

        计算矩阵的Euclidean范数。
select madlib.matrix_norm('mat_a_sparse', 'row=rownum, col=col_num, val=entry', '2');
        结果:
  matrix_norm  
---------------
 24.9399278267
(1 row)
版权声明:本文为博主原创文章,未经博主允许不得转载。

相关文章推荐

HAWQ取代传统数仓实践(十三)——事实表技术之周期快照

一、周期快照简介        周期快照事实表中的每行汇总了发生在某一标准周期,如一天、一周或一月的多个度量。其粒度是周期性的时间段,而不是单个事务。周期快照事实表通常包含许多数据的总计,因为任何与事...

HAWQ取代传统数仓实践(三)——初始ETL(Sqoop、HAWQ)

一、用sqoop用户建立初始抽取脚本        本示例要用Sqoop将MySQL的数据抽取到HDFS上的指定目录,然后利用HAWQ外部表功能将HDFS数据文件装载到内部表中。表1汇总了示例中维度表...

HAWQ论文笔记

1、背景HAWQ是一个构建在HDFS之上的MPP(massively parallel processing)SQL引擎,不像其他构建在hadoop之上的SQL引擎,HAWQ支持标准SQL,并且完整的...

基于Hadoop生态圈的数据仓库实践 —— 进阶技术(一)

一、增加列         数据仓库最常碰到的扩展是给一个已经存在的维度表和事实表添加列。本节说明如何在客户维度表和销售订单事实表上添加列,并在新列上应用SCD2,以及对定时装载脚本所做的修改。假设需...

HAWQ技术解析(八) —— 大表分区

一、HAWQ中的分区表        与大多数关系数据库一样,HAWQ也支持分区表。这里所说的分区表是指HAWQ的内部分区表,外部分区表在后面“外部数据”篇讨论。在数据仓库应用中,事实表通常有非常多的...

HAWQ取代传统数仓实践(八)——维度表技术之角色扮演维度

单个物理维度可以被事实表多次引用,每个引用连接逻辑上存在差异的角色维度。例如,事实表可以有多个日期,每个日期通过外键引用不同的日期维度,原则上每个外键表示不同的日期维度视图,这样引用具有不同的含义。这...

挑战数据结构与算法面试题——80题全解析(一)

题目来源“数据结构与算法面试题80道”。

HAWQ技术解析(六) —— 定义对象

HAWQ本质上是一个数据库系统,所以这里所说的对象指的是数据库对象。和其它关系数据库类似,HAWQ中有数据库、表空间、表、视图、自定义数据类型、自定义函数、序列等对象。本篇将简述这些对象的创建与管理。...

基于Hadoop生态圈的数据仓库实践 —— 环境搭建(三)

三、建立数据仓库示例模型         Hadoop及其相关服务安装配置好后,下面用一个小而完整的示例说明多维模型及其相关ETL技术在Hadoop上的具体实现。 1. 设计ERD         ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:深度学习:神经网络中的前向传播和反向传播算法推导
举报原因:
原因补充:

(最多只允许输入30个字)