315 lines
8.0 KiB
Plaintext
315 lines
8.0 KiB
Plaintext
<snippet>
|
|
<subclass>afryca.ase.Snippet</subclass>
|
|
<file></file>
|
|
<category>Library</category>
|
|
<name>pca</name>
|
|
<description></description>
|
|
<code>
|
|
var pca = (typeof exports === "undefined")?(function pca() {}):(exports);
|
|
if(typeof global !== "undefined") { global.pca = pca; }
|
|
|
|
pca.PCA = function(preferences, isDecisionMatrix) {
|
|
//Initialize DM matrix
|
|
var dm = pca.createConsensusMatrix(preferences.length, preferences[0][0].length);
|
|
var alternativesPreferencesExperts = [];
|
|
|
|
var preference;
|
|
var alternativesPreferences;
|
|
for(var ex = 0; ex < preferences.length; ex++){
|
|
preference = preferences[ex];
|
|
|
|
alternativesPreferences = pca.computeAlternativesDominance(preference, isDecisionMatrix);
|
|
alternativesPreferencesExperts[ex] = pca.substractMeanAlternativesDominance(alternativesPreferences);
|
|
|
|
pca.addRowToDecisionMatrix(dm, alternativesPreferencesExperts[ex], ex);
|
|
}
|
|
|
|
//Compute covariance-variance matrix
|
|
var mcov = pca.computeCovarianceMatrix(dm);
|
|
|
|
//Descomposition
|
|
var descomposition = pca.generateDescomposition(mcov);
|
|
|
|
//Eigen values
|
|
var eigenValues = pca.generateEigenValues(descomposition);
|
|
var maxIndexes = pca.getMaxEigenValue(eigenValues);
|
|
var max1 = maxIndexes[0];
|
|
var max2 = maxIndexes[1];
|
|
|
|
var eigenValue1 = eigenValues[max1];
|
|
var eigenValue2 = eigenValues[max2];
|
|
|
|
//EigenVectors
|
|
var eigenVector1 = pca.generateEigenVector(descomposition, max1);
|
|
var eigenVector2 = pca.generateEigenVector(descomposition, max2);
|
|
|
|
//Coordinates
|
|
var result = new Array(2);
|
|
result[0] = new Array(preferences.length);
|
|
result[1] = new Array(preferences.length);
|
|
|
|
for(var expert = 0; expert < preferences.length; expert++) {
|
|
result[0][expert] = pca.computeCoordinate(alternativesPreferencesExperts[expert], eigenVector1);
|
|
result[1][expert] = pca.computeCoordinate(alternativesPreferencesExperts[expert], eigenVector2);
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
pca.createConsensusMatrix = function(rows, cols) {
|
|
var matrix = [];
|
|
for(var i = 0; i < rows; i++) {
|
|
matrix[i] = [];
|
|
for(var j = 0; j < cols; j++) {
|
|
matrix[i][j] = 0;
|
|
}
|
|
}
|
|
return matrix;
|
|
}
|
|
|
|
pca.computeAlternativesDominance = function(preference, isDecisionMatrix) {
|
|
var numberOfAlternatives = preference[0].length;
|
|
if(isDecisionMatrix) {
|
|
var numberOfCriteria = preference.length;
|
|
var values = []
|
|
var acum;
|
|
for (var i = 0; i < numberOfAlternatives; i++) {
|
|
acum = 0;
|
|
for (var j = 0; j < numberOfCriteria; j++) {
|
|
acum += preference[j][i];
|
|
}
|
|
acum /= numberOfCriteria;
|
|
values[i] = acum;
|
|
}
|
|
return values;
|
|
} else {
|
|
var cm = pca.createConsensusMatrix(numberOfAlternatives, numberOfAlternatives);
|
|
var value, value1, value2;
|
|
for (var i = 0; i < (numberOfAlternatives - 1); i++) {
|
|
for (var j = (i + 1); j < numberOfAlternatives; j++) {
|
|
value1 = preference[i][j];
|
|
value2 = preference[j][i];
|
|
value = value1 - value2;
|
|
|
|
if (value > 0) {
|
|
cm[i][j] = value;
|
|
cm[j][i] = 0;
|
|
} else {
|
|
cm[j][i] = -value;
|
|
cm[i][j] = 0;
|
|
}
|
|
}
|
|
}
|
|
return pca.computeDominanceValues(cm);
|
|
}
|
|
}
|
|
|
|
pca.computeDominanceValues = function(cm) {
|
|
var values = [];
|
|
var value;
|
|
var max;
|
|
|
|
for (var i = 0; i < cm.length; i++) {
|
|
max = 0;
|
|
for (var j = 0; j < cm.length; j++) {
|
|
if (i != j) {
|
|
value = cm[j][i];
|
|
if (value > max) {
|
|
max = value;
|
|
}
|
|
}
|
|
}
|
|
values[i] = Math.round(max * 100.0) / 100.0;
|
|
}
|
|
|
|
return values;
|
|
}
|
|
|
|
pca.substractMeanAlternativesDominance = function(alternativesPreferences) {
|
|
var mean = 0;
|
|
for(var i = 0; i < alternativesPreferences.length; ++i) {
|
|
mean += alternativesPreferences[i];
|
|
}
|
|
|
|
mean /= alternativesPreferences.length;
|
|
|
|
for(var i = 0; i < alternativesPreferences.length; ++i) {
|
|
alternativesPreferences[i] -= mean;
|
|
}
|
|
|
|
return alternativesPreferences;
|
|
}
|
|
|
|
|
|
pca.addRowToDecisionMatrix = function(dm, alternativesPreferences, expert) {
|
|
for(var i = 0; i < dm[0].length; ++i) {
|
|
dm[expert][i] = alternativesPreferences[i];
|
|
}
|
|
}
|
|
|
|
pca.computeCovarianceMatrix = function(dm) {
|
|
var mx = MatrixUtils.createRealMatrix(dm);
|
|
var cov = new Covariance(mx).getCovarianceMatrix();
|
|
return cov.getData();
|
|
}
|
|
|
|
pca.generateDescomposition = function(preferencesAux) {
|
|
var matrix = MatrixUtils.createRealMatrix(preferencesAux);
|
|
var descomposition = new EigenDecomposition(matrix);
|
|
return descomposition;
|
|
}
|
|
|
|
pca.generateEigenValues = function(descomposition) {
|
|
var eigenValues = descomposition.getRealEigenvalues();
|
|
var eigenValuesAux = new Array(eigenValues.length);
|
|
for(var h = 0;h < eigenValues.length; h++) {
|
|
eigenValuesAux[h] = Math.round(eigenValues[h] * 1000) / 1000;
|
|
}
|
|
|
|
return eigenValuesAux;
|
|
}
|
|
|
|
pca.generateEigenVector = function(descomposition, max) {
|
|
var eigenVector = descomposition.getEigenvector(max);
|
|
var eigenVectorAux = [];
|
|
for(var h = 0;h < eigenVector.getDimension(); h++){
|
|
eigenVectorAux[h] = eigenVector.getEntry(h);
|
|
}
|
|
return eigenVectorAux;
|
|
}
|
|
|
|
pca.getMaxEigenValue = function(eigenValues) {
|
|
var max1 = -1;
|
|
var indexMax1;
|
|
for(var i = 0; i < eigenValues.length; ++i) {
|
|
if(max1 < eigenValues[i]) {
|
|
max1 = eigenValues[i];
|
|
indexMax1 = i;
|
|
}
|
|
}
|
|
|
|
var indexMax2;
|
|
var max2 = -1;
|
|
for(var i = 0; i < eigenValues.length; ++i) {
|
|
if(i != indexMax1) {
|
|
if(max2 < eigenValues[i]) {
|
|
max2 = eigenValues[i];
|
|
indexMax2 = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
var indexes = [];
|
|
indexes[0] = indexMax1;
|
|
indexes[1] = indexMax2;
|
|
return indexes;
|
|
}
|
|
|
|
pca.computeCoordinate = function(v1, v2) {
|
|
var acum = 0;
|
|
for(var i = 0; i < v1.length; ++i) {
|
|
acum += v1[i] * v2[i];
|
|
}
|
|
return acum;
|
|
}
|
|
|
|
pca.PCA3D = function(preferences, isDecisionMatrix) {
|
|
//Initialize DM matrix
|
|
var dm = pca.createConsensusMatrix(preferences.length, preferences[0][0].length);
|
|
var alternativesPreferencesExperts = [];
|
|
|
|
var preference;
|
|
var alternativesPreferences;
|
|
for(var ex = 0; ex < preferences.length; ex++){
|
|
preference = preferences[ex];
|
|
|
|
alternativesPreferences = pca.computeAlternativesDominance(preference, isDecisionMatrix);
|
|
alternativesPreferencesExperts[ex] = pca.substractMeanAlternativesDominance(alternativesPreferences);
|
|
|
|
pca.addRowToDecisionMatrix(dm, alternativesPreferencesExperts[ex], ex);
|
|
}
|
|
|
|
//Compute covariance-variance matrix
|
|
var mcov = pca.computeCovarianceMatrix(dm);
|
|
|
|
//Descomposition
|
|
var descomposition = pca.generateDescomposition(mcov);
|
|
|
|
//Eigen values
|
|
var eigenValues = pca.generateEigenValues(descomposition);
|
|
var maxIndexes = pca.getMaxEigenValue3D(eigenValues);
|
|
|
|
//Indexes of maximal eigen values
|
|
var max1 = maxIndexes[0];
|
|
var max2 = maxIndexes[1];
|
|
var max3 = maxIndexes[2];
|
|
|
|
var eigenValue1 = eigenValues[max1];
|
|
var eigenValue2 = eigenValues[max2];
|
|
var eigenValue3 = eigenValues[max3];
|
|
|
|
//EigenVectors
|
|
var eigenVector1 = pca.generateEigenVector(descomposition, max1);
|
|
var eigenVector2 = pca.generateEigenVector(descomposition, max2);
|
|
var eigenVector3 = pca.generateEigenVector(descomposition, max3);
|
|
|
|
//Coordinates
|
|
var result = new Array(2);
|
|
result[0] = new Array(preferences.length);
|
|
result[1] = new Array(preferences.length);
|
|
result[2] = new Array(preferences.length);
|
|
|
|
for(var expert = 0; expert < preferences.length; expert++) {
|
|
result[0][expert] = pca.computeCoordinate(alternativesPreferencesExperts[expert], eigenVector1);
|
|
result[1][expert] = pca.computeCoordinate(alternativesPreferencesExperts[expert], eigenVector2);
|
|
result[2][expert] = pca.computeCoordinate(alternativesPreferencesExperts[expert], eigenVector3);
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
pca.getMaxEigenValue3D = function(eigenValues) {
|
|
var max1 = -1;
|
|
var indexMax1;
|
|
for(var i = 0; i < eigenValues.length; ++i) {
|
|
if(max1 < eigenValues[i]) {
|
|
max1 = eigenValues[i];
|
|
indexMax1 = i;
|
|
}
|
|
}
|
|
|
|
var indexMax2;
|
|
var max2 = -1;
|
|
for(var i = 0; i < eigenValues.length; ++i) {
|
|
if(i != indexMax1) {
|
|
if(max2 < eigenValues[i]) {
|
|
max2 = eigenValues[i];
|
|
indexMax2 = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
var indexMax3;
|
|
var max3 = -1;
|
|
for(var i = 0; i < eigenValues.length; ++i) {
|
|
if(i != indexMax1 && i != indexMax2) {
|
|
if(max3 < eigenValues[i]) {
|
|
max3 = eigenValues[i];
|
|
indexMax3 = i;
|
|
}
|
|
}
|
|
}
|
|
|
|
var indexes = [];
|
|
indexes[0] = indexMax1;
|
|
indexes[1] = indexMax2;
|
|
indexes[2] = indexMax3;
|
|
return indexes;
|
|
}
|
|
|
|
|
|
pca
|
|
</code>
|
|
</snippet> |