use of de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition in project elki by elki-project.
the class AutotuningPCA method processQueryResult.
@Override
public PCAResult processQueryResult(DoubleDBIDList results, Relation<? extends NumberVector> database) {
assertSortedByDistance(results);
final int dim = RelationUtil.dimensionality(database);
List<double[][]> best = new ArrayList<>(dim);
for (int i = 0; i < dim; i++) {
best.add(null);
}
double[] beststrength = new double[dim];
for (int i = 0; i < dim; i++) {
beststrength[i] = -1;
}
int[] bestk = new int[dim];
// 'history'
LinkedList<Cand> prev = new LinkedList<>();
// TODO: starting parameter shouldn't be hardcoded...
int smooth = 3;
int startk = 4;
if (startk > results.size() - 1) {
startk = results.size() - 1;
}
// TODO: add smoothing options, handle border cases better.
for (int k = startk; k < results.size(); k++) {
// sorted eigenpairs, eigenvectors, eigenvalues
double[][] covMat = covarianceMatrixBuilder.processQueryResults(results, database);
EigenvalueDecomposition evd = new EigenvalueDecomposition(covMat);
SortedEigenPairs eigenPairs = new SortedEigenPairs(evd, false);
int filteredEigenPairs = filter.filter(eigenPairs.eigenValues());
// correlationDimension = #strong EV
int thisdim = filteredEigenPairs;
// FIXME: handle the case of no strong EVs.
assert ((thisdim > 0) && (thisdim <= dim));
double thisexplain = computeExplainedVariance(eigenPairs, filteredEigenPairs);
prev.add(new Cand(covMat, thisexplain, thisdim));
if (prev.size() >= 2 * smooth + 1) {
// all the same dimension?
boolean samedim = true;
for (Iterator<Cand> it = prev.iterator(); it.hasNext(); ) {
if (it.next().dim != thisdim) {
samedim = false;
}
}
if (samedim) {
// average their explain values
double avgexplain = 0.0;
for (Iterator<Cand> it = prev.iterator(); it.hasNext(); ) {
avgexplain += it.next().explain;
}
avgexplain /= prev.size();
if (avgexplain > beststrength[thisdim - 1]) {
beststrength[thisdim - 1] = avgexplain;
best.set(thisdim - 1, prev.get(smooth).m);
bestk[thisdim - 1] = k - smooth;
}
}
prev.removeFirst();
}
}
// Try all dimensions, lowest first.
for (int i = 0; i < dim; i++) {
if (beststrength[i] > 0.0) {
// If the best was the lowest or the biggest k, skip it!
if (bestk[i] == startk + smooth) {
continue;
}
if (bestk[i] == results.size() - smooth - 1) {
continue;
}
double[][] covMat = best.get(i);
// System.err.println("Auto-k: "+bestk[i]+" dim: "+(i+1));
return processCovarMatrix(covMat);
}
}
// intended.
return processCovarMatrix(covarianceMatrixBuilder.processQueryResults(results, database));
}
use of de.lmu.ifi.dbs.elki.math.linearalgebra.EigenvalueDecomposition in project elki by elki-project.
the class LinearDiscriminantAnalysisFilter method computeProjectionMatrix.
@Override
protected double[][] computeProjectionMatrix(List<V> vectorcolumn, List<? extends ClassLabel> classcolumn, int dim) {
Map<ClassLabel, IntList> classes = partition(classcolumn);
// Fix indexing of classes:
List<ClassLabel> keys = new ArrayList<>(classes.keySet());
// Compute centroids:
List<Centroid> centroids = computeCentroids(dim, vectorcolumn, keys, classes);
final double[][] sigmaB, sigmaI;
// Between classes covariance:
{
CovarianceMatrix covmake = new CovarianceMatrix(dim);
for (Centroid c : centroids) {
covmake.put(c);
}
sigmaB = covmake.destroyToSampleMatrix();
}
{
// (Average) within class variance:
CovarianceMatrix covmake = new CovarianceMatrix(dim);
int numc = keys.size();
for (int i = 0; i < numc; i++) {
double[] c = centroids.get(i).getArrayRef();
// TODO: different weighting strategies? Sampling?
for (IntIterator it = classes.get(keys.get(i)).iterator(); it.hasNext(); ) {
covmake.put(minusEquals(vectorcolumn.get(it.nextInt()).toArray(), c));
}
}
sigmaI = covmake.destroyToSampleMatrix();
if (new LUDecomposition(sigmaI).det() == 0) {
for (int i = 0; i < dim; i++) {
sigmaI[i][i] += 1e-10;
}
}
}
double[][] sol = times(inverse(sigmaI), sigmaB);
EigenvalueDecomposition decomp = new EigenvalueDecomposition(sol);
SortedEigenPairs sorted = new SortedEigenPairs(decomp, false);
return transpose(sorted.eigenVectors(tdim));
}
Aggregations