前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >HAWQ + MADlib 玩转数据挖掘之(二)——矩阵

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

作者头像
用户1148526
发布2018-01-03 15:29:21
1.3K0
发布2018-01-03 15:29:21
举报
文章被收录于专栏:Hadoop数据仓库Hadoop数据仓库

        矩阵是Madlib中数据的基本格式,通常是二维的。在Madlib中,数组的概念与向量类似,数组通常是一维的,是矩阵的一种特殊形式。

一、矩阵表示

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

1. 稠密

        矩阵被表示为一维数组的分布式集合,例如3x10的矩阵如下表:

代码语言:javascript
复制
 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. 稀疏

        使用行列下标指示矩阵中每一个非零项,例如:

代码语言:javascript
复制
 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)数组运算示例

        建立一个数据表,包含两个整型数组列,并添加数据。

代码语言:javascript
复制
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列的最小值、最大值、均值和标准差。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        执行数组加减。

代码语言:javascript
复制
select id, 
       madlib.array_add(array1,array2),
       madlib.array_sub(array1,array2)
  from array_tbl;

        结果:

代码语言:javascript
复制
 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。

代码语言:javascript
复制
select id, 
       madlib.array_mult(array1,array2),
       madlib.array_div(array1,array2)
  from array_tbl
 where 0 != all(array2);

        结果:

代码语言:javascript
复制
 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)

        计算数组的点积,并根据点积定义验证结果。

代码语言:javascript
复制
select id, 
       madlib.array_dot(array1, array2),
       madlib.array_sum(madlib.array_mult(array1,array2))
  from array_tbl;

        结果:

代码语言:javascript
复制
 id | array_dot | array_sum 
----+-----------+-----------
  1 |       165 |       165
  2 |       745 |       745
(2 rows)

        数组元素乘标量值3。

代码语言:javascript
复制
select id,
       array1, 
       madlib.array_scalar_mult(array1,3)
  from array_tbl;

        结果:

代码语言:javascript
复制
 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。

代码语言:javascript
复制
select madlib.array_fill(madlib.array_of_float(9), 1.3::float);

        结果:

代码语言:javascript
复制
              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实现。

代码语言:javascript
复制
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;

        之后就可以调用函数展开二维数组:

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)稠密矩阵运算示例

        创建实例稠密矩阵表和数据。

代码语言:javascript
复制
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}');

        矩阵转置。

代码语言:javascript
复制
select madlib.matrix_trans('"mat_b"', 'row=row_id, val=vector','mat_r');
select * from mat_r order by row_id;

        结果:

代码语言:javascript
复制
 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)

        提取矩阵的主对角线。

代码语言:javascript
复制
select madlib.matrix_extract_diag('mat_b', 'row=row_id, val=vector');

        结果:

代码语言:javascript
复制
  matrix_extract_diag   
------------------------
 {9,3,2,4,0,3,10,6,0,5}
(1 row)

        矩阵相加。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        矩阵相乘。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        创建对角矩阵。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 row_id | col_id | val 
--------+--------+-----
      1 |      1 |   9
      2 |      2 |   6
      3 |      3 |   3
      4 |      4 |  10
(4 rows)

        创建单位矩阵。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 row_id | col_id | val 
--------+--------+-----
      1 |      1 |   1
      2 |      2 |   1
      3 |      3 |   1
      4 |      4 |   1
(4 rows)

        提取指定下标的行或列。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
          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表示计算每一行的最大最小值,返回一个列向量。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
         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)

        用稀疏格式初始化矩阵。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 row_id | col_id | entry 
--------+--------+-------
      5 |      4 |     0
(1 row)

        用稠密格式初始化矩阵。

代码语言:javascript
复制
drop table if exists mat_r;
select madlib.matrix_zeros(5, 4, 'mat_r', 'fmt=dense');
select * from mat_r order by row;

        结果:

代码语言:javascript
复制
 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初始化矩阵。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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初始化稠密矩阵。

代码语言:javascript
复制
drop table if exists mat_r;
select madlib.matrix_ones(5, 4, 'mat_r', 'fmt=dense');
select * from mat_r order by row;

        结果:

代码语言:javascript
复制
 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)

        两个矩阵元素相乘。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        按维度求和,本例中每行求和。

代码语言:javascript
复制
select madlib.matrix_sum('mat_a', 'row=row_id, val=row_vec', 2);

        结果:

代码语言:javascript
复制
           matrix_sum            
---------------------------------
 {66,55,67,46,70,56,76,46,58,39}
(1 row)

        获取维度均值。

代码语言:javascript
复制
select madlib.matrix_mean('mat_a', 'row=row_id, val=row_vec', 2);

        结果:

代码语言:javascript
复制
               matrix_mean               
-----------------------------------------
 {6.6,5.5,6.7,4.6,7,5.6,7.6,4.6,5.8,3.9}
(1 row)

        计算矩阵范数,本例求欧几里德范数。

代码语言:javascript
复制
select madlib.matrix_norm('mat_a', 'row=row_id, val=row_vec', '2');

        结果:

代码语言:javascript
复制
  matrix_norm  
---------------
 64.1014820421
(1 row)

        标量乘矩阵。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        获取矩阵的行列维度数。

代码语言:javascript
复制
select madlib.matrix_ndims('"mat_a"', 'row=row_id, val=row_vec');

        结果:

代码语言:javascript
复制
 matrix_ndims 
--------------
 {10,10}
(1 row)

        向量乘矩阵。

代码语言:javascript
复制
select madlib.matrix_vec_mult('mat_a', 'row=row_id, val=row_vec', array[1,2,3,4,5,6,7,8,9,10]);

        结果:

代码语言:javascript
复制
              matrix_vec_mult              
-------------------------------------------
 {365,325,358,270,377,278,411,243,287,217}
(1 row)

        求逆矩阵。

代码语言:javascript
复制
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;

        求广义逆矩阵。

代码语言:javascript
复制
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;

        提取矩阵的特征值。

代码语言:javascript
复制
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分解。

代码语言:javascript
复制
代码语言:javascript
复制
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分解。

代码语言:javascript
复制
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分解。

代码语言:javascript
复制
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;

        求矩阵的核范数。

代码语言:javascript
复制
select madlib.matrix_nuclear_norm('"mat_a"', 'row=row_id, val=row_vec');

        结果:

代码语言:javascript
复制
 matrix_nuclear_norm 
---------------------
       118.852685995
(1 row)

        求矩阵的秩。

代码语言:javascript
复制
select madlib.matrix_rank('mat_a', 'row=row_id, val=row_vec');

        结果:

代码语言:javascript
复制
 matrix_rank 
-------------
          10
(1 row)

(3)稀疏矩阵运算示例

        稠密矩阵转为稀疏矩阵。

代码语言:javascript
复制
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;

        创建稀疏矩阵表及其数据。

代码语言:javascript
复制
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);

        获取行列维度数。

代码语言:javascript
复制
select madlib.matrix_ndims('mat_a_sparse', 'row="rownum", val=entry');

        结果:

代码语言:javascript
复制
 matrix_ndims 
--------------
 {10,10}
(1 row)

        矩阵转置。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        获取矩阵的主对角线。

代码语言:javascript
复制
select madlib.matrix_extract_diag('mat_a_sparse', 'row=rownum, val=entry');

        结果:

代码语言:javascript
复制
  matrix_extract_diag  
-----------------------
 {9,2,0,0,0,0,0,0,0,0}
(1 row)

        添加两个稀疏矩阵,然后转换成稠密格式。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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)

        矩阵相乘。

代码语言:javascript
复制
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;

        结果:

代码语言:javascript
复制
 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范数。

代码语言:javascript
复制
select madlib.matrix_norm('mat_a_sparse', 'row=rownum, col=col_num, val=entry', '2');

        结果:

代码语言:javascript
复制
  matrix_norm  
---------------
 24.9399278267
(1 row)
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2017年07月19日,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、矩阵表示
    • 1. 稠密
      • 2. 稀疏
      • 二、矩阵运算
        • 1. 数组运算
          • 2. 矩阵运算
          领券
          问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档