Java 将自然语言问题转换为SQL查询

Java 将自然语言问题转换为SQL查询,java,desktop-application,opennlp,Java,Desktop Application,Opennlp,我想使用opennlp Java库将自然语言问题转换为SQL查询,即 谁在索契赢得了女子花样滑冰冠军 应转换为 select name from winners where event='skating_woman' 有人知道哪些课程是有用的,以及如何做到这一点吗 还粘贴了我尝试过的代码。 我已将问题转换为语句,然后再转换为标记 /////////1st part String paragraph = "Did Matt win the men slalom?"; InputStream i

我想使用opennlp Java库将自然语言问题转换为SQL查询,即

谁在索契赢得了女子花样滑冰冠军

应转换为

select name from winners where event='skating_woman'
有人知道哪些课程是有用的,以及如何做到这一点吗

还粘贴了我尝试过的代码。

我已将问题转换为语句,然后再转换为标记

/////////1st part

String paragraph = "Did Matt win the men slalom?";
InputStream is1 = new FileInputStream("bins/en-sent.bin");
SentenceModel model1 = new SentenceModel(is1);
SentenceDetectorME sdetector = new SentenceDetectorME(model1);
String sentences[] = sdetector.sentDetect(paragraph);
System.out.println(sentences[0]);
is1.close();

////////2nd part
InputStream is2 = new FileInputStream("bins/en-token.bin");
TokenizerModel model2 = new TokenizerModel(is2);
Tokenizer tokenizer = new TokenizerME(model2);
String tokens[] = tokenizer.tokenize(sentences[0]);
for (String a : tokens)
    System.out.println(a);
is2.close();

简单的回答是,你“可以”做到这一点,但这是不切实际的,几乎是不可能的。。原因很简单,你可能会有很多类似的问题,它们的意思完全相同。使用SQL查询,您必须保留特定的语法才能获取数据。。。使用标准语言,您可能有100种不同的语法来获得相同的东西。将其映射到SQL语言是非常不切实际的,几乎是不可能的

是的,您可以强制用户使用特定的单词或特定的问题格式,这样您的程序就可以将它们解释为SQL查询——但这再次打破了您想要实现的范例,不是吗

编辑:

因为你太绝望了;)你可以“潜在地”做这样的事情

让我们想象一个非常简单的查询

SELECT * FROM USERS WHERE AGE = '20';
可能的人类语言问题是什么

  • 你能让我看看所有20岁的人吗
  • 展示20岁的人
  • 这个群体中有多少人的年龄是20岁
  • 这张桌子上有多少人已经20年了
  • 我们有20岁的人吗
  • 搜索所有20岁的人
然后你可以做的是创建某种
Map
where-ie

Key = USERS;
Value = people, humans, 
还有另一张地图

Key = SELECT;
Value = Can you show me, Display, Do we have, Search, How many;

以此类推-这将创建一个复杂的映射,其中包含所有可能的短语,这些短语可以表示相同的内容,并对应于给定的SQL查询语法元素。这可能不是最好的解决方案,但我可能会这么做-至少这是我开始时要做的

我现在没有时间发布代码,但请看一下opennlp句子块和文档分类程序。我认为你可以——非常有创造性地——使用doccat来建立你的“键”,使用句子切块器来建立名词和动词短语(不是代词,实际上是多词短语),并结合结果。因此,在查询时,您将对句子进行分类以建立一个键,然后对句子进行分块,然后执行一个连接到键表的查询,然后模糊地(可能是全文索引)短语表。只是一个想法,如果它是有趣的,我会张贴代码作为编辑。您必须使用示例构建doccat模型

编辑

下面是如何使用opennlp文档分类程序获取一组类别的概率分布,您需要提供一个具有doccat模型路径的属性文件:

import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import opennlp.tools.doccat.DoccatModel;
import opennlp.tools.doccat.DocumentCategorizerME;


/**
 *
 * @author Owner
 */
public class SentimentFinder {

  private DoccatModel doccatModel;
  private DocumentCategorizerME documentCategorizerME;
  Properties props =null;

  public void init() {
    try {
      if (doccatModel == null) {
        doccatModel = new DoccatModel(new File(props.getProperty("opennlp.sentiment.model.generic")));
        documentCategorizerME = new DocumentCategorizerME(doccatModel);

      }
    } catch (IOException ex) {
      ex.printStackTrace();
    }
  }

  /**
   * Classifies text via a maxent model. Try to keep chunks of text small, or
   * typically there will be all low scores with little difference.
   *
   * @param text the string to be classified
   * @return
   */
  public Map<String, Double> probDist(String text) {
    Map<String, Double> probDist = new HashMap<String, Double>();
    if (doccatModel == null) {
      init();
    }
    double[] categorize = documentCategorizerME.categorize(text);
    int catSize = documentCategorizerME.getNumberOfCategories();
    for (int i = 0; i < catSize; i++) {
      String category = documentCategorizerME.getCategory(i);
      probDist.put(category, categorize[documentCategorizerME.getIndex(category)]);
    }
    return probDist;

  }
}
或者类似的东西

退房

该产品提供的技术支持搜索框将英语转换为SQL,其构建目的是构建关系数据库的答案引擎

它可以识别各种过滤器、分组和其他分析元素,因此可以回答以下问题:

  • 显示过去4个月来自法国的所有订单
  • 按上周总金额显示前5名订单
  • 每个客户的平均订单数量是多少

    等等

您必须配置系统以识别表、字段和术语


注意:我在kueri工作。这可能比你想象的要难。请看-这是一个很好的自然语言模糊性的例子-作者J.Pitrat。是的,添加您尝试过但未获得预期输出的代码。我已将问题转换为语句,然后再转换为标记。嘿,您是对的,很难实现。但是我有我想要实现的数据库的数据字典。我想为具有示例表的特定数据库实现它。知道如何继续吗?-1表示这几乎是不可能的,特别是对于一个封闭的数据集@艾哈迈德马苏德(AhmedMasud),然后做一个简单的应用程序,让100人使用“他们的语言”在应用程序中执行命令…@MaciejCygan LOL你真的不知道你在说什么,这确实发生了。你看过我给你的链接了吗?自然语言处理是一个非常有趣和不断发展的领域。这里还有一些东西给你,以防万一你错过了@AhmedMasud好的,我已经在这个网站上看到了现场演示。是的,它正在发生,所以你是对的,但它还远远没有完成。查询非常原始,通常归结为单个单词。是的,听起来很有趣。如果你也发布代码,这会很有帮助。仅供参考,有几种方法可以使用我发布的内容,但它们都有问题,你需要设置一些启发式阈值。
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import opennlp.tools.chunker.ChunkerME;
import opennlp.tools.chunker.ChunkerModel;
import opennlp.tools.postag.POSModel;
import opennlp.tools.postag.POSTaggerME;
import opennlp.tools.tokenize.TokenizerME;
import opennlp.tools.tokenize.TokenizerModel;
import opennlp.tools.util.Span;

/**
 *
 * Extracts noun phrases from a sentence. To create sentences using OpenNLP use
 * the SentenceDetector classes.
 */
public class OpenNLPNounPhraseExtractor {

  static final int N = 2;

  public static void main(String[] args) {

    try {
      HashMap<String, Integer> termFrequencies = new HashMap<>();
      String modelPath = "c:\\temp\\opennlpmodels\\";
      TokenizerModel tm = new TokenizerModel(new FileInputStream(new File(modelPath + "en-token.zip")));
      TokenizerME wordBreaker = new TokenizerME(tm);
      POSModel pm = new POSModel(new FileInputStream(new File(modelPath + "en-pos-maxent.zip")));
      POSTaggerME posme = new POSTaggerME(pm);
      InputStream modelIn = new FileInputStream(modelPath + "en-chunker.zip");
      ChunkerModel chunkerModel = new ChunkerModel(modelIn);
      ChunkerME chunkerME = new ChunkerME(chunkerModel);
      //this is your sentence
      String sentence = "Barack Hussein Obama II  is the 44th awesome President of the United States, and the first African American to hold the office.";
      //words is the tokenized sentence
      String[] words = wordBreaker.tokenize(sentence);
      //posTags are the parts of speech of every word in the sentence (The chunker needs this info of course)
      String[] posTags = posme.tag(words);
      //chunks are the start end "spans" indices to the chunks in the words array
      Span[] chunks = chunkerME.chunkAsSpans(words, posTags);
      //chunkStrings are the actual chunks
      String[] chunkStrings = Span.spansToStrings(chunks, words);
      for (int i = 0; i < chunks.length; i++) {
        String np = chunkStrings[i];
        if (chunks[i].getType().equals("NP")) {
          if (termFrequencies.containsKey(np)) {
            termFrequencies.put(np, termFrequencies.get(np) + 1);
          } else {
            termFrequencies.put(np, 1);
          }
        }
      }
      System.out.println(termFrequencies);

    } catch (IOException e) {
    }
  }

}
select * from categories a inner join nounphrases b on a.id = b.catid where catname = @thecatIjustgotfromtheclassifier and contains(text,'search term')