RSS
热门关键字:  数据挖掘  数据仓库  商业智能  人工智能  搜索引擎

分词程序集成了一个可以提取词干的开源项目成果

来源: 作者:unkonwn 时间:2004-12-06 点击:

这两天正好在项目中需要提取词干(word stemming),词干是什么?比如documentation这个词,它的词干就是document。再比如tables这个复数形式,它的词干就是tabl。词干也许可以理解为类似于词根一样的概念。我没有去查准确的定义,不过我想它的用处是显而易见的。我们如果想比较两个词的相似程度,比如下面两个词:go和went。这怎么办,其实从目的上讲我们是希望这两个词有较高的相似度的(语义上极为相似),然而从简单的字符串处理方法上,比如编辑距离的处理方式,这两个词也许就很不相似了。然而经过提取词干以后,一切就不一样了,went能够被还原成go,很有用的方法。再比如典型的应用:stem和stemming这两个词如果要考虑语义相似性,那应当是非常相似的(只不过是两种时态而已),可是从编辑距离或者VSM的角度考虑,也许他们的相似性要大打折扣。然而stemming提取词干以后,就还原成了stem。 数据挖掘研究院

我想过自己去实现一个这样的工具,然而翻阅了一些经典的英语语法书籍,发现要考虑的事情太多了,感兴趣的可以去这个地方看看:http://www.phon.ucl.ac.uk/home/dick/enc/intro.htm  于是我寻找各种现有的开源项目。其实首先接触到的是一个叫做KIMMO的工具,我也是无意中通过它才知道了提取词干这回事。它是用脚本语言编写的,我对这个方面不很熟悉,不敢贸然使用。然后才知道提取词干方面也许是一个很权威的方法:Porter Stemming算法,它的主页是:http://www.tartarus.org/~martin/PorterStemmer/  幸运的,我找到了它的一个开源的应用,是他们自己的工作结晶,一个叫做Snowball的项目,地址是:http://snowball.tartarus.org/  他们的库可以在这儿下载:http://snowball.tartarus.org/dist/libstemmer_java.tgz

数据挖掘研究院

集成这个工具来提取词干是很方便的,要注意的是这个工具不仅支持提取英文词干,也支持法语、俄语等多种其他语言(当然不包括中文)。下面是一个典型的应用实例,我将它集成到了我的分词程序中,以下是全部源代码。其中,为了适合我们应用的需要,将数字部分保留了,浮点数也可以被提取和保留下来,然而因为时间紧迫的关系暂时用了两边扫描。 数据挖掘研究院


import java.util.*;
import java.lang.reflect.Method;
import org.tartarus.snowball.*; 数据挖掘实验室

public class SplitWords {
    /* 分隔符的集合 */
    private final String delimiters = " f~!@#$%^&*()_+|`-=\{}[]:";′<>?,./′1234567890";

数据挖掘研究院

    /* 语言 */
    private final String language = "english";

数据挖掘实验室

    public String[] split(String source) {
        /* 提取数字 */
        Vector vectorForNumber = new Vector();
        flag3: for (int i = 0; i < source.length(); i++) {
            char thisChar = source.charAt(i);
            StringBuffer thisNumber = new StringBuffer();
            boolean hasDigit = false;
            if (Character.isDigit(thisChar)) {
                thisNumber.append(thisChar);
                for (++i; i < source.length(); i++) {
                    thisChar = source.charAt(i); 数据挖掘研究院
                    if ((thisChar == ′.′) && !hasDigit) {
                        thisNumber.append(thisChar);
                        hasDigit = true;
                    } else if (Character.isDigit(thisChar)) {
                        thisNumber.append(thisChar);
                    } else {
                        if (thisNumber.length() != 0) {


                            vectorForNumber.addElement(thisNumber.toString());
                            continue flag3;
                        }
                    }
                }
                if (thisNumber.length() != 0) {
                    vectorForNumber.addElement(thisNumber.toString());

数据挖掘研究院


                }
            }
        } 数据挖掘研究院

        /* 剔除. */
        int positionOfDot;
        StringBuffer tempSource = new StringBuffer(source);
        while ((positionOfDot = tempSource.indexOf(".")) != -1) {
            tempSource.deleteCharAt(positionOfDot);
        }
        source = tempSource.toString();

        /* 根据分隔符分词 */
        StringTokenizer stringTokenizer = new StringTokenizer(source,
                delimiters); 数据挖掘研究院

        /* 所有的词 */
        Vector vector = new Vector();

        /* 全大写的词 -- 不用提词干所以单独处理 */
        Vector vectorForAllUpperCase = new Vector(); 数据挖掘研究院

        /* 根据大写字母分词 */
        flag0: while (stringTokenizer.hasMoreTokens()) {
            String token = stringTokenizer.nextToken();

数据挖掘研究院

            /* 全大写的词单独处理 */
            boolean allUpperCase = true;
            for (int i = 0; i < token.length(); i++) {
                if (!Character.isUpperCase(token.charAt(i))) {
                    allUpperCase = false;
                }
            }
            if (allUpperCase) {
                vectorForAllUpperCase.addElement(token);
                continue flag0;

数据挖掘研究院


            } 数据挖掘实验室

            /* 非全大写的词 */
            int index = 0;
            flag1: while (index < token.length()) {
                flag2: while (true) {
                    index++;
                    if ((index == token.length())
                            || !Character.isLowerCase(token.charAt(index))) {
                        break flag2; 数据挖掘研究院
                    }
                }
                vector.addElement(token.substring(0, index).toLowerCase());
                token = token.substring(index);
                index = 0;
                continue flag1;
            }
        } 数据挖掘研究院

        /* 提词干 */
        try {
            Class stemClass = Class.forName("org.tartarus.snowball.ext."
                    + language + "Stemmer");
            SnowballProgram stemmer = (SnowballProgram) stemClass.newInstance();
            Method stemMethod = stemClass.getMethod("stem", new Class[0]);
            Object[] emptyArgs = new Object[0];
            for (int i = 0; i < vector.size(); i++) {
                stemmer.setCurrent((String) vector.elementAt(i));

数据挖掘研究院


                stemMethod.invoke(stemmer, emptyArgs);
                vector.setElementAt(stemmer.getCurrent(), i);
            }
        } catch (Exception e) {
            e.printStackTrace();
        } 数据挖掘实验室

        /* 合并 */
        for (int i = 0; i < vectorForAllUpperCase.size(); i++) {
            vector.addElement(vectorForAllUpperCase.elementAt(i));
        }
        for (int i = 0; i < vectorForNumber.size(); i++) {
            vector.addElement(vectorForNumber.elementAt(i));
        }

数据挖掘研究院

        /* 转为数组形式 */
        String[] array = new String[vector.size()];
        Enumeration enumeration = vector.elements();
        int index = 0;
        while (enumeration.hasMoreElements()) {
            array[index] = (String) enumeration.nextElement();
            index++;
        }

数据挖掘研究院

        /* 打印显示 */
        for (int i = 0; i < array.length; i++) {
            System.out.print(array[i] + " ");
        } 数据挖掘研究院

        /* 返回 */
        return array;
    }

数据挖掘研究院

    public static void main(String args[]) {
        SplitWords sw = new SplitWords();
        sw
                .split("These 232 tables are for ARE-Company using only. The I.S.B.N number of J.Smith′s book is ISBN302.1.2.");
        //sw.split("123");
    }
}

数据挖掘研究院

最新评论共有 0 位网友发表了评论
发表评论
评论内容:不能超过250字,需审核,请自觉遵守互联网相关政策法规。
匿名?