Commit c834f282 authored by Julia Fischer's avatar Julia Fischer

Aufgabe 2 verbessert um Test auf Eindeutigkeit eines Ergebnisses anhand Score

parent f4bc5dfc
Pipeline #2790 skipped
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -4,27 +4,18 @@ import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
import org.apache.solr.analysis.LowerCaseFilterFactory;
import org.apache.solr.analysis.SnowballPorterFilterFactory;
import org.apache.solr.analysis.StandardTokenizerFactory;
import org.apache.lucene.analysis.de.GermanAnalyzer;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.Analyzer;
import org.hibernate.search.annotations.AnalyzerDef;
import org.hibernate.search.annotations.Field;
import org.hibernate.search.annotations.Index;
import org.hibernate.search.annotations.Indexed;
import org.hibernate.search.annotations.Parameter;
import org.hibernate.search.annotations.Store;
import org.hibernate.search.annotations.TokenFilterDef;
import org.hibernate.search.annotations.TokenizerDef;
@Entity
@Indexed
@Table(name = "alpha_id")
@AnalyzerDef(name = "customanalyzer", tokenizer = @TokenizerDef(factory = StandardTokenizerFactory.class), filters = {
@TokenFilterDef(factory = LowerCaseFilterFactory.class),
@TokenFilterDef(factory = SnowballPorterFilterFactory.class, params = {
@Parameter(name = "language", value = "German") }) })
@Analyzer(impl = GermanAnalyzer.class)
public class AlphaID {
private Integer validity;
......@@ -57,6 +48,8 @@ public class AlphaID {
}
@Id
@Analyzer(impl = GermanAnalyzer.class)
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
public String getAlpha_id() {
return alpha_id;
}
......@@ -65,8 +58,8 @@ public class AlphaID {
this.alpha_id = alpha_id;
}
@Analyzer(definition = "customanalyzer")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
@Analyzer(impl = GermanAnalyzer.class)
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
public String getPrimary_key() {
return primary_key;
}
......@@ -91,8 +84,8 @@ public class AlphaID {
this.extra_key = extra_key;
}
@Analyzer(definition = "customanalyzer")
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.NO)
@Analyzer(impl = GermanAnalyzer.class)
@Field(index = Index.YES, analyze = Analyze.YES, store = Store.YES)
public String getText() {
return text;
}
......
package org.uebung7.medReader;
import java.util.ArrayList;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.search.FullTextQuery;
import org.hibernate.search.FullTextSession;
import org.hibernate.search.Search;
import org.hibernate.search.query.dsl.QueryBuilder;
......@@ -14,6 +16,13 @@ import org.hibernate.search.query.dsl.QueryBuilder;
*/
public class App {
/*
* Verhältnis von Score 1 zu Score 2 muss mindestens 1,5 betragen. Ein
* Verhältnis von 1,0 bedeutet, dass die ersten beiden Suchergebnisse den
* gleichen Score erhalten haben
*/
public static final float RATIO = 1.5f;
/**
* Indizierung
*
......@@ -28,31 +37,128 @@ public class App {
fullTextSession.close();
}
/**
* Info: Die Suchergebnisse der Lucene-Textsuche sind soriert nach Score -
* der beste Treffer steht ganz oben.
*
* Ermittelt anhand zweier Scores (Score des ersten und Score des zweiten
* Suchergebnisses), ob das erste Suchergebnis signifikant besser passt als
* das zweite. Dies wird über das Verhältnis der Scores erreicht.
*
* @param score1
* @param score2
* @return true, wenn Ergebnis eindeutig, sonst false
*/
private static boolean isUnique(float score1, float score2) {
float resultRatio = score1 / score2;
if (resultRatio >= RATIO) {
return true;
}
return false;
}
/**
*
* Suche: Lucene-Query mit Suchbegriff searchValue erstellen und gegen die
* indizierten Felder ausführen.
* indizierten Felder ausführen. Ebenfalls wird der Score des
* Suchergebnisses mit ermittelt.
*
* @param searchValue
* @return Liste von ICD10-Diagnosen
*/
private static List<AlphaID> search(String searchValue) {
Session session = HibernateUtil.getSession();
FullTextSession fullTextSession = Search.getFullTextSession(session);
// Lucene Query erstellen - Suche in "text" (Diagnose-Namen) und
// "primary_key" (ICD10-Codes)
QueryBuilder queryBuilder = fullTextSession.getSearchFactory().buildQueryBuilder().forEntity(AlphaID.class)
.get();
org.apache.lucene.search.Query luceneQuery = queryBuilder.keyword().onFields("text", "primary_key")
.matching(searchValue).createQuery();
// wrap Lucene query in a javax.persistence.Query
org.hibernate.Query fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery, AlphaID.class);
org.hibernate.search.FullTextQuery fullTextQuery = fullTextSession.createFullTextQuery(luceneQuery,
AlphaID.class);
List<AlphaID> icd10CodeList = fullTextQuery.list();
// Suchergebnis beinhaltet neben Entität AlphaID auch den jeweiligen
// Score des Suchergebnisses
fullTextQuery.setProjection(FullTextQuery.THIS, FullTextQuery.SCORE);
List searchResults = fullTextQuery.list();
fullTextSession.close();
return icd10CodeList;
// Liste mit Suchergebnissen und Scores
return searchResults;
}
/**
* Erhält eine Liste mit den Suchergebnissen.
*
* Variante 1: Wenn mehr als 1 Suchergebnis vorliegt wird geprüft, ob das
* erste Suchergebnis eindeutig passt. Wenn JA, wird nur dieses ausgegeben.
* Wenn NEIN, werden alle Suchergebnisse ausgegeben
*
* Variante 2: Wenn genau ein Suchergebnis vorliegt, wird auch nur dieses
* zurückgegeben
*
* Variante 3 : Wenn kein Suchergebnis vorhanden ist, passiert nichts.
*
*
*/
private static List<AlphaID> reduceResultIfUnique(List results) {
List<AlphaID> diagnosen = new ArrayList<AlphaID>();
// Variante 1: Es wurden mehr als eine passende Diagnose gefunden
if (results.size() > 1) {
Object[] res1 = (Object[]) results.get(0);
float score1 = (float) res1[1];
Object[] res2 = (Object[]) results.get(1);
float score2 = (float) res2[1];
boolean isUnique = isUnique(score1, score2);
// Variante 3.1: Ergebnis ist eindeutig, da Verhältnis der Scores
// von Suchergebnis 1 und Suchergebnis 2 größer als RATIO --> Nur
// erstes Suchergebnis zurückgeben
if (isUnique) {
AlphaID alphaID = (AlphaID) res1[0];
Object score = res1[1];
diagnosen.add(alphaID);
// Variante 3.2: Ergebnis zu uneindeutig; alle Ergebnisse -->
// Alle Ergebnisse zurückgeben
// ausgeben
} else {
for (int k = 0; k < results.size(); k++) {
Object[] res = (Object[]) results.get(k);
AlphaID alphaID = (AlphaID) res[0];
Object score = res[1];
diagnosen.add(alphaID);
}
}
// Variante 2: Es wurde genau eine passende Diagnose gefunden
} else if (results.size() == 1) {
Object[] res = (Object[]) results.get(0);
AlphaID alphaID = (AlphaID) res[0];
float score = (float) res[1];
diagnosen.add(alphaID);
// Variante 3: Es wurde keine passende Diagnose gefunden
} else {
}
return diagnosen;
}
public static void main(String[] args) throws InterruptedException {
......@@ -61,18 +167,35 @@ public class App {
doIndex();
// Such-String
String searchValue = "Soziale Phobie";
searchValue = searchValue.replace("ohne", "").replace("mit", "");
String searchValue = "";
// searchValue = "ozufgefcdfdfbnf"; // kein Ergebnis
// searchValue = "Dysthymia"; // nur ein Ergebnis
searchValue = "Soziale Phobien"; // mehrere Ergebnisse - 1. eindeutig
// searchValue = "Gemini"; // mehrere Ergebnisse -kein Ergebnis
// eindeutig
// Diagnosen aus den Arztbriefen - zum Testen einzeln auskommentieren
// searchValue = "Dysthymia";
// searchValue = "Soziale Phobie";
// searchValue = "Migräne ohne Aura [gewöhnliche Migräne]";
// searchValue = "Meningeom rechts frontal";
// searchValue = "Symptomatische Epilepsie mit fokalen Anfällen";
// searchValue = "Bekannter paroxysmaler Lagerungsschwindel";
// searchValue = "Arterieller Hypertonus";
// searchValue = "Postpunktionelle Beschwerdesymptomatik";
// Suchen
List<AlphaID> result = search(searchValue);
List<AlphaID> searchResult = search(searchValue);
// Suchergebnis analysieren hinsichtlich eindeutiger Ergebnisse
List<AlphaID> diagnosen = reduceResultIfUnique(searchResult);
// Ausgabe der Ergebnisse
System.out.println(
"\n >>>>>>> Es wurden " + result.size() + " Einträge gefunden für '" + searchValue + "' <<<<<<< \n");
"\n >>>>>>> Es wurden " + diagnosen.size() + " Einträge gefunden für '" + searchValue + "' <<<<<<< \n");
for (AlphaID icd10 : result) {
System.out.println(icd10.getAlpha_id() + " - " + icd10.getPrimary_key() + " - " + icd10.getText());
for (AlphaID diagnose : diagnosen) {
System.out.println(diagnose.getAlpha_id() + " - " + diagnose.getPrimary_key() + " - " + diagnose.getText());
}
System.exit(0);
......
log4j.rootLogger=off, stdout, R
log4j.rootLogger=ERROR, stdout, R
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment