У меня есть кусок кода, который выполняет вычисления на матрице путем итерации по его строкам и столбцам. Кусочек исчисления выполнен в виде косинусного расстояния, с кодом, который я нашел в Интернете (не удалось получить ссылку прямо сейчас).как ускорить этот код? исчисление итерации по строкам и столбцам матрицы
Может быть 10 000 строк и столбцов. Матрица симметрична, поэтому мне просто нужно повторить ее половину. Значения плавают.
Проблема: она очень медленная (это займет от 3 до 6 часов). Может ли кто-нибудь указать мне на улучшения? Спасибо!
Замечание о коде: для гибкости используется абстрактный класс: таким образом, расчет косинуса, определенный в отдельном классе, может быть легко заменен другим.
Код:
import Jama.Matrix;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.concurrent.ExecutionException;
public abstract class AbstractSimilarity {
HashSet<Triple<Double, Integer, Integer>> set = new HashSet();
public ArrayList<Thread> listThreads = new ArrayList();
public void transform(Matrix matrixToBeTransformed) throws InterruptedException,
ExecutionException {
int numDocs = termDocumentMatrix.getColumnDimension();
Main.similarityMatrix = new Matrix(numDocs, numDocs);
System.out.println("size of the matrix: " + numDocs + "x " + numDocs);
//1. iteration through all rows of the matrixToBeTransformed
for (int i = numDocs - 1; i >0 ; i--) {
System.out.println("matrix treatment... " + ((float) i/(float) numDocs * 100) + "%");
//2. isolates the row i of this matrixToBeTransformed
Matrix sourceDocMatrix = matrixToBeTransformed.getMatrix(
0, matrixToBeTransformed.getRowDimension() - 1, i, i);
// 3. Iterates through all columns of the matrixToBeTransformed
// for (int j = 0; j < numDocs; j++) {
// if (j < i) {
//
// //4. isolates the column j of this matrixToBeTransformed
// Matrix targetDocMatrix = matrixToBeTransformed.getMatrix(
// 0, matrixToBeTransformed.getRowDimension() - 1, j, j);
//5. computes the similarity between this given row and this given column and writes it in a resultMatrix
// Main.resultMatrix.set(i, j, computeSimilarity(sourceDocMatrix, targetDocMatrix));
// } else {
// Main.resultMatrix.set(i, j, 0);
// }
//
// }
}
Класс, который определяет вычисление было сделано:
import Jama.Matrix;
public class CosineSimilarity extends AbstractSimilarity{
@Override
protected double computeSimilarity(Matrix sourceDoc, Matrix targetDoc) {
double dotProduct = sourceDoc.arrayTimes(targetDoc).norm1();
double eucledianDist = sourceDoc.normF() * targetDoc.normF();
return dotProduct/eucledianDist;
}
}
Это проект домашней работы? Можете ли вы не использовать математическое программное обеспечение, такое как MatLab? –
Это профессиональный проект в академических кругах, и мне нужно использовать Java для него - bc моих собственных ограничений, я боюсь! – seinecle
Профилированы ли вы, чтобы узнать, какая часть вашего алгоритма занимает самое длинное время? Просто добавив 'new Date(). GetTime();' в начале/конце операций, и их вычитание может дать вам хорошее представление. – Marcelo