entropyx
Version:
A simple data mining library, written in TypeScript
86 lines • 2.74 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.PageRank = void 0;
class PageRank {
constructor(options = {}) {
this.beta = options.beta ?? 0.85;
this.maxIterations = options.maxIterations ?? 100;
this.tolerance = options.tolerance ?? 1e-6;
}
fit(adjacency) {
const n = adjacency.length;
if (n === 0) {
return { ranks: [] };
}
const M = this.buildTransitionMatrix(adjacency);
for (let i = 0; i < n; i++) {
for (let j = 0; j < n; j++) {
M[i][j] = M[i][j] * this.beta + (1 - this.beta) / n;
}
}
const A = this.transpose(M);
let ranks = new Array(n).fill(1 / n);
for (let iteration = 0; iteration < this.maxIterations; iteration++) {
const oldRanks = [...ranks];
const newScores = A.map((row) => this.dot(ranks, row));
ranks = this.normalize(newScores);
if (this.sumOfDifferences(oldRanks, ranks) < this.tolerance) {
break;
}
}
return { ranks };
}
buildTransitionMatrix(adjacency) {
const n = adjacency.length;
const M = Array.from({ length: n }, () => new Array(n).fill(0));
for (let i = 0; i < n; i++) {
const row = adjacency[i];
const rowSum = row.reduce((acc, val) => acc + val, 0);
if (rowSum === 0) {
for (let j = 0; j < n; j++) {
M[i][j] = 1 / n;
}
}
else {
for (let j = 0; j < n; j++) {
M[i][j] = row[j] / rowSum;
}
}
}
return M;
}
transpose(matrix) {
const rows = matrix.length;
const cols = matrix[0].length;
const result = Array.from({ length: cols }, () => new Array(rows).fill(0));
for (let i = 0; i < rows; i++) {
for (let j = 0; j < cols; j++) {
result[j][i] = matrix[i][j];
}
}
return result;
}
dot(a, b) {
let sum = 0;
for (let i = 0; i < a.length; i++) {
sum += a[i] * b[i];
}
return sum;
}
normalize(ranks) {
const sum = ranks.reduce((acc, val) => acc + val, 0);
if (sum === 0) {
return ranks.map(() => 1 / ranks.length);
}
return ranks.map((val) => val / sum);
}
sumOfDifferences(a, b) {
let sum = 0;
for (let i = 0; i < a.length; i++) {
sum += Math.abs(a[i] - b[i]);
}
return sum;
}
}
exports.PageRank = PageRank;
//# sourceMappingURL=page-rank.js.map
;