Giter Site home page Giter Site logo

Comments (9)

elonzh avatar elonzh commented on May 18, 2024 1

CharTable 是一个很好的正规化工具,但是忽略大小写会导致需要输出正规化之后内容含义不正确,只能在这种场景下自定义数据表,但是 CharTable.CONVERT 是静态属性,切换数据表又会让其他需要忽略大小写的场景麻烦起来

from hanlp.

yuchaozhou avatar yuchaozhou commented on May 18, 2024

1.用户是不考虑输入的字母是大写还是小写的问题的
这个是不是在建索引的时候就得定义清楚,索引的词项表也同样处理。如 所有英文字母均归范化为”小写“
2.无论输入的是 爱听4g 还是 爱听4G 都能分出来[爱听4g/nz]
词典中若无该新词,后其召回不了[爱听4g/nz]专名

博主速来:)

from hanlp.

a198720 avatar a198720 commented on May 18, 2024

"爱听4G" 是 我加入到自定义扩展词库中的. 有这样的场景:在对数据建立索引的时候,我对"爱听4g"这个词进行分词(但是自定义词库中是"爱听4G"),那么分词之后再进行单词小写化的结果就是:[爱/v, 听/v, 4g/nz].Yuchao Z 所说的大小写是后期搜索引擎中token标准化term时候需要考虑的吧? 这样处理也行,不过需要对词库标准化处理,比如词库中的所有的词都必须是小写化,这样我在token标准化之前,直接将输入文本统一小写化也能解决.但是感觉这样比较冗余. 考虑直接在分词的过程中,不考虑输入词与词库中单词的大小写问题,直接输出小写化之后的结果.这样更简单一些.比如IK的分词机制:实现加入关键词"爱听4G"
keyword = "爱听4G";
analyzer = new IKAnalyzer(true);
sb = new StringBuilder();
try {
TokenStream ts = analyzer.tokenStream("", new StringReader(keyword));
ts.reset();
CharTermAttribute cta = ts.addAttribute(CharTermAttribute.class);
while(ts.incrementToken()){
String term = cta.toString();
sb.append(term+" , ");
}
ts.end();
ts.close();
} catch (IOException e) {
e.printStackTrace();
}
System.out.println("分词前:"+keyword);
System.out.println(" ["+sb.toString()+"]");
long time2 = System.currentTimeMillis();
==========================结果===================================
加载扩展词典:ext.dic
分词前:[爱听4G]
分词后:[爱听4g , ]

from hanlp.

hankcs avatar hankcs commented on May 18, 2024

这其实不难,最直接的做法无非是,在加载词典和输入文本的时候都进行一个toLowerCase,但是我希望做得优雅高效。有几个问题欢迎大家讨论:

  1. toLowerCase效率不高。HanLP中的CRFSegment使用了一个CharTable,可以将任意字符规范化,包括繁体->简体,全角->半角,大写->小写等等。我比较倾向于用CharTable做规范化。
  2. 规范化了之后,分词的结果也被修改得和原文不一样了,比如词典是 爱听4G, “爱听4G”分词结果变成了[爱听4g/nz]。一部分人认为这是合理的,我觉得应该再转回来,变成[爱听4G/nz],不知道大家意见怎么样?
  3. 如果要支持这个特性,那么就不会提供一个局部的配置接口enableFuzzyCase之类的,因为词典的加载是全局的。所以只能提供一个全局的配置,影响所有分词器。而且切换配置后还必须删缓存重建。

from hanlp.

a198720 avatar a198720 commented on May 18, 2024

第一个问题:String类的toLowerCase 实现方法是挺复杂的,效率不是很高,我感觉放入到CharacterHelper或者是CharTable中应该都行.我参考的是lucene-query 中的小写化处理方式,直接对代码点操作,应该是比较高的效率了.供楼主参考:
/**

  • 转换每一个unicode代码点为小写.使用{@link Character#toLowerCase(int)}.
  • @param buffer the char buffer to lowercase
  • @param offset the offset to start at
  • @param limit the max char in the buffer to lower case
    */
    public final void toLowerCase(final char[] buffer, final int offset, final int limit) {
    assert buffer.length >= limit;
    assert offset <=0 && offset <= buffer.length;
    for (int i = offset; i < limit;) {
    i += Character.toChars(
    Character.toLowerCase(
    codePointAt(buffer, i, limit)), buffer, i);
    }
    }

第二个问题:能够做一个开关,在用于索引的时候,需要小写化,那么我就不需要还原原词了,这样在索引的时候,就不需要二次处理,直接开启开关即可.

第三个问题:楼主说的全局配置,是不是在加载词典的时候,就将所有的词小写化存储了. 如果我们不在加载词典的时候将词小写化,而是在对文本分词时,将从词库中取出的词再小写化处理.这种方式相对来说用影响分词速度,就是不知道影响的程度有多大?博主可以做个评测.

这是我的观点哈.

from hanlp.

hankcs avatar hankcs commented on May 18, 2024

感谢建议。

  1. CharTable是直接用数组下标转换字符,比调用任何方法都要快。
  2. 我又想了想,正规化本来就是用于检索系统的,最后又转为大写的话就没意义了。还是不转了。
  3. 对。影响程度非常大,由于内部采用了DAT,所以不可能动态大小写。

from hanlp.

hankcs avatar hankcs commented on May 18, 2024

现在HanLP已经支持了这个特性,在hanlp.properties中加入

#是否执行字符正规化(繁体->简体,全角->半角,大写->小写),切换配置后必须删缓存
Normalization=true

即可。

或者试试com/hankcs/demo/DemoNormalization.java这个例子。

        HanLP.Config.Normalization = true;
        CustomDictionary.insert("爱听4G", "nz 1000");
        Segment segment = new ViterbiSegment();
        System.out.println(segment.seg("爱听4g"));
        System.out.println(segment.seg("爱听4G"));
        System.out.println(segment.seg("爱听4G"));
        System.out.println(segment.seg("爱听4G"));
        System.out.println(segment.seg("愛聽4G"));

from hanlp.

a198720 avatar a198720 commented on May 18, 2024

测试发现对标准分词的支持还不是太好,如下:
代码:
public static void main(String[] args)
{
HanLP.Config.Normalization = true;
CustomDictionary.insert("爱听4G", "nz 1000");
System.out.println("标准分词:"+StandardTokenizer.segment("爱听4G"));
System.out.println("标准分词:"+StandardTokenizer.segment("爱听4g"));
System.out.println("索引分词:"+IndexTokenizer.segment("爱听4G"));
}
======================结果===================================
标准分词:[爱/v, 听/v, 4/m, G/nx]
标准分词:[爱听4g/nz]
索引分词:[爱听4g/nz, 4g/nz]

from hanlp.

hankcs avatar hankcs commented on May 18, 2024

昨天修复了这个问题,忘了提交了。现在已经没问题了:74050be

from hanlp.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.