|
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |
java.lang.Object | +--norsys.netica.Generic | +--norsys.netica.Net
A Bayesian belief network or decision network.
Field Summary | |
static int |
BELIEF_UPDATE
A form of autoUpdate. |
static long |
FIRST_CASE
Pass this to read the first case. |
static long |
NEXT_CASE
Pass this to read the case following the last case read. |
static long |
NO_MORE_CASES
Returned by Netica when trying to read past the last case. |
Fields inherited from class norsys.netica.Generic |
NAME_MAX |
Constructor Summary | |
Net()
Creates and returns a new net, initially having no nodes, and places it in the current default Environ (see getDefaultEnviron). |
|
Net(Environ env)
Creates and returns a new net, initially having no nodes. |
|
Net(Streamer inStream)
Reads a net from inStream, and returns the new net read, or throws a Netica Exception, if reading was impossible. |
Method Summary | |
void |
absorb(NodeList nodeList)
Absorbs the passed nodes, so that they are removed from the net, but the net's overall joint probability distribution for the remaining nodes is unchanged. |
void |
compile()
Compiles this net for fast belief updating (i.e., junction tree propagation). |
void |
delete()
Deprecated. Call |
NodeList |
duplicateNodes(NodeList nodeList)
Duplicates the nodes in nodeList, and puts the duplicates in this net. |
static NodeList |
duplicateNodes(NodeList nodeList,
Net newNet)
Deprecated. |
void |
finalize()
Removes this net from the system, and releases all resources it uses (e.g., frees memory), including all its substructures (e.g., nodes). |
int |
generateRandomCase(NodeList nodeList,
int method,
double timeout)
Generate a random case by simulation. |
static java.util.Vector |
getAllNets(Environ env)
Retrieves from the given env a Vector of all the Nets defined in that Environ. |
int |
getAutoUpdate()
Returns this net's current auto-updating value. |
static java.lang.String |
getConstructorClass()
Retrieves the classname of the class that Netica-J uses when automatically constructing new Nets. |
static java.lang.String |
getConstructorClassName()
Deprecated. |
NodeList |
getElimOrder()
Returns a list of the nodes of this net in their "elimination order" (which is used for triangulation in the compilation of this net), or null if there is no order currently associated with this net. |
java.lang.String |
getFileName()
Returns the name of the file (including full path) that this net was last written to or read from. |
double |
getFindingsProbability()
Returns the joint probability of the findings entered into net so far (including any negative or likelihood findings). |
double |
getJointProbability(NodeList nodeList,
int[] nodeStates)
Returns the joint probability that each node in nodeList is in the corresponding state of nodeStates, given the findings currently entered in the Bayes net. |
int[] |
getMostProbableConfig(NodeList nodeList)
Finds the most probable configuration, also known as the most probable explanation (MPE), for all the nodes in the net. |
Node |
getNode(java.lang.String nodeName)
Returns the node of this net which has a name exactly matching name (case sensitive comparison). |
NodeList |
getNodes()
Returns a list of all the nodes in this net. |
void |
optimizeDecisions(NodeList nodeList)
Deprecated. |
void |
readCase(long[] casePosn,
Streamer file,
NodeList nodeList,
long[] idNum,
double[] freq)
Reads a set of findings (i.e., a case) from a file containing one or more cases. |
java.lang.String |
reportJunctionTree()
Returns a string containing a report of the junction tree for this net, similar to that produced by the Netica Application operation "Report -> Junction Tree". |
void |
retractFindings()
Retracts all findings (i.e., the current case) from all the nodes in this net, except "constant" nodes (use |
void |
reviseCPTsByCaseFile(Streamer file,
NodeList nodeList,
double degree)
Revises the CPTs of these nodes, to account for the cases in the given file. |
void |
reviseCPTsByFindings(NodeList nodeList,
double degree)
Revises the CPTs of these nodes, to account for the currently entered case. |
void |
setAutoUpdate(int autoupdate)
Turns auto-updating on or off. |
static void |
setConstructorClass(java.lang.String netClassNm)
Sets the classname that Netica-J will use to independently construct Nets. |
static void |
setConstructorClassName(java.lang.String netClassNm)
Deprecated. |
void |
setElimOrder(NodeList elimOrder)
Sets an "Elimination order" of all the nodes in this net, used to guide compiling to find an efficient junction tree. |
double |
sizeCompiled()
Returns the total size of the internal structure created by compiling a net (i.e., the junction tree, including sepsets), considering the findings currently entered. |
void |
uncompile()
Releases the resources (e.g., memory) used by a compiled net. |
void |
write(Streamer outStream)
Writes this net to a stream specified by outStream. |
long |
writeCase(NodeList nodeList,
Streamer file,
long idNum,
double freq)
Saves in file the set of findings currently entered in nodeList, so that later they can be read back with readCase. |
Methods inherited from class norsys.netica.Generic |
addListener, eventOccurred, getComment, getEnviron, getName, getNthUserField, getTitle, getUserData, getUserField, removeListener, setComment, setName, setTitle, setUserData, setUserField, toString, user |
Methods inherited from class java.lang.Object |
clone, equals, getClass, hashCode, notify, notifyAll, wait, wait, wait |
Field Detail |
public static final long FIRST_CASE
public static final long NEXT_CASE
public static final long NO_MORE_CASES
public static final int BELIEF_UPDATE
Constructor Detail |
public Net(Environ env) throws NeticaException
A default name of "Unnamed_#" will be assigned to the net, where '#' is an integer beginning from 1. It is suggested you later change the name using Generic.setName
.
Parameters:
Environ | env | The Environ in which this new net will be placed. |
finalize | (reverse operation) Frees the memory used by a net | |
Net() | Creates the net in the default Environ | |
Net(Streamer) | Create a net, by reading it from a stream | |
getAllNets | Retrieve all nets created so far | |
Generic.setName | Set the name | |
Node | Add nodes to the new net | |
setAutoUpdate | Good to set this immediately after creating net, since the default value varies between Netica versions |
public Net() throws NeticaException
public Net(Streamer inStream) throws NeticaException
NeticaError.getWarnings
.
If there were findings entered when the net was written to file, they will be present after reading, so you may want to do a retractFindings right after reading the net.
The Net will be created in the same Environ as inStream is in.
Parameters:
Streamer | inStream | The stream to read from |
write | Saves a net to file in a format understood by this constructor | |
getFileName | Later retrieve the name of the file that net was read from |
See write
Method Detail |
public static java.lang.String getConstructorClassName()
Net.getConstructorClass
.public static java.lang.String getConstructorClass()
setConstructorClass | Set the className to be used for this purpose. |
public static void setConstructorClassName(java.lang.String netClassNm) throws NeticaException
Net.setConstructorClass
.public static void setConstructorClass(java.lang.String netClassNm) throws NeticaException
If Netica-J has to construct a Net as a part of some operation (where you don't explicitly call a constructor), this is the class it will use. For example, this determines the type of Nets returned by getAllNets.
If you would like Netica to use a class other than norsys.netica.Net, say a class of your own that extends norsys.netica.Net, then use this method to tell Netica which class to use. The class must be available on the CLASSPATH, must extend norsys.netica.Net, and must have a default (parameterless) constructor; otherwise a NeticaException will be thrown.
Parameters:
String | netClassNm | The name of a class, available on the CLASSPATH, that is an instance or extension of norsys.netica.Net |
getConstructorClass | Retrieve the name of the current Class used for this purpose. | |
Node.setConstructorClass | Same for Nodes. |
Net.setConstructorClass("com.myCompany.myProject.MyNet"); MyNet net = (MyNet) new Net();where ../com/myCompany/myProject/MyNet.java looks like:/* * MyNet.java * * Example of how to extend norsys.netica.Net. */ package com.myCompany.myProject; import norsys.netica.*; public class MyNet extends Net { String myStuff = "shoes"; // your fields public MyNet() throws NeticaException { super(); } public MyNet (Environ env) throws NeticaException { super (env); } public MyNet (Streamer inStream) throws NeticaException { super (inStream); } }
public void compile() throws NeticaException
If the net is an auto-update net (see setAutoUpdate) then belief updating will be done immediately afterwards, but if it isn't, then updating won't be done until you request a belief (e.g. with getBeliefs).
When the net is compiled, first an "elimination ordering" is determined, which is a list giving all the nodes of the net in some order, and using that list a "junction tree" of cliques is formed. The efficiency of the junction tree may depend greatly on the elimination ordering used, so it is important to find a good elimination ordering. You can determine the elimination ordering used by calling getElimOrder, and you can control it by calling setElimOrder before calling compile.
Calling compile after the net is already compiled has no effect, unless the net or its elimination ordering has been changed, in which case the net will be recompiled.
Version:
uncompile | (reverse operation) Releases memory used by a compiled net | |
getBeliefs | Use the compiled net to find new beliefs given findings | |
sizeCompiled | Size and speed of the junction tree formed during compiling | |
setElimOrder | Set the elimination ordering to use when compiling the net | |
getElimOrder | Obtain the elimination ordering used to compile the net | |
reportJunctionTree | Print out the junction tree formed during compiling | |
setAutoUpdate | Have compiled net automatically find new beliefs when findings entered | |
setMaxMemoryUsage | In case this method is consuming too much memory |
public void uncompile() throws NeticaException
It doesn't change the elimination ordering.
Calling uncompile when the net is not compiled has no effect.
sizeCompiled can be used to determine how much memory will be released.
Version:
compile | (reverse operation) | |
sizeCompiled | To determine how much memory will be released | |
finalize | Discard the whole Net |
public Node getNode(java.lang.String nodeName) throws NeticaException
name can be any string; it need not be a legal IDname (of course if is not legal, null will be returned).
To search a node list for a node with a given name, see the FindNodeNamed example below.
Parameters:
String | name | The name of the node sought. |
Generic.getName | (inverse method) Returns the name of the node |
Example #2:The following method is available in NetEx.java which extends Net.java:/** * Find a node by name. Like getNode(String nodeName), except that * throws a NeticaException if the name doesn't exist. * @param name The name of the node sought * @returns The node with that name */ public Node getExistingNode (String nodeName) throws NeticaException { Node node = getNode (nodeName); if (node == null){ throw new NeticaException ("There is no node named " + nodeName + " in net " + getName()); } return node; }
The following method is available in NodeListEx.java which extends NodeList.java:/** * Returns the index of the node identified by name within this list of nodes, * or -1, if it doesn't appear. * @param name the name of the node sought * @returns the index of the node with that name, or -1 if there isn't one */ public int findNodeNamed (String name) throws NeticaException { Net net = getNet(); Node node = net.getNode (name); if (node == null) return -1; return indexOf (node); }
public void finalize() throws NeticaException
Called by the garbage collector, when this net can no longer be referenced. However, you may wish to call it directly to ensure or hasten the freeing of native resources.
Version:
Node.delete | Removes a node from a net, and releases the memory it uses |
finalize
in class java.lang.Object
public void delete() throws NeticaException
finalize
instead. This method will be phased out.
public int generateRandomCase(NodeList nodeList, int method, double timeout) throws NeticaException
Generates a random case for nodeList (i.e., positive findings for each of them), by sampling from a probability distribution matching that of the net containing nodeList, and conditioned on all findings already entered in the net.
timeout indicates how much time to allocate for the task (in relative units). If it cannot finish in time, it will return a negative quantity (no Netica exception will be thrown). If method is 1, or no findings are entered, then it always returns successfully, and within a fixed amount of time, so then timeout is ignored.
If method is 2, then forward sampling is used. This evaluates equations directly if they are available, rather than just using CPT entries (which may just approximate the equation). However, it uses a rejection method, so it may be very slow if the findings currently entered are improbable.
If method is 1, then the net must be compiled, and the junction tree is used to do very fast sampling with no rejections (i.e. findings don't slow it down).
If method is 0 (the recommended value), then the default method is used. Currently this is method 2 if rejections won't be a problem or the net is uncompiled, otherwise method 1.
Parameters:
NodeList | nodeList | The nodes to include for the random case. | ||
int | method | The method to use in generating the case; one of 0, 1, or 2. | ||
double | timeout | The time to allocate to the generation task, in relative units. |
getFinding | Retrieve the random case generated | |
getValueEntered | Retrieve the random case generated for a continuous node, method 0 |
public NodeList getNodes() throws NeticaException
If this net has no directed cycles, the list will be in topological order (i.e., a parent will always appear before its children).
To obtain the number of nodes in the net, use the length of the returned list (it will not contain duplicates or null entries), e.g., getNodes().size(); .
Consecutive calls to this method may yield lists in different orders.
Version:
Node.delete | Removes a node from the net |
The following method is available in NetEx.java:/** * Returns a list of all the nodes in this net, with the exception * of those nodes that are of kind: Node.CONSTANT_NODE. */ public NodeList getNonConstantNodes () throws NeticaException { NodeList nodes = getNodes(); NodeList nc_nodes = new NodeList (this); Enumeration enum = nodes.elements(); while (enum.hasMoreElements()) { Node node = (Node) enum.nextElement(); if (node.getKind() != Node.CONSTANT_NODE) { nc_nodes.add (node); } } return nc_nodes; }
public int getAutoUpdate() throws NeticaException
Returns BELIEF_UPDATE, or greater, if belief updating will be done automatically whenever some finding (positive, likelihood or value) is entered for a node in this net, otherwise it returns 0. The returned value can later be passed to setAutoUpdate to restore the current condition.
Version:
setAutoUpdate | Sets value |
See enterFinding for an example of saving and restoring auto-update.
public void setAutoUpdate(int autoupdate) throws NeticaException
Pass BELIEF_UPDATE for autoupdate to have the new beliefs of a compiled net calculated immediately whenever new findings are entered, or 0 to inhibit this (in which case they will be calculated when needed, e.g. by getBeliefs).
A reason for inhibiting automatic updating is because updating (also known as "propagation") is time and memory consuming, and you may want to enter many findings before doing it. However, an advantage to having updating done after each finding is entered, is that each new finding will be checked for consistency with the findings already entered.
If you are going to be retracting a finding for a node, and then entering a new one, sometimes very significant performance gains can be made by ensuring auto-updating is turned off during the retraction (see example of enterFinding).
If the net is auto-updating, and you make a call to a single Netica method which enters findings for several nodes at once (e.g. reading a case), then Netica will use just a single updating to account for them all.
If you are turning auto-updating on, and the net is compiled but not updated, then updating will be done before this method returns, which may be time consuming.
It is best to always set auto-updating one way or the other after creating a new net, since the default value may vary between Netica versions.
When a net is written to file, the auto-update value is included.
Parameters:
int | autoupdate | The new auto-updating value. |
getAutoUpdate | Retrieves value | |
compile | Auto-updating doesn't occur until net is compiled | |
getBeliefs | Forces a belief update if one is required |
See enterFinding for an example of saving and restoring auto-update.
public double getFindingsProbability() throws NeticaException
If the computations for belief updating haven't been done since the last findings were entered, or the last net modifications made, they will be done before this method returns, which can be quite time consuming.
WARNING: The number will not be valid if likelihood findings were entered.
Version:
getJointProbability | Explore probability of case without entering findings | |
isBeliefUpdated | Indicates if getFindingsProbability will trigger belief updating | |
getBeliefs | Finds the marginal probability for each of the nodes |
public NodeList getElimOrder() throws NeticaException
Compiling a net, or using setElimOrder, can add an elimination ordering to a net, while changing the net structure, or using setElimOrder, can remove an ordering from the net.
Only appropriate nodes will be included in the list returned (for example, nodes of kind CONSTANT_NODE won't be).
Version:
setElimOrder | Sets it | |
sizeCompiled | See how good the ordering is | |
reportJunctionTree | Analyze the effect of the order |
public void setElimOrder(NodeList elimOrder) throws NeticaException
Associates the list of nodes elimOrder with this net to be used as its "elimination order" the next time this net is compiled.
elimOrder must include all the nodes of this net without any duplication (except it should not include any nodes whose kind is UTILITY_NODE or CONSTANT_NODE). Alternately, elimOrder can be null, in which case any elimination order currently associated with this net will be removed.
The elimination order guides the process of triangulation during the compilation of this net, and can effect both the time and memory efficiency of belief updating considerably.
If no elimination order is supplied, Netica finds one automatically as the first step of compiling. When a net is written to file, the elimination order is included. Whenever the structure of a net changes, Netica removes the existing elimination order.
Calling this method has no effect on the current compilation; it only takes action during the next compilation. It doesn't matter if the net is compiled or not when this method is called.
Parameters:
NodeList | elimOrder | The nodes arranged in the desired elimination order. |
getElimOrder | Retrieves the elimination order currently being used | |
compile | Do or redo the compilation to use the new elimination order | |
sizeCompiled | See how good the current ordering is | |
reportJunctionTree | Analyze the effect of the current order |
public double getJointProbability(NodeList nodeList, int[] nodeStates) throws NeticaException
This method is designed to work fast when retrieving many joint probabilities from nodes that were put in the same clique (see below) during net compilation. The first time it is called it will take longer to return, but on subsequent calls it will return very fast if these conditions are met:
1. nodeList is the same list for each call.
2. No calls to it with a different nodeList list were made in between.
3. No new findings have been entered or retracted.
4. No change was made to the net requiring re-compilation.
5. Each node of nodeList was placed in the same clique during compiling.
If conditions 1 or 2 are violated, it will still be much faster than doing a new belief updating, but not as fast as if they aren't violated. If the other conditions are violated, then it will take the same time as 1 or 2 belief updatings.
All of nodeList must come from the same Bayes net.
None of nodeList should have a likelihood finding (but they may have other types of findings, and other nodes in the net may have likelihood findings).
You can be sure a set of nodes will be placed in the same clique if there is some "family" in the Bayes net which contains all of them.
A family consists of a node and its parents. The method FormCliqueWith (in the example below and in NetEx.java) can be used to ensure that all of nodeList will be put in the same clique during the next compile.
Parameters:
NodeList | nodeList | collection of nodes for which the joint probability is sought | ||
int[] | nodeStates | states of the nodes in nodeList, one state per node. |
getFindingsProbability | Joint probability for current findings | |
getBeliefs | Posterior probability for a single node | |
getCPTable | Gets CPT entries of a node |
// Ensures that at the next compile all of nodes will be put in the same clique.
// It is useful for the getJointProbability method.
// It works by adding a dummy node with 1 state, and returning that node (or null if it
// wasn't necessary to add one).
// Its effects can be completely undone by calling delete on the node it returns.
//
static Node formCliqueWith (NodeList nodes){
Net net;
Node newNode;
int numNodes = nodes.size();
if (numNodes <= 1) return NULL;
net = nodes.getNet();
newNode = new Node (null, 1, net);
for (int i = 0; i < numNodes; ++i){
Node node = (Node) nodes.get (i);
newNode.addLink (node);
}
return newNode;
}
public void retractFindings() throws NeticaException
Node.retractFindings
for that).
This includes positive findings (state and real value), negative findings, and likelihood findings.
If this net does not have any findings, calling this will have no effect.
If the net is an auto-update net (see setAutoUpdate), then a belief updating will be done to reflect the removal of findings, before this method returns (otherwise it will just be done when needed).
Version:
Node.retractFindings | To remove the findings for just one node |
public void reviseCPTsByFindings(NodeList nodeList, double degree) throws NeticaException
The current case (i.e., findings entered) is used to revise each node's conditional probabilities. This is different from belief updating, which finds the beliefs for nodes (i.e., posterior probabilities), given conditional probability relations between them and the findings that have been entered. Instead, revising the probabilities changes the conditional probability tables (CPTs) between the nodes to account for the current case.
The first few times this is called for a node, the probabilities will change considerably, because the node has little experience, but after many cases have been entered, each new case will result in only a small change.
degree indicates how the case should be weighted. The normal value for degree is 1. If a positive integer n is passed, it will have the same effect as calling this method n times to tally up n identical cases. If degree is 0, the call will have no effect. If the case is learned by calling with degree = 1, it can later be "unlearned" by calling with degree = -1.
In general, if it is called with degree = d at one point in time, and then with the same case and degree = c at another time, the overall effect will be the same as a single call with degree = d + c, even if there were many intervening calls with other cases and other degrees, and even if d or c or both are negative. If a call to fadeCPTable was made in between, then d will be weighted by the degree passed to fadeCPTable.
The order in which cases are presented has no effect.
If a node already has CPT and experience tables, this method uses the experience table to provide a "confidence" for each of the probabilities in the CPT table. The higher the experience of a probability, the less it will be altered. It is okay if a node starts with no CPT or experience tables, since then Netica will start it off with a uniform distribution having the minimum experience. However, when calling this method, a node cannot have a CPT table and no experience table, since then Netica will not know what confidence to assign the existing probabilities of the CPT table, and an exception will be thrown.
Parameters:
NodeList | nodeList | a list of the nodes whose CPTs you want revised. | ||
double | degree | how the case should be weighted (usually 1.0). |
reviseCPTsByCaseFile | Batch version, more efficient than one at a time | |
fadeCPTable | Use between calls to reviseCPTsByFindings when the world is changing during learning |
public void reviseCPTsByCaseFile(Streamer file, NodeList nodeList, double degree) throws NeticaException
It is okay if the case file has missing data, or has data on nodes not included in nodeList, or even has data on nodes not in the net containing nodeList. However the probabilities of a node are only modified by cases supplying a value for the node and for all of its parents.
Parameters:
Streamer | file | The file of cases. | ||
NodeList | nodeList | a list of the nodes whose CPTs you want revised. | ||
double | degree | how the case should be weighted (usually 1.0). |
reviseCPTsByFindings | Revise probabilities with a single case |
public void write(Streamer outStream) throws NeticaException
(Note, the word 'file' is used loosely in the following to mean either a file-system file or the block of data sent via the stream.)
If outStream is attached to a file, and it already exists, it is overwritten. The net is always saved using a "safe-save", which writes it to a new file, and then if there was no problem, it deletes the old file and changes the name of the new file to that of the old. That way there is no risk of data loss in case of an interruption due to a software error or hardware failure.
It is advised to write nets to files with extension ".dne" (i.e., the file name passed to Streamer ends with ".dne"). That way they can be more easily identified by other people and other programs, such as Netica Application.
If there are findings entered in this net, you may want to retract them with retractFindings before writing this net, since otherwise they will be saved in the file.
If the file size is very large, it may be because of large tables (such as CPTs). If these are defined by equations, it may be worthwhile to delete them with deleteTables before writing the net to file, and restoring them with equationToTable after reading the net back in.
The net will be written in the DNET file format, which all versions of Netica API and Netica Application can read. See the Norsys website for more information on the DNET format (at location ftp://ftp.norsys.com/dl/ look for file: DNET_File_Format.txt)
Parameters:
Streamer | outStream | The stream where the net will be written. |
Streamer | Generates the required Streamer | |
Net(Streamer) | Reads back the net saved | |
retractFindings | May want to retract findings before saving net | |
writeCase | Just save the findings currently entered as a case | |
getFileName | Later retrieve the name of the file written to |
net.write (new Streamer ("..nets/temp.dne"));Example #2:
For an example of writing to a byte array using ByteArrayOutputStream, see Streamer(OutputStream).
public long writeCase(NodeList nodeList, Streamer file, long idNum, double freq) throws NeticaException
It saves findings of discrete nodes and values of continuous nodes, but not likelihood findings, or negative findings (i.e. findings which say that a node is not in some state).
If file already exists, this will add the case to it (unless it is not a case file, in which case an exception will be thrown). If you wish to write over the existing file, delete it before calling this.
The first case determines what columns will be included in the file. Each node in nodeList will become one column.
Pass -1 for idNum and/or freq if you do not want columns for them to appear in the case file. If any cases will need them, they must be included in the first case written to the file.
It returns the file position of the new case (which can later be passed to readCase).
It only saves findings from the nodes of nodeList, and if the file already exists, it won't save findings from any of nodeList that were not included in the node list used to first construct the file.
It is advised to give case files the extension ".cas" (i.e., the file name passed to Streamer ends with ".cas"). That way they can be more easily identified by the Netica Application program.
You can control the characters Netica uses to separate findings, and to indicate a finding is absent, with the methods setCaseFileDelimChar and setMissingDataChar, respectively.
Parameters:
NodeList | nodeList | The nodes to use for creating the case. | ||
Streamer | file | File to write. | ||
long | idNum | |||
double | freq |
readCase | Reads back the case that writeCase saves | |
write | Saves the whole net, including findings | |
setCaseFileDelimChar | Controls which character Netica uses to separate findings | |
setMissingDataChar | Controls which character Netica uses to indicate a node has no finding |
public void readCase(long[] casePosn, Streamer file, NodeList nodeList, long[] idNum, double[] freq) throws NeticaException
The case file is an ascii text file with each case on one row, and the first row being the list of nodes as column headings. Each entry is separated by a comma, space or tab. Such a format is quite common; it can be produced by a spreadsheet program like Excel, or by the Netica method writeCase.
It only reads findings into the nodes listed in nodeList. Other nodes in the net will not have any new findings entered, even if findings for them appear in the file. It is okay if nodeList contains some nodes not mentioned in the file. If nodeList is empty, no new findings will be entered.
WARNING: It does not retract findings that are already in nodeList, and will even generate errors if the findings in the file are inconsistent with findings already in nodeList. So you probably want to call retractFindings first.
In general it reads from file the case at casePosn[0], or if casePosn[0] is NEXT_CASE it reads the next case after the last one read from file, and sets casePosn[0] to the position of the case it just read. In detail:
Called with: | File condition: | Action taken: | |||
casePosn = null | - file has no cases | generates error | |||
- file has 1 or more cases | reads first case | ||||
casePosn[0] = FIRST_CASE | - file has no cases | returns with casePosn[0] = NO_MORE_CASES | |||
- otherwise | reads first case & sets casePosn[0] to it | ||||
casePosn[0] = NEXT_CASE | - all cases read | returns with casePosn[0] = NO_MORE_CASES | |||
- otherwise | reads next case & sets casePosn[0] to it | ||||
casePosn[0] = NO_MORE_CASES | generates error | ||||
casePosn[0] = case | - indicated case is in file | reads indicated case | |||
- indicated case isn't in file | generates error |
Make sure casePosn[0] is initialized on entry. If you want to read cases by random access, casePosn[0] should be set to a value previously returned by writeCase or readCase (not the case idNum).
When reading multiple sequential cases from the same file using NEXT_CASE, the norsys.netica.Streamer object keeps track of the current file position. So different parts of your program, or different threads, can read from the same file in an interleaved way without interference, provided they each have their own norsys.netica.Streamer. But each sequential series of reads must use a single norsys.netica.Streamer (so the example below wouldn't work if the readCase call was replaced with: readCase (..., Streamer (filename, env), ...); because that would make a new norsys.netica.Streamer each time it was called).
If idNum is non-null, then on return idNum[0] will be set to the ID number of the case, or -1 if it doesn't have one. If freq[0] is non-null, then on return freq[0] will be set to the frequency (i.e., multiplicity) of the case stored with that case, or 1.0 if it doesn't have one.
Parameters:
long[] | casePosn | Array of one element allowing you to control which case is to be read and, upon return, informing you which case was read. | ||
Streamer | file | The case file to be read. | ||
NodeList | nodeList | The set of nodes defining what subset of case data will be read in to affect the net. | ||
long[] | idNum | Array of one element which upon return will be set to the ID number of the case read, or -1, if that case did not have one. | ||
double[] | freq | Array of one element which upon return will be set to the multiplicity of the case read, or 1.0, if that case did not have one. |
writeCase | Save it so that readCase can read it back | |
retractFindings | You may want to call this before reading a case | |
getNodes | Usually use this for the nodes argument | |
Streamer | To create the norsys.netica.Streamer for the file argument |
// Usage of net.readCase() usually follows a pattern like that below. // // This example is meant as a template for methods that scan through // a case file. // Streamer caseFile = new Streamer (filename); // create fresh local Streamer NodeList allNodes = net.getNodes(); long[] casePosn = new long[1]; casePosn[0] = Net.FIRST_CASE; while (true) { net.retractFindings(); net.readCase(casePosn, caseFile, allNodes, null, null); if (caseposn[0] == Net.NO_MORE_CASES) break; // ... do stuff with the case now entered ... caseposn[0] = Net.NEXT_CASE; } caseFile.close();
public void absorb(NodeList nodeList) throws NeticaException
Absorbs all of nodeList from their net. This removes and deletes (frees) the nodes while maintaining the global relationship (i.e. joint distribution) of the remaining nodes. In the probabilistic literature this is often referred to as "summing out" variables (or "maxing out" when they are decision nodes).
In order to maintain the joint distribution, Netica may have to add links. Absorbing a nature node which has no finding will only add links from the parents of the removed node and its children's parents, to the removed node's children. However, if it has a finding, many links between the ancestors of the removed node may be added (possibly resulting in very large CPT tables leading to slow behavior or an out-of-memory condition). Absorbing nodes with likelihood findings or negative findings is the worst. When a decision node is absorbed, links will be added from its parents to its children. No links are added when a utility node is absorbed. Added links never created a directed cycle, when there wasn't one to begin with.
The order of the nodes in nodeList doesn't matter. The order in which the absorptions are done will be chosen to minimize intermediate calculations (and if decision nodes are involved, it will be similar to that described in Shachter86).
If it is not possible to absorb all of nodeList, as many as possible will be absorbed, and then an exception will be thrown explaining why the next node couldn't be absorbed. Reasons it may not be possible to continue are: nodes are missing CPTs, presence of disconnected links, more than one link from a node to another, presence of directed cycles, unacceptable structure between decision and utility nodes, or multiple utility nodes.
WARNING: After calling this method, nodeList will contain only deleted nodes, so trying to use it will probably result in exceptions being thrown.
Parameters:
NodeList | nodeList | The list of nodes to be absorbed. |
Node.delete | Removes a node without maintaining joint distribution | |
setMaxMemoryUsage | In case this method is consuming too much memory |
/** * Handy method to absorb a single node. * @param node the node to be removed from its net */ public static void absorb (Node node) throws NeticaException { Net net = node.getNet(); NodeList nodes = new NodeList (net); nodes.add(node); net.absorb(nodes); }
public int[] getMostProbableConfig(NodeList nodeList) throws NeticaException
For nodeList, currently you must pass a list returned by getNodes.
The returned array will contain the configuration of highest joint probability given the currently entered findings. Each element of the returned array is the state for the corresponding node of nodeList (i.e. they are in the same order, and have the same length).
The net must be compiled before calling this method.
After finding the most probable configuration, you can use getJointProbability to find its probability (see example below).
You can mix calls to this method with calls to getBeliefs (which finds posterior probabilities).
This method does not work when likelihood findings are entered. In that case you must make child nodes corresponding to the observations, whose CPTs are the likelihoods, and enter a positive finding for them.
If you must have the MPE of a smaller set of nodes than all the nodes in the net, you can use absorb to remove the other nodes first.
Keep in mind that in the MPE, some nodes may be assigned states that are quite unlikely (i.e. the state won't be the one with the highest probability as returned by getBeliefs). That may be necessary in order to achieve the highest overall joint probability, considering the assignment of states to the other nodes. Before using this method, consider carefully whether you really want the MPE, or rather just a list of the most probable state for each of the nodes.
The algorithm Netica uses to find the MPE is known as a "max propagation" in the junction tree.
Parameters:
NodeList | nodeList | currently, this must be all the nodes in this net. You can call getNodes to create this list. |
getJointProbability | Find the actual joint probability of a configuration | |
getBeliefs | Can find the most probable state for a single node only |
// The following puts the most probable configuration in config, // and its probability in maxprob. // net.compile(); NodeList allnodes = net.getNodes (net); int[] config = net.getMostProbableConfig (allnodes); double maxprob = net.getJointProbability (allnodes, config); // ... use config and maxprob ...
public void optimizeDecisions(NodeList nodeList) throws NeticaException
NodeList | nodeList | a list of decision nodes whose optimal decision functions are sought. |
public static NodeList duplicateNodes(NodeList nodeList, Net newNet) throws NeticaException
A new list of the duplicated nodes will be returned. The order of the new list will correspond with the order of the old list. The old list, and the nodes it refers to, will not be modified.
All connectivity strictly between the duplicated nodes will be maintained during the duplication. Parents of duplicated nodes that aren't also being duplicated will result in disconnected links, if the nodes are being duplicated into a different net.
If a duplicated node has the same name as a node already in newNet, then the name of the duplicated node will be modified by adding a numeric suffix to its name (or changing its numeric suffix if it already has one).
If you wish to duplicate a single node, see the "DuplicateNode" example below. If you wish to duplicate a whole net, see "DuplicateNet" below.
Parameters:
NodeList | nodeList | A list of nodes to duplicate. | ||
Net | newNet | The destination net to be given the newly created nodes. |
NodeList(NodeList) | Just duplicates the list, but not the nodes | |
Node | Creates a new node in a net | |
Node.delete | Removes a node from its net and frees it |
Example #2:The following method is available in NodeListEx.java:/** * This transfers nodes from the net they are in to newNet, * and returns a new list of the new nodes in the same order as they * appeared in nodes. * * In the process, each node in nodes is deleted, and a new one created, * so don't try and use any of the old nodes ( if you do, a NeticaException * will be thrown.) * @param nodes the nodes to be deleted * @param newNet the net to receive copies of the nodes to be deleted */ public static NodeList transferNodes (NodeList nodes, Net newNet) throws NeticaException { NodeList newNodes = nodes.getNet().duplicateNodes (nodes, newNet); while (nodes.size() > 0){ Node node = (Node) nodes.remove(0); node.delete(); } return newNodes; }
Example #3:The following method is available in NodeEx.java:/** * Make a copy of ourself and place it in newNet. * @param newNet the net where the newly constructed node will be placed. */ public Node duplicate (Net newNet) throws NeticaException { NodeList nodes = new NodeList (getNet()); nodes.add (this); NodeList newNodes = Net.duplicateNodes (nodes, newNet); return (Node) newNodes.get(0); } The following will duplicate a node within the same net. It is available in NodeEx.java:/** * Make a copy of the current node in its own net. */ public Node duplicate() throws NeticaException { return duplicate ((Net)this.getNet()); }
/** * Make a copy of a net, giving it the name, newName. * @param net the net to duplicate * @param newName the name of the new net */ static Net duplicate (Net net, String newName) throws NeticaException { Net newNet = new Net (newName); NodeList newNodes = net.duplicateNodes (net.getNodes(), newNet); NodeList elimOrder = net.getElimOrder (net); NodeList newOrder = NodeListEx.mapNodeList (elimOrder, newNet); newNet.setElimOrder (newOrder); newNet.setAutoUpdate (net.getNetAutoUpdate()); newNet.setTitle (net.getTitle()); newNet.setComment (net.getComment()); newNet.user().setReference (net.user().getReference()); // If desired return newNet; }
public NodeList duplicateNodes(NodeList nodeList) throws NeticaException
A new list of the duplicated nodes will be returned. The order of the new list will correspond with the order of the old list. The old list, and the nodes it refers to, will not be modified.
All connectivity strictly between the duplicated nodes will be maintained during the duplication. Parents of duplicated nodes that aren't also being duplicated will result in disconnected links, if the nodes are being duplicated into a different net.
If a duplicated node has the same name as a node already in this net, then the name of the duplicated node will be modified by adding a numeric suffix to its name (or changing its numeric suffix if it already has one).
If you wish to duplicate a single node, see the "DuplicateNode" example below. If you wish to duplicate a whole net, see "DuplicateNet" below.
Parameters:
NodeList | nodeList | A list of nodes to duplicate. |
NodeList(NodeList) | Just duplicates the list, but not the nodes | |
Node | Creates a new node in a net | |
Node.delete | Removes a node from its net and frees it |
Example #2:The following method is available in NodeListEx.java:/** * This transfers nodes from the net they are in to newNet, * and returns a new list of the new nodes in the same order as they * appeared in nodes. * * In the process, each node in nodes is deleted, and a new one created, * so don't try and use any of the old nodes ( if you do, a NeticaException * will be thrown.) * @param nodes the nodes to be deleted * @param newNet the net to receive copies of the nodes to be deleted */ public static NodeList transferNodes (NodeList nodes, Net newNet) throws NeticaException { NodeList newNodes = newNet.duplicateNodes (nodes); while (nodes.size() > 0){ Node node = (Node) nodes.remove(0); node.delete(); } return newNodes; }
Example #3:The following method is available in NodeEx.java:/** * Make a copy of ourself and place it in newNet. * @param newNet the net where the newly constructed node will be placed. */ public Node duplicate (Net newNet) throws NeticaException { NodeList nodes = new NodeList (getNet()); nodes.add (this); NodeList newNodes = newNet.duplicateNodes (nodes); return (Node) newNodes.get(0); } The following will duplicate a node within the same net. It is available in NodeEx.java:/** * Make a copy of this node in its own net. */ public Node duplicate() throws NeticaException { return duplicate (getNet()); }
/** * Make a copy of a net, giving it the name, newName. * @param net the net to duplicate * @param newName the name of the new net */ static Net duplicate (Net net, String newName) throws NeticaException { Net newNet = new Net (newName); NodeList newNodes = newNet.duplicateNodes (net.getNodes()); NodeList elimOrder = net.getElimOrder (net); NodeList newOrder = NodeListEx.mapNodeList (elimOrder, newNet); newNet.setElimOrder (newOrder); newNet.setAutoUpdate (net.getNetAutoUpdate()); newNet.setTitle (net.getTitle()); newNet.setComment (net.getComment()); newNet.user().setReference (net.user().getReference()); // If desired return newNet; }
public java.lang.String getFileName() throws NeticaException
If this net was not read from a file, and has not yet been written to a file, null is returned.
Version:
Generic.getName | The actual internal name of the net | |
Generic.getTitle | ||
Net(Streamer) | Initializes net's filename with the name of the file read, if the input stream was a file | |
write | Sets or changes net's filename | |
Streamer.getFileName |
public java.lang.String reportJunctionTree() throws NeticaException
The report consists of one line for each clique, consisting of the clique's index, a list of cliques (i.e. their indexes) which the clique is connected to, and finally a list of nodes in the clique. At the end is the total statespace size of all the cliques, then the total size (with sepsets) added, and finally the total size with sepsets reduced by simplifications due to any findings currently entered.
The net must already be compiled before calling this.
Version:
compile | Need to compile the net first | |
sizeCompiled | Just gets the overall size of the junction tree |
// Below is example output from reportJunctionTree for the "Asia" Bayes net. Clique [Joined To] Size Member nodes (* means home) 0 [1] 4 (*VisitAsia, *Tuberculosis) 1 [0 2] 8 (Tuberculosis, Cancer, *TbOrCa) 2 [1 3 4] 8 (Cancer, TbOrCa, Bronchitis) 3 [2 5] 8 (TbOrCa, Bronchitis, *Dyspnea) 4 [2] 8 (*Smoking, *Cancer, *Bronchitis) 5 [3] 4 (*XRay, TbOrCa) Sum of clique sizes = 40 (with sepsets = 56)
public double sizeCompiled() throws NeticaException
The net must already be compiled before calling this (see compile).
Maximum inference time for belief updating, and memory required for compiling and updating, are both linearly related to the quantity returned (the number of bytes required is 4 times the number returned). They are maximum, providing this net does not have any positive findings entered which are later removed.
The value returned will be at its maximum before any findings are entered, and with each new positive finding entered, it will decrease or remain constant. Any likelihood or negative findings entered will not alter the value returned, unless they are equivalent to a positive finding.
Version:
reportJunctionTree | Provides more information on junction tree | |
compile | Need to compile the net first | |
setElimOrder | Elimination order can have a major effect on the compiled size |
public static java.util.Vector getAllNets(Environ env) throws NeticaException
Environ | env | the Environ whose nets we seek |
The following method is available in NetEx.java:/** * Find a net in the given Environ by it's name. Comparison must be an exact match and * is case sensitive. Returns the first net that matches, or null, if there was no match. * @param name The name of the net sought. * @param env The Environ to search within. * @returns The net with that name, or null, if not found. */ public static Net getNetNamed (String name, Environ env) throws NeticaException { Vector nets = Net.getAllNets (env); Enumeration enum = nets.elements(); while (enum.hasMoreElements()) { Net net = (Net) enum.nextElement(); if (net.getName().equals (name)) { return net; } } return null; }
|
||||||||
PREV CLASS NEXT CLASS | FRAMES NO FRAMES | |||||||
SUMMARY: INNER | FIELD | CONSTR | METHOD | DETAIL: FIELD | CONSTR | METHOD |