-
Notifications
You must be signed in to change notification settings - Fork 1.9k
Prediction engine for time series. #1618
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
||
if (rows.Count == 0 && outputRow is IStatefulRow) | ||
rows.Add((IStatefulRow)outputRow); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this feels like an unroll of 1 level of recursion. Can't GetStatefulRows
also handle case where mapper is not a CompositeRowToRowMapper
? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🕐
…to timeseriesengine
…to timeseriesengine
if (prediction == null) | ||
prediction = new TDst(); | ||
|
||
//Update State. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
//Up [](start = 12, length = 4)
// Update state.
and // Predict.
#Resolved
/// to get the dependencies on input columns and the getters for the output columns, given an active set of output columns. | ||
/// </summary> | ||
|
||
public sealed class TimeSeriesRowToRowMapperTransform : RowToRowTransformBase, IRowToRowMapper, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TimeSeriesRowToRowMapperTransform [](start = 24, length = 33)
Why did you need to clone it, and why is it public? #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// <summary> | ||
/// Run prediction pipeline on one example. | ||
/// </summary> | ||
/// <param name="example">The example to run on.</param> | ||
/// <param name="prediction">The object to store the prediction in. If it's <c>null</c>, a new one will be created, otherwise the old one | ||
/// is reused.</param> | ||
public void Predict(TSrc example, ref TDst prediction) | ||
public virtual void Predict(TSrc example, ref TDst prediction) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
virtual [](start = 15, length = 7)
If 2 existing implementations are dissimilar, what's the value in having a virtual method? Make it abstract
#Resolved
@@ -7,30 +7,40 @@ | |||
|
|||
namespace Microsoft.ML.Runtime.Data | |||
{ | |||
public sealed class PredictionFunction<TSrc, TDst> : PredictionFunctionBase<TSrc, TDst> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PredictionFunction [](start = 24, length = 18)
I honestly don't understand the purpose of PredictionFunction
. Why introduce a hierarchy of useless classes? I would much rather rename PredictionEngine
to PredictionFunction
and be done with it.
It doesn't have to be done in this PR, but could you just use PredictionEngine
only, to simplify that future change? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm with you 100% on this. I have the same thought when I was making this change.
In reply to: 236007234 [](ancestors = 236007234)
} | ||
|
||
internal virtual void CreatePredictionEngine(IHostEnvironment env, ITransformer transformer, out PredictionEngineBase<TSrc, TDst> engine) => |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CreatePredictionEngine [](start = 30, length = 22)
use return value instead of out
parameter #Resolved
/// <summary> | ||
/// A chain of transformers (possibly empty) that end with a <typeparamref name="TLastTransformer"/>. | ||
/// For an empty chain, <typeparamref name="TLastTransformer"/> is always <see cref="ITransformer"/>. | ||
/// </summary> | ||
public sealed class TransformerChain<TLastTransformer> : ITransformer, ICanSaveModel, IEnumerable<ITransformer> | ||
public sealed class TransformerChain<TLastTransformer> : ITransformer, ICanSaveModel, IEnumerable<ITransformer>, ITransformerAccessor | ||
where TLastTransformer : class, ITransformer |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is confusing. You now can access the inner transformers in 3 ways: via foreach
(as an IEnumerable
), via the internal field Transformers
and via ITransformerAccessor.Transformers
. Let's reduce it to one. Maybe make in an IEnumerable
of pairs, if you need access to scopes
#Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or you could make Transformers
and Scopes
public and IReadOnlyList
s
In reply to: 236007659 [](ancestors = 236007659)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I created this interface so that I can access transformers and scope from an ITransfomer reference because casting ITransfomer to TransformerChain is messy.
In reply to: 236007746 [](ancestors = 236007746,236007659)
@@ -306,10 +307,10 @@ public abstract class AnomalyDetectionStateBase : StateBase | |||
protected SequentialAnomalyDetectionTransformBase<TInput, TState> Parent; | |||
|
|||
// A windowed buffer to cache the update values to the martingale score in the log scale. | |||
private FixedSizeQueue<Double> _logMartingaleUpdateBuffer; | |||
private FixedSizeQueue<Double> LogMartingaleUpdateBuffer { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LogMartingaleUpdateBuffer [](start = 43, length = 25)
why this change? #Resolved
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
also, could you add this assembly to be tracked by RoboTom?
In reply to: 236008010 [](ancestors = 236008010)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need this value for saving the state in the case of IID. I will add TS binary to be tracked by RoboTom.
In reply to: 236008263 [](ancestors = 236008263,236008010)
public bool IsRowToRowMapper => false; | ||
public bool IsRowToRowMapper => true; | ||
|
||
public TState StateRef{ get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
public TState StateRef{ get; set; } [](start = 8, length = 35)
I don't see this as a good idea at all.
The whole cloning mechanism could be implemented completely internally, without making anything public, or mutable. Just don't use MemberwiseClone
, and write it yourself. This also has the benefit of self-documenting what's being cloned and how. #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you'll need to revert your changes to |
{ | ||
private ValuePinger[][] _pingers; | ||
private int _rowPosition; | ||
public ITransformer CheckPoint => Transformer; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Transformer [](start = 42, length = 11)
This would mean that if you checkpoint something, it's a mutable object. As far as I recall, we agreed to keep mutable transformers completely inside the prediction engine. This means that you need to CloneTransformers
here.
Also, make it a method: ITransformer GetCurrentTransformer()
or something like this. #Pending
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm confused but please help me understand your concern here. Isn't that what I'm doing below? I have changed the API for checkpointing where the user passes a modelpath and prediction engine writes the model with updated state there.
In reply to: 236009638 [](ancestors = 236009638)
I finished reviewing the iteration 24 on 11/23. This code still has minor cleanup needed, but I'm more concerned of whether the batch prediction is affected (for some reason you had to skip the time series tests). #Resolved |
Thanks, Pete. Batch Prediction is not affected, I have enabled batch prediction tests and they are passing. In reply to: 441307172 [](ancestors = 441307172) |
Prediction engine for time series that updates the time series transform state at the time of prediction. Next iteration will add more tests.