als-statistics
Version:
Modular JS statistics toolkit for Node.js and the browser: descriptive stats, correlations (Pearson/Spearman/Kendall), t-tests & ANOVA (Student/Welch), reliability (Cronbach’s alpha), regression (linear/logistic), clustering (DBSCAN/HDBSCAN), and table/co
51 lines (42 loc) • 1.8 kB
JavaScript
import { RegressionBase } from "./regression-base.js"
const sigmoid = (z) => 1 / (1 + Math.exp(-z))
class LogisticRegression extends RegressionBase {
tol = 1e-6;
constructor(samples, yName, xNames, step, learningRate = 0.01, epochs = 1000) {
super(samples, yName, xNames, step)
this.learningRate = learningRate
this.epochs = epochs
}
calculate() {
super.calculate()
const correct = this.yHat.reduce((acc, pred, i) => acc + (pred === this.y[i] ? 1 : 0), 0)
this.accuracy = correct / this.n
return this
}
computeCoefficients() {
this.coefficients = Array(this.k).fill(0)
for (let epoch = 0; epoch < this.epochs; epoch++) { // Градиентный спуск
const preds = this.predictProba(this.X)
const errors = preds.map((p, i) => p - this.y[i])
const grads = Array(this.k).fill(0) // Градиенты
for (let i = 0; i < this.n; i++) {
for (let j = 0; j < this.k; j++) {
grads[j] += this.X[i][j] * errors[i]
}
}
for (let j = 0; j < this.k; j++) { // Обновление коэффициентов
this.coefficients[j] -= this.learningRate * grads[j] / this.n
}
const gradNorm = grads.reduce((sum, g) => sum + g * g, 0);
if (gradNorm < this.tol * this.tol) break; // Early stop
}
}
predictProba(X) {
return X.map(row => sigmoid(row.reduce((sum, val, j) => sum + val * this.coefficients[j], 0)))
}
predict(X, threshold = 0.5) {
return this.predictProba(X).map(p => (p >= threshold ? 1 : 0))
}
get result() { return { ...super.result, Accuracy: this.accuracy } }
}
export default LogisticRegression