use ndarray::{Array1, Array2};
use crate::error::{Result, SklearnError};
pub trait Estimator {
type Input;
type Target;
type Model: Predictor<Input = Self::Input>;
fn fit(&self, x: &Self::Input, y: &Self::Target) -> Result<Self::Model>;
}
pub trait Predictor {
type Input;
type Output;
fn predict(&self, x: &Self::Input) -> Result<Self::Output>;
}
pub trait Transformer {
type Input;
type Output;
fn fit(&self, x: &Self::Input) -> Result<Self>
where
Self: Sized;
fn transform(&self, x: &Self::Input) -> Result<Self::Output>;
fn fit_transform(&mut self, x: &Self::Input) -> Result<Self::Output>
where
Self: Sized,
{
let _ = self.fit(x)?;
self.transform(x)
}
}
pub fn validate_features(x: &Array2<f64>) -> Result<()> {
if x.nrows() == 0 {
return Err(SklearnError::ShapeMismatch {
expected: "至少一行".to_string(),
actual: "0行".to_string(),
});
}
if x.ncols() == 0 {
return Err(SklearnError::ShapeMismatch {
expected: "至少一列".to_string(),
actual: "0列".to_string(),
});
}
for &val in x.iter() {
if val.is_nan() || val.is_infinite() {
return Err(SklearnError::InvalidData);
}
}
Ok(())
}
pub fn validate_target(y: &Array1<f64>) -> Result<()> {
if y.is_empty() {
return Err(SklearnError::ShapeMismatch {
expected: "非空数组".to_string(),
actual: "空数组".to_string(),
});
}
for &val in y.iter() {
if val.is_nan() || val.is_infinite() {
return Err(SklearnError::InvalidData);
}
}
Ok(())
}