Disclaimer: Signal Ward is an educational simulation. All clinical scenarios are fictional. Nothing in this course constitutes medical advice.
Dr. KarimiOur first milestone: Diagnostic One needs to tell the difference between an allergy note, a progress note, and a discharge summary. Can you build that, Khalil?
KhalilSo it's like... routing. A request comes in and I need to send it to the right handler based on its content?
VikramThat's exactly right. A classifier is a router for data. It looks at the features and decides which category they belong to.
You use Array.map() constantly — transforming each element in an array. A classifier does the same thing: it takes each input feature, multiplies it by a learned weight, adds a bias, and the result determines the category.
items.map(x => x * weight + bias)prediction = tf.add(tf.mul(input, weights), bias)A linear classifier is just weighted addition. Each feature gets a weight that the model learns during training. Higher weight means that feature matters more for the prediction.
import * as tf from '@tensorflow/tfjs';
// Features: [has_allergy_word, has_medication, has_vitals, has_discharge_word, has_follow_up]
const allergyNote = tf.tensor([1, 1, 0, 0, 0]);
const progressNote = tf.tensor([0, 0, 1, 0, 0]);
const dischargeNote = tf.tensor([0, 1, 0, 1, 1]);
// Learned weights for "is this an allergy note?"
const allergyWeights = tf.tensor([0.9, 0.3, -0.1, -0.5, -0.2]);
const bias = tf.scalar(0.1);
// Score = sum(features * weights) + bias
function classify(features: tf.Tensor, weights: tf.Tensor, b: tf.Tensor): number {
const score = features.mul(weights).sum().add(b);
return score.dataSync()[0];
}
console.log('Allergy note score:', classify(allergyNote, allergyWeights, bias)); // ~1.3 (high)
console.log('Progress note score:', classify(progressNote, allergyWeights, bias)); // ~0.0 (low)
console.log('Discharge note score:', classify(dischargeNote, allergyWeights, bias)); // ~-0.1 (low)A raw score isn't a classification yet. We apply a sigmoid function to squash it between 0 and 1 — turning it into a probability.
// Sigmoid: squash any number to the 0-1 range
// Like CSS clamp() but for probabilities
function sigmoid(x: number): number {
return 1 / (1 + Math.exp(-x));
}
// High score → high probability
console.log(sigmoid(1.3)); // ~0.79 → likely an allergy note
console.log(sigmoid(0.0)); // 0.50 → uncertain
console.log(sigmoid(-0.1)); // ~0.48 → probably not an allergy note
// In TensorFlow.js, use tf.sigmoid()
const scores = tf.tensor([1.3, 0.0, -0.1]);
const probabilities = tf.sigmoid(scores);
probabilities.print(); // [0.786, 0.500, 0.475]Build a classifier that scores clinical notes as allergy-related or not.
Write a classify function that takes a feature tensor and weight tensor, multiplies them element-wise, sums the result, adds a bias of 0.1, and returns the sigmoid of the score using tf.sigmoid(). Return the result of dataSync()[0].
import * as tf from '@tensorflow/tfjs'; function classify(features: tf.Tensor, weights: tf.Tensor): number { const bias = 0.1; // 1. Multiply features by weights element-wise // 2. Sum the result // 3. Add bias // 4. Apply sigmoid and return the value return null; // your code here } const features = tf.tensor([1, 1, 0, 0, 0]); const weights = tf.tensor([0.9, 0.3, -0.1, -0.5, -0.2]); const result = classify(features, weights);
The first classifier correctly categorizes 3 out of 4 test notes. It's rough, but it works.
Next: understanding how tokenization breaks text into processable units.