mirror of
https://github.com/eclipse-sailing-analytics/sailing-analytics.git
synced 2026-11-13 22:15:26 +00:00
Adjusted evaluation framework to support various transition probability
calculator types for hmm based model
This commit is contained in:
1 parent
e12212b87d
commit
9c8ced025f
7 files changed
+66
-15
No files matched your search
+2
-1
@@ -85,7 +85,8 @@ public class TwdTransitionImporter {
|
||||
|
||||
private static List<TwdTransition> getTwdTransitions(
|
||||
List<ManeuverWithProbabilisticTypeClassification> sortedManeuvers, String regattaName) {
|
||||
SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator simpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator = new SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator();
|
||||
SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator simpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator = new SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator(
|
||||
true);
|
||||
List<TwdTransition> result = new ArrayList<>(sortedManeuvers.size()
|
||||
* ManeuverTypeForClassification.values().length * ManeuverTypeForClassification.values().length);
|
||||
int maneuverIndex = 0;
|
||||
|
||||
+35
-5
@@ -15,14 +15,18 @@ import com.sap.sailing.windestimation.aggregator.advancedhmm.DistanceAndDuration
|
||||
import com.sap.sailing.windestimation.aggregator.clustering.ManeuverClassificationForClusteringImpl;
|
||||
import com.sap.sailing.windestimation.aggregator.clustering.ManeuverClusteringBasedWindEstimationTrackImpl;
|
||||
import com.sap.sailing.windestimation.aggregator.hmm.BestPathsCalculator;
|
||||
import com.sap.sailing.windestimation.aggregator.hmm.GraphNodeTransitionProbabilitiesCalculator;
|
||||
import com.sap.sailing.windestimation.aggregator.hmm.IntersectedWindRangeBasedTransitionProbabilitiesCalculator;
|
||||
import com.sap.sailing.windestimation.aggregator.hmm.ManeuverSequenceGraph;
|
||||
import com.sap.sailing.windestimation.aggregator.hmm.SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator;
|
||||
import com.sap.sailing.windestimation.aggregator.hmm.TwdTransitionClassifierBasedTransitionProbabilitiesCalculator;
|
||||
import com.sap.sailing.windestimation.aggregator.outlierremoval.MeanBasedOutlierRemovalWindEstimator;
|
||||
import com.sap.sailing.windestimation.aggregator.outlierremoval.NeighborBasedOutlierRemovalWindEstimator;
|
||||
import com.sap.sailing.windestimation.data.ManeuverTypeForClassification;
|
||||
import com.sap.sailing.windestimation.data.RaceWithEstimationData;
|
||||
import com.sap.sailing.windestimation.model.classifier.maneuver.ManeuverWithEstimatedType;
|
||||
import com.sap.sailing.windestimation.model.classifier.maneuver.ManeuverWithProbabilisticTypeClassification;
|
||||
import com.sap.sailing.windestimation.model.classifier.twdtransition.TwdTransitionClassifiersCache;
|
||||
import com.sap.sailing.windestimation.model.regressor.twdtransition.GaussianBasedTwdTransitionDistributionCache;
|
||||
import com.sap.sailing.windestimation.model.store.ModelStore;
|
||||
import com.sap.sailing.windestimation.windinference.MiddleCourseBasedTwdCalculatorImpl;
|
||||
@@ -40,9 +44,30 @@ public class ManeuverClassificationsAggregatorFactory {
|
||||
this.modelCacheKeepAliveMillis = modelCacheKeepAliveMillis;
|
||||
}
|
||||
|
||||
public ManeuverClassificationsAggregator hmm() {
|
||||
return new ManeuverSequenceGraph(
|
||||
new BestPathsCalculator(new IntersectedWindRangeBasedTransitionProbabilitiesCalculator()));
|
||||
public ManeuverClassificationsAggregator hmm(
|
||||
HmmTransitionProbabilitiesCalculator transitionProbabilitiesCalculatorType,
|
||||
boolean propagateIntersectedWindRangeOfHeadupAndBearAway) {
|
||||
GraphNodeTransitionProbabilitiesCalculator transitionProbabilitiesCalculator = null;
|
||||
switch (transitionProbabilitiesCalculatorType) {
|
||||
case SIMPLE:
|
||||
transitionProbabilitiesCalculator = new SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator(
|
||||
propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
break;
|
||||
case INTERSECTED:
|
||||
transitionProbabilitiesCalculator = new IntersectedWindRangeBasedTransitionProbabilitiesCalculator(
|
||||
propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
break;
|
||||
case CLASSIFIER:
|
||||
transitionProbabilitiesCalculator = new TwdTransitionClassifierBasedTransitionProbabilitiesCalculator(
|
||||
new TwdTransitionClassifiersCache(modelStore, modelCacheKeepAliveMillis),
|
||||
propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
break;
|
||||
case GAUSSIAN_REGRESSOR:
|
||||
transitionProbabilitiesCalculator = new DistanceAndDurationAwareWindTransitionProbabilitiesCalculator(
|
||||
new GaussianBasedTwdTransitionDistributionCache(modelStore, modelCacheKeepAliveMillis),
|
||||
propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
}
|
||||
return new ManeuverSequenceGraph(new BestPathsCalculator(transitionProbabilitiesCalculator));
|
||||
}
|
||||
|
||||
public ManeuverClassificationsAggregator clustering() {
|
||||
@@ -92,10 +117,15 @@ public class ManeuverClassificationsAggregatorFactory {
|
||||
return new NeighborBasedOutlierRemovalWindEstimator(new MiddleCourseBasedTwdCalculatorImpl());
|
||||
}
|
||||
|
||||
public ManeuverClassificationsAggregator advancedHmm() {
|
||||
public ManeuverClassificationsAggregator advancedHmm(boolean propagateIntersectedWindRangeOfHeadupAndBearAway) {
|
||||
return new AdvancedManeuverGraph(
|
||||
new AdvancedBestPathsCalculatorImpl(new DistanceAndDurationAwareWindTransitionProbabilitiesCalculator(
|
||||
new GaussianBasedTwdTransitionDistributionCache(modelStore, modelCacheKeepAliveMillis))));
|
||||
new GaussianBasedTwdTransitionDistributionCache(modelStore, modelCacheKeepAliveMillis),
|
||||
propagateIntersectedWindRangeOfHeadupAndBearAway)));
|
||||
}
|
||||
|
||||
public enum HmmTransitionProbabilitiesCalculator {
|
||||
INTERSECTED, SIMPLE, CLASSIFIER, GAUSSIAN_REGRESSOR
|
||||
}
|
||||
|
||||
}
|
||||
+7
-2
@@ -2,6 +2,7 @@ package com.sap.sailing.windestimation;
|
||||
|
||||
import com.sap.sailing.domain.maneuverdetection.CompleteManeuverCurveWithEstimationData;
|
||||
import com.sap.sailing.domain.polars.PolarDataService;
|
||||
import com.sap.sailing.windestimation.ManeuverClassificationsAggregatorFactory.HmmTransitionProbabilitiesCalculator;
|
||||
import com.sap.sailing.windestimation.data.ManeuverForEstimation;
|
||||
import com.sap.sailing.windestimation.data.RaceWithEstimationData;
|
||||
import com.sap.sailing.windestimation.data.transformer.ManeuverForEstimationTransformer;
|
||||
@@ -19,6 +20,8 @@ public class SimpleConfigurableManeuverBasedWindEstimationComponentImpl extends
|
||||
ManeuverBasedWindEstimationComponentImpl<RaceWithEstimationData<CompleteManeuverCurveWithEstimationData>> {
|
||||
|
||||
private static final int MODEL_CACHE_KEEP_ALIVE_MILLIS = 3600000;
|
||||
private static final HmmTransitionProbabilitiesCalculator transitionProbabilitiesCalculatorType = HmmTransitionProbabilitiesCalculator.INTERSECTED;
|
||||
private static final boolean propagateIntersectedWindRangeOfHeadupAndBearAway = true;
|
||||
|
||||
public SimpleConfigurableManeuverBasedWindEstimationComponentImpl(ManeuverFeatures maneuverFeatures,
|
||||
ModelStore modelStore, PolarDataService polarService,
|
||||
@@ -54,9 +57,10 @@ public class SimpleConfigurableManeuverBasedWindEstimationComponentImpl extends
|
||||
polarService, modelStore, modelCacheKeepAliveMillis);
|
||||
switch (this) {
|
||||
case HMM:
|
||||
return factory.hmm();
|
||||
return factory.hmm(transitionProbabilitiesCalculatorType,
|
||||
propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
case ADVANCED_HMM:
|
||||
return factory.advancedHmm();
|
||||
return factory.advancedHmm(propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
case CLUSTERING:
|
||||
return factory.clustering();
|
||||
case MEAN_OUTLIER:
|
||||
@@ -67,4 +71,5 @@ public class SimpleConfigurableManeuverBasedWindEstimationComponentImpl extends
|
||||
throw new IllegalArgumentException(this + " implementation type is unsupported");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
+3
-1
@@ -15,7 +15,9 @@ public class DistanceAndDurationAwareWindTransitionProbabilitiesCalculator
|
||||
private final GaussianBasedTwdTransitionDistributionCache gaussianBasedTwdTransitionDistributionCache;
|
||||
|
||||
public DistanceAndDurationAwareWindTransitionProbabilitiesCalculator(
|
||||
GaussianBasedTwdTransitionDistributionCache gaussianBasedTwdTransitionDistributionCache) {
|
||||
GaussianBasedTwdTransitionDistributionCache gaussianBasedTwdTransitionDistributionCache,
|
||||
boolean propagateIntersectedWindRangeOfHeadupAndBearAway) {
|
||||
super(propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
this.gaussianBasedTwdTransitionDistributionCache = gaussianBasedTwdTransitionDistributionCache;
|
||||
}
|
||||
|
||||
|
||||
+11
-5
@@ -15,6 +15,12 @@ public class IntersectedWindRangeBasedTransitionProbabilitiesCalculator
|
||||
|
||||
protected static final int MIN_BEATING_ANGLE_PLUS_MIN_RUNNING_ANGLE = 40;
|
||||
private static final double MAX_ABS_WIND_COURSE_DEVIATION_TOLERANCE_WITHIN_ANALYSIS_INTERVAL_IN_DEGREES = 40;
|
||||
private final boolean propagateIntersectedWindRangeOfHeadupAndBearAway;
|
||||
|
||||
public IntersectedWindRangeBasedTransitionProbabilitiesCalculator(
|
||||
boolean propagateIntersectedWindRangeOfHeadupAndBearAway) {
|
||||
this.propagateIntersectedWindRangeOfHeadupAndBearAway = propagateIntersectedWindRangeOfHeadupAndBearAway;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Pair<IntersectedWindRange, Double> mergeWindRangeAndGetTransitionProbability(GraphNode previousNode,
|
||||
@@ -26,11 +32,11 @@ public class IntersectedWindRangeBasedTransitionProbabilitiesCalculator
|
||||
double transitionProbabilityUntilCurrentNode = -1;
|
||||
IntersectedWindRange intersectedWindRangeUntilCurrentNode = null;
|
||||
for (GraphNode node : currentLevel.getLevelNodes()) {
|
||||
WindCourseRange previousWindCourseRange = previousNode
|
||||
.getManeuverType() == ManeuverTypeForClassification.BEAR_AWAY
|
||||
|| previousNode.getManeuverType() == ManeuverTypeForClassification.HEAD_UP
|
||||
? previousIntersectedWindRange
|
||||
: previousNode.getValidWindRange();
|
||||
WindCourseRange previousWindCourseRange = propagateIntersectedWindRangeOfHeadupAndBearAway
|
||||
&& (previousNode.getManeuverType() == ManeuverTypeForClassification.BEAR_AWAY
|
||||
|| previousNode.getManeuverType() == ManeuverTypeForClassification.HEAD_UP)
|
||||
? previousIntersectedWindRange
|
||||
: previousNode.getValidWindRange();
|
||||
IntersectedWindRange intersectedWindRange = previousWindCourseRange.intersect(node.getValidWindRange(),
|
||||
CombinationModeOnViolation.INTERSECTION);
|
||||
TwdTransition twdTransition = constructTwdTransition(durationPassed, distancePassed,
|
||||
|
||||
+5
@@ -6,6 +6,11 @@ import com.sap.sse.common.Bearing;
|
||||
public class SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator
|
||||
extends IntersectedWindRangeBasedTransitionProbabilitiesCalculator {
|
||||
|
||||
public SimpleIntersectedWindRangeBasedTransitionProbabilitiesCalculator(
|
||||
boolean propagateIntersectedWindRangeOfHeadupAndBearAway) {
|
||||
super(propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected WindCourseRange getJibeWindRange(ManeuverForEstimation maneuver) {
|
||||
Bearing middleCourse = maneuver.getMiddleCourse();
|
||||
|
||||
+3
-1
@@ -10,7 +10,9 @@ public class TwdTransitionClassifierBasedTransitionProbabilitiesCalculator
|
||||
private final TwdTransitionClassifiersCache twdTransitionClassifiersCache;
|
||||
|
||||
public TwdTransitionClassifierBasedTransitionProbabilitiesCalculator(
|
||||
TwdTransitionClassifiersCache twdTransitionClassifiersCache) {
|
||||
TwdTransitionClassifiersCache twdTransitionClassifiersCache,
|
||||
boolean propagateIntersectedWindRangeOfHeadupAndBearAway) {
|
||||
super(propagateIntersectedWindRangeOfHeadupAndBearAway);
|
||||
this.twdTransitionClassifiersCache = twdTransitionClassifiersCache;
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user