From 6246f020fdeffe821952221424ebfe4fe5f972f0 Mon Sep 17 00:00:00 2001 From: "Alexander.A.Kuznetsov" Date: Wed, 11 Nov 2009 22:21:14 +0000 Subject: [PATCH] working on prefixes hypotities git-svn-id: https://russianmorphology.googlecode.com/svn/trunk@86 d817d54c-26ab-11de-abc9-2f7d1455ff7a --- 1.txt | 0 ...potises.java => PrefixesRulesBuilder.java} | 24 +- .../generator/RussianPrefixesBuilder.java | 3 +- .../src/test/java/org/apache/lucene/text.txt | 372 ++++++++++++++++++ .../lucene/morphology/LuceneMorphology.java | 10 +- .../apache/lucene/morphology/Morphology.java | 6 +- .../morphology/MorphologyWithPrefix.java | 52 +++ .../apache/lucene/morphology/PrefixRule.java | 61 +++ .../lucene/morphology/russian/TestSpeed.java | 60 +++ .../russian/russian-morphology-test.txt | 4 +- 10 files changed, 577 insertions(+), 15 deletions(-) create mode 100644 1.txt rename dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/{PrefixesHypotises.java => PrefixesRulesBuilder.java} (71%) create mode 100644 dictionary-reader/src/test/java/org/apache/lucene/text.txt create mode 100644 morph/src/main/java/org/apache/lucene/morphology/MorphologyWithPrefix.java create mode 100644 morph/src/main/java/org/apache/lucene/morphology/PrefixRule.java create mode 100644 russian/src/main/java/org/apache/lucene/morphology/russian/TestSpeed.java diff --git a/1.txt b/1.txt new file mode 100644 index 0000000..e69de29 diff --git a/dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/PrefixesHypotises.java b/dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/PrefixesRulesBuilder.java similarity index 71% rename from dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/PrefixesHypotises.java rename to dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/PrefixesRulesBuilder.java index c0d8d42..70724ba 100644 --- a/dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/PrefixesHypotises.java +++ b/dictionary-reader/src/main/java/org/apache/lucene/morphology/dictionary/PrefixesRulesBuilder.java @@ -1,18 +1,20 @@ package org.apache.lucene.morphology.dictionary; +import org.apache.lucene.morphology.PrefixRule; + import java.util.*; import java.io.IOException; import java.io.BufferedReader; -public class PrefixesHypotises extends DictonaryReader { +public class PrefixesRulesBuilder extends DictonaryReader { private Map> rules = new HashMap>(); - public PrefixesHypotises(String fileName, Set ingnoredForm) { + public PrefixesRulesBuilder(String fileName, Set ingnoredForm) { super(fileName, ingnoredForm); } - public PrefixesHypotises(String fileName, String fileEncoding, Set ingnoredForm) { + public PrefixesRulesBuilder(String fileName, String fileEncoding, Set ingnoredForm) { super(fileName, fileEncoding, ingnoredForm); } @@ -23,6 +25,22 @@ public class PrefixesHypotises extends DictonaryReader { System.out.println(rules); } + public List getPrefixRules(){ + List prefixRules = new ArrayList(); + for(FlexiaModel key:rules.keySet()){ + PrefixRule prefixRule = new PrefixRule(); + prefixRule.setPrefix(key.getPrefix()); + prefixRule.setLastLetter(key.getSuffix().charAt(0)); + HashSet map = new HashSet(); + for(FlexiaModel fm:rules.get(key)){ + map.add(fm.getCode()); + } + prefixRule.setForms(map); + prefixRules.add(prefixRule); + } + return prefixRules; + } + @Override protected void readWords(BufferedReader reader, WordProccessor wordProccessor) throws IOException { sckipBlock(reader); diff --git a/dictionary-reader/src/main/java/org/apache/lucene/morphology/generator/RussianPrefixesBuilder.java b/dictionary-reader/src/main/java/org/apache/lucene/morphology/generator/RussianPrefixesBuilder.java index dd5fc48..e0b12a7 100644 --- a/dictionary-reader/src/main/java/org/apache/lucene/morphology/generator/RussianPrefixesBuilder.java +++ b/dictionary-reader/src/main/java/org/apache/lucene/morphology/generator/RussianPrefixesBuilder.java @@ -17,7 +17,6 @@ package org.apache.lucene.morphology.generator; import org.apache.lucene.morphology.dictionary.*; -import org.apache.lucene.morphology.russian.RussianLetterDecoderEncoder; import java.io.IOException; import java.util.HashSet; @@ -26,7 +25,7 @@ import java.util.HashSet; public class RussianPrefixesBuilder { public static void main(String[] args) throws IOException { GrammaReader grammaInfo = new GrammaReader("dictonary/Dicts/Morph/rgramtab.tab"); - PrefixesHypotises dictonaryReader = new PrefixesHypotises("dictonary/Dicts/SrcMorph/RusSrc/morphs.mrd", new HashSet()); + PrefixesRulesBuilder dictonaryReader = new PrefixesRulesBuilder("dictonary/Dicts/SrcMorph/RusSrc/morphs.mrd", new HashSet()); //RussianLetterDecoderEncoder decoderEncoder = new RussianLetterDecoderEncoder(); //StatiticsCollector statiticsCollector = new StatiticsCollector(grammaInfo, decoderEncoder); diff --git a/dictionary-reader/src/test/java/org/apache/lucene/text.txt b/dictionary-reader/src/test/java/org/apache/lucene/text.txt new file mode 100644 index 0000000..b06e800 --- /dev/null +++ b/dictionary-reader/src/test/java/org/apache/lucene/text.txt @@ -0,0 +1,372 @@ +[ ть + у + ем + ешь + ете + ет + ут + + ла + ло + ли + я + ши + ем + емте + по ай + ь + по айте + ьте + ущий + ущего + ущему + ущего + ущий + ущим + ущем + ущая + ущей + ущей + ущую + ущей + ущею + ущей + ущее + ущего + ущему + ущее + ущим + ущем + ущие + ущих + ущим + ущих + ущие + ущими + ущих + ший + шего + шему + шего + ший + шим + шем + шая + шей + шей + шую + шей + шею + шей + шее + шего + шему + шее + шим + шем + шие + ших + шим + ших + шие + шими + ших] +[ большой + большого + большому + большого + большой + большим + большом + большая + большой + большой + большую + большой + большою + большой + большое + большого + большому + большое + большим + большом + большие + больших + большим + больших + большие + большими + больших + велик + велика + велико + велики + больше + по больше + наи больший + наи большего + наи большему + наи большего + наи больший + наи большим + наи большем + наи большая + наи большей + наи большей + наи большую + наи большей + наи большею + наи большей + наи большее + наи большего + наи большему + наи большее + наи большим + наи большем + наи большие + наи больших + наи большим + наи больших + наи большие + наи большими + наи больших] +[ вероятный + вероятного + вероятному + вероятного + вероятный + вероятным + вероятном + вероятная + вероятной + вероятной + вероятную + вероятной + вероятною + вероятной + вероятное + вероятного + вероятному + вероятное + вероятным + вероятном + вероятные + вероятных + вероятным + вероятных + вероятные + вероятными + вероятных + вероятен + вероятна + вероятно + вероятны + вероятнее + вероятней + по вероятнее + по вероятней + вероятнейший + наи невероятнейший + вероятнейшего + наи невероятнейшего + вероятнейшему + наи невероятнейшему + вероятнейшего + наи невероятнейшего + вероятнейший + наи невероятнейший + вероятнейшим + наи невероятнейшим + вероятнейшем + наи невероятнейшем + вероятнейшая + наи невероятнейшая + вероятнейшей + наи невероятнейшей + вероятнейшей + наи невероятнейшей + вероятнейшую + наи невероятнейшую + вероятнейшей + вероятнейшею + наи невероятнейшей + наи невероятнейшею + вероятнейшей + наи невероятнейшей + вероятнейшее + наи невероятнейшее + вероятнейшего + наи невероятнейшего + вероятнейшему + наи невероятнейшему + вероятнейшее + наи невероятнейшее + вероятнейшим + наи невероятнейшим + вероятнейшем + наи невероятнейшем + вероятнейшие + наи невероятнейшие + вероятнейших + наи невероятнейших + вероятнейшим + наи невероятнейшим + вероятнейших + наи невероятнейших + вероятнейшие + наи невероятнейшие + вероятнейшими + наи невероятнейшими + вероятнейших + наи невероятнейших] +[ аленький + аленького + аленькому + аленького + аленький + аленьким + аленьком + аленькая + аленькой + аленькой + аленькую + аленькой + аленькою + аленькой + аленькое + аленького + аленькому + аленькое + аленьким + аленьком + аленькие + аленьких + аленьким + аленьких + аленькие + аленькими + аленьких + ал + ала + ало + алы + еньше + по еньше + алейший + наи еньший + алейшего + наи еньшего + алейшему + наи еньшему + алейшего + наи еньшего + алейший + наи еньший + алейшим + наи еньшим + алейшем + наи еньшем + алейшая + наи еньшая + алейшей + наи еньшей + алейшей + наи еньшей + алейшую + наи еньшую + алейшей + алейшею + наи еньшей + наи еньшею + алейшей + наи еньшей + алейшее + наи еньшее + алейшего + наи еньшего + алейшему + наи еньшему + алейшее + наи еньшее + алейшим + наи еньшим + алейшем + наи еньшем + алейшие + наи еньшие + алейших + наи еньших + алейшим + наи еньшим + алейших + наи еньших + алейшие + наи еньшие + алейшими + наи еньшими + алейших + наи еньших] +[ ьный + ьного + ьному + ьного + ьный + ьным + ьном + ьная + ьной + ьной + ьную + ьной + ьною + ьной + ьное + ьного + ьному + ьное + ьным + ьном + ьные + ьных + ьным + ьных + ьные + ьными + ьных + ен + ьна + ьно + ьны + ьны + ьнее + ьней + по ьнее + по ьней + наи ьнейший + наи ьнейшего + наи ьнейшему + наи ьнейшего + наи ьнейший + наи ьнейшим + наи ьнейшем + наи ьнейшая + наи ьнейшей + наи ьнейшей + наи ьнейшую + наи ьнейшей + наи ьнейшею + наи ьнейшей + наи ьнейшее + наи ьнейшего + наи ьнейшему + наи ьнейшее + наи ьнейшим + наи ьнейшем + наи ьнейшие + наи ьнейших + наи ьнейшим + наи ьнейших + наи ьнейшие + наи ьнейшими + наи ьнейших] \ No newline at end of file diff --git a/morph/src/main/java/org/apache/lucene/morphology/LuceneMorphology.java b/morph/src/main/java/org/apache/lucene/morphology/LuceneMorphology.java index 3c09d44..8c8a1e1 100644 --- a/morph/src/main/java/org/apache/lucene/morphology/LuceneMorphology.java +++ b/morph/src/main/java/org/apache/lucene/morphology/LuceneMorphology.java @@ -34,14 +34,8 @@ public class LuceneMorphology extends Morphology { } @Override - public List getMorhInfo(String s) { - ArrayList result = new ArrayList(); - int[] ints = decoderEncoder.encodeToArray(revertWord(s)); - int ruleId = findRuleId(ints); - for (Heuristic h : rules[rulesId[ruleId]]) { - result.add(h.transofrmWord(s)); - } - return result; + protected String createForm(String form, String grammaInfo) { + return form; } protected void readRules(BufferedReader bufferedReader) throws IOException { diff --git a/morph/src/main/java/org/apache/lucene/morphology/Morphology.java b/morph/src/main/java/org/apache/lucene/morphology/Morphology.java index 0202562..bf8de9d 100644 --- a/morph/src/main/java/org/apache/lucene/morphology/Morphology.java +++ b/morph/src/main/java/org/apache/lucene/morphology/Morphology.java @@ -68,11 +68,15 @@ public class Morphology { int[] ints = decoderEncoder.encodeToArray(revertWord(s)); int ruleId = findRuleId(ints); for (Heuristic h : rules[rulesId[ruleId]]) { - result.add(h.transofrmWord(s) + "|" + grammaInfo[h.getFormMorphInfo()]); + result.add(createForm(h.transofrmWord(s),grammaInfo[h.getFormMorphInfo()])); } return result; } + protected String createForm(String form,String grammaInfo){ + return form+"|"+grammaInfo; + } + protected int findRuleId(int[] ints) { int low = 0; int high = separators.length - 1; diff --git a/morph/src/main/java/org/apache/lucene/morphology/MorphologyWithPrefix.java b/morph/src/main/java/org/apache/lucene/morphology/MorphologyWithPrefix.java new file mode 100644 index 0000000..b340d93 --- /dev/null +++ b/morph/src/main/java/org/apache/lucene/morphology/MorphologyWithPrefix.java @@ -0,0 +1,52 @@ +package org.apache.lucene.morphology; + +import java.io.IOException; +import java.io.InputStream; +import java.util.Map; +import java.util.List; +import java.util.HashMap; +import java.util.ArrayList; + + +public class MorphologyWithPrefix extends Morphology { + private Map prefixRuleMap = new HashMap(); + + public MorphologyWithPrefix(String fileName, LetterDecoderEncoder decoderEncoder) throws IOException { + super(fileName, decoderEncoder); + } + + public MorphologyWithPrefix(InputStream inputStream, LetterDecoderEncoder decoderEncoder) throws IOException { + super(inputStream, decoderEncoder); + } + + public MorphologyWithPrefix(int[][] separators, short[] rulesId, Heuristic[][] rules, String[] grammaInfo) { + super(separators, rulesId, rules, grammaInfo); + } + + @Override + public List getMorhInfo(String s) { + if (s.length() < 4) { + return super.getMorhInfo(s); + } + String ruleIndex = "" + s.charAt(0) + s.charAt(s.length() - 1); + PrefixRule prefixRule = prefixRuleMap.get(ruleIndex); + if (prefixRule == null) { + return super.getMorhInfo(s); + } + if (s.startsWith(prefixRule.getPrefix())) { + return super.getMorhInfo(s); + } + String sWithoutPrefix = s.substring(prefixRule.getPrefix().length()); + + int[] ints = decoderEncoder.encodeToArray(revertWord(sWithoutPrefix)); + int ruleId = findRuleId(ints); + ArrayList result = new ArrayList(); + for (Heuristic h : rules[rulesId[ruleId]]) { + String morphInfo = grammaInfo[h.getFormMorphInfo()]; + if(prefixRule.getForms().contains(morphInfo)){ + result.add(createForm(h.transofrmWord(sWithoutPrefix),"pr")); + } + } + return result.size() > 0 ? result : super.getMorhInfo(s); + } +} diff --git a/morph/src/main/java/org/apache/lucene/morphology/PrefixRule.java b/morph/src/main/java/org/apache/lucene/morphology/PrefixRule.java new file mode 100644 index 0000000..a5f0c69 --- /dev/null +++ b/morph/src/main/java/org/apache/lucene/morphology/PrefixRule.java @@ -0,0 +1,61 @@ +package org.apache.lucene.morphology; + +import java.io.Serializable; +import java.util.HashSet; + + +public class PrefixRule implements Serializable { + private Character lastLetter; + private String prefix; + private HashSet forms; + + public Character getLastLetter() { + return lastLetter; + } + + public void setLastLetter(Character lastLetter) { + this.lastLetter = lastLetter; + } + + public String getPrefix() { + return prefix; + } + + public void setPrefix(String prefix) { + this.prefix = prefix; + } + + public HashSet getForms() { + return forms; + } + + public void setForms(HashSet forms) { + this.forms = forms; + } + + public String getHashString() { + return "" + prefix.charAt(0) + lastLetter; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + + PrefixRule that = (PrefixRule) o; + + if (forms != null ? !forms.equals(that.forms) : that.forms != null) return false; + if (lastLetter != null ? !lastLetter.equals(that.lastLetter) : that.lastLetter != null) return false; + if (prefix != null ? !prefix.equals(that.prefix) : that.prefix != null) return false; + + return true; + } + + @Override + public int hashCode() { + int result = lastLetter != null ? lastLetter.hashCode() : 0; + result = 31 * result + (prefix != null ? prefix.hashCode() : 0); + result = 31 * result + (forms != null ? forms.hashCode() : 0); + return result; + } +} diff --git a/russian/src/main/java/org/apache/lucene/morphology/russian/TestSpeed.java b/russian/src/main/java/org/apache/lucene/morphology/russian/TestSpeed.java new file mode 100644 index 0000000..e0b33f8 --- /dev/null +++ b/russian/src/main/java/org/apache/lucene/morphology/russian/TestSpeed.java @@ -0,0 +1,60 @@ +/** + * Copyright 2009 Alexander Kuznetsov + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.morphology.russian; + +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.analysis.Token; + +import java.io.IOException; +import java.io.FileInputStream; +import java.io.InputStreamReader; +import java.util.HashSet; + +/** + * Created by IntelliJ IDEA. + * User: akuznetsov + * Date: 31.10.2009 + * Time: 14:01:11 + * To change this template use File | Settings | File Templates. + */ +public class TestSpeed { + + public static void main(String[] args) throws IOException { + RussianAnalayzer russianAnalayzer = new RussianAnalayzer(); + bookProccess(russianAnalayzer, "C:/tmp/_Aleksandr_Suhov_Tanets_na_raskalennyih_uglyah1.fb2"); + Long stat = System.currentTimeMillis(); + bookProccess(russianAnalayzer, "C:/tmp/_Aleksandr_Suhov_Tanets_na_raskalennyih_uglyah1.fb2"); + System.out.println("Done in " + (System.currentTimeMillis() - stat)); + } + + private static void bookProccess(RussianAnalayzer russianAnalayzer, String bookName) throws IOException { + FileInputStream inputStream = new FileInputStream(bookName); + TokenStream tokenStream = russianAnalayzer.tokenStream(null,new InputStreamReader(inputStream,"UTF-8")); + final Token reusableToken = new Token(); + long count = 0; + Token nextToken; + for (; ;) { + nextToken = tokenStream.next(reusableToken); + // System.out.println(" " + nextToken.term()); + count++; + if (nextToken == null) { + break; + } + + } + //System.out.println("Words " + count); + } +} diff --git a/russian/src/test/resources/org/apache/lucene/morphology/russian/russian-morphology-test.txt b/russian/src/test/resources/org/apache/lucene/morphology/russian/russian-morphology-test.txt index fdf34da..a874169 100644 --- a/russian/src/test/resources/org/apache/lucene/morphology/russian/russian-morphology-test.txt +++ b/russian/src/test/resources/org/apache/lucene/morphology/russian/russian-morphology-test.txt @@ -18,4 +18,6 @@ на на тест тест тесто спам спам -спама спам \ No newline at end of file +спама спам +наигранный наигранный +наивный наивный \ No newline at end of file