- 浏览: 72837 次
- 性别:
- 来自: 大连
文章分类
最新评论
-
须等待:
强烈同意。。。。这个编辑器简直太不好用了!
对于在Ubuntu下的Eclipse上安装SVN客户端插件Subclipse的补充 -
nudtgk2000:
flysnail 写道 思路挺好,
谢谢鼓励,还是初学者,不 ...
重写CountDownLatch以实现线程状态监视 -
flysnail:
思路挺好,:)
重写CountDownLatch以实现线程状态监视
/* Porter stemmer in Java. The original paper is in Porter, 1980, An algorithm for suffix stripping, Program, Vol. 14, no. 3, pp 130-137, See also http://www.tartarus.org/~martin/PorterStemmer History: Release 1 Bug 1 (reported by Gonzalo Parra 16/10/99) fixed as marked below. The words 'aed', 'eed', 'oed' leave k at 'a' for step 3, and b[k-1] is then out outside the bounds of b. Release 2 Similarly, Bug 2 (reported by Steve Dyrdahl 22/2/00) fixed as marked below. 'ion' by itself leaves j = -1 in the test for 'ion' in step 5, and b[j] is then outside the bounds of b. Release 3 Considerably revised 4/9/00 in the light of many helpful suggestions from Brian Goetz of Quiotix Corporation (brian@quiotix.com). Release 4 */ import java.io.*; /** * Stemmer, implementing the Porter Stemming Algorithm * * The Stemmer class transforms a word into its root form. The input * word can be provided a character at time (by calling add()), or at once * by calling one of the various stem(something) methods. */ class Stemmer { private char[] b; private int i, /* offset into b */ i_end, /* offset to end of stemmed word */ j, k; private static final int INC = 50; /* unit of size whereby b is increased */ public Stemmer() { b = new char[INC]; i = 0; i_end = 0; } /** * Add a character to the word being stemmed. When you are finished * adding characters, you can call stem(void) to stem the word. */ public void add(char ch) { if (i == b.length) { char[] new_b = new char[i+INC]; for (int c = 0; c i; c++) new_b[c] = b[c]; b = new_b; } b[i++] = ch; } /** Adds wLen characters to the word being stemmed contained in a portion * of a char[] array. This is like repeated calls of add(char ch), but * faster. */ public void add(char[] w, int wLen) { if (i+wLen >= b.length) { char[] new_b = new char[i+wLen+INC]; for (int c = 0; c i; c++) new_b[c] = b[c]; b = new_b; } for (int c = 0; c wLen; c++) b[i++] = w[c]; } /** * After a word has been stemmed, it can be retrieved by toString(), * or a reference to the internal buffer can be retrieved by getResultBuffer * and getResultLength (which is generally more efficient.) */ public String toString() { return new String(b,0,i_end); } /** * Returns the length of the word resulting from the stemming process. */ public int getResultLength() { return i_end; } /** * Returns a reference to a character buffer containing the results of * the stemming process. You also need to consult getResultLength() * to determine the length of the result. */ public char[] getResultBuffer() { return b; } /* cons(i) is true => b[i] is a consonant. */ private final boolean cons(int i) { switch (b[i]) { case 'a': case 'e': case 'i': case 'o': case 'u': return false; case 'y': return (i==0) ? true : !cons(i-1); default: return true; } } /* m() measures the number of consonant sequences between 0 and j. if c is a consonant sequence and v a vowel sequence, and <..> indicates arbitrary presence, <c><v> gives 0 <c>vc<v> gives 1 <c>vcvc<v> gives 2 <c>vcvcvc<v> gives 3 .... */ private final int m() { int n = 0; int i = 0; while(true) { if (i > j) return n; if (! cons(i)) break; i++; } i++; while(true) { while(true) { if (i > j) return n; if (cons(i)) break; i++; } i++; n++; while(true) { if (i > j) return n; if (! cons(i)) break; i++; } i++; } } /* vowelinstem() is true => 0,...j contains a vowel */ private final boolean vowelinstem() { int i; for (i = 0; i = j; i++) if (! cons(i)) return true; return false; } /* doublec(j) is true => j,(j-1) contain a double consonant. */ private final boolean doublec(int j) { if (j 1) return false; if (b[j] != b[j-1]) return false; return cons(j); } /* cvc(i) is true => i-2,i-1,i has the form consonant - vowel - consonant and also if the second c is not w,x or y. this is used when trying to restore an e at the end of a short word. e.g. cav(e), lov(e), hop(e), crim(e), but snow, box, tray. */ private final boolean cvc(int i) { if (i 2 || !cons(i) || cons(i-1) || !cons(i-2)) return false; { int ch = b[i]; if (ch == 'w' || ch == 'x' || ch == 'y') return false; } return true; } private final boolean ends(String s) { int l = s.length(); int o = k-l+1; if (o 0) return false; for (int i = 0; i l; i++) if (b[o+i] != s.charAt(i)) return false; j = k-l; return true; } /* setto(s) sets (j+1),...k to the characters in the string s, readjusting k. */ private final void setto(String s) { int l = s.length(); int o = j+1; for (int i = 0; i l; i++) b[o+i] = s.charAt(i); k = j+l; } /* r(s) is used further down. */ private final void r(String s) { if (m() > 0) setto(s); } /* step1() gets rid of plurals and -ed or -ing. e.g. caresses -> caress ponies -> poni ties -> ti caress -> caress cats -> cat feed -> feed agreed -> agree disabled -> disable matting -> mat mating -> mate meeting -> meet milling -> mill messing -> mess meetings -> meet */ private final void step1() { if (b[k] == 's') { if (ends("sses")) k -= 2; else if (ends("ies")) setto("i"); else if (b[k-1] != 's') k--; } if (ends("eed")) { if (m() > 0) k--; } else if ((ends("ed") || ends("ing")) && vowelinstem()) { k = j; if (ends("at")) setto("ate"); else if (ends("bl")) setto("ble"); else if (ends("iz")) setto("ize"); else if (doublec(k)) { k--; { int ch = b[k]; if (ch == 'l' || ch == 's' || ch == 'z') k++; } } else if (m() == 1 && cvc(k)) setto("e"); } } /* step2() turns terminal y to i when there is another vowel in the stem. */ private final void step2() { if (ends("y") && vowelinstem()) b[k] = 'i'; } /* step3() maps double suffices to single ones. so -ization ( = -ize plus -ation) maps to -ize etc. note that the string before the suffix must give m() > 0. */ private final void step3() { if (k == 0) return; /* For Bug 1 */ switch (b[k-1]) { case 'a': if (ends("ational")) { r("ate"); break; } if (ends("tional")) { r("tion"); break; } break; case 'c': if (ends("enci")) { r("ence"); break; } if (ends("anci")) { r("ance"); break; } break; case 'e': if (ends("izer")) { r("ize"); break; } break; case 'l': if (ends("bli")) { r("ble"); break; } if (ends("alli")) { r("al"); break; } if (ends("entli")) { r("ent"); break; } if (ends("eli")) { r("e"); break; } if (ends("ousli")) { r("ous"); break; } break; case 'o': if (ends("ization")) { r("ize"); break; } if (ends("ation")) { r("ate"); break; } if (ends("ator")) { r("ate"); break; } break; case 's': if (ends("alism")) { r("al"); break; } if (ends("iveness")) { r("ive"); break; } if (ends("fulness")) { r("ful"); break; } if (ends("ousness")) { r("ous"); break; } break; case 't': if (ends("aliti")) { r("al"); break; } if (ends("iviti")) { r("ive"); break; } if (ends("biliti")) { r("ble"); break; } break; case 'g': if (ends("logi")) { r("log"); break; } } } /* step4() deals with -ic-, -full, -ness etc. similar strategy to step3. */ private final void step4() { switch (b[k]) { case 'e': if (ends("icate")) { r("ic"); break; } if (ends("ative")) { r(""); break; } if (ends("alize")) { r("al"); break; } break; case 'i': if (ends("iciti")) { r("ic"); break; } break; case 'l': if (ends("ical")) { r("ic"); break; } if (ends("ful")) { r(""); break; } break; case 's': if (ends("ness")) { r(""); break; } break; } } /* step5() takes off -ant, -ence etc., in context <c>vcvc<v>. */ private final void step5() { if (k == 0) return; /* for Bug 1 */ switch (b[k-1]) { case 'a': if (ends("al")) break; return; case 'c': if (ends("ance")) break; if (ends("ence")) break; return; case 'e': if (ends("er")) break; return; case 'i': if (ends("ic")) break; return; case 'l': if (ends("able")) break; if (ends("ible")) break; return; case 'n': if (ends("ant")) break; if (ends("ement")) break; if (ends("ment")) break; /* element etc. not stripped before the m */ if (ends("ent")) break; return; case 'o': if (ends("ion") && j >= 0 && (b[j] == 's' || b[j] == 't')) break; /* j >= 0 fixes Bug 2 */ if (ends("ou")) break; return; /* takes care of -ous */ case 's': if (ends("ism")) break; return; case 't': if (ends("ate")) break; if (ends("iti")) break; return; case 'u': if (ends("ous")) break; return; case 'v': if (ends("ive")) break; return; case 'z': if (ends("ize")) break; return; default: return; } if (m() > 1) k = j; } /* step6() removes a final -e if m() > 1. */ private final void step6() { j = k; if (b[k] == 'e') { int a = m(); if (a > 1 || a == 1 && !cvc(k-1)) k--; } if (b[k] == 'l' && doublec(k) && m() > 1) k--; } /** Stem the word placed into the Stemmer buffer through calls to add(). * Returns true if the stemming process resulted in a word different * from the input. You can retrieve the result with * getResultLength()/getResultBuffer() or toString(). */ public void stem() { k = i - 1; if (k > 1) { step1(); step2(); step3(); step4(); step5(); step6(); } i_end = k+1; i = 0; } /* Stem the inFileName into outFileName */ public void stem(String inFileName,String outFileName) { char[] w=new char[501]; Stemmer s = new Stemmer(); // for (int i = 0; i args.length; i++) try { FileInputStream in = new FileInputStream(inFileName); FileOutputStream out = new FileOutputStream(outFileName); try { while(true) { int ch = in.read(); if (ch > 0xa0) { out.write(ch); continue; } else if (Character.isLetter((char) ch)) { int j = 0; while(true) { ch = Character.toLowerCase((char) ch); w[j] = (char) ch; if (j 500) j++; ch = in.read(); if (!Character.isLetter((char) ch) || ch > 0xa0) // Read to the end of one word { /* to test add(char ch) */ for (int c = 0; c j; c++) s.add(w[c]); /* or, to test add(char[] w, int j) */ /* s.add(w, j); */ s.stem(); { String u; /* and now, to test toString() : */ u = s.toString(); /* to test getResultBuffer(), getResultLength() : */ /* u = new String(s.getResultBuffer(), 0, s.getResultLength()); */ int len=u.length(); for (int k=0;k<len;k++) out.write((char)(u.charAt(k))); // out.write(u); } break; } } } if (ch 0) break; out.write((char)ch); } } catch (IOException e) { System.out.println("error reading " + inFileName + "or write "+ outFileName + "error!"); } } catch (FileNotFoundException e) { System.out.println("file " + inFileName + " not found" + "or" + "file" +outFileName + "open error"); } } public static void main(String []argv) { //String spath="e:\\lengzi\\software\\weka-3-5-0\\reut2-000stopwordsremoval.sgm"; //String dpath="e:\\lengzi\\software\\weka-3-5-0\\reut2-000stemmer.sgm"; // Stemmer s = new Stemmer(); //s.stem(spath,dpath); String spath; String dpath,dpath1; String sfile = "E:\\TRAIN2"; String dfile = "e:\\TRAIN3"; File sfolder = new File(sfile); File[ ] entries = sfolder.listFiles( ); Stemmer s = new Stemmer(); for(int i=0; i<entries.length; i++) { spath = entries[i].getPath(); dpath1 =dfile+"\\"+entries[i].getName(); File subfolder = new File(spath); File[] subentries = subfolder.listFiles(); for(int j=0; j<subentries.length;j++) { spath = subentries[j].getPath(); dpath = dpath1+"\\"+subentries[j].getName(); try{ FileWriter fw = new FileWriter(dpath); fw.close(); }catch (IOException e) { System.out.println("error!"); } s.stem(spath,dpath); } } } }
一篇学习笔记:波特词干算法——残阳似血的博客 , 有对算法的详细讲解和资源链接
一个使用了Porter Stemmer 的例子:分词程序集成了一个可以提取词干的开源项目成果 , 借鉴用法
发表评论
-
Weka 3.6.9 加载libsvm类包的正解
2014-05-24 10:59 5929Weka 3.6.9本身不带libsvm的类包,百度网上铺天 ... -
byte型检查
2012-09-09 21:14 805byte b; //... ... // 范围检查,确保只 ... -
java.io.InputStream.mark(int readlimit) 方法的个人理解
2012-05-16 16:04 0在马士兵java课程的IO这一章[1]中遇到 java.io ... -
马士兵课程笔记(续7) —— 流
2012-03-20 18:51 0Java 流式输入/输出原理 ... -
马士兵课程笔记(续6)
2012-03-18 18:31 1262容器 概念 Java API 所提供的用于在程序中 ... -
走了一段值得的弯路
2012-03-16 21:27 1048class C { int i; S ... -
马士兵课程笔记(续5)
2012-03-09 19:28 1452常用类 字符串相关类(String, StringBuff ... -
马士兵课程笔记(续4)
2012-02-28 21:58 1134数组 数组可以看成是多个相同类型数据组合,对这些数据的统一 ... -
马士兵课程笔记(续3)
2012-02-22 16:47 1518抽象类 关键字abstract 含有抽象方法的类必须声明 ... -
马士兵课程笔记(续2)
2012-01-03 15:50 1141J2SDK中主要的包介绍 位置%JAVAHOME%\jr ... -
马士兵课程笔记
2011-11-14 07:47 1265J2EE框架 EJB (Enterprise Ja ... -
Linux命令收集罐
2011-10-23 16:54 920查看系统进程——ps 要对 ... -
对配hadoop时用到的一些命令,查到的详细解释做个笔记
2011-10-19 15:56 830$ ssh-keygen -t dsa -P '' -f ~/ ... -
调试手记 2011/07/27
2011-07-27 15:13 7391、 关于求模运算。 在MicroblogCrawle ...
相关推荐
应用最为广泛的、中等复杂程度的、基于后缀剥离的词干提取算法是波特词干算法,也叫波特词干器(Porter Stemmer)。详见官方网站。比较热门的检索系统包括Lucene、Whoosh等中的词干过滤器就是采用的波特词干算法。
波特词干算法由Martin Porter于1980年提出,并发表在《Program》杂志上。该算法的主要目的是通过一系列规则来识别并删除英语单词的后缀,从而得到单词的基本形式或词干。这种方法虽然简单,但在当时已经是非常有效的...
Porter Stemmer是一种著名的英文词干提取算法,由Martin Porter在1980年提出,主要用于处理英文文本,减少词汇的形态变化,将词汇还原到它们的基本形式,以便于文本分析、信息检索和自然语言处理等领域。在VC...
wink-porter2-stemmer Martin F Porter博士实现 的屈折字划分成使用其碱形式wink-porter2-stemmer 。 安装 使用进行安装: npm install wink-porter2-stemmer --save ...使用Porter2词干算法阻止变
retext-porter-stemmer 实现。 安装 : npm install retext-porter-stemmer retext-porter-stemmer也可用于 , 和 ,以及作为AMD,CommonJS和globals模块的和模块。 用法 var retext = require ( 'retext' ) ; ...
Porter词干算法是一种在自然语言处理中广泛使用的文本预处理技术,它的主要目标是将词汇还原到其基本形式,通常称为词干。这个过程被称为词干化,它有助于减少词汇多样性,使得文本分析和信息检索更为高效。Rust 是...
德国施特默使用 Porter 词干分析器算法将一个词简化为德语词干。 参考: - http://snowball.tartarus.org/algorithms/porter/stemmer.html- http://snowball.tartarus.org/algorithms/german/stemmer.html用法:$...
Fast-stemmer 只是对多线程的简单封装 波特词干算法 这个 gem 添加了一个 String#stem 方法,它与 stemmer gem 冲突。 它比后者快一个数量级(并且使用更少的内存)。
Porter拉丁词干算法是自然语言处理(NLP)领域中广泛应用的一个词干提取算法,由Martin Porter在1973年提出。它主要用于英语文本,但经过一些调整,也可以应用于其他拉丁语系的语言,如西班牙语、法语、意大利语等。...
在英文中,常见的词干提取算法有Porter Stemmer和Lancaster Stemmer。Porter Stemmer是由Martin Porter开发的,它通过一套规则化的步骤来去掉单词的后缀,如“-ing”、“-ed”、“-s”等,但不保证得到的词干是词汇...
#Martin Porter阻止算法 有关完整详细信息,请参见。 在特定条件下,辅音是AEIOU和Y以外的字母或单词。 元音是非辅音字母。 使用的符号 c =辅音 v =元音 m =度量 C = 0或更多辅音 V = 0或更多的元音 m = 0表示空...
MySQL Porter Stemmer 是一个用于MySQL数据库的文本处理工具,它实现了Porter stemming算法,该算法主要用于英文词汇的词干提取。在信息检索、文本分析和自然语言处理领域,词干提取是一个关键步骤,通过减少词汇到...
**前端开源库-en-stemmer** 是一个专为前端开发者设计的开源库,它主要实现了英语词干提取(Stemming)算法,特别是波特(Porter)词干提取算法。词干提取是自然语言处理(NLP)领域的一个重要技术,它的目标是将...
这是从Ansi-C到Martin Porter 1980发布的阻止例程的ooRexx的ooRexx逐行端口。Porter的原始源代码已被注释掉并由相应的(oo)Rexx代码尽可能地模拟。 这不是良好或快速(oo)Rexx编程的示例,它仅是Porter阻止例程...
Go的Porter Stemmer这是Martin Porter的Porter词干算法的C实现的相当简单的端口。 该端口基于的C版本可从以下位置下载:http://tartarus.org/~martin/Port Go的Porter Stemmer这是Martin Porter的Porter干算法的C...
"porter-stemmer"是一个广泛使用的英文词干提取算法,主要应用于自然语言处理(NLP)领域。在Python中,porter-stemmer算法通常通过特定的库如nltk(Natural Language Toolkit)或Snowball Stemmer来实现。词干提取...
在Go语言中实现Porter-Stemmer算法,开发者通常会创建一个Stemmer接口,定义一个`Stem`方法来接收一个英文单词并返回其词干。此外,可能会包含一些辅助函数,用于执行上述的各个步骤,如处理元音变化、前缀和后缀等...
porter stemming算法是一种广泛应用于英文文本处理中的词干提取方法,由Martin Porter在1973年提出。它的主要目的是减少单词的不同形式,将它们还原到基本的形式,通常被称为词根或词干。这种方法有助于在信息检索、...
Porter算法,全称为Porter Stemming Algorithm,是马丁·波特(Martin Porter)在1979年开发的一种英文词干提取算法。它主要用于去除英语单词中的常见形态和屈折变化,以便在信息检索系统中进行术语标准化。Porter...
· stemr软件包提供了 English(porter2)stemmer算法的javascript(TypeScript)实现。例子 import { stem } from "stemr" ;stem ( "stemming" ) ;// => "stem