/// <summary> /// Selects the best group of queries, then compares them to the appropriate label. /// If the query's expected reward is better than the label, it returns the query. /// If the label's expected reward is better, than it returns null, to indicate querying is not the recommended action. /// </summary> /// <param name="dataVector"></param> /// <returns></returns> public Query GetBestQuery(DataVector dataVector) { //Try to add new details if (dataVector.GetType() == typeof(DataVectorTraining)) { AddMissingQueriesAndLabels((DataVectorTraining)dataVector); } //Get best queries (general) var bestQueriesGroup = GetAverageGroupQueries(); //Build list of possible queries, that match datavector var possibleQueries = bestQueriesGroup.Where(q => dataVector.Features.Find(f => q.Key.Feature.Equals(f)) != null ).ToList(); //If no possibilities if (possibleQueries.Count == 0) { return(null); } //Result variable Query bestQueryResult = null; //Default: don't query, because the labels provide the best reward. #region Find best query, Version 1 //Find best query for each label by expected reward List <KeyValuePair <Query, double> > bestQueries = new List <KeyValuePair <Query, double> >(); foreach (var labelPair in Labels.ToList()) { //Get label details FeatureValuePair theLabel = labelPair.Key; double theLabelExpectedReward = labelPair.Value; //Filter list by label var bestQueriesByLabel = possibleQueries.Where(q => q.Key.Label.Equals(theLabel)).ToList(); if (bestQueriesByLabel.Count == 0) { continue; } //Get best query details var bestQueryPair = bestQueriesByLabel.OrderByDescending(p => p.Value).First(); Query bestQuery = bestQueryPair.Key; double bestQueryExpectedReward = bestQueryPair.Value; //Is query better than label if (bestQueryExpectedReward > theLabelExpectedReward) { bestQueries.Add(bestQueryPair); } } //Pick final answer if (bestQueries.Count > 0) { bestQueryResult = bestQueries.OrderByDescending(q => q.Value).First().Key; } #endregion #region Find best query, Version 2 -- this may work, and would be faster. ////Find best query pair //var bestQueryPair2 = possibleQueries.OrderByDescending(p => p.Value).First(); //Query bestQuery2 = bestQueryPair2.Key; //double bestQuery2ExpectedReward = bestQueryPair2.Value; ////Find label //var labelPair2 = Labels.ToList().Find(p => p.Key.Equals(bestQuery2.Label)); //Feature theLabel2 = labelPair2.Key; //double theLabel2ExpectedReward = labelPair2.Value; ////If query has higher expected reward, select it as the option. //Query bestQueryResult2 = null; //if (bestQuery2ExpectedReward > theLabel2ExpectedReward) // bestQueryResult2 = bestQuery2; #endregion return(bestQueryResult); }
public object Classify_ByPolicy(DataVector dataVector, bool byProbability) { //Start with root state State rootState = StateSpace[0]; // 0 is the hashcode for a state with no features. var labels = rootState.Labels; State currentState = rootState; while (true) { //Set current state's labels labels = currentState.Labels; //Find best query Query recommendedQuery = currentState.GetBestQuery(dataVector); //If no query, then end search. Use current labels. if (recommendedQuery == null) { break; } //Search for next state State nextState = null; int nextHashCode = currentState.GetHashCodeWith(recommendedQuery.Feature); if (StateSpace.ContainsKey(nextHashCode)) { nextState = StateSpace[nextHashCode]; } else { break; } //Go to next state currentState = nextState; } //Select method for using the labels if (byProbability) { //Select best label, by percentage probabilty double r = rand.NextDouble() * labels.Sum(p => p.Value); // Random value between 0 and the sum of expected rewards double runningTotal = 0; object bestLabelValue = null; foreach (var label in labels.OrderBy(p => p.Value)) { runningTotal += label.Value; if (r < runningTotal) { bestLabelValue = label.Key.Value; break; } } return(bestLabelValue); } else { //By highest expected reward return(labels.OrderByDescending(p => p.Value).First().Key.Value); } }
public object Classify_ByTree(DataVector dataVector, bool byProbability) { return(DecisionTree.Classify(dataVector, byProbability)); }
/// <summary> /// Uses the current policy to classify a datavector and return the best classification label. /// </summary> /// <param name="dataVector"></param> /// <returns>Classification label</returns> public object Classify_ByPolicy(DataVector dataVector) { return(Classify_ByPolicy(dataVector, true)); }
/// <summary> /// Uses the resulting "DecisionTree", summarized from the policy, to quickly classify a given datavector. /// </summary> /// <param name="dataVector"></param> /// <returns>Classification label</returns> public object Classify_ByTree(DataVector dataVector) { return(DecisionTree.Classify(dataVector)); }