/
MathFloatTransform.java
86 lines (76 loc) · 2.68 KB
/
MathFloatTransform.java
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
package com.airbnb.aerosolve.core.transforms;
import com.airbnb.aerosolve.core.FeatureVector;
import com.airbnb.aerosolve.core.util.Util;
import com.google.common.base.Optional;
import com.typesafe.config.Config;
import java.util.List;
import java.util.Map;
import java.util.function.DoubleFunction;
/**
* Apply given Math function on specified float features defined by fieldName1 and keys
* fieldName1: feature family name
* keys: feature names
* outputName: output feature family name (feature names or keys remain the same)
* function: a string that specified the function that is going to apply to the given feature
*/
public class MathFloatTransform implements Transform {
private String fieldName1; // feature family name
private List<String> keys; // feature names
private String outputName; // output feature family name
private String functionName; // a string that specified the function that is going to apply to the given feature
private Optional<DoubleFunction<Double>> func;
@Override
public void configure(Config config, String key) {
fieldName1 = config.getString(key + ".field1");
if (config.hasPath(key + ".keys")) {
keys = config.getStringList(key + ".keys");
}
outputName = config.getString(key + ".output");
functionName = config.getString(key + ".function");
func = getFunction();
}
@Override
public void doTransform(FeatureVector featureVector) {
Map<String, Map<String, Double>> floatFeatures = featureVector.getFloatFeatures();
if (keys.isEmpty()) {
return;
}
if (!func.isPresent()) {
return;
}
if (floatFeatures == null) {
return;
}
Map<String, Double> feature1 = floatFeatures.get(fieldName1);
if (feature1 == null) {
return;
}
Map<String, Double> output = Util.getOrCreateFloatFeature(outputName, floatFeatures);
for (String key : keys) {
Double v = feature1.get(key);
if (v != null) {
Double result = func.get().apply(v);
if (!result.isNaN() && !result.isInfinite()) {
output.put(key, result);
}
}
}
}
private Optional<DoubleFunction<Double>> getFunction() {
switch (functionName) {
case "sin":
return Optional.of((double x) -> Math.sin(x));
case "cos":
return Optional.of((double x) -> Math.cos(x));
case "log10":
// return the original value if x <= 0
return Optional.of((double x) -> Math.log10(x));
case "log":
// return the original value if x <= 0
return Optional.of((double x) -> Math.log(x));
case "abs":
return Optional.of((double x) -> Math.abs(x));
}
return Optional.<DoubleFunction<Double>>absent();
}
}