2016-07-07 3 views
0

ドイツ語の言語アナライザーを使用して一部のコンテンツをトークン化しています。私は基本的に "小文字"、 "german_stop"、 "german_keywords"、 "german_normalization"、 "german_stemmer"のマクロフィルタであることを知っています。言語アナライザー(ドイツ語)を構成する方法やカスタムノーマライザーを作成する方法

私の問題はノミラル化フィルタと関係があります。ここにはElasticsearch DocumentationLucene Implementationのフィルタがあります。問題は、ueとoeがドイツ語の文字ä、öとüとして扱われ、したがってa、o、uに変換されるということです。

第2の変換は良好ですが、第1の変換はそれが解決するよりも多くの問題につながります。本当にä、ü、öを表すドイツのテキストには、通常、ae、ue、oeはありません。彼らが実際に現れる時代のほとんどは、「Aearodynamik」(空気力学)のようなラテン語や英語に由来する外国語の中にあります。フィルターは 'Ae'を 'Ä'と解釈し、 'A'に変換します。これはトークンとして 'arodynamik'を生成します。通常、検索語もそのフィルタで正規化されるため、これは問題にはなりません。しかし、これはワイルドカード検索と組み合わせると問題になります:

「FooEdit」のような言葉を想像してみましょう。これは 'foodit'にトークン化されます。 'edit OR * edit *'(ユーザーが 'edit'を検索したときの私の通常の検索)の検索では、 'edit'の 'e'が失われてしまい結果が得られません。私のコンテンツにはそのような言葉がたくさんあり、人々は部分的な言葉を探しているので、それは端正なケースではないようです。

私の質問は、 'ae - > a'変換を取り除く方法は何ですか?私が理解しているのは、これがGerman2 snowball algorithmの一部なので、これはおそらく変更できません。それは、私が正規化全体のステップを取り除かなければならないことを意味するのでしょうか、私が好きではない部分を取り除くだけで私の独自のバージョンのSnowballアルゴリズムを提供できますか?(カスタム正規化のためのスノーボールアルゴリズム)?あなたが言ったように

乾杯

トム

答えて

0

は、ドイツのアナライザは、あなたが記載された手順を組み合わせたパイプラインです。 (Documentation

理論上、上記のように独自のアナライザを指定し、german_normalizationフィルタを別のものに置き換えることができます。たとえば、Pattern Replace Token Filterです。私はそれを使用したことはありませんが、構文がChar Replace Token Filter(link)と等しいと思います。

+0

問題は、ワイルドカード、ファジー、正規表現のクエリ節が解析されないため、「エアロディー」が「arodynamik」と一致しないことです。 – femtoRgon

+0

@femtoRgon私は正しく読まなかった: – Slomo

0

この変換は、語幹ではなくGermanNormalizationFilterで処理されます。それはクラスが(多くのステマーとは違って)理解することは本当に難しいことではありません、と私は正しく理解していれば、あなたが欲しい欲しい取得する1行の変更のようになります。

public final class CustomGermanNormalizationFilter extends TokenFilter { 
    // FSM with 3 states: 
    private static final int N = 0; /* ordinary state */ 
    private static final int V = 1; /* stops 'u' from entering umlaut state */ 
    private static final int U = 2; /* umlaut state, allows e-deletion */ 

    private final CharTermAttribute termAtt = addAttribute(CharTermAttribute.class); 

    public CustomGermanNormalizationFilter(TokenStream input) { 
    super(input); 
    } 

    @Override 
    public boolean incrementToken() throws IOException { 
    if (input.incrementToken()) { 
     int state = N; 
     char buffer[] = termAtt.buffer(); 
     int length = termAtt.length(); 
     for (int i = 0; i < length; i++) { 
     final char c = buffer[i]; 
     switch(c) { 
//Removing this case should prevent e-deletion for "ae" 
//  case 'a': 
      case 'o': 
      state = U; 
      break; 
      case 'u': 
      state = (state == N) ? U : V; 
      break; 
      case 'e': 
      if (state == U) 
       length = StemmerUtil.delete(buffer, i--, length); 
      state = V; 
      break; 
      case 'i': 
      case 'q': 
      case 'y': 
      state = V; 
      break; 
      case 'ä': 
      buffer[i] = 'a'; 
      state = V; 
      break; 
      case 'ö': 
      buffer[i] = 'o'; 
      state = V; 
      break; 
      case 'ü': 
      buffer[i] = 'u'; 
      state = V; 
      break; 
      case 'ß': 
      buffer[i++] = 's'; 
      buffer = termAtt.resizeBuffer(1+length); 
      if (i < length) 
       System.arraycopy(buffer, i, buffer, i+1, (length-i)); 
      buffer[i] = 's'; 
      length++; 
      state = N; 
      break; 
      default: 
      state = N; 
     } 
     } 
     termAtt.setLength(length); 
     return true; 
    } else { 
     return false; 
    } 
    } 
} 

german_normalizationの代わりに、やるべきことを使いますトリック。

+0

そうです、コード内でどのように振舞うべきかの詳細を変更するのは問題ではありませんが、アルゴリズム自体に変更を加えても、私はどのように使用できるのか分かりません。 (私の最初の質問の最後の文)。 – Tom

関連する問題