我想使用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();
答案 0 :(得分:4)
对此的简单回答是,你可以"可以"做它 - 但它不切实际,几乎不可能。简单的原因是你可以有许多类似的问题,可以完全相同。使用SQL查询,您必须保留特定的语法才能获取数据...使用标准语言,您可能有100种不同的语法来获取相同的内容。将其映射到SQL语言是非常不切实际的,几乎是不可能的。
是的,你可以强迫用户使用特定的单词或特定的问题格式,这样你的程序就可以将它们解释为SQL查询 - 但这又打破了你想要实现的范式
编辑:
因为你太绝望了;)你可以"潜在地"做这样的事
让我们想象一个非常简单的查询
SELECT * FROM USERS WHERE AGE = '20';
有哪些可能的人类语言问题?
你可以做的是创建某种Map<key,value>
,即ie。
Key = USERS;
Value = people, humans,
另一张地图
Key = SELECT;
Value = Can you show me, Display, Do we have, Search, How many;
依此类推 - 这将创建一个复杂的地图,其中包含所有可能的短语,这些短语可能意味着相同的东西并且对应于给定的SQL查询语法元素。这可能不是最好的解决方案,但它可能是我可能做的 - 至少这是我将要开始的
答案 1 :(得分:3)
我现在没有时间发布代码,但请查看opennlp句子chunker和文档分类程序。我认为你可以 - 创造性地 - 使用doccat建立你的“关键”和句子chunker来建立名词和动词短语(不是标记,但实际上是多字短语)并结合结果。因此,在查询时,您将对句子进行分类以建立密钥,然后对句子进行分块,然后执行连接到密钥表的查询,然后模糊(可能是全文索引)短语表。只是一个想法,如果有趣,我会将代码发布为编辑。你必须使用样本构建doccat模型。
修改
以下是如何使用opennlp文档分类程序获取一组类别的概率dist,您需要提供一个具有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;
}
}
这里是如何用一个句子chunker和句子短语
来组织句子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) {
}
}
}
所以我想的是对输入文本进行分类,然后提取并存储名词短语,然后在查询时对输入进行分类,得到一个类别,然后在SQL中执行类似的操作
select * from categories a inner join nounphrases b on a.id = b.catid where catname = @thecatIjustgotfromtheclassifier and contains(text,'search term')
或类似的东西
答案 2 :(得分:1)
查看Kueri.me
该产品提供的技术支持将英语转换为SQL的搜索框,它构建用于构建关系数据库的答案引擎。
它可以识别各种过滤器,分组和其他分析元素,因此它可以回答诸如
之类的问题每位客户的平均订单数
依此类推。
您必须将系统配置为识别您的表格,字段和行话。
注意:我在kueri.me工作