HAWQ + MADlib 玩转数据挖掘之(二)——矩阵
矩阵是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 玩转数据挖掘之(二)——矩阵的更多相关文章
- HAWQ + MADlib 玩转数据挖掘之(四)——低秩矩阵分解实现推荐算法
一.潜在因子(Latent Factor)推荐算法 本算法整理自知乎上的回答@nick lee.应用领域:"网易云音乐歌单个性化推荐"."豆瓣电台音乐推荐"等. ...
- HAWQ + MADlib 玩转数据挖掘之(五)——奇异值分解实现推荐算法
一.奇异值分解简介 奇异值分解简称SVD(singular value decomposition),可以理解为:将一个比较复杂的矩阵用更小更简单的三个子矩阵的相乘来表示,这三个小矩阵描述了大矩阵重要 ...
- HAWQ + MADlib 玩转数据挖掘之(一)——安装
一.MADlib简介 MADlib是Pivotal公司与伯克利大学合作的一个开源机器学习库,提供了精确的数据并行实现.统计和机器学习方法对结构化和非结构化数据进行分析,主要目的是扩展数据库的分析能力, ...
- HAWQ + MADlib 玩转数据挖掘之(七)——关联规则方法之Apriori算法
一.关联规则简介 关联规则挖掘的目标是发现数据项集之间的关联关系,是数据挖据中一个重要的课题.关联规则最初是针对购物篮分析(Market Basket Analysis)问题提出的.假设超市经理想更多 ...
- HAWQ + MADlib 玩转数据挖掘之(六)——主成分分析与主成分投影
一.主成分分析(Principal Component Analysis,PCA)简介 在数据挖掘中经常会遇到多个变量的问题,而且在多数情况下,多个变量之间常常存在一定的相关性.例如,网站的" ...
- HAWQ + MADlib 玩转数据挖掘之(三)——向量
一.定义 这里不讨论向量严格的数学定义.在Madlib中,可以把向量简单理解为矩阵.矩阵是Madlib中数据的基本格式,当矩阵只有一维时,就是向量,1行n列的矩阵称为行向量,m行1列的矩阵称为列向量, ...
- 菜鸟玩云计算之十二:KVM虚拟机更改大小
菜鸟玩云计算之十二:KVM虚拟机更改大小 参考: http://www.missionfamilybank.org/expanding-resizing-your-qcow2-virtual-mach ...
- 用SQL玩转数据挖掘之MADlib(一)——安装
一.MADlib简介 MADlib是Pivotal公司与伯克利大学合作的一个开源机器学习库,提供了精确的数据并行实现.统计和机器学习方法对结构化和非结构化数据进行分析,主要目的是扩展数据库的分析能力, ...
- BZOJ3577:玩手机(最大流,二维ST表)
Description 现在有一堆手机放在坐标网格里面(坐标从1开始),坐标(i,j)的格子有s_(i,j)个手机. 玩手机当然需要有信号,不过这里的手机与基站与我们不太一样.基站分为两种:发送站和接 ...
随机推荐
- 20145322《Java程序设计》第3次实验报告
实验内容,, 组队使用 git 上传代码并且互相下载对方代码修改之后再上传. 实现代码的重载 一. 使用git 上传代码 过程如图: 仨人成功上传后的代码图如下: 使用git 相互更改代码 执行git ...
- IO多路复用客户端-服务器模型
IO多路复用服务器 -- 实现字符回射 服务器端 /************************************************************************* ...
- #ifndef用法
用于避免重复包含头文件 #ifndef _STDIO_H_ #define _STDIO_H_ ...... #endif
- layer弹出层的关闭及父页面的刷新问题
当在主页面执行添加或修改时,用弹出层是比较好的选择,如何关闭弹出层并对父级页面进行操作呢 首先在父级页面中打开一个添加页面(弹出层) 在添加页面的表单提交函数中添加如下代码: function for ...
- C# Nginx平滑加权轮询算法
代码很简单,但算法很经典,话不多说,直接上代码. public struct ServerConfig { /// <summary> /// 初始权重 /// </summary& ...
- 【链接】SpringBoot启动错误
[错误解决]SpringBoot启动错误 https://blog.csdn.net/Small_Mouse0/article/details/78551900
- STL的其他用法(adjacent_find, find_first_of, sort_heap, merge, binary_search)总结
2017-08-20 17:26:07 writer:pprp 1.adjacent_find() 下面是源码实现: template <class ForwardIterator> Fo ...
- linux下增加useradd提示existing lock file /etc/subgid.lock without a PID
# useradd git -g git useradd: existing lock file /etc/subgid.lock without a PID useradd: cannot lock ...
- url传递数据类型
php中传递数据,get或post方式为啥用字符串传递,为什么不能直接用数组形式,用的话可以吗
- css实现标题文字过长截取...
css实现网页中文字过长截取... title class应该这样写: .title{ width:300px; white-space:nowrap; overflow:hidden; text-o ...