如果您称为距离矩阵的矩阵实际上是核矩阵,那么您的要求应该可以做到。由于您使用的是 KPCA,我假设可能是这种情况,因此我将在下面展示一种使用不同大小的内核矩阵创建使用 KPCA 学习和转换方法的方法。
// Let's say those were our original data points
double[][] data =
{
new double[] { 2.5, 2.4 },
new double[] { 0.5, 0.7 },
new double[] { 2.2, 2.9 },
new double[] { 1.9, 2.2 },
new double[] { 3.1, 3.0 },
new double[] { 2.3, 2.7 },
new double[] { 2.0, 1.6 },
new double[] { 1.0, 1.1 },
new double[] { 1.5, 1.6 },
new double[] { 1.1, 0.9 }
};
现在,假设我们已经以某种方式获得了他们的核矩阵 K。注意:计算 K 的方法类似于
double[] mean = data.Mean(dimension: 0);
double[][] x = data.Subtract(mean, dimension: 0);
Linear kernel = new Linear();
double[][] K = kernel.ToJagged(x);
现在,假设 K 已经可用,我们可以创建一个 KPCA 为
var pca = new KernelPrincipalComponentAnalysis(kernel, PrincipalComponentMethod.KernelMatrix);
然后用学习它
pca.Learn(K); // note: we pass the kernel matrix instead of the data points
对于上面的例子,我们会有
// Those are the expected eigenvalues, in descending order:
double[] eigenvalues = pca.Eigenvalues.Divide(data.Length - 1); // { 1.28, 0.049 };
// And this will be their proportion:
double[] proportions = pca.ComponentProportions; // { 0.96, 0.03 };
// We can transform the inputs using
double[][] actual = pca.Transform(K);
// The output should be similar to
double[,] expected = new double[,]
{
{ 0.827970186, -0.175115307 },
{ -1.77758033, 0.142857227 },
{ 0.992197494, 0.384374989 },
{ 0.274210416, 0.130417207 },
{ 1.67580142, -0.209498461 },
{ 0.912949103, 0.175282444 },
{ -0.099109437, -0.349824698 },
{ -1.14457216, 0.046417258 },
{ -0.438046137, 0.017764629 },
{ -1.22382056, -0.162675287 },
}.Multiply(-1);
现在,最后,要回答关于如何使用我们的 KPCA 来转换不同大小的核矩阵的问题,我们可以使用
double[][] newData = // this is a smaller matrix than the original
{
new double[] { 2.2, 2.7 },
new double[] { 1.2, 4.9 },
new double[] { 1.8, 0.2 },
};
// Subtract the mean before computing a kernel matrix
double[][] y = newData.Subtract(mean, dimension: 0);
// Create the kernel matrix for new data
double[][] newK = kernel.ToJagged2(y, x);
// Transform using the new kernel matrix
double[][] output = pca.Transform(newK);
// Output will be similar to
double[][] expected =
{
new double[] { -0.845161763306007, -0.24880030917481 },
new double[] { -1.78468140697569, -2.47530044148084 },
new double[] { 1.26393423496622, 1.15181172492746 }
};