最大エントロピーをテキストの分類に使用します.
作者:金良[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
このアルゴリズムの鍵となるステップは2(a)であり、すなわち方程式の中のステップを求めます.δiです.f(※(x,y)が定数であれば、どんなx,yに対しても、f(※(x,y)=Mがあります.δi=1 MlogEP~(fi)EP(fi)
2.最大エントロピーでテキストを分類するにはどうすればいいですか?
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)の表現).同じように、無視します.影響はありません.
トレーニングの効果:
反復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
これまでの繰り返しのトレーニングとテストエラー率を下図のように可視化します.はトレーニングセットでモデルの効果が良いことを発見しましたが、テストセットでは効果があまりにも悪く、モデルにズレがあるかもしれません.
特徴権の分布
上の図からは、ほとんどの特徴の値は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})
さらに読む