Merge branch 'development' into issue-115
This commit is contained in:
@@ -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();
|
||||||
|
|||||||
@@ -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]));
|
||||||
|
|||||||
@@ -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
@@ -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
@@ -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 })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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>> {
|
||||||
|
|||||||
@@ -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,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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>> {
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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
@@ -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: ¶meters,
|
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;
|
||||||
|
|||||||
@@ -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()
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user