最大エントロピーをテキストの分類に使用します.


最大熵用于文本分类_第1张图片
作者:金良[email protected])csdnブログ:http://blog.csdn.net/u012176591
オリジナルデータセットと完全なコードを参照してください.http://download.csdn.net/detail/u012176591/8675665
関連する論文「最大エントロピーモデルを使って中国語テキストの分類」
1.改良された反復スケールアルゴリズムIIS:
入力:特徴関数f 1,f 2,⋯,fn;経験分布P~(X,Y)、モデルPw(y 124 x)
出力:最適パラメータ値wi;最適モデルPw
  • ペアのすべてのi∈{1,2,⋯,n}に対して、初値wi=0
  • をとります.
  • ペア毎のi{1,2,⋯,n}:
  • (a)令δiは方程式Σx,yP~(x)P(y 124 x)fi(x,y)exp(δif((zhi(x,y)=EP~(fi)の解で、ここではf((zhi)=Σni=1 fi(x,y)
  • (b)更新wi値:wi←wi+δi
  • すべてのwiが収束しない場合は、ステップ2.
  • を繰り返す.
    このアルゴリズムの鍵となるステップは2(a)であり、すなわち方程式の中のステップを求めます.δiです.f(※(x,y)が定数であれば、どんなx,yに対しても、f(※(x,y)=Mがあります.δi=1 MlogEP~(fi)EP(fi)
    2.最大エントロピーでテキストを分類するにはどうすればいいですか?
  • コードのprobはPw(y 124 x)であり、テキストxがカテゴリに属する確率を表し、probはテキスト数*カテゴリの行列である.Pw(y|x)=1 Zw(x)exp(Σni=1 wifi(x,y))のうち、Zw(x)=Σyexp(Σni=1 wifi(x,y)
  • EP_prorはEP~(f)=Σx,yP~(x,y)f(x,y)であり、特徴関数f(x,y)の先行分布P~(x,y)に関する期待値である.EP_postとは、EP(f)=Σx、yP~(x)P(y)f(x,y)であり、特徴関数f(x,y)であり、事後分布P(x,y)=P~(x)P(y 124 x)の期待値であり、P(y 124 x)は我々のモデルである.最大エントロピーモデルP(y 124 x)は、EP~(f)=EP(f)を要求し、これは、wordNum_ctgyNumの制約条件を意味し、各特徴には制約条件がある.
  • 予測テキストカテゴリは、使用される数式Pw(y|x)=exp(Σni=1 wifi(x,y)Σyexp(Σni=1 wifi(x,y))であり、テキストx,Pw(y|x)の最大クラスyは、判定のクラスである.分母部分Σy exp(Σni=1 wifi(x,y)はカテゴリの判定に無関係であることがわかったので、分子部分exp(Σni=1 wifi(x,y)を計算すれば良い.
  • 単語wとカテゴリCの特徴関数
    fw,C'(C,t)={葑( t,w)\璖(t)0 C=C'C≠C’
    これらのうち、ㄩ(t,w)38089;(t)はワードwが文書tに現れた先行確率を表しています.すべてのテキストの単語の重複しない集合の元素数がwodNumであり、分類の個数がctgyNumであると仮定します.特徴はワードNum(8727)ctgyNum個であり、一つのワードNumを構成しています.(このテキストに登場するものと出現していないものを含む)とカテゴリCの数は、特徴関数として機能する特徴行列を形成しています.このマトリクスは、このテキストには所属していないカテゴリがある列要素は全部0で、このテキストにはない単語がある行も全部0で、非0要素の和は1です.プログラムでは、各テキストに対して、その非0特徴およびその特徴値のみを記録します.(textsの要素は辞書です.このような考えを反映しています.辞書にはそのテキストが属するカテゴリCが含まれています.EP~(f)とEP(f)は、特徴行列の次元の大きさと同じです.また、EP~(f)は、本質的にすべてのテキストの特徴行列の合計(この例ではすべてのテキストの出現確率が均等とみなされます.だから、EP~(f)とEP x(f)の表現).同じように、無視します.影響はありません.
  • 本例ではEP~(f)=Σx,yP~(x,y)f(x,y)=Σxf(x,y)しかないので、yがxのカテゴリに等しい場合はP~(x,y)が1 textNumであり、つまり単一テキストの出現確率であり、残りはすべて0である.つまり、テキストの確率は、ここではテキストごとに異なり、一つのカテゴリだけに属しているので、P~(x)=1 textNumはEP~(f)=EP(f)によって、Σxf(x,y)=Σx,yP(y 124 x)f(x,y)と推知できます.
  • 更新量δi=1 MlogEP~(fi)EP(fi)では、M=maxΣki=1 f(xi)は、すべてのテキストにおける特徴値の和の最大値であり、fw、C′(C,t)の公式によりここMの値が1であることが分かります.
  • 3.トレーニングとテスト効果
    トレーニングの効果:
    反復0回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:1総エラー率:0.00064830353885反復1回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:5総エラー率:0.00182415176943反復2回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:7総エラー率:7総エラー率:12402553反復総テキスト数:2741総エラー個数:8総エラー率:0.00291864283108反復4回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:7総エラー率:0.0025538124772反復5回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:7総エラー率:0.0025538124772反復後の総練習結果:総テキスト数この数:2741総エラー個数:7総エラー率:0.0025538124772反復7回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:5総エラー率:0.00182415176943反復8回後のモデル効果:トレーニング総テキスト個数:2741総エラー個数:4総エラー率:0.001459341554反復9回後のモデル数:総テキスト数2741誤りの数:3総エラー率:0.0010944910616
    テストの効果:
    反復0回後のモデル効果:総テキスト個数をテストする:709総エラー個数:129総エラー率:0.81946403385反復1回後のモデル効果:総テキスト個数をテストする:709総エラー個数:179総エラー個数:121総エラー率:0.17662901反復2回後のモデル効果:総テキスト個数をテストする:709総エラー個数:合計118エラー率:0.66152794反復後のモデル総テキスト個数をテストします.709総エラー個数:118総エラー率:0.66431593794反復後のモデル効果:総テキスト個数をテストします.709総エラー個数:118総エラー率:0.66431593794反復後のモデル効果:総テキスト個数をテストします.709総エラー個数:119総エラー率:0.16842036反復後のモデルの効果:総テキストテスト数:709総エラー個数:120総エラー率:0.69252468265反復7回後のモデル効果:総テキスト個数をテストします.709総エラー個数:117総エラー率:0.160211569反復8回後のモデル効果:総テキスト個数をテストします.709総エラー個数:117総エラー率:0.1569反復9後のモデル効果:総テキスト数をテストします.18総エラー率:0.66431593794
    これまでの繰り返しのトレーニングとテストエラー率を下図のように可視化します.最大熵用于文本分类_第2张图片はトレーニングセットでモデルの効果が良いことを発見しましたが、テストセットでは効果があまりにも悪く、モデルにズレがあるかもしれません.
    特徴権の分布
    最大熵用于文本分类_第3张图片
    上の図からは、ほとんどの特徴の値は0であることが分かります.非0の値をより明確に分析するために、以下の図を作成すると、特徴の値は正規分布に従うことが分かります.
    4.Pythonソース
    十分な注釈があります.もしまだ読めないなら、最大エントロピーモデルの原理を推測したり、Pythonプログラミングを勉強したりします.
    def get_ctgy(fname):#               
            index = {'fi':0,'lo':1,'co':2,'ho':3,'ed':4,'te':5,
                     'ca':6,'ta':7,'sp':8,'he':9,'ar':10,'fu':11}
            return index[fname[:2]]
    
    def updateWeight():
    
            #EP_post     *      
            for i in range(wordNum):
                for j in range(ctgyNum):
                    EP_post[i][j] = 0.0 #[[0.0 for x in range(ctgyNum)] for y in range(wordNum)]
            # prob     *      ,               
            cond_prob_textNum_ctgyNum = [[0.0 for x in range(ctgyNum)] for y in range(textNum)]
            #  p(  |  )
    
            for i in range(textNum):#      
                    zw = 0.0  #     
                    for j in range(ctgyNum):#      
                            tmp = 0.0
                            #texts_list_dict          ,           :        。
                            for (feature,feature_value) in texts_list_dict[i].items():
                                #v    f(x,y),     ,      ,
                                #k        ,v                    。
                                    #feature_weight     *      , EP_prior  
                                    tmp+=feature_weight[feature][j]*feature_value #feature_weight          ,          ,           
                            tmp = math.exp(tmp)
                            zw+=tmp #zw      
                            cond_prob_textNum_ctgyNum[i][j]=tmp                        
                    for j in range(ctgyNum):
                            cond_prob_textNum_ctgyNum[i][j]/=zw
            #          feature_weight      prob  (   *     ,                ),
            #       prob    feature_weight  。
    
    
            for x in range(textNum):
                    ctgy = category[x] #            
                    for (feature,feature_value) in texts_list_dict[x].items(): #             
                            EP_post[feature][ctgy] += (cond_prob_textNum_ctgyNum[x][ctgy]*feature_value)# p(x)        
            #         w
            for i in range(wordNum):
                    for j in range(ctgyNum):
                            if (EP_post[i][j]<1e-17) |  (EP_prior[i][j]<1e-17) :
                                    continue                        
    
                            feature_weight[i][j] += math.log(EP_prior[i][j]/EP_post[i][j])        
    
    def modelTest():
            testFiles = os.listdir('data\\test\\')
            errorCnt = 0
            totalCnt = 0
    
            #matrix    *      ,      
            matrix = [[0 for x in range(ctgyNum)] for y in range(ctgyNum)]
            for fname in testFiles: #     
    
                    lines = open('data\\test\\'+fname)
                    ctgy = get_ctgy(fname) #                  
                    probEst = [0.0 for x in range(ctgyNum)]         #        
                    for line in lines: #                          
                            arr = line.split('\t')
                            if not words_dict.has_key(arr[0]) : 
                                continue        #                       
                            word_id,freq = words_dict[arr[0]],float(arr[1])
                            for index in range(ctgyNum):#      
                                #feature_weight    *      
                                probEst[index] += feature_weight[word_id][index]*freq
                    ctgyEst = 0
                    maxProb = -1
                    for index in range(ctgyNum):
                            if probEst[index]>maxProb:
                                ctgyEst = index
                                maxProb = probEst[index]
                    totalCnt+=1
                    if ctgyEst!=ctgy: 
                        errorCnt+=1
                    matrix[ctgy][ctgyEst]+=1
                    lines.close()
            #print "%-5s" % ("  "),
            #for i in range(ctgyNum):
            # print "%-5s" % (ctgyName[i]), 
            #print '
    ',
    #for i in range(ctgyNum): # print "%-5s" % (ctgyName[i]), # for j in range(ctgyNum): # print "%-5d" % (matrix[i][j]), # print '
    ',
    print " :"+str(totalCnt)+" :"+str(errorCnt)+" :"+str(errorCnt/float(totalCnt)) def prepare(): i = 0 lines = open('data\\words.txt').readlines() #words_dict , , :{'\xd0\xde\xb5\xc0\xd4\xba': 0} for word in lines: word = word.strip() words_dict[word] = i i+=1 # f EP(f) files = os.listdir('data\\train\\') #train .txt index = 0 for fname in files: # file_feature_dict = {} lines = open('data\\train\\'+fname) ctgy = get_ctgy(fname) # , category[index] = ctgy #data/train/ for line in lines: # : 0.00980392156863 # line , arr = line.split('\t') # word_id,freq= words_dict[arr[0]],float(arr[1]) file_feature_dict[word_id] = freq #EP_prior * EP_prior[word_id][ctgy]+=freq texts_list_dict[index] = file_feature_dict index+=1 lines.close() def train(): for loop in range(4): print " %d :" % loop updateWeight() modelTest() textNum = 2741 # data/train/ wordNum = 44120 #data/words.txt , ctgyNum = 12 #feature_weight * feature_weight = np.zeros((wordNum,ctgyNum))#[[0 for x in range(ctgyNum)] for y in range(wordNum)] ctgyName = [' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' ',' '] words_dict = {} # EP_prior 12( )* 44197( ) , EP_prior = np.zeros((wordNum,ctgyNum)) EP_post = np.zeros((wordNum,ctgyNum)) #print np.shape(EP_prior) texts_list_dict = [0]*textNum # category = [0]*textNum # print " :......" prepare() print " , ....." train()
    ソースからのファイルのデータ形式の解析words.txtには、トレーニングデータセットに出現するすべての単語の重複しない集合であり、各行の単語は次の通りである.
    testとtrinフォルダはそれぞれテストデータセットとトレーニングデータセットです.この2つのフォルダのファイルフォーマットとコンテンツフォーマットは区別されていません.各ファイルは1つのテキストに対応しています.ファイル名の前の2つの文字は対応するテキストが属するカテゴリを表しています.ファイル内容はこのテキストの中にすべて出現する単語の確率です.以下のとおりです.
    hist図のコードを作る:
    weight = feature_weight.reshape((1,44120*12))[0]
    #weight = np.log10(weight+1)
    plt.hist(weight, 100)
    plt.title(u'        ',{'fontname':'STFangsong','fontsize':18})
    plt.xlabel(u'     ',{'fontname':'STFangsong','fontsize':18})
    plt.ylabel(u'  ',{'fontname':'STFangsong','fontsize':18})
    
    
    
    エラー率のコード:
    train_precision = [0.000364830353885,0.00182415176943,0.0025538124772,0.00291864283108,0.0025538124772,
                      0.0025538124772,0.0025538124772,0.00182415176943,0.00145932141554,0.00109449106166]
    
    test_precision = [0.181946403385,0.170662905501,0.166431593794,0.166431593794,0.166431593794,0.16784203103,
                     0.169252468265,0.165021156559,0.165021156559,0.166431593794]
    iteration = range(1,11)
    
    fig,ax = plt.subplots(nrows=1,ncols=1)
    ax.plot(iteration,train_precision,'-og',label=u'    ')
    ax.plot(iteration,test_precision,'-sr',label=u'    ')
    
    
    ax.legend(prop={'family':'SimHei','size':15})
    
    ax.set_xlabel(u'    ',{'fontname':'STFangsong','fontsize':18})
    
    ax.set_ylabel(u'    ',{'fontname':'STFangsong','fontsize':18})
    ax.set_title(u'         ',{'fontname':'STFangsong','fontsize':18})
    さらに読む
  • 自然言語処理の最大エントロピーモデルhttp://icl.pku.edu.cn/ICLseminars/2003spring/%E6%9C%80%E5%A4%A7%E7%86%B5%E6%A8%A1%E5%9E%8B.pdf
  • MaxEntModel.ppthttp://read.pudn.com/downloads131/ebook/557682/MaxEntModel%20.ppt 中には対称硬貨問題(表現能力、不確定度、なぜ対数を取って、一回に3つの最小値を取るホフマン符号化)があり、条件エントロピーの公式定義の理解、鞍点問題があります.(詳しくは鞍のところを見てくださいhttp://zh.wikipedia.org/wiki/%E9%9E%8D%E9%BB%9E ブラックプラグマトリックスhttp://zh.wikipedia.org/wiki/%E6%B5%B7%E6%A3%AE%E7%9F%A9%E9%98%B5 )極めて大きな尤度関数が、連合エントロピーから条件エントロピーに変換される導出プロセス
  • .
  • 最大エントロピーのJava実現http://www.hankcs.com/nlp/maximum-entropy-java-implementation.html
  • 最大エントロピーテキスト分類アルゴリズムの実装(コードあり)http://www.blogbus.com/myjuno-logs/240428649.html データセットhttp://www.searchforum.org.cn/tansongbo/corpus.htm
  • 最大エントロピーモデルの簡単な実装(2つのコードがあり、1つは別の簡略版)http://yjliu.net/blog/2012/07/22/easy-implementation-on-maxent.html
  • 张乐:Maximum Entropy Modelinghttp://homepages.inf.ed.ac.uk/lzhang10/maxent.html
  • Jarバッグ(ソースなし)のmaxent:Maxent software for species habitat modelinghttps://www.cs.princeton.edu/~schapire/maxent/
  • AシンプルC++library for maximum entropy classicationhttp://www.logos.ic.i.u-tokyo.ac.jp/~ツルオカ/maxent/
  • 最大エントロピーモデルの図モデル(factor graph):確率マップモデル-ベノス-最大エントロピーーーー-隠し馬-最大エントロピー馬-馬ランダム場