| /* ----------------------------------------------------------------------- *//** |
| * |
| * @file pca.sql_in |
| * |
| * @brief Principal Component Analysis |
| * |
| * @sa For a brief introduction to Principal Component Analysis, see the module |
| * description \ref grp_pca. |
| * |
| *//* ----------------------------------------------------------------------- */ |
| |
| m4_include(`SQLCommon.m4') |
| |
| /** |
| |
| @addtogroup grp_pca_train |
| |
| @brief Produces a model that transforms a number of (possibly) correlated |
| variables into a (smaller) number of uncorrelated variables called principal |
| components. |
| |
| <div class ="toc"><b>Contents</b> |
| <ul> |
| <li class="level1"><a href="#train">Training Function</a></li> |
| <li class="level1"><a href="#examples">Examples</a></li> |
| <li class="level1"><a href="#notes">Notes</a></li> |
| <li class="level1"><a href="#background_pca">Technical Background</a></li> |
| <li class="level1"><a href="#literature">Literature</a></li> |
| <li class="level1"><a href="#related">Related Topics</a></li> |
| </ul> |
| </div> |
| |
| Principal component analysis (PCA) is a mathematical procedure that uses an |
| orthogonal transformation to convert a set of observations of possibly |
| correlated variables into a set of values of linearly uncorrelated variables |
| called principal components. This transformation is defined in such a way that |
| the first principal component has the largest possible variance (i.e., |
| accounts for as much of the variability in the data as possible), and each |
| succeeding component in turn has the highest variance possible under the |
| constraint that it be orthogonal to (i.e., uncorrelated with) the preceding |
| components. |
| |
| See the \ref background_pca "Technical Background" for an introduction to |
| principal component analysis and the implementation notes. |
| |
| @anchor train |
| @par Training Function |
| The training functions have the following formats: |
| <pre class="syntax"> |
| pca_train( source_table, |
| out_table, |
| row_id, |
| k, |
| grouping_cols, |
| lanczos_iter, |
| use_correlation, |
| result_summary_table |
| ) |
| </pre> |
| and |
| <pre class="syntax"> |
| pca_sparse_train( source_table, |
| out_table, |
| row_id, |
| col_id, |
| val_id, |
| row_dim, |
| col_dim, |
| k, |
| grouping_cols, |
| lanczos_iter, |
| use_correlation, |
| result_summary_table |
| ) |
| </pre> |
| |
| \b Arguments |
| <DL class="arglist"> |
| <DT>source_table</DT> |
| <DD>TEXT. Name of the input table containing the data for PCA training. |
| The input data matrix should have \f$ N \f$ rows |
| and \f$ M \f$ columns, where \f$ N \f$ is the number of data points, and \f$ M |
| \f$ is the number of features for each data point. |
| |
| A dense input table is expected to be in the one of the |
| two standard MADlib dense matrix formats, and a sparse input table |
| should be in the standard MADlib sparse matrix format. |
| |
| The two standard MADlib dense matrix formats are |
| <pre>{TABLE|VIEW} <em>source_table</em> ( |
| <em>row_id</em> INTEGER, |
| <em>row_vec</em> FLOAT8[], |
| )</pre> |
| and |
| <pre>{TABLE|VIEW} <em>source_table</em> ( |
| <em>row_id</em> INTEGER, |
| <em>col1</em> FLOAT8, |
| <em>col2</em> FLOAT8, |
| ... |
| )</pre> |
| |
| Note that the column name <em>row_id</em> is taken as an input parameter, |
| and should contain a continguous list of row indices (starting at 1) for the input matrix. |
| |
| The input table for sparse PCA is expected to be in the form: |
| |
| <pre>{TABLE|VIEW} <em>source_table</em> ( |
| ... |
| <em>row_id</em> INTEGER, |
| <em>col_id</em> INTEGER, |
| <em>val_id</em> FLOAT8, |
| ... |
| )</pre> |
| |
| The <em>row_id</em> and <em>col_id</em> columns specify which entries |
| in the matrix are nonzero, and the <em>val_id</em> column defines the values |
| of the nonzero entries. |
| </DD> |
| |
| <DT>out_table</DT> |
| <DD>TEXT. The name of the table that will contain the output. The output is divided into three tables. |
| |
| The primary output table (<em>out_table</em>) encodes the principal components with the |
| <em>k</em> highest eigenvalues. The table has the following columns: |
| <table class="output"> |
| <tr> |
| <th>row_id</th> |
| <td>Eigenvalue rank in descending order of the eigenvalue size.</td> |
| </tr> |
| <tr> |
| <th>principal_components</th> |
| <td>Vectors containing elements of the principal components.</td> |
| </tr> |
| <tr> |
| <th>eigen_values</th> |
| <td>The eigenvalues associated with each principal component.</td> |
| </tr> |
| </table> |
| |
| The table <em>out_table</em>_means contains the column means. |
| This table has just one column: |
| <table class="output"> |
| <tr> |
| <th>column_means</th> |
| <td>A vector containing the column means for the input matrix.</td> |
| </tr> |
| </table> |
| |
| The optional table <em>result_summary_table</em> contains information about the performance of the PCA. The contents of this table are described under the <em>result_summary_table</em> argument. |
| </DD> |
| |
| <DT>row_id</DT> |
| <DD>TEXT. Column name containing the row IDs in the input source table. The column |
| needs to be of type that can be cast to INT and should only contain values between 1 and |
| <em>N</em>. For dense matrix format, it should contain all continguous integers from 1 to <em>N</em>.</DD> |
| |
| <DT>col_id</DT> |
| <DD>TEXT. Column name of containing the col IDS in sparse matrix representation |
| (sparse matrices only). The column should be of type that can be cast to INT and |
| contain values between 1 and <em>M</em>.</DD> |
| |
| <DT>val_id</DT> |
| <DD>TEXT. Name of 'val_id' column in sparse matrix representation (sparse matrices only). </DD> |
| |
| <DT>row_dim</DT> |
| <DD>INTEGER. The number of rows in the sparse matrix (sparse matrices only). </DD> |
| |
| <DT>col_dim</DT> |
| <DD>INTEGER. The number of columns in the sparse matrix (sparse matrices only). </DD> |
| |
| <DT>k</DT> |
| <DD>INTEGER. The number of principal components to calculate from the input data. </DD> |
| |
| <DT>grouping_cols (optional)</DT> |
| <DD>TEXT, default: NULL. Currently <em>grouping_cols</em> is present as a placeholder for forward |
| compatibility. The parameter is planned to be implemented as a comma-separated |
| list of column names, with the source data grouped using the combination of all the columns. |
| An independent PCA model will be computed for each combination of the grouping columns.</DD> |
| |
| <DT>lanczos_iter (optional)</DT> |
| <DD>INTEGER, default: minimum of {k+40, smallest matrix dimension}. The number of Lanczos iterations for the SVD calculation. |
| The Lanczos iteration number roughly corresponds to the accuracy of the SVD |
| calculation, and a higher iteration number corresponds to greater accuracy |
| but longer computation time. The number of iterations must be at least as |
| large as the value of <em>k</em>, but no larger than the smallest dimension |
| of the matrix. If the iteration number is given as zero, then the default |
| number of iterations is used.</DD> |
| |
| <DT>use_correlation (optional)</DT> |
| <DD>BOOLEAN, default FALSE. Whether to use the correlation matrix for calculating the principal components instead of the covariance matrix. Currently |
| <em>use_correlation</em> is a placeholder for forward compatibility, and |
| this value must be set to false.</DD> |
| |
| <DT>result_summary_table (optional)</DT> |
| <DD>TEXT, default NULL. Name of the optional summary table. When NULL, no summary table is generated. |
| |
| This sumary table has the following columns: |
| <table class="output"> |
| <tr> |
| <th>rows_used</th> |
| <td>INTEGER. Number of data points in the input.</td> |
| </tr> |
| <tr> |
| <th>exec_time (ms)</th> |
| <td>FLOAT8. Number of milliseconds for the PCA calculation to run.</td> |
| </tr> |
| <tr> |
| <th>iter</th> |
| <td>INTEGER. Number of iterations used in the SVD calculation.</td> |
| </tr> |
| <tr> |
| <th>recon_error</th> |
| <td>FLOAT8. The absolute error in the SVD approximation.</td> |
| </tr> |
| <tr> |
| <th>relative_recon_error</th> |
| <td>FLOAT8. The relative error in the SVD approximation.</td> |
| </tr> |
| <tr> |
| <th>use_correlation</th> |
| <td>BOOLEAN. Indicates if the correlation matrix was used.</td> |
| </tr> |
| </table> |
| </DD> |
| </DL> |
| |
| |
| @anchor examples |
| @examp |
| |
| -# View online help for the PCA training function. |
| <pre class="example"> |
| SELECT madlib.pca_train(); |
| </pre> |
| |
| -# Create the sample data. |
| <pre class="example"> |
| DROP TABLE IF EXISTS mat; |
| CREATE TABLE mat ( |
| row_id integer, |
| row_vec double precision[] |
| ); |
| COPY mat (row_id, row_vec) FROM stdin; |
| 1 {1,2,3} |
| 2 {2,1,2} |
| 3 {3,2,1} |
| \\. |
| </pre> |
| |
| -# Run the PCA function: |
| <pre class="example"> |
| DROP TABLE result_table; |
| SELECT pca_train( 'mat', |
| 'result_table', |
| 'row_id', |
| 3 |
| ); |
| </pre> |
| |
| -# View the PCA results: |
| <pre class="example"> |
| SELECT * FROM result_table; |
| </pre> |
| Result |
| <pre class="result"> |
| row_id | principal_components | eigen_values |
| --------+--------------------------------------------------------------+---------------------- |
| 1 | {-0.707106781186548,-1.2490009027033e-16,0.707106781186548} | 1.4142135623731 |
| 2 | {5.55111512312578e-17,1,0} | 0.577350269189626 |
| 3 | {-0.707106781186547,1.11022302462516e-16,-0.707106781186548} | 1.07795017977832e-16 |
| </pre> |
| |
| @anchor notes |
| @par Notes |
| |
| - Table names can be optionally schema qualified (current_schemas() would be |
| searched if a schema name is not provided) and all table and column names |
| should follow case-sensitivity and quoting rules per the database. |
| (For instance, 'mytable' and 'MyTable' both resolve to the same entity, i.e. 'mytable'. |
| If mixed-case or multi-byte characters are desired for entity names then the |
| string should be double-quoted; in this case the input would be '"MyTable"'). |
| |
| - Because of the centering step in PCA (see |
| \ref background_pca "Technical Background"), sparse matrices almost always |
| become dense during the training process. Thus, this implementation |
| automatically densifies sparse matrix input, and there should be no expected |
| performance improvement in using sparse matrix input over dense matrix input. |
| |
| |
| @anchor background_pca |
| @par Technical Background |
| |
| The PCA implemented here uses an SVD decomposition implementation to recover |
| the principal components (as opposed to the directly computing the eigenvectors |
| of the covariance matrix). Let \f$ \boldsymbol X \f$ be the data matrix, and |
| let \f$ \hat{x} \f$ be a vector of the column averages of \f$ \boldsymbol{X}\f$. |
| PCA computes the matrix \f$ \hat{\boldsymbol X} \f$ as |
| \f[ |
| \hat{\boldsymbol X} = {\boldsymbol X} - \vec{e} \hat{x}^T |
| \f] |
| where \f$ \vec{e} \f$ is the vector of all ones. |
| |
| PCA then computes the SVD matrix factorization |
| \f[ |
| \hat{\boldsymbol X} = {\boldsymbol U}{\boldsymbol \Sigma}{\boldsymbol V}^T |
| \f] |
| where \f$ {\boldsymbol \Sigma} \f$ is a diagonal matrix. The eigenvalues are |
| recovered as the entries of \f$ {\boldsymbol \Sigma}/(\sqrt{N-1}) \f$, and the principal |
| components are the rows of \f$ {\boldsymbol V} \f$. |
| |
| |
| It is important to note that the PCA implementation assumes that the user will |
| use only the principal components that have non-zero eigenvalues. The SVD |
| calculation is done with the Lanczos method, with does not guarantee |
| correctness for singular vectors with zero-valued eigenvalues. Consequently, |
| principal components with zero-valued eigenvalues are not guaranteed to be correct. |
| Generally, this will not be problem unless the user wants to use the |
| principal components for the entire eigenspectrum. |
| |
| |
| @anchor literature |
| @literature |
| |
| [1] Principal Component Analysis. http://en.wikipedia.org/wiki/Principal_component_analysis |
| |
| [2] Shlens, Jonathon (2009), A Tutorial on Principal Component Analysis |
| |
| |
| |
| @anchor related |
| @par Related Topics |
| |
| File pca.sql_in documenting the SQL functions |
| |
| \ref grp_pca_project |
| |
| |
| |
| */ |
| |
| -- ----------------------------------------------------------------------- |
| -- PCA for Dense matrices |
| -- ----------------------------------------------------------------------- |
| /* |
| @brief Compute principal components for a dense matrix stored in a |
| database table |
| */ |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| k INTEGER, -- Number of principal components to compute |
| grouping_cols TEXT, -- Comma-separated list of grouping columns (Default: NULL) |
| lanczos_iter INTEGER, -- The number of Lanczos iterations for the SVD calculation (Default: min(k+40, smallest Matrix dimension)) |
| use_correlation BOOLEAN, -- If True correlation matrix is used for principal components (Default: False) |
| result_summary_table TEXT -- Table name to store summary of results (Default: NULL) |
| ) |
| RETURNS VOID AS $$ |
| PythonFunction(pca, pca, pca) |
| $$ LANGUAGE plpythonu |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| -- Overloaded functions for optional parameters |
| -- ----------------------------------------------------------------------- |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| k INTEGER,-- Number of principal components to compute |
| grouping_cols TEXT, -- Comma-separated list of grouping columns |
| lanczos_iter INTEGER,-- The number of Lanczos iterations for the SVD calculation |
| use_correlation BOOLEAN -- If True correlation matrix is used for principal components |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_train($1, $2, $3, $4, $5, $6, $7, NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| k INTEGER,-- Number of principal components to compute |
| grouping_cols TEXT, -- Comma-separated list of grouping columns |
| lanczos_iter INTEGER -- The number of Lanczos iterations for the SVD calculation |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_train($1, $2, $3, $4, $5, $6, False , NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| k INTEGER,-- Number of principal components to compute |
| grouping_cols TEXT -- Comma-separated list of grouping columns |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_train($1, $2, $3, $4, $5, 0, False , NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| k INTEGER -- Number of principal components to compute |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_train($1, $2, $3, $4, NULL, 0, False, NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| |
| -- Information Functions |
| -- ----------------------------------------------------------------------- |
| |
| CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.pca_train( |
| usage_string VARCHAR -- usage string |
| ) |
| RETURNS TEXT AS $$ |
| PythonFunctionBodyOnly(`pca', `pca') |
| return pca.pca_help_message(schema_madlib, usage_string) |
| $$ LANGUAGE plpythonu IMMUTABLE |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `CONTAINS SQL', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.pca_train() |
| RETURNS VARCHAR AS $$ |
| BEGIN |
| RETURN MADLIB_SCHEMA.pca_train(''); |
| END; |
| $$ LANGUAGE plpgsql IMMUTABLE |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `CONTAINS SQL', `'); |
| |
| -- ----------------------------------------------------------------------- |
| -- PCA for Sparse matrices |
| -- ----------------------------------------------------------------------- |
| /* |
| @brief Compute principal components for a sparse matrix stored in a |
| database table |
| */ |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_sparse_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Name of 'row_id' column in sparse matrix representation |
| col_id TEXT, -- Name of 'col_id' column in sparse matrix representation |
| val_id TEXT, -- Name of 'val_id' column in sparse matrix representation |
| row_dim INTEGER, -- Number of rows in the sparse matrix |
| col_dim INTEGER, -- Number of columns in the sparse matrix |
| k INTEGER, -- Number of eigenvectors with dominant eigenvalues, sorted decreasingly |
| grouping_cols TEXT, -- Comma-separated list of grouping columns (Default: NULL) |
| lanczos_iter INTEGER, -- The number of Lanczos iterations for the SVD calculation (Default: min(k+40, smallest Matrix dimension)) |
| use_correlation BOOLEAN, -- If True correlation matrix is used for principal components (Default: False) |
| result_summary_table TEXT -- Table name to store summary of results (Default: NULL) |
| ) |
| RETURNS VOID AS $$ |
| PythonFunction(pca, pca, pca_sparse) |
| $$ LANGUAGE plpythonu |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| -- Overloaded functions for optional parameters |
| -- ----------------------------------------------------------------------- |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_sparse_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| col_id TEXT, -- Name of 'col_id' column in sparse matrix representation |
| val_id TEXT, -- Name of 'val_id' column in sparse matrix representation |
| row_dim INTEGER, -- Number of rows in the sparse matrix |
| col_dim INTEGER, -- Number of columns in the sparse matrix |
| k INTEGER, -- Number of principal components to compute |
| grouping_cols TEXT, -- Comma-separated list of grouping columns |
| lanczos_iter INTEGER, -- The number of Lanczos iterations for the SVD calculation |
| use_correlation BOOLEAN -- If True correlation matrix is used for principal components |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_sparse_train($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_sparse_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| col_id TEXT, -- Name of 'col_id' column in sparse matrix representation |
| val_id TEXT, -- Name of 'val_id' column in sparse matrix representation |
| row_dim INTEGER, -- Number of rows in the sparse matrix |
| col_dim INTEGER, -- Number of columns in the sparse matrix |
| k INTEGER, -- Number of principal components to compute |
| grouping_cols TEXT, -- Comma-separated list of grouping columns |
| lanczos_iter INTEGER -- The number of Lanczos iterations for the SVD calculation |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_sparse_train($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, False , NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_sparse_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| col_id TEXT, -- Name of 'col_id' column in sparse matrix representation |
| val_id TEXT, -- Name of 'val_id' column in sparse matrix representation |
| row_dim INTEGER, -- Number of rows in the sparse matrix |
| col_dim INTEGER, -- Number of columns in the sparse matrix |
| k INTEGER, -- Number of principal components to compute |
| grouping_cols TEXT -- Comma-separated list of grouping columns |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_sparse_train($1, $2, $3, $4, $5, $6, $7, $8, $9, 0, False , NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION |
| MADLIB_SCHEMA.pca_sparse_train( |
| source_table TEXT, -- Source table name (dense matrix) |
| pc_table TEXT, -- Output table name for the principal components |
| row_id TEXT, -- Column name for the ID for each row |
| col_id TEXT, -- Name of 'col_id' column in sparse matrix representation |
| val_id TEXT, -- Name of 'val_id' column in sparse matrix representation |
| row_dim INTEGER, -- Number of rows in the sparse matrix |
| col_dim INTEGER, -- Number of columns in the sparse matrix |
| k INTEGER -- Number of principal components to compute |
| ) |
| RETURNS VOID AS $$ |
| SELECT MADLIB_SCHEMA.pca_sparse_train($1, $2, $3, $4, $5, $6, $7, $8, NULL, 0, False, NULL) |
| $$ LANGUAGE SQL |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `MODIFIES SQL DATA', `'); |
| |
| |
| |
| -- ----------------------------------------------------------------------- |
| -- Information Functions |
| -- ----------------------------------------------------------------------- |
| |
| CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.pca_sparse_train( |
| usage_string VARCHAR -- usage string |
| ) |
| RETURNS TEXT AS $$ |
| PythonFunctionBodyOnly(`pca', `pca') |
| return pca.pca_sparse_help_message(schema_madlib, usage_string) |
| $$ LANGUAGE plpythonu IMMUTABLE |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `CONTAINS SQL', `'); |
| |
| |
| CREATE OR REPLACE FUNCTION MADLIB_SCHEMA.pca_sparse_train() |
| RETURNS TEXT AS $$ |
| BEGIN |
| RETURN MADLIB_SCHEMA.pca_sparse_train(''); |
| END; |
| $$ LANGUAGE plpgsql IMMUTABLE |
| m4_ifdef(`__HAS_FUNCTION_PROPERTIES__', `CONTAINS SQL', `'); |