/// <summary> /// Initializes a new instance of the QuestionBuilder class according to given values. /// </summary> /// <param name="oper">The given value of operator.</param> /// <param name="value">The given value.</param> public QuestionBuilder(QuestionOperator oper, int value) { if (value < 0) { throw new ArgumentException("The given integer value shouldn't be less than 0"); } // If the operator is belong to, it can be consider as equal since the value set only have one value. if (oper == QuestionOperator.Belong) { oper = QuestionOperator.Equal; } // If the operator is greater or equal, it can be consider as less. // So, the returned question will be an equalable question with opposite answer. // The opposite answer won't impact the decision tree and related logic. if (oper == QuestionOperator.GreaterEqual) { oper = QuestionOperator.Less; } // If the operator is greater, it can be consider as less or equal. // So, the returned question will be an equalable question with opposite answer. // The opposite answer won't impact the decision tree and related logic. if (oper == QuestionOperator.Greater) { oper = QuestionOperator.LessEqual; } Question question = new Question { Oper = oper, ValueSetName = value.ToString(CultureInfo.InvariantCulture), }; switch (oper) { case QuestionOperator.Equal: question.ValueSet = new List<string> { question.ValueSetName }.AsReadOnly(); break; case QuestionOperator.Less: question.ValueSet = BuildLessQuestionValueSetStartsWithDigit(value).AsReadOnly(); break; case QuestionOperator.LessEqual: question.ValueSet = BuildLessQuestionValueSetStartsWithDigit(value + 1).AsReadOnly(); break; default: throw new NotSupportedException(Helper.NeutralFormat("Unsupported question operator \"{0}\"", oper.ToString())); } _questionList.Add(question); }
/// <summary> /// Build question for not applicable feature value. /// </summary> /// <param name="featureName">The corresponding feature name.</param> /// <param name="leftSeparator">The left separator of this feature.</param> /// <param name="rightSeparator">The right separator of this feature.</param> /// <returns>The question for not applicable feature value.</returns> public static string BuildNotApplicableFeatureQuestion(string featureName, string leftSeparator, string rightSeparator) { Question question = new Question { FeatureName = featureName, LeftSeparator = leftSeparator, RightSeparator = rightSeparator, Oper = QuestionOperator.Equal, ValueSetName = Label.NotApplicableFeatureValue, ValueSet = new List<string> { Label.NotApplicableFeatureValue }.AsReadOnly(), }; return question.Expression; }
/// <summary> /// Initializes a new instance of the QuestionBuilder class according to values, range and value type. /// </summary> /// <param name="values">The valid values.</param> /// <param name="minValue">The minimum feature value for generating questions.</param> /// <param name="maxValue">The maximum feature value for generating questions.</param> /// <param name="valueType">The value type.</param> public QuestionBuilder(IEnumerable<int> values, int minValue, int maxValue, LingFeatureValueType valueType) { List<int> sortedValues = new List<int>(values); sortedValues.Sort(); // Creates the equal questions for enumerable or null type feature. if (valueType == LingFeatureValueType.Null || valueType == LingFeatureValueType.Enumerable) { for (int i = 0; i < sortedValues.Count; i++) { if ((minValue > 0 && sortedValues[i] < minValue) || (maxValue > 0 && sortedValues[i] > maxValue)) { continue; } string value = sortedValues[i].ToString(CultureInfo.InvariantCulture); List<string> valueSet = new List<string> { value }; Question question = new Question { Oper = QuestionOperator.Equal, ValueSetName = value, ValueSet = valueSet.AsReadOnly(), }; _questionList.Add(question); } } // Creates the less equal questions for integer or null type feature. if (valueType == LingFeatureValueType.Null || valueType == LingFeatureValueType.Integer) { for (int i = 0; i < sortedValues.Count; i++) { if ((minValue > 0 && sortedValues[i] < minValue) || (maxValue > 0 && sortedValues[i] > maxValue)) { continue; } string value = sortedValues[i].ToString(CultureInfo.InvariantCulture); List<string> valueSet = new List<string>(); for (int j = 0; j <= sortedValues[i]; ++j) { valueSet.Add(j.ToString(CultureInfo.InvariantCulture)); } Question question = new Question { Oper = QuestionOperator.LessEqual, ValueSetName = value, ValueSet = valueSet.AsReadOnly(), }; _questionList.Add(question); } } }
/// <summary> /// Initializes a new instance of the QuestionBuilder class according to given values. /// </summary> /// <param name="oper"> /// The given value of operator. /// </param> /// <param name="name"> /// The given name. /// </param> /// <param name="valueSet"> /// The given value set. /// </param> public QuestionBuilder(QuestionOperator oper, string name, List<string> valueSet) { Question question = new Question { Oper = oper, ValueSetName = name, ValueSet = valueSet.AsReadOnly(), }; _questionList.Add(question); }
/// <summary> /// Initializes a new instance of the QuestionBuilder class according to integer values. /// </summary> /// <param name="values">The valid values.</param> public QuestionBuilder(IEnumerable<int> values) { List<int> sortedValues = new List<int>(values); sortedValues.Sort(); // Creates the equal question first. for (int i = 0; i < sortedValues.Count; i++) { string value = sortedValues[i].ToString(CultureInfo.InvariantCulture); List<string> valueSet = new List<string> { value }; Question question = new Question { Oper = QuestionOperator.Equal, ValueSetName = value, ValueSet = valueSet.AsReadOnly(), }; _questionList.Add(question); } // Then the less equal question. for (int i = 1; i < sortedValues.Count; i++) { Question question = new Question { Oper = QuestionOperator.LessEqual, ValueSetName = sortedValues[i].ToString(CultureInfo.InvariantCulture), ValueSet = BuildLessQuestionValueSetStartsWithDigit(sortedValues[i] + 1).AsReadOnly(), }; _questionList.Add(question); } }
/// <summary> /// Initializes a new instance of the QuestionBuilder class according to enum. /// </summary> /// <param name="enumType">A enum type used to generate questions.</param> public QuestionBuilder(Type enumType) { string[] names = Enum.GetNames(enumType); foreach (string name in names) { Question question = new Question { Oper = QuestionOperator.Equal, ValueSetName = name, }; int value = (int)Enum.Parse(enumType, name); List<string> valueSet = new List<string> { value.ToString(CultureInfo.InvariantCulture) }; question.ValueSet = valueSet.AsReadOnly(); _questionList.Add(question); } }
/// <summary> /// Initializes a new instance of the QuestionBuilder class according to a name and its value. /// </summary> /// <param name="namedValues">A dictionary to hold the name and its value.</param> public QuestionBuilder(Dictionary<string, object> namedValues) { foreach (KeyValuePair<string, object> kvp in namedValues) { List<string> valueSet = new List<string> { kvp.Value.ToString() }; Question question = new Question { Oper = QuestionOperator.Equal, ValueSetName = kvp.Key, ValueSet = valueSet.AsReadOnly(), }; _questionList.Add(question); } }
/// <summary> /// Initializes a new instance of the QuestionBuilder class according to phonetic question file. /// </summary> /// <param name="phoneticQuestionFile">The phonetic question file from Hts.</param> /// <param name="phonemes">The valid phoneme set, used to validate the phonetic questions.</param> public QuestionBuilder(string phoneticQuestionFile, IEnumerable<string> phonemes) { // Load the all phonetic question firstly. PhoneQuestion[] phoneticQuestions = LoadPhoneticQuestions(phoneticQuestionFile, phonemes); // For each phonetic question, assign its fields to a Question item. foreach (PhoneQuestion phoneQuestion in phoneticQuestions) { Question question = new Question { Oper = QuestionOperator.Belong, ValueSetName = phoneQuestion.Name, ValueSet = phoneQuestion.Phones.AsReadOnly(), }; _questionList.Add(question); } }
/// <summary> /// Loads the forest from the forest file, for example, .INF file. /// </summary> /// <param name="forestFileName">The location of the input file.</param> /// <returns>DecisionForest.</returns> public DecisionForest Load(string forestFileName) { Helper.ThrowIfNull(forestFileName); bool quesSection = true; bool treeSection = false; Collection<string> treeLines = new Collection<string>(); foreach (string line in Helper.FileLines(forestFileName, Encoding.ASCII, false)) { // Load question sets and count decision tree if (quesSection) { if (line.IndexOf(Question.QuestionKeyword, StringComparison.Ordinal) < 0) { quesSection = false; } else { Question question = new Question(line); _nameIndexedQuestions.Add(question.Name, question); } } if (!quesSection) { string trimLine = line.Trim(); if (!string.IsNullOrEmpty(trimLine)) { // tree start if (!treeSection) { treeSection = true; treeLines.Clear(); } treeLines.Add(trimLine); } else { // tree end if (treeSection) { DecisionTree tree = new DecisionTree(); tree.Load(treeLines); _treeList.Add(tree); treeSection = false; } } } } if (treeSection) { throw new InvalidDataException( Helper.NeutralFormat("Invalidate last line for Decision Tree {0}", forestFileName)); } return this; }