Merge branch 'development' into issue-115

This commit is contained in:
Malte Londschien
2021-10-28 09:54:22 +02:00
17 changed files with 33 additions and 34 deletions
+5 -5
View File
@@ -117,7 +117,7 @@ impl<T: Debug + PartialEq, F: RealNumber, D: Distance<T, F>> CoverTree<T, F, D>
} }
let e = self.get_data_value(self.root.idx); let e = self.get_data_value(self.root.idx);
let mut d = self.distance.distance(&e, p); let mut d = self.distance.distance(e, p);
let mut current_cover_set: Vec<(F, &Node<F>)> = Vec::new(); let mut current_cover_set: Vec<(F, &Node<F>)> = Vec::new();
let mut zero_set: Vec<(F, &Node<F>)> = Vec::new(); let mut zero_set: Vec<(F, &Node<F>)> = Vec::new();
@@ -175,7 +175,7 @@ impl<T: Debug + PartialEq, F: RealNumber, D: Distance<T, F>> CoverTree<T, F, D>
if ds.0 <= upper_bound { if ds.0 <= upper_bound {
let v = self.get_data_value(ds.1.idx); let v = self.get_data_value(ds.1.idx);
if !self.identical_excluded || v != p { if !self.identical_excluded || v != p {
neighbors.push((ds.1.idx, ds.0, &v)); neighbors.push((ds.1.idx, ds.0, v));
} }
} }
} }
@@ -200,7 +200,7 @@ impl<T: Debug + PartialEq, F: RealNumber, D: Distance<T, F>> CoverTree<T, F, D>
let mut zero_set: Vec<(F, &Node<F>)> = Vec::new(); let mut zero_set: Vec<(F, &Node<F>)> = Vec::new();
let e = self.get_data_value(self.root.idx); let e = self.get_data_value(self.root.idx);
let mut d = self.distance.distance(&e, p); let mut d = self.distance.distance(e, p);
current_cover_set.push((d, &self.root)); current_cover_set.push((d, &self.root));
while !current_cover_set.is_empty() { while !current_cover_set.is_empty() {
@@ -230,7 +230,7 @@ impl<T: Debug + PartialEq, F: RealNumber, D: Distance<T, F>> CoverTree<T, F, D>
for ds in zero_set { for ds in zero_set {
let v = self.get_data_value(ds.1.idx); let v = self.get_data_value(ds.1.idx);
if !self.identical_excluded || v != p { if !self.identical_excluded || v != p {
neighbors.push((ds.1.idx, ds.0, &v)); neighbors.push((ds.1.idx, ds.0, v));
} }
} }
@@ -287,7 +287,7 @@ impl<T: Debug + PartialEq, F: RealNumber, D: Distance<T, F>> CoverTree<T, F, D>
if point_set.is_empty() { if point_set.is_empty() {
self.new_leaf(p) self.new_leaf(p)
} else { } else {
let max_dist = self.max(&point_set); let max_dist = self.max(point_set);
let next_scale = (max_scale - 1).min(self.get_scale(max_dist)); let next_scale = (max_scale - 1).min(self.get_scale(max_dist));
if next_scale == std::i64::MIN { if next_scale == std::i64::MIN {
let mut children: Vec<Node<F>> = Vec::new(); let mut children: Vec<Node<F>> = Vec::new();
+2 -2
View File
@@ -74,7 +74,7 @@ impl<T, F: RealNumber, D: Distance<T, F>> LinearKNNSearch<T, F, D> {
} }
for i in 0..self.data.len() { for i in 0..self.data.len() {
let d = self.distance.distance(&from, &self.data[i]); let d = self.distance.distance(from, &self.data[i]);
let datum = heap.peek_mut(); let datum = heap.peek_mut();
if d < datum.distance { if d < datum.distance {
datum.distance = d; datum.distance = d;
@@ -104,7 +104,7 @@ impl<T, F: RealNumber, D: Distance<T, F>> LinearKNNSearch<T, F, D> {
let mut neighbors: Vec<(usize, F, &T)> = Vec::new(); let mut neighbors: Vec<(usize, F, &T)> = Vec::new();
for i in 0..self.data.len() { for i in 0..self.data.len() {
let d = self.distance.distance(&from, &self.data[i]); let d = self.distance.distance(from, &self.data[i]);
if d <= radius { if d <= radius {
neighbors.push((i, d, &self.data[i])); neighbors.push((i, d, &self.data[i]));
+1 -2
View File
@@ -53,8 +53,7 @@ impl<'a, T: PartialOrd + Debug> HeapSelection<T> {
if self.sorted { if self.sorted {
&self.heap[0] &self.heap[0]
} else { } else {
&self self.heap
.heap
.iter() .iter()
.max_by(|a, b| a.partial_cmp(b).unwrap()) .max_by(|a, b| a.partial_cmp(b).unwrap())
.unwrap() .unwrap()
+1 -1
View File
@@ -6,7 +6,7 @@
clippy::upper_case_acronyms clippy::upper_case_acronyms
)] )]
#![warn(missing_docs)] #![warn(missing_docs)]
#![warn(missing_doc_code_examples)] #![warn(rustdoc::missing_doc_code_examples)]
//! # SmartCore //! # SmartCore
//! //!
+1 -1
View File
@@ -93,7 +93,7 @@ pub trait EVDDecomposableMatrix<T: RealNumber>: BaseMatrix<T> {
sort(&mut d, &mut e, &mut V); sort(&mut d, &mut e, &mut V);
} }
Ok(EVD { V, d, e }) Ok(EVD { d, e, V })
} }
} }
+1 -1
View File
@@ -330,7 +330,7 @@ impl<T: RealNumber> DenseMatrix<T> {
cur_r: 0, cur_r: 0,
max_c: self.ncols, max_c: self.ncols,
max_r: self.nrows, max_r: self.nrows,
m: &self, m: self,
} }
} }
} }
+2 -2
View File
@@ -178,7 +178,7 @@ impl<T: RealNumber + ScalarOperand> BaseVector<T> for ArrayBase<OwnedRepr<T>, Ix
} }
fn copy_from(&mut self, other: &Self) { fn copy_from(&mut self, other: &Self) {
self.assign(&other); self.assign(other);
} }
} }
@@ -385,7 +385,7 @@ impl<T: RealNumber + ScalarOperand + AddAssign + SubAssign + MulAssign + DivAssi
} }
fn copy_from(&mut self, other: &Self) { fn copy_from(&mut self, other: &Self) {
self.assign(&other); self.assign(other);
} }
fn abs_mut(&mut self) -> &Self { fn abs_mut(&mut self) -> &Self {
+2 -1
View File
@@ -249,7 +249,8 @@ impl<T: RealNumber> BernoulliNBDistribution<T> {
} }
} }
/// BernoulliNB implements the categorical naive Bayes algorithm for categorically distributed data. /// BernoulliNB implements the naive Bayes algorithm for data that follows the Bernoulli
/// distribution.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct BernoulliNB<T: RealNumber, M: Matrix<T>> { pub struct BernoulliNB<T: RealNumber, M: Matrix<T>> {
+1 -1
View File
@@ -232,8 +232,8 @@ impl<T: RealNumber> CategoricalNBDistribution<T> {
class_labels, class_labels,
class_priors, class_priors,
coefficients, coefficients,
n_categories,
n_features, n_features,
n_categories,
category_count, category_count,
}) })
} }
+3 -2
View File
@@ -33,7 +33,7 @@ use crate::naive_bayes::{BaseNaiveBayes, NBDistribution};
#[cfg(feature = "serde")] #[cfg(feature = "serde")]
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
/// Naive Bayes classifier for categorical features /// Naive Bayes classifier using Gaussian distribution
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
struct GaussianNBDistribution<T: RealNumber> { struct GaussianNBDistribution<T: RealNumber> {
@@ -179,7 +179,8 @@ impl<T: RealNumber> GaussianNBDistribution<T> {
} }
} }
/// GaussianNB implements the categorical naive Bayes algorithm for categorically distributed data. /// GaussianNB implements the naive Bayes algorithm for data that follows the Gaussian
/// distribution.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct GaussianNB<T: RealNumber, M: Matrix<T>> { pub struct GaussianNB<T: RealNumber, M: Matrix<T>> {
+1 -1
View File
@@ -212,7 +212,7 @@ impl<T: RealNumber> MultinomialNBDistribution<T> {
} }
} }
/// MultinomialNB implements the categorical naive Bayes algorithm for categorically distributed data. /// MultinomialNB implements the naive Bayes algorithm for multinomially distributed data.
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))] #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
#[derive(Debug, PartialEq)] #[derive(Debug, PartialEq)]
pub struct MultinomialNB<T: RealNumber, M: Matrix<T>> { pub struct MultinomialNB<T: RealNumber, M: Matrix<T>> {
@@ -50,14 +50,14 @@ impl<T: RealNumber> FirstOrderOptimizer<T> for GradientDescent<T> {
let f_alpha = |alpha: T| -> T { let f_alpha = |alpha: T| -> T {
let mut dx = step.clone(); let mut dx = step.clone();
dx.mul_scalar_mut(alpha); dx.mul_scalar_mut(alpha);
f(&dx.add_mut(&x)) // f(x) = f(x .+ gvec .* alpha) f(dx.add_mut(&x)) // f(x) = f(x .+ gvec .* alpha)
}; };
let df_alpha = |alpha: T| -> T { let df_alpha = |alpha: T| -> T {
let mut dx = step.clone(); let mut dx = step.clone();
let mut dg = gvec.clone(); let mut dg = gvec.clone();
dx.mul_scalar_mut(alpha); dx.mul_scalar_mut(alpha);
df(&mut dg, &dx.add_mut(&x)); //df(x) = df(x .+ gvec .* alpha) df(&mut dg, dx.add_mut(&x)); //df(x) = df(x .+ gvec .* alpha)
gvec.dot(&dg) gvec.dot(&dg)
}; };
@@ -66,7 +66,7 @@ impl<T: RealNumber> FirstOrderOptimizer<T> for GradientDescent<T> {
let ls_r = ls.search(&f_alpha, &df_alpha, alpha, fx, df0); let ls_r = ls.search(&f_alpha, &df_alpha, alpha, fx, df0);
alpha = ls_r.alpha; alpha = ls_r.alpha;
fx = ls_r.f_x; fx = ls_r.f_x;
x.add_mut(&step.mul_scalar_mut(alpha)); x.add_mut(step.mul_scalar_mut(alpha));
df(&mut gvec, &x); df(&mut gvec, &x);
gnorm = gvec.norm2(); gnorm = gvec.norm2();
} }
+3 -3
View File
@@ -117,14 +117,14 @@ impl<T: RealNumber> LBFGS<T> {
let f_alpha = |alpha: T| -> T { let f_alpha = |alpha: T| -> T {
let mut dx = state.s.clone(); let mut dx = state.s.clone();
dx.mul_scalar_mut(alpha); dx.mul_scalar_mut(alpha);
f(&dx.add_mut(&state.x)) // f(x) = f(x .+ gvec .* alpha) f(dx.add_mut(&state.x)) // f(x) = f(x .+ gvec .* alpha)
}; };
let df_alpha = |alpha: T| -> T { let df_alpha = |alpha: T| -> T {
let mut dx = state.s.clone(); let mut dx = state.s.clone();
let mut dg = state.x_df.clone(); let mut dg = state.x_df.clone();
dx.mul_scalar_mut(alpha); dx.mul_scalar_mut(alpha);
df(&mut dg, &dx.add_mut(&state.x)); //df(x) = df(x .+ gvec .* alpha) df(&mut dg, dx.add_mut(&state.x)); //df(x) = df(x .+ gvec .* alpha)
state.x_df.dot(&dg) state.x_df.dot(&dg)
}; };
@@ -206,7 +206,7 @@ impl<T: RealNumber> FirstOrderOptimizer<T> for LBFGS<T> {
) -> OptimizerResult<T, X> { ) -> OptimizerResult<T, X> {
let mut state = self.init_state(x0); let mut state = self.init_state(x0);
df(&mut state.x_df, &x0); df(&mut state.x_df, x0);
let g_converged = state.x_df.norm(T::infinity()) < self.g_atol; let g_converged = state.x_df.norm(T::infinity()) < self.g_atol;
let mut converged = g_converged; let mut converged = g_converged;
+2 -4
View File
@@ -134,10 +134,8 @@ where
U: RealNumber, U: RealNumber,
V: BaseVector<U>, V: BaseVector<U>,
{ {
match self.get_num(category) { self.get_num(category)
None => None, .map(|&idx| make_one_hot::<U, V>(idx, self.num_categories))
Some(&idx) => Some(make_one_hot::<U, V>(idx, self.num_categories)),
}
} }
/// Invert one-hot vector, back to the category /// Invert one-hot vector, back to the category
+2 -2
View File
@@ -377,7 +377,7 @@ impl<'a, T: RealNumber, M: Matrix<T>, K: Kernel<T, M::RowVector>> Optimizer<'a,
Optimizer { Optimizer {
x, x,
y, y,
parameters: &parameters, parameters,
svmin: 0, svmin: 0,
svmax: 0, svmax: 0,
gmin: T::max_value(), gmin: T::max_value(),
@@ -589,7 +589,7 @@ impl<'a, T: RealNumber, M: Matrix<T>, K: Kernel<T, M::RowVector>> Optimizer<'a,
for i in 0..self.sv.len() { for i in 0..self.sv.len() {
let v = &self.sv[i]; let v = &self.sv[i];
let z = v.grad - gm; let z = v.grad - gm;
let k = cache.get(sv1, &v); let k = cache.get(sv1, v);
let mut curv = km + v.k - T::two() * k; let mut curv = km + v.k - T::two() * k;
if curv <= T::zero() { if curv <= T::zero() {
curv = self.tau; curv = self.tau;
+2 -2
View File
@@ -380,7 +380,7 @@ impl<T: RealNumber> DecisionTreeClassifier<T> {
depth: 0, depth: 0,
}; };
let mut visitor = NodeVisitor::<T, M>::new(0, samples, &order, &x, &yi, 1); let mut visitor = NodeVisitor::<T, M>::new(0, samples, &order, x, &yi, 1);
let mut visitor_queue: LinkedList<NodeVisitor<'_, T, M>> = LinkedList::new(); let mut visitor_queue: LinkedList<NodeVisitor<'_, T, M>> = LinkedList::new();
@@ -541,7 +541,7 @@ impl<T: RealNumber> DecisionTreeClassifier<T> {
- T::from(tc).unwrap() / T::from(n).unwrap() - T::from(tc).unwrap() / T::from(n).unwrap()
* impurity(&self.parameters.criterion, &true_count, tc) * impurity(&self.parameters.criterion, &true_count, tc)
- T::from(fc).unwrap() / T::from(n).unwrap() - T::from(fc).unwrap() / T::from(n).unwrap()
* impurity(&self.parameters.criterion, &false_count, fc); * impurity(&self.parameters.criterion, false_count, fc);
if self.nodes[visitor.node].split_score == Option::None if self.nodes[visitor.node].split_score == Option::None
|| gain > self.nodes[visitor.node].split_score.unwrap() || gain > self.nodes[visitor.node].split_score.unwrap()
+1 -1
View File
@@ -280,7 +280,7 @@ impl<T: RealNumber> DecisionTreeRegressor<T> {
depth: 0, depth: 0,
}; };
let mut visitor = NodeVisitor::<T, M>::new(0, samples, &order, &x, &y_m, 1); let mut visitor = NodeVisitor::<T, M>::new(0, samples, &order, x, &y_m, 1);
let mut visitor_queue: LinkedList<NodeVisitor<'_, T, M>> = LinkedList::new(); let mut visitor_queue: LinkedList<NodeVisitor<'_, T, M>> = LinkedList::new();