private double getRank(NodeReference answerCandidate, MultiTraceLog2 pattern) { var commonTraceNodes = getCommonTraceNodes(answerCandidate, pattern); var rank = 0.0; var initialNodeCount = pattern.InitialNodes.Count(); foreach (var traceNode in commonTraceNodes) { var compatibleNodes = traceNode.CompatibleInitialNodes.ToArray(); var edgeImportance = 1.0 * compatibleNodes.Length / initialNodeCount; rank += edgeImportance; } //TODO here could be more precise formula return(rank / commonTraceNodes.Count()); }
private IEnumerable <PathSubstitution> getSubstitutedPaths(MultiTraceLog2 pattern, NodeReference substitutionNode, ComposedGraph graph) { var substitution = new SubstitutionValidator(substitutionNode, graph); var filteredNodes = getFilteredTraces(pattern); foreach (var traceNode in filteredNodes.Reverse()) { if (traceNode.CurrentEdge == null) { //we skip substitution to answer continue; } if (substitution.IsCompatible(traceNode)) { yield return(new PathSubstitution(substitutionNode, traceNode)); } } }
private IEnumerable <TraceNode2> getFilteredTraces(MultiTraceLog2 pattern) { TraceNode2[] result; if (!_cachedFilteredTraces.TryGetValue(pattern, out result)) { var start = DateTime.Now; result = pattern.TraceNodes.Where(n => { //TODO this is workaround how to filter out irrelevant paths var pathLen = n.Path.Count(); var distinctPathLen = n.Path.Distinct().Count(); return(pathLen == distinctPathLen); }).OrderByDescending(t => t.CompatibleInitialNodes.Count()).Take(100).ToArray(); _cachedFilteredTraces[pattern] = result; // Console.WriteLine("GetFilteredTraces {0}s", (DateTime.Now - start).TotalSeconds); } return(result); }
internal PatternSubstitutionMatch PatternMatchProbability(MultiTraceLog2 pattern, string questionSignature, IEnumerable <NodeReference> questionEnities, ComposedGraph graph) { var bestSubstitutions = new List <PathSubstitution>(); foreach (var node in questionEnities) { var currentBestConfidence = 0.0; PathSubstitution currentBestPath = null; foreach (var path in getSubstitutedPaths(pattern, node, graph)) { var currentPath = path; var originalNodes = currentPath.OriginalTrace.CurrentNodes; var confidence = currentPath.Rank / pattern.InitialNodes.Count(); //TODO consider context confidence *= SubstitutionProbability(currentPath.Substitution, originalNodes); currentPath = currentPath.Reranked(confidence); if (currentBestConfidence < confidence) { currentBestPath = currentPath; currentBestConfidence = confidence; } } if (currentBestPath == null) { //substitution was not found return(null); } bestSubstitutions.Add(currentBestPath); } //TODO we would like to have match information in the output return(new PatternSubstitutionMatch(bestSubstitutions)); }
private IEnumerable <TraceNode2> getCommonTraceNodes(NodeReference answerCandidate, MultiTraceLog2 pattern) { var compatibleTraces = new List <TraceNode2>(); var filteredTraces = getFilteredTraces(pattern); foreach (var node in filteredTraces) { if (node.PreviousNode == null) { if (node.CurrentNodes.Contains(answerCandidate)) { //candidate matches directly as an answer compatibleTraces.Add(node); } } else { var tracePath = node.Path; if (_graph.GetForwardTargets(new[] { answerCandidate }, tracePath).Any()) { compatibleTraces.Add(node); } } } return(compatibleTraces); }
private IEnumerable <Ranked <NodeReference> > rankCandidates(IEnumerable <NodeReference> answerCandidates, MultiTraceLog2 pattern) { var candidates = new List <Ranked <NodeReference> >(); foreach (var answerCandidate in answerCandidates) { var rank = getRank(answerCandidate, pattern); candidates.Add(new Ranked <NodeReference>(answerCandidate, rank)); } return(candidates); }