IKAnalyzer中文分詞,計算句子類似度

IKAnalyzer中文分詞,計算句子類似度

1、簡介

    IKAnalyzer是一個開源的,基於java語言開發的輕量級的中文分詞工具包。以開源項目Luence爲應用主體的,結合詞典分詞和文法分析算法的中文分詞組件。獨立於Lucene項目,同時提供了對Lucene的默認優化實現。(簡介來源:百度百科
java

2、準備

    項目結構:
算法

    

    IKAnalyzer2012FF_u1.jar 下載數組

    lucene-core-4.6.1.jar 下載工具

    ext.dic測試

    stopword.dic優化

    IKAnalyzer.cfg.xmlspa

3、分詞

    分詞因爲比較簡單,就直接粘貼代碼了.net

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;
}


4、計算類似度

    計算句子類似度,①經常使用方法有基於語義和詞序類似度計算方法②基於關係向量模型
code

    基於語義和詞序的句子類似度計算方法簡介orm

    定義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={w一、w2,....wn},對T中的每個詞Wi,計算Wi在Ti中的語義分數Ci,T中每一個分詞的語義分數組成的一個向量稱爲Ti基於T的語義向量,表示爲Si={C1,C2,...,Cn}。

           在該算法中,基於T分別計算Ti和Tj的語義向量Si、Sj,以計算Si做爲說明,過程以下:

    一、對於T中的每個詞wi,若是wi 在Ti 中出現,則在語義向量Si中將wi 的語義分數Ci設爲1。

    二、若是Ti中不包含wi,則計算wi 在 Ti 中的語義分數 Ci=a(a爲預先設定的閾值 , 無閾值設爲0 ,本文中閾值爲0.2 ) 。

        根據語義向量計算語義類似度方法以下圖:

        

         詞序類似度計算法方法以下:

                

    其中r一、r2 分別爲T一、T2的詞序向量,以T1爲例,其計算方法以下:

    一、對於T中的每個詞wi,若是T1中包含該次,則r1中該次的取值爲該詞在T1中出現的詞序。不然在T1中找出與wi最類似的詞Wi。

    二、若是wi 和 wi 的類似度大於一個給定的閾值(實驗取值爲0.4),wi在r1中的取值設爲wi在Ti中出現的詞序。

    三、若是兩種狀況均爲發生,則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;  //S一、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源碼地址

原創做者:博客已經遷移,點擊查看

相關文章
相關標籤/搜索