IKAnalyzer中文分词,计算句子相似度

来源:互联网 发布:淘宝小号防限购2016 编辑:程序博客网 时间:2024/04/28 14:30

IKAnalyzer中文分词,计算句子相似度

一、简介 

    IKAnalyzer是一个开源的,基于java语言开发的轻量级的中文分词工具包。以开源项目Luence为应用主体的,结合词典分词和文法分析算法的中文分词组件。独立于Lucene项目,同时提供了对Lucene的默认优化实现。(简介来源: 百度百科) 

二、准备 

    项目结构: 

     

     IKAnalyzer2012FF_u1.jar 下载

     lucene-core-4.6.1.jar 下载

    ext.dic

    stopword.dic

    IKAnalyzer.cfg.xml

三、分词

    分词由于比较简单,就直接粘贴代码了

public static Vector<String> participle( String str ) {Vector<String> str1 = new Vector<String>() ;//对输入进行分词try {    StringReader reader = new StringReader( str );     IKSegmenter ik = new IKSegmenter(reader,true);//当为true时,分词器进行最大词长切分     Lexeme lexeme = null ;    while( ( lexeme = ik.next() ) != null ) {str1.add( lexeme.getLexemeText() );     }    if( str1.size() == 0 ) {    return null ;    }         //分词后    System.out.println( "str分词后:" + str1 );    } catch ( IOException e1 ) {System.out.println();}return str1;}


四、计算相似度

    计算句子相似度,①常用方法有基于语义和词序相似度计算方法,②基于关系向量模型 

    基于语义和词序的句子相似度计算方法简介

    定义1:给定一个句子Ti,经过汉语分词系统分词后,得到的所有词W1构成的向量称为句子Ti的向量表示,表示为Ti = {w1,w2,.....wn}。 

     例子1:T1:这个中文分词可不可以,用着方不方便。分词后:T1=[这个, 中文分词, 可不可以, 用着, 方, 不, 方便]。向量表示T1={这个, 中文分词, 可不可以, 用着, 方, 不, 方便}

                T2:这个中文分词比较方便,用着方便还可以。分词后:T2=[这个, 中文分词, 比较方便, 用着, 方便, 还可以]。向量表示T2={这个, 中文分词, 比较方便, 用着, 方便, 还可以}

    定义2:给定一个句子Ti的向量表示,Ti中词的个数称为Ti的向量长度,表示为Len(Ti). 

     例子2:对于句子T1和T2的向量长度表示为:Len(T1)=7,Len(T1)=6。

    定义3:给定两个句子Ti、Tj的向量表示,将Ti、Tj中的所有词Wi进行合并,并且对于重复初想的词只保留一个,由此得到两个向量之和,称为Ti、Tj的并集,表示T=T1 U T2={这个, 中文分词, 可不可以, 比较方便,用着, 方, 不, 方便,还可以},很显然,并集长度Len(T)<=Len(T1)+Len(T2)。

    定义4:给定一个句子Ti的向量表示Ti = {w1,w2,.....wn}和一个词wi,依次计算wi和Ti中每一个词的相似度(值为0到1之间),所以所有结果中的最大值称为wi在Ti中的语义分数,表示为Ci。

    定义5:给定两个句子Ti、Tj的向量表示,Ti和Tj的集合T={w1、w2,....wn},对T中的每一个词Wi,计算Wi在Ti中的语义分数Ci,T中每个分词的语义分数组成的一个向量称为Ti基于T的语义向量,表示为Si={C1,C2,...,Cn}。 

           在该算法中,基于T分别计算Ti和Tj的语义向量Si、Sj,以计算Si作为说明,过程如下: 

    1、对于T中的每一个词wi,如果wi 在Ti 中出现,则在语义向量Si中将wi 的语义分数Ci设为1。 

    2、如果Ti中不包含wi,则计算wi 在 Ti 中的语义分数 Ci=a(a为预先设定的阈值 , 无阈值设为0 ,本文中阈值为0.2 ) 。 

        根据语义向量计算语义相似度方法如下图: 

         

         词序相似度计算法方法如下: 

                 

    其中r1、r2 分别为T1、T2的词序向量,以T1为例,其计算方法如下:

    1、对于T中的每一个词wi,如果T1中包含该次,则r1中该次的取值为该词在T1中出现的词序。否则在T1中找出与wi最相似的词Wi。

    2、如果wi 和 wi 的相似度大于一个给定的阈值(实验取值为0.4),wi在r1中的取值设为wi在Ti中出现的词序。

    3、如果两种情况均为发生,则wi在r1中的取值设为null。  

    然而,根据语义向量计算语义相似度方法中,想到了之前看过的一篇博客,通过 余玄定理来实现,计算方法如下

//阈值public static double YUZHI = 0.2 ;/** * 返回百分比 * @author: Administrator * @Date: 2015年1月22日 * @param T1 * @param T2 * @return */public static double getSimilarity(Vector<String> T1, Vector<String> T2) throws Exception {int size = 0 , size2 = 0 ;    if ( T1 != null && ( size = T1.size() ) > 0 && T2 != null && ( size2 = T2.size() ) > 0 ) {            Map<String, double[]> T = new HashMap<String, double[]>();                //T1和T2的并集T    String index = null ;        for ( int i = 0 ; i < size ; i++ ) {        index = T1.get(i) ;            if( index != null){            double[] c = T.get(index);                c = new double[2];                c[0] = 1;//T1的语义分数Ci                c[1] = YUZHI;//T2的语义分数Ci                T.put( index, c );            }        }         for ( int i = 0; i < size2 ; i++ ) {        index = T2.get(i) ;        if( index != null ){        double[] c = T.get( index );        if( c != null && c.length == 2 ){        c[1] = 1; //T2中也存在,T2的语义分数=1                }else {                    c = new double[2];                    c[0] = YUZHI; //T1的语义分数Ci                    c[1] = 1; //T2的语义分数Ci                    T.put( index , c );                }            }        }                    //开始计算,百分比        Iterator<String> it = T.keySet().iterator();        double s1 = 0 , s2 = 0, Ssum = 0;  //S1、S2        while( it.hasNext() ){        double[] c = T.get( it.next() );        Ssum += c[0]*c[1];        s1 += c[0]*c[0];        s2 += c[1]*c[1];        }        //百分比        return Ssum / Math.sqrt( s1*s2 );    } else {        throw new Exception("传入参数有问题!");    }}

测试结果

str分词后:[这个, 中文分词, 可不可以, 用着, 方, 不, 方便]str分词后:[这个, 中文分词, 比较方便, 用着, 方便, 还可以]

相似度:0.7595872466989299

代码地址: twosnail源码地址

原创作者: twosnail(两只蜗牛)

转载地址:http://itindex.net/detail/52615-ikanalyzer-%E4%B8%AD%E6%96%87%E5%88%86%E8%AF%8D-%E8%AE%A1%E7%AE%97

0 0
原创粉丝点击