Я написал программу, которая принимает вопрос от пользователя. Затем он сопоставляет этот вопрос со списком предварительно определенных вопросов и возвращает ответ. Предполагается, что он точный и соответствует только тем вопросам, которые близки (нечеткие совпадения) или в точности совпадают с заданными пользователем.
Мой SSSCE:
Код:
#include <iostream>
#include <cstdint>
#include <algorithm>
#include <numeric>
#include <functional>
int min_index(const std::vector<int>& list)
{
int index = 0;
int smallest = list[0];
for (size_t i = 0; i < list.size(); ++i) {
if (list[i] < smallest) {
smallest = list[i];
index = i;
}
}
return index;
}
std::uint32_t LevenshteinDistance(const std::string &First, const std::string &Second)
{
const std::size_t FirstLength = First.size();
const std::size_t SecondLength = Second.size();
std::vector<std::uint32_t> Current(SecondLength + 1);
std::vector<std::uint32_t> Previous(SecondLength + 1);
std::size_t I = 0;
std::generate(Previous.begin(), Previous.end(), [&] {return I++; });
for (I = 0; I < FirstLength; ++I)
{
Current[0] = I + 1;
for (std::size_t J = 0; J < SecondLength; ++J)
{
auto Cost = First[I] == Second[J] ? 0 : 1;
Current[J + 1] = std::min(std::min(Current[J] + 1, Previous[J + 1] + 1), Previous[J] + Cost);
}
Current.swap(Previous);
}
return Previous[SecondLength];
}
std::vector<std::string> questions =
{
"What is the most popular program at GBC?",
"How much is the tuition at GBC?",
"Do I have to pay my fees before I can register?",
"What are my fee payment options?",
"How do I know when I'm allowed to register?",
"How do I add and/or drop courses from my timetable?",
"What do I do if I can't find my PASSWORD?",
"How do I withdraw from a program?",
"What are the college policies?",
"How much math do I need to know?",
"What is the program code for computer programming?",
"What is stu-view?",
"What is the college best known for?",
"How easy is it to find work after program completion?",
"What if I plan to continue my education after?"};
std::vector<std::string> answers =
{
"Fashion",
"3000 a semester",
"Yes you have to pay the fees before registering",
"You may pay online on your student account through the student portal",
"You may register two weeks or more before the start of the program",
"You may drop courses from online through the student portal",
"You can call ... and an agent will assist you",
"You may withdraw using the student portal online",
"They are located at the following link...",
"It depends on the program you are entering",
"T127 is the code for computer science",
"Stu-View is a student portal to manage student account and view marks.",
"The cafeteria food",
"Depends on the field of work and timing",
"You may do so within three years after program completion"};
int main()
{
std::string user_question = "program";
std::vector<int> distances = std::vector<int>(questions.size(), 0);
for (size_t I = 0; I < questions.size(); ++I)
{
int dist = LevenshteinDistance(user_question, questions[I]);
distances[I] = dist;
}
std::cout<<"Distance: "<<distances[min_index(distances)]<<"\n";
std::cout<<"User-Question: "<<user_question<<"\n";
std::cout<<"Question-Key: "<<questions[min_index(distances)]<<"\n";
std::cout<<"Answer-Value: "<<answers[min_index(distances)]<<"\n";
return 0;
}
Таким образом, в приведенном выше, пользователь вводит "program"
.. Предполагается найти наиболее близкое совпадение из списка вопросов и вернуть соответствующий ответ ..
Тем не менее, он печатает:
Distance: 17
User-Question: program
Question-Key: What is stu-view?
Answer-Value: Stu-View is a student portal to manage student account and view marks.
Он должен был иметь лучшие результаты или точность, но, кажется, его не волнует, есть ли в предложении ключевые слова, введенные пользователем: S Это работает для небольших случаев, но для большой базы данных или выше, где более 5 предложений. , это трудно. Особенно с небольшими ключевыми словами; л
Что я делаю неправильно? Любые идеи, как я могу это исправить и сделать это более точным? Я пробовал HammingDistance, похожие результаты ..
И то и другое "program"
а также "What is stu-view?"
довольно короткие по сравнению с другими строками. Проще преобразовать "program"
в "What is stu-view?"
чем преобразовать "program"
в "What is the most popular program at GBC?"
несмотря на то, что слово "program"
распространено
Что я делаю неправильно?
Я не думаю, что вы делаете что-то не так. Если вы не удовлетворены результатом, это означает, что ваш текущий формализм (минимизация расстояния Левенштейна) не тот, который вам нужен.
Вы можете найти более локальные решения: например, Токенизируя строки, вычисляйте попарно левенштейновское расстояние между словами, затем объединяйте результаты (среднее, выше инф …)
Лучшие решения потребовали бы некоторой библиографии (вероятно, неконтролируемая тема машинного обучения)
Других решений пока нет …