📄 avaliador.java
字号:
package br.ufrj.cos.bri.model;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.Set;
import java.util.StringTokenizer;
import javax.persistence.EntityManager;
import javax.persistence.Query;
import org.apache.lucene.analysis.snowball.SnowballAnalyzer;
import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field;
import org.apache.lucene.index.IndexReader;
import org.apache.lucene.index.IndexWriter;
import org.apache.lucene.index.IndexWriter.MaxFieldLength;
import org.apache.lucene.queryParser.QueryParser;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.ScoreDoc;
import org.apache.lucene.search.Searcher;
import org.apache.lucene.search.TopDocCollector;
public class Avaliador {
public static final String TITULO = "titulo";
public static final String ABSTRACT = "textoAbstract";
public static final String TITULOABSTRACT = "tituloAbstract";
public static final String DOCCOMPLETO = "textoCompleto";
public static final String LUCENE = "LUCENE";
public static final String MYSQL = "MYSQL";
private static final String BOOLEANMODE = "BOOLEAN MODE";
private static final String NATURALLANGUAGE = "NATURAL LANGUAGE MODE";
private static final String NATURALLANGUAGEQUERYEXPANSION = "NATURAL LANGUAGE MODE WITH QUERY EXPANSION";
private static final String BOOLEANQUERY = "BOOLEAN QUERY";
private static final String PRHASEQUERY = "PRHASE QUERY";
private static final String FUZZYQUERY = "FUZZY QUERY";
public Avaliador() {
}
public static List<double[]> geraResultadosPrecisionRecall(String campoConsulta, EntityManager em) {
List<double[]> resultadosConsulta = new ArrayList<double[]>();
System.out.println("Analisando resultado em modo booleano");
double[] resultadoBooleanMode = geraResultadosPrecisionRecallMySQL(campoConsulta, BOOLEANMODE, em);
System.out.println("Analisando resultado no modo natural language");
double[] resultadoNaturalLanguage = geraResultadosPrecisionRecallMySQL(campoConsulta, NATURALLANGUAGE, em);
System.out.println("Analisando resultado no modo natural language com query expansion");
double[] resultadoNaturalLanguageQueryExpansion = geraResultadosPrecisionRecallMySQL(campoConsulta, NATURALLANGUAGEQUERYEXPANSION, em);
resultadosConsulta.add(resultadoBooleanMode);
resultadosConsulta.add(resultadoNaturalLanguage);
resultadosConsulta.add(resultadoNaturalLanguageQueryExpansion);
return resultadosConsulta;
}
public static List<double[]> geraResultadosPrecisionRecallLucene(String campoConsulta, EntityManager em) {
List<double[]> resultadosConsulta = new ArrayList<double[]>();
System.out.println("Analisando resultado com boolean query");
double[] resultadoBooleanQuery = calculaPrecisionRecallLucene(campoConsulta, Avaliador.BOOLEANQUERY, em);
System.out.println("Analisando resultado com phrase query");
double[] resultadoPhraseQuery = calculaPrecisionRecallLucene(campoConsulta, Avaliador.PRHASEQUERY, em);
System.out.println("Analisando resultado com fuzzy query");
double[] resultadoFuzzyQuery = calculaPrecisionRecallLucene(campoConsulta, Avaliador.FUZZYQUERY, em);
resultadosConsulta.add(resultadoBooleanQuery);
resultadosConsulta.add(resultadoPhraseQuery);
resultadosConsulta.add(resultadoFuzzyQuery);
return resultadosConsulta;
}
private static double[] geraResultadosPrecisionRecallMySQL(String campoConsulta, String tipoQuery, EntityManager em) {
double[] totalArrayPrecision = new double[11];
List<Pergunta> queryPergunta = em.createQuery("select p from Pergunta p").getResultList();
double numeroPerguntas = queryPergunta.size();
for (Pergunta p: queryPergunta) {
double[] precisionRecallPergunta = new double[11];
double numeroRespostasRelevantes = Double.parseDouble(p.getNumeroResultados());
List<ItemScore> respostasRelevantes = p.getItens();
String sql = "select * from (SELECT *, MATCH ("+ campoConsulta +") AGAINST (? IN "+ tipoQuery +") as score FROM Documento order by score desc) t where t.score > 0";
Query q = em.createNativeQuery(sql, Documento.class);
q.setParameter(1, p.getQuery());
List<Documento> respostasEncontradas = q.getResultList();
List<PrecisionRecall> documentosRelevantes = verificaDocumentosRelevantes(respostasEncontradas, respostasRelevantes, numeroRespostasRelevantes);
calculaPrecision(precisionRecallPergunta, documentosRelevantes);
acumula(precisionRecallPergunta, totalArrayPrecision);
}
geraMediaPrecision(totalArrayPrecision, numeroPerguntas);
return totalArrayPrecision;
}
private static void geraMediaPrecision(double[] totalArrayPrecision, double numeroPerguntas) {
for (int i = 0; i < totalArrayPrecision.length; i++) {
totalArrayPrecision[i] /= numeroPerguntas;
}
}
private static void acumula(double[] arrayPrecision, double[] totalArrayPrecision) {
for (int i = 0; i < totalArrayPrecision.length; i++) {
totalArrayPrecision[i] += arrayPrecision[i];
}
}
private static void calculaPrecision(double[] precisionRecallPergunta, List<PrecisionRecall> documentosRelevantes) {
for (int i = 0; i < precisionRecallPergunta.length; i++) {
double d = i * 0.1;
double max = 0;
for (PrecisionRecall pr: documentosRelevantes) {
double recall = pr.getRecall();
double precision = pr.getPrecision();
if ((d <= recall) && ( max <= precision )) {
max = precision;
precisionRecallPergunta[i] = precision;
}
}
}
}
private static List<PrecisionRecall> verificaDocumentosRelevantes(List<Documento> respostasEncontradas, List<ItemScore> respostasRelevantes, double numeroRespostasRelevantes) {
List<PrecisionRecall> documentosRelevantes = new ArrayList<PrecisionRecall>();
for (Documento documento: respostasEncontradas) {
String numeroRegistro = documento.getNumeroRegistro().trim();
int numRegistro = Integer.valueOf(numeroRegistro);
for (ItemScore itemScore: respostasRelevantes) {
String numeroValor = itemScore.getValor();
int numValor = Integer.parseInt(numeroValor);
if (numRegistro == numValor) {
PrecisionRecall precisionRecall = new PrecisionRecall();
precisionRecall.setDocumento(documento);
documentosRelevantes.add(precisionRecall);
int posicaoDocumentoNaLista = respostasEncontradas.indexOf(documento) + 1;
double dE = documentosRelevantes.size();
double pDL = Double.valueOf(posicaoDocumentoNaLista) ;
double precision = dE/ pDL;
double recall = documentosRelevantes.size()/numeroRespostasRelevantes;
precisionRecall.setPrecision(precision);
precisionRecall.setRecall(recall);
break;
}
}
}
return documentosRelevantes;
}
public static String[] listaStopWords(File fileStopWords) {
List<String> sw = new ArrayList<String>();
try {
Scanner scan = new Scanner(fileStopWords);
while (scan.hasNext()) {
sw.add(scan.nextLine());
}
scan.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
}
return sw.toArray(new String[0]);
}
public static void criaIndiceLucene(EntityManager em) {
try {
File index = new File("index");
index.mkdir();
File fileStopWords = new File("stopwords.txt");
String[] stopWords = listaStopWords(fileStopWords);
IndexWriter w = new IndexWriter(index, new SnowballAnalyzer("English", stopWords), true, new MaxFieldLength(10000000));
List<Documento> documentos = em.createQuery("select d from Documento d").getResultList();
for (Documento d: documentos) {
addDoc(w, d);
}
w.optimize();
w.close();
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -