2011-03-22 46 views
24

Tôi đang xử lý một số văn bản tiếng Anh trong một ứng dụng Java và tôi cần phải chặn chúng. Ví dụ: từ văn bản "tiện nghi/tiện nghi", tôi cần phải nhận được "amenit".Bắt đầu từ tiếng Anh với Lucene

Chức năng trông giống như:

String stemTerm(String term){ 
    ... 
} 

Tôi đã tìm thấy Lucene Analyzer, nhưng có vẻ quá phức tạp đối với những gì tôi cần. http://lucene.apache.org/java/2_2_0/api/org/apache/lucene/analysis/PorterStemFilter.html

Có cách nào để sử dụng nó để chặn các từ mà không xây dựng Máy phân tích không? Tôi không hiểu tất cả hoạt động kinh doanh của Analyser ...

EDIT: Tôi thực sự cần một sự lemmatization. Lucene có thể làm điều này không?

+5

Tại sao bạn cần phải xuất phát từ bản thân? Lucene có một máy phân tích tên là SnowballAnalyzer mà bạn vừa tạo ra với tên gốc, ví dụ: 'SnowballAnalyzer mới (" tiếng Anh ");'. – Thomas

+0

Thực hiện thuật toán Knuth-Pratt http://www.fmi.uni-sofia.bg/fmi/logic/vboutchkova/sources/KMPMatch_java.html –

Trả lời

19
import org.apache.lucene.analysis.PorterStemmer; 
... 
String stemTerm (String term) { 
    PorterStemmer stemmer = new PorterStemmer(); 
    return stemmer.stem(term); 
} 

Xem here để biết thêm chi tiết. Nếu xuất phát là tất cả những gì bạn muốn làm, thì bạn nên sử dụng this thay vì Lucene.

Chỉnh sửa: Bạn nên viết hoa term trước khi chuyển đến stem().

+1

Có thể kết hợp bộ lọc cho các từ dừng với trình chặn không? – Mulone

+0

Bạn có muốn lọc các từ dừng từ một chuỗi có nhiều từ hoặc bạn đã mã hóa (tách biệt) các từ đó và chỉ muốn kiểm tra một từ duy nhất? Nếu nó chỉ là một thuật ngữ duy nhất như trên, thì chỉ cần tạo một 'Set' của tất cả các từ dừng và làm một' .contains() '. – nikhil500

+1

Kể từ phiên bản hiện tại của Lucene (3.5), PorterStemmer, mặc dù nó tồn tại, không được công khai. Tôi không chắc ai/cái gì sử dụng nó, nhưng chúng tôi không thể. –

6

Tại sao bạn không sử dụng "EnglishAnalyzer"? Thật đơn giản để sử dụng nó và tôi nghĩ rằng nó sẽ giải quyết vấn đề của bạn:

EnglishAnalyzer en_an = new EnglishAnalyzer(Version.LUCENE_34); 
QueryParser parser = new QueryParser(Version.LUCENE_34, "your_field", en_an); 
String str = "amenities"; 
System.out.println("result: " + parser.parse(str)); //amenit 

Hy vọng nó sẽ giúp bạn!

+2

"your_field" này đang làm gì? Tài liệu cho biết một "trường mặc định cho cụm từ truy vấn" bí ẩn. –

+0

Điều đó cắt nó thành các từ, nhưng không xuất phát. Ít nhất không phải là tôi. –

+0

Nó xuất phát rất cơ bản. Nó không bắt đầu và thay đổi nó để bắt đầu. – Whitecat

5

Ví dụ trước đây được áp dụng bắt nguồn cho một truy vấn tìm kiếm, vì vậy nếu bạn là thú vị để ngăn chặn một văn bản đầy đủ, bạn có thể thử như sau:

import java.io.*; 
import org.apache.lucene.analysis.*; 
import org.apache.lucene.analysis.tokenattributes.*; 
import org.apache.lucene.analysis.snowball.*; 
import org.apache.lucene.util.*; 
... 
public class Stemmer{ 
    public static String Stem(String text, String language){ 
     StringBuffer result = new StringBuffer(); 
     if (text!=null && text.trim().length()>0){ 
      StringReader tReader = new StringReader(text); 
      Analyzer analyzer = new SnowballAnalyzer(Version.LUCENE_35,language); 
      TokenStream tStream = analyzer.tokenStream("contents", tReader); 
      TermAttribute term = tStream.addAttribute(TermAttribute.class); 

      try { 
       while (tStream.incrementToken()){ 
        result.append(term.term()); 
        result.append(" "); 
       } 
      } catch (IOException ioe){ 
       System.out.println("Error: "+ioe.getMessage()); 
      } 
     } 

     // If, for some reason, the stemming did not happen, return the original text 
     if (result.length()==0) 
      result.append(text); 
     return result.toString().trim(); 
    } 

    public static void main (String[] args){ 
     Stemmer.Stem("Michele Bachmann amenities pressed her allegations that the former head of her Iowa presidential bid was bribed by the campaign of rival Ron Paul to endorse him, even as one of her own aides denied the charge.", "English"); 
    } 
} 

Lớp TermAttribute đã bị phản đối và sẽ không còn được hỗ trợ trong Lucene 4, nhưng các tài liệu không rõ ràng về những gì để sử dụng tại chỗ của nó.

Cũng trong ví dụ đầu tiên PorterStemmer không khả dụng dưới dạng lớp (ẩn) để bạn không thể sử dụng trực tiếp.

Hy vọng điều này sẽ hữu ích.

+0

Câu trả lời của Giancarlo là chính xác với một thay đổi nhỏ của TermAttribute thành CharTermAttribute vì TermAttribute không được chấp nhận. – amas

0

Ling pipe cung cấp một số mã thông báo. Chúng có thể được sử dụng để bắt đầu và ngừng loại bỏ từ. Một phương tiện đơn giản và hiệu quả của nó là bắt nguồn.

19

SnowballAnalyzer bị phản đối, bạn có thể sử dụng Lucene Porter Stemmer thay vì:

PorterStemmer stem = new PorterStemmer(); 
stem.setCurrent(word); 
stem.stem(); 
String result = stem.getCurrent(); 

Hope trợ giúp này!

+2

PorterStemmer không còn công khai nữa (ngớ ngẩn) - xem thêm http://stackoverflow.com/questions/15422485/lucene-porter-stemmer-not-public – 8bitjunkie

3

Đây là cách bạn có thể sử dụng Snowball Stemmer trong JAVA:

import org.tartarus.snowball.ext.EnglishStemmer; 

EnglishStemmer english = new EnglishStemmer(); 
String[] words = tokenizer("bank banker banking"); 
for(int i = 0; i < words.length; i++){ 
     english.setCurrent(words[i]); 
     english.stem(); 
     System.out.println(english.getCurrent()); 
} 
Các vấn đề liên quan