Skip to content
Open
Changes from 1 commit
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
ea4e04d
chore: adding the initial baseline for AdaboostClassifier
JasonShin Jan 22, 2019
648a841
wip: adaboost fit
JasonShin Jan 23, 2019
fa2b185
wip: creating a sum of weights of missclassified samples
JasonShin Jan 23, 2019
32a8f51
wip: flipping polarity if error is > 0.5
JasonShin Jan 23, 2019
5e084ef
wip: saving the smallest error configuration for the DecisionStump
JasonShin Jan 23, 2019
e2ec2d9
wip: altering training weight
JasonShin Jan 24, 2019
f7d3197
wip: normalizing weight
JasonShin Jan 24, 2019
a15cbde
wip: calculating w
JasonShin Jan 25, 2019
d7cfe03
refactor: temporary lint fix
JasonShin Jan 26, 2019
16cb9d8
chore: updating feature values code to use TFJS as much as possible
JasonShin Jan 26, 2019
0aff8d2
chore: finished the fit function
JasonShin Jan 27, 2019
a287c48
chore: applying oleg's suggestion on not using ... everywhere
JasonShin Jan 27, 2019
c4657fb
chore: removed datasync, finished predictions implementation
JasonShin Jan 27, 2019
ba57aea
wip: still fixing the NaN issue
JasonShin Jan 27, 2019
8f7d93c
fix: fixed the NaN issue by using preprocessing in index.repl.ts
JasonShin Jan 28, 2019
5be98a8
fix: fixing a prediction equation mistake
JasonShin Jan 28, 2019
9840622
refactor: changed if statements to use tfjs
JasonShin Jan 30, 2019
92c0dad
chore: adding exp to the weight calculation in the end
JasonShin Jan 31, 2019
1a16754
chore: saving work
JasonShin Jan 31, 2019
95a593e
Delete test.py
JasonShin Feb 23, 2019
d3d9eb4
Merge branch 'develop' into feature/adaboost
JasonShin Mar 30, 2019
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
chore: removed datasync, finished predictions implementation
  • Loading branch information
JasonShin committed Jan 27, 2019
commit c4657fb7003ea16bcf7794ae84646598836fd37f
60 changes: 38 additions & 22 deletions src/lib/ensemble/weight_boosting.ts
Original file line number Diff line number Diff line change
Expand Up @@ -96,35 +96,28 @@ export class AdaboostClassifier implements IMlModel<number> {
clf.alpha = 0.5 * Math.log((1.0 - minError) / (minError + 1e-10));

// Set all predictions to 1 initially then extracts into a pure array
const predictions = [...tf.ones(tensorY.shape).dataSync()];
// const predictions = [...tf.ones(tensorY.shape).dataSync()];
const predictions = tf.ones(tensorY.shape);
const minusOnes = tf.fill(tensorY.shape, -1);

// The indexes where the sample values are below threshold
const negativeIndexes = [
...tensorX
// X[:, indices]
.gather(tf.tensor1d([clf.featureIndex]), 1)
// * polarity
.mul(clf.getTsPolarity())
// < polarity * threshold
.less(clf.getTsPolarity().mul(clf.getTsThreshold()))
// Return a flatten data
.dataSync()
];

// Equivalent with 1/-1 to update weights
for (let pi = 0; pi < predictions.length; pi++) {
predictions[pi] = negativeIndexes[pi] === 1 ? -1 : 1;
}
const negativeIndex = tensorX
// X[:, indices]
.gather(tf.tensor1d([clf.featureIndex]), 1)
// * polarity
.mul(clf.getTsPolarity())
// < polarity * threshold
.less(clf.getTsPolarity().mul(clf.getTsThreshold()));

// Turn predictions back to tfjs
const tensorPredictions = tf.tensor(predictions);
// Label those as '-1'
const labeledPreds = minusOnes.where(negativeIndex, predictions);

// Misclassified samples gets larger weights and correctly classified samples smaller
w = w.mul(
tf
.scalar(-clf.alpha)
.mul(tensorY)
.mul(tensorPredictions)
.mul(labeledPreds)
);

// Normalize to one
Expand All @@ -142,8 +135,31 @@ export class AdaboostClassifier implements IMlModel<number> {
public predict(
X: Type2DMatrix<number> | Type1DMatrix<number>
): number[] | number[][] {
console.info(X);
return undefined;
const tensorX = tf.tensor2d(X);
const nSamples = tensorX.shape[0];
let yPred = tf.zeros([nSamples, 1]);
const predictions = tf.ones(yPred.shape);
const minusOnes = tf.fill(yPred.shape, -1);

for (let i = 0; i < this.classifiers.length; i++) {
const clf = this.classifiers[i];
const negativeIndex = clf
// clf.polarity * X[:, clf.feature_index]
.getTsPolarity()
.mul(tensorX.gather(tf.tensor1d([clf.featureIndex]), 1))
// < clf.polarity * clf.threshold
.less(clf.getTsPolarity().mul(clf.getTsThreshold()));

// Label those as '-1'
const labeledPreds = minusOnes.where(negativeIndex, predictions);

// Add predictions weighted by the classifiers alpha
// (alpha indicative of classifier's proficiency)
yPred = yPred.add(tf.scalar(clf.alpha)).mul(labeledPreds);
}

yPred = tf.sign(yPred).squeeze();
return [...yPred.dataSync()];
}

public toJSON(): TypeModelState {
Expand Down