Is it possible to access the graphs produced by WekaForecaster API as visible in Weka Explorer. I see that the API per se does not have any function access. Thanks!
I figured out the answer.
Create a TSEvaluation object
Call evaluateForecaster(TSForecaster forecaster, boolean buildModel, java.io.PrintStream... progress)
Call graphFutureForecastOnTesting(GraphDriver driver, TSForecaster forecaster, java.util.List targetNames) which returns a JPanel
For example-
// Your instances
Instances train;
// Your WekaForecaster
WekaForecaster forecaster;
...
// Custom hold out set size
int holdOutSetSize = 1;
// Init evaluator
TSEvaluation eval = new TSEvaluation(train, holdOutSetSize);
boolean buildModel = false;
// Evaluate the forecaster
eval.evaluateForecaster(forecaster, buildModel, System.out);
// Get graph in JPanel after evaluation on training with custom hold out set size
JPanel trainGraph = eval.graphFutureForecastOnTraining(GraphDriver.getDefaultDriver(),
forecaster, AbstractForecaster.
stringToList(forecaster.getFieldsToForecast()));
Cheers!
References:
http://weka.sourceforge.net/doc.packages/timeseriesForecasting/weka/classifiers/timeseries/eval/TSEvaluation.html
Related
What should the return value in a map function be for the resulting mono to be MonoEmpty?
example:
Mono<Void> empty = Mono.just("ping").map(s-> ????);
or should the pattern be to do a flatMap if I need this functionality?
Mono<Void> empty = Mono.just("ping").flatMap(s-> Mono.empty());
If you need a transformation to take place most of the time, but be empty on some condition, use handle (which has the capacity to map to nothing without the overhead of flatMap):
Mono<String> emptyIfNotPing = Mono.just("ping")
.handle((t, sink) -> {
if (t.equals("ping")) sink.next("pong");
else sink.complete();
});
If you never care about the elements and just want to propagate terminal signals (onComplete and onError), you can either use ignoreElement (which maintains the generic type) or then() (which turns into a Mono<Void>):
Mono<String> source = Mono.just("foo");
Mono<Void> emptyWithTypeLoss = source.then();
Mono<String> emptyWithoutTypeLoss = source.ignoreElement();
I have a BehaviorSubject that I would like to reset - by that I mean I want the latest value to not be available, just as if it was just created.
I don't seem to see an API to do this but I suppose there is another way to achieve the same result?
My desired behavior is that I need to emit events, and I'd like subscribers to get the latest event when they subscribe - if a particular manager is in a 'started' state. But when this manager is 'stopped' the latest event should not be available (just like if it was never started in the first place).
I assume you want to clear the BehaviorSubject (because otherwise don't call onComplete on it). That is not supported but you can achieve a similar effect by having a current value that is ignored by consumers:
public static final Object EMPTY = new Object();
BehaviorSubject<Object> subject = BehaviorSubject.createDefault(EMPTY);
Observable<YourType> obs = subject.filter(v -> v != EMPTY).cast(YourType.class);
obs.subscribe(System.out::println);
// send normal data
subject.onNext(1);
subject.onNext(2);
// clear the subject
subject.onNext(EMPTY);
// this should not print anything
obs.subscribe(System.out::println);
Another method of switching the value of an observable on and off is to use switchMap() to flip between the actual observable and an empty one.
Let's assume you have a manager object, and it has a observable that shows its state. Then,
subjectObservable = manager.getStateObservable()
.switchMap( state -> state == ON ? subject : Observable.never() );
will only emit values while the manager is in the ON state.
Just use setTimeout like this:
setOtpoint(value) {
this._setOption.next(value);
// Clear BehaviorSubject after emit value
setTimeout(() => {
this._setOption.next(null);
}, 100);
}
I find out a better solution for some cases and is:
subject.skiplast(1)
it can work to clean the last position on stream that is being retained because of the BehaviorSubject "behavior"
A problem with #akarnokd's answer is that the .cast prevents YourType from being an interface or a generic type such as List<String>.
Another option is to filter on a boolean field that you can switch on and off.
private BehaviorSubject<PandoraApp> subject = BehaviorSubject.create();
private boolean enabled = true;
Observable<PandoraApp> observable = subject.filter(v -> enabled);
If methods are being called on different threads you can use AtomicBoolean for the filter flag.
Here is my lib for this:
implementation "com.github.kolyall:rxjava2-empty:1.0.36"
Example:
private val myBehaviorSubject = BehaviorSubjectOptional.createOptional<MyItem?>()
errorBehaviorSubject.toObservable()
.subscribe{ item-> Log.d("onNext1", "item = $item")}
var item:MyItem? = MyItem()
myBehaviorSubject.onNextOptional(item)
//For reset:
myBehaviorSubject.clear()
//OR
item = null
myBehaviorSubject.onNextOptional(item)
errorBehaviorSubject.toObservable()
.subscribe{ item-> Log.d("onNext2", "item = $item")}
I'm using a sliding time window of X size and Y period. In order to mark the output of each window, I'd like to get the timestamp of the current window of PCollection.
PCollection<T> windowedInput = input
.apply(Window<T>into(
SlidingWindows.of(Duration.standardMinutes(10))
.every(Duration.standardMinutes(1))));
// Extract key from each input and run a function per group.
//
// Q: ExtractKey() depends on the window triggered time.
// How can I pass the timestamp of windowedInputs to ExtractKey()?
PCollection<KV<K, Iterable<T>>> groupedInputs = windowedInputs
.apply(ParDo.of(new ExtractKey()))
.apply(GroupByKey.<K, Ts>create());
// Run Story clustering and write outputs.
//
// Q: Also I'd like to add a window timestamp suffix to the output.
// How can I pass (or get) the timestamp to SomeDoFn()?
PCollection<String> results = groupedInputs.apply(ParDo.of(new SomeDoFn()));
A DoFn is allowed to access the window of the current element via an optional BoundedWindow parameter on the #ProcessElement method:
class SomeDoFn extends DoFn<KV<K, Iterable<T>>, String> {
#ProcessElement
public void process(ProcessContext c, BoundedWindow window) {
...
}
}
So basically, while I'm not new to this, I've somewhat forgotten the set up for adding nodes to a linear linked list. Basically, I have a cap for the number of nodes that I can add, and currently, I have:
"storage" is a binary tree with ONLY next nodes.
private void addToStorage(Node node){
if(storage.size() <= maxSize) // Current Size of storage
{
node.data = null;
node.prev = null;
node.next = storage;
storage = node;
}
}
Is this the correct way to implement this function? If not, how should I go about doing it using a similar method?
Considering that you are able to retrieve the last node stored somewhere inside that storage object or from somewere else:
add(Node node) {
if(prevNode != null)
prevNode.next = node;
node.prev = prevNode;
node.next = null;
}
Also, there's no point of nulling the data since it's usually set before calling add.
Ok so here is a clearer explanation :
I have now understood that I need to use sparse ou SparseMultigraph type to be able to have bidirectional edges so I have changed my GraphML class as such :
class GraphML
{
public GraphML(String filename) throws ParserConfigurationException, SAXException, IOException
{
//Step 1 we make a new GraphML Reader. We want a directed Graph of type node and edge.
GraphMLReader<SparseMultigraph<node, edge>, node, edge> gmlr =
new GraphMLReader<SparseMultigraph<node, edge>, node, edge>(new VertexFactory(), new EdgeFactory());
//Next we need a Graph to store the data that we are reading in from GraphML. This is also a directed Graph
// because it needs to match to the type of graph we are reading in.
final SparseMultigraph<node, edge> graph = new SparseMultigraph<node, edge>();
gmlr.load(filename, graph);
// gmlr.load(filename, graph); //Here we read in our graph. filename is our .graphml file, and graph is where we
// will store our graph.
BidiMap<node, String> vertex_ids = gmlr.getVertexIDs(); //The vertexIDs are stored in a BidiMap.
Map<String, GraphMLMetadata<node>> vertex_color = gmlr.getVertexMetadata(); //Our vertex Metadata is stored in a map.
Map<String, GraphMLMetadata<edge>> edge_meta = gmlr.getEdgeMetadata(); // Our edge Metadata is stored in a map.
// Here we iterate through our vertices, n, and we set the value and the color of our nodes from the data we have
// in the vertex_ids map and vertex_color map.
for (node n : graph.getVertices())
{
n.setValue(vertex_ids.get(n)); //Set the value of the node to the vertex_id which was read in from the GraphML Reader.
n.setColor(vertex_color.get("d0").transformer.transform(n)); // Set the color, which we get from the Map, vertex_color.
//Let's print out the data so we can get a good understanding of what we've got going on.
System.out.println("ID: "+n.getID()+", Value: "+n.getValue()+", Color: "+n.getColor());
}
// Just as we added the vertices to the graph, we add the edges as well.
for (edge e : graph.getEdges())
{
e.setValue(edge_meta.get("d1").transformer.transform(e)); //Set the edge's value.
System.out.println("Edge ID: "+e.getID());
}
TreeBuilder treeBuilder = new TreeBuilder(graph);
// create a simple graph for the demo:
//First we make a VisualizationViewer, of type node, edge. We give it our Layout, and the Layout takes a graph in it's constructor.
//VisualizationViewer<node, edge> vv = new VisualizationViewer<node, edge>(new FRLayout<node, edge>(graph));
VisualizationViewer<node, edge> vv = new VisualizationViewer<node, edge>(new TreeLayout<node, edge>(treeBuilder.getTree()));
//Next we set some rendering properties. First we want to color the vertices, so we provide our own vertexPainter.
vv.getRenderContext().setVertexFillPaintTransformer(new vertexPainter());
//Then we want to provide labels to our nodes, Jung provides a nice function which makes the graph use a vertex's ToString function
//as it's way of labelling. We do the same for the edge. Look at the edge and node classes for their ToString function.
vv.getRenderContext().setVertexLabelTransformer(new ToStringLabeller<node>());
vv.getRenderContext().setEdgeLabelTransformer(new ToStringLabeller<edge>());
// Next we do some Java stuff, we create a frame to hold the graph
final JFrame frame = new JFrame();
frame.setTitle("GraphMLReader for Trees - Reading in Attributes"); //Set the title of our window.
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); //Give a close operation.
//Here we get the contentPane of our frame and add our a VisualizationViewer, vv.
frame.getContentPane().add(vv);
//Finally, we pack it to make sure it is pretty, and set the frame visible. Voila.
frame.pack();
frame.setVisible(true);
}
}
And then changed my tree builder class constructor to SparseMultigraph :
public class TreeBuilder
{
DelegateForest<node,edge> mTree;
TreeBuilder(SparseMultigraph<node, edge> graph)
{
mTree = new DelegateForest<node, edge>();
for (node n : graph.getVertices())
{
mTree.addVertex(n);
}
for (edge e : graph.getEdges())
{
mTree.addEdge(e, graph.getSource(e),graph.getDest(e));
}
}
public DelegateForest<node, edge> getTree()
{
return mTree;
}
}
when I run my Main class :
public class Main
{
public static void main(String[] args) throws ParserConfigurationException, SAXException, IOException
{
String filename = "attributes.graphml";
if(args.length > 0)
filename = args[0];
new GraphML(filename);
}
}
I don't get an error but edges are not present (node are their in the graph but not properly displayed).
Thanks
Zied