1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//! Example demonstrating FunctionTransformer for custom data transformations
//!
//! NOTE: FunctionTransformer is not yet implemented in sklears_preprocessing.
//! This example is currently non-functional and serves as a placeholder for future implementation.
// Commented out: FunctionTransformer not yet implemented
// use scirs2_core::ndarray::{array, Array2};
// use sklears_core::{error::Result, traits::Transform, types::Float};
// use sklears_preprocessing::{transforms, FunctionTransformer};
// Dummy type for when no inverse function is provided
// type NoInverse = fn(&Array2<Float>) -> Result<Array2<Float>>;
/*
// Original example code - commented out until FunctionTransformer is implemented
fn _example_main() -> Result<()> {
println!("=== FunctionTransformer Example ===\n");
// Sample data
let x = array![
[1.0, 2.0, 3.0],
[4.0, 5.0, 6.0],
[7.0, 8.0, 9.0],
[10.0, 11.0, 12.0],
];
println!("Original data:");
println!("{:.2}\n", x);
// Example 1: Log transformation
println!("1. Log transformation:");
let log_transformer = FunctionTransformer::<_, NoInverse>::new(transforms::log).fit(&x, &())?;
let x_log = log_transformer.transform(&x)?;
println!("{:.2}\n", x_log);
// Example 2: Square root transformation
println!("2. Square root transformation:");
let sqrt_transformer =
FunctionTransformer::<_, NoInverse>::new(transforms::sqrt).fit(&x, &())?;
let x_sqrt = sqrt_transformer.transform(&x)?;
println!("{:.2}\n", x_sqrt);
// Example 3: Custom transformation (z-score normalization per column)
println!("3. Custom z-score normalization:");
let zscore_fn = |data: &Array2<Float>| -> Result<Array2<Float>> {
let mut result = data.clone();
let n_features = data.ncols();
for j in 0..n_features {
let col = data.column(j);
let mean = col.mean().unwrap_or(0.0);
let std = col.std(0.0);
if std > 0.0 {
for i in 0..data.nrows() {
result[[i, j]] = (result[[i, j]] - mean) / std;
}
}
}
Ok(result)
};
let zscore_transformer = FunctionTransformer::<_, NoInverse>::new(zscore_fn).fit(&x, &())?;
let x_zscore = zscore_transformer.transform(&x)?;
println!("{:.2}\n", x_zscore);
// Example 4: Log1p and Expm1 with inverse
println!("4. Log1p transformation with inverse:");
let data_with_zeros = array![[0.0, 1.0, 2.0], [3.0, 4.0, 5.0],];
let log1p_transformer = FunctionTransformer::new(transforms::log1p)
.inverse_func(transforms::expm1)
.check_inverse(true)
.fit(&data_with_zeros, &())?;
let x_log1p = log1p_transformer.transform(&data_with_zeros)?;
println!("After log1p:");
println!("{:.4}\n", x_log1p);
// Example 5: Clipping values
println!("5. Clipping transformation:");
let data_with_outliers = array![[-10.0, 0.0, 5.0], [1.0, 100.0, 3.0], [2.0, 4.0, 200.0],];
// Custom clip function (closures need special handling)
let clip_fn =
|x: &Array2<Float>| -> Result<Array2<Float>> { Ok(x.mapv(|val| val.clamp(0.0, 10.0))) };
let clip_transformer =
FunctionTransformer::<_, NoInverse>::new(clip_fn).fit(&data_with_outliers, &())?;
let x_clipped = clip_transformer.transform(&data_with_outliers)?;
println!("Original with outliers:");
println!("{:.1}", data_with_outliers);
println!("\nAfter clipping to [0, 10]:");
println!("{:.1}\n", x_clipped);
// Example 6: Sigmoid transformation for logistic scaling
println!("6. Sigmoid transformation:");
let logit_data = array![[-2.0, -1.0, 0.0], [1.0, 2.0, 3.0],];
let sigmoid_transformer =
FunctionTransformer::<_, NoInverse>::new(transforms::sigmoid).fit(&logit_data, &())?;
let x_sigmoid = sigmoid_transformer.transform(&logit_data)?;
println!("Logit values: {:?}", logit_data);
println!("After sigmoid:");
println!("{:.4}\n", x_sigmoid);
// Example 7: Combining multiple transformations
println!("7. Pipeline of transformations:");
// First apply log1p
let x_step1 = FunctionTransformer::<_, NoInverse>::new(transforms::log1p)
.fit(&x, &())?
.transform(&x)?;
// Then apply a custom scaling by 10
let scale_fn =
|data: &Array2<Float>| -> Result<Array2<Float>> { Ok(data.mapv(|val| val * 10.0)) };
let x_step2 = FunctionTransformer::<_, NoInverse>::new(scale_fn)
.fit(&x_step1, &())?
.transform(&x_step1)?;
println!("After log1p then scale by 10:");
println!("{:.2}\n", x_step2);
println!("FunctionTransformer provides flexibility for any stateless transformation!");
Ok(())
}
*/