///|
/// Weighted probability ensemble with online expert reweighting.
pub struct WeightedProbabilityEnsemble {
weights : Array[Double]
mut observations : Int
}
///|
pub fn WeightedProbabilityEnsemble::new(
experts : Int,
) -> WeightedProbabilityEnsemble {
let size = if experts < 0 { 0 } else { experts }
{ weights: Array::make(size, 1.0), observations: 0 }
}
///|
pub fn WeightedProbabilityEnsemble::experts(
self : WeightedProbabilityEnsemble,
) -> Int {
self.weights.length()
}
///|
pub fn WeightedProbabilityEnsemble::predict(
self : WeightedProbabilityEnsemble,
predictions : Array[Double],
) -> Double {
let size = if predictions.length() < self.weights.length() {
predictions.length()
} else {
self.weights.length()
}
let mut numerator = 0.0
let mut denominator = 0.0
for i in 0.. Unit {
let size = if predictions.length() < self.weights.length() {
predictions.length()
} else {
self.weights.length()
}
for i in 0.. Array[Double] {
copy_vector(self.weights)
}
///|
pub fn WeightedProbabilityEnsemble::normalized_weights(
self : WeightedProbabilityEnsemble,
) -> Array[Double] {
let total = sum_values(self.weights)
if total <= 0.0 {
Array::make(self.weights.length(), 0.0)
} else {
scale_values(self.weights, 1.0 / total)
}
}
///|
pub fn WeightedProbabilityEnsemble::observations(
self : WeightedProbabilityEnsemble,
) -> Int {
self.observations
}
///|
pub fn WeightedProbabilityEnsemble::reset(
self : WeightedProbabilityEnsemble,
) -> Unit {
self.weights.fill(1.0)
self.observations = 0
}
///|
/// Online bagging around Adagrad logistic learners.
pub struct OnlineBaggingClassifier {
models : Array[AdagradLogisticRegression]
rng : DeterministicRng
mut observations : Int
}
///|
pub fn OnlineBaggingClassifier::new(
model_count : Int,
dimension : Int,
seed? : UInt64 = 1,
) -> OnlineBaggingClassifier {
let count = if model_count < 0 { 0 } else { model_count }
{
models: Array::makei(count, _ => AdagradLogisticRegression::new(dimension)),
rng: DeterministicRng::new(seed),
observations: 0,
}
}
///|
pub fn OnlineBaggingClassifier::models(self : OnlineBaggingClassifier) -> Int {
self.models.length()
}
///|
pub fn OnlineBaggingClassifier::predict(
self : OnlineBaggingClassifier,
features : Array[Double],
) -> Double {
if self.models.is_empty() {
0.5
} else {
let mut total = 0.0
for model in self.models {
total += model.predict(features)
}
total / self.models.length().to_double()
}
}
///|
pub fn OnlineBaggingClassifier::update(
self : OnlineBaggingClassifier,
features : Array[Double],
label : Double,
) -> Unit {
for model in self.models {
let copies = poisson_one(self.rng)
for _ in 0.. Int {
let mut count = 0
if rng.next_double() < 0.37 {
count += 1
}
if rng.next_double() < 0.18 {
count += 1
}
if rng.next_double() < 0.08 {
count += 1
}
count
}
///|
pub fn OnlineBaggingClassifier::observations(
self : OnlineBaggingClassifier,
) -> Int {
self.observations
}
///|
pub fn OnlineBaggingClassifier::member_predictions(
self : OnlineBaggingClassifier,
features : Array[Double],
) -> Array[Double] {
self.models.map(model => model.predict(features))
}
///|
pub fn OnlineBaggingClassifier::reset(self : OnlineBaggingClassifier) -> Unit {
for model in self.models {
model.reset()
}
self.observations = 0
}