矩阵是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 + MADlib 玩转数据挖掘之(二)——矩阵的更多相关文章

  1. HAWQ + MADlib 玩转数据挖掘之(四)——低秩矩阵分解实现推荐算法

    一.潜在因子(Latent Factor)推荐算法 本算法整理自知乎上的回答@nick lee.应用领域:"网易云音乐歌单个性化推荐"."豆瓣电台音乐推荐"等. ...

  2. HAWQ + MADlib 玩转数据挖掘之(五)——奇异值分解实现推荐算法

    一.奇异值分解简介 奇异值分解简称SVD(singular value decomposition),可以理解为:将一个比较复杂的矩阵用更小更简单的三个子矩阵的相乘来表示,这三个小矩阵描述了大矩阵重要 ...

  3. HAWQ + MADlib 玩转数据挖掘之(一)——安装

    一.MADlib简介 MADlib是Pivotal公司与伯克利大学合作的一个开源机器学习库,提供了精确的数据并行实现.统计和机器学习方法对结构化和非结构化数据进行分析,主要目的是扩展数据库的分析能力, ...

  4. HAWQ + MADlib 玩转数据挖掘之(七)——关联规则方法之Apriori算法

    一.关联规则简介 关联规则挖掘的目标是发现数据项集之间的关联关系,是数据挖据中一个重要的课题.关联规则最初是针对购物篮分析(Market Basket Analysis)问题提出的.假设超市经理想更多 ...

  5. HAWQ + MADlib 玩转数据挖掘之(六)——主成分分析与主成分投影

    一.主成分分析(Principal Component Analysis,PCA)简介 在数据挖掘中经常会遇到多个变量的问题,而且在多数情况下,多个变量之间常常存在一定的相关性.例如,网站的" ...

  6. HAWQ + MADlib 玩转数据挖掘之(三)——向量

    一.定义 这里不讨论向量严格的数学定义.在Madlib中,可以把向量简单理解为矩阵.矩阵是Madlib中数据的基本格式,当矩阵只有一维时,就是向量,1行n列的矩阵称为行向量,m行1列的矩阵称为列向量, ...

  7. 菜鸟玩云计算之十二:KVM虚拟机更改大小

    菜鸟玩云计算之十二:KVM虚拟机更改大小 参考: http://www.missionfamilybank.org/expanding-resizing-your-qcow2-virtual-mach ...

  8. 用SQL玩转数据挖掘之MADlib(一)——安装

    一.MADlib简介 MADlib是Pivotal公司与伯克利大学合作的一个开源机器学习库,提供了精确的数据并行实现.统计和机器学习方法对结构化和非结构化数据进行分析,主要目的是扩展数据库的分析能力, ...

  9. BZOJ3577:玩手机(最大流,二维ST表)

    Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...

随机推荐

  1. 20145313张雪纯 《Java程序设计》第3周学习总结

    20145313张雪纯 <Java程序设计>第3周学习总结 教材学习内容总结 4.1.1 定义类 package four; class Clothes{ String color; ch ...

  2. 20145328 《Java程序设计》第6周学习总结

    20145328 <Java程序设计>第6周学习总结 教材学习内容总结 输入/输出 InputStream与OutputStream 从应用程序角度来看,如果要将数据从来源取出,可以使用输 ...

  3. arm-linux工具

    arm-linux工具的功能如下: arm-linux-addr2line 把程序地址转换为文件名和行号.在命令行中给它一个地址和一个可执行文件名,它就会使用这个可执行文件的调试信息指出在给出的地址上 ...

  4. 内核启动时在挂载ubi文件系统时提示UBIFS error (ubi0:0 pid 1): ubifs_read_superblock: min. I/O unit mismatch

    一.背景 1.1 笔者机器的内核错误信息如下: UBIFS error (ubi0:0 pid 1): ubifs_read_superblock: min. I/O unit mismatch: 2 ...

  5. Ubuntu 设置为固定ip

    vmware设置为桥接模式 使用root登陆ubuntu 使用gedit打开/etc/network/interfaces auto lo iface lo inet loopback auto en ...

  6. SaltStack匹配target-第六篇

    练习内容 Salt远程执行中目标选择常用的模式 1.通配符匹配 2.正则表达式匹配 3.List支持 4.Grains匹配 5.IP地址匹配 6.混合匹配 7.Node groups 远程执行格式 t ...

  7. mysql索引的建立和使用

    转自[http://www.cnblogs.com/mywebname/articles/555696.html] 一.索引的概念        索引就是加快检索表中数据的方法.数据库的索引类似于书籍 ...

  8. 从0开始 数据结构 AC自动机 hdu 2222

    参考博客 失配指针原理 使当前字符失配时跳转到另一段从root开始每一个字符都与当前已匹配字符段某一个后缀完全相同且长度最大的位置继续匹配,如同KMP算法一样,AC自动机在匹配时如果当前字符串匹配失败 ...

  9. tcp cubic代码分析

    /* * TCP CUBIC: Binary Increase Congestion control for TCP v2.3 * Home page: * http://netsrv.csc.ncs ...

  10. 可能是最好的 Rx 初学者教程

    译文:https://zhuanlan.zhihu.com/p/25552305 原文:https://gist.github.com/staltz/868e7e9bc2a7b8c1f754