Class: TM::Chunk

Inherits:
Object
  • Object
show all
Defined in:
lib/nysol/chunk.rb

Overview

文節を表すクラス

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(xmlChunk, sentence) ⇒ Chunk

Returns a new instance of Chunk.



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
# File 'lib/nysol/chunk.rb', line 97

def initialize(xmlChunk, sentence)
	# 双方向リストの設定
	if sentence.chunks.size>0 then
		@prev = sentence.chunks.last
	else
		@prev = sentence.dummy
	end
	@next = sentence.dummy
	@prev.next = self if @prev!=nil

	# 各種メンバ変数設定
	@sentence = sentence
	@tokens = []
	@dummy  = TM::Token.new(nil,self)
	@revPol = 1
	if xmlChunk==nil then
		@id   = nil  # dummy Chunk(双方向リストの終端)
		@linkID = ""
		@tokens << TM::Token.new(nil,self)
	else
		@id   = xmlChunk.attribute("id").to_s
		@linkID = xmlChunk.attribute("link").to_s
		@linked = Array.new
		@phrase = numConv(xmlChunk.attribute("phrase").to_s)
		
		@rawPhrase = numConv(xmlChunk.attribute("rawPhrase").to_s)
		@phraseTok = xmlChunk.attribute("phraseTok").to_s
		@phraseOrg = xmlChunk.attribute("phrase").to_s
#puts "@phraseTok=#{@phraseTok}\t#{@phrase}"
		@phraseType = xmlChunk.attribute("phraseType").to_s
		@caseType   = xmlChunk.attribute("caseType").to_s
		@isQuotation = FALSE
		@isQuotation = TRUE if xmlChunk.attribute("end_of_quotation").to_s=="true"
		@isConditional=FALSE
		@isConditional=TRUE if xmlChunk.attribute("conditional").to_s=="true"
		@isWish = FALSE
		@isWish = TRUE if xmlChunk.attribute("wish").to_s=="true"
		xmlChunk.elements.each("token"){|xmlToken|
			@tokens << TM::Token.new(xmlToken,self)
		}
		@cEntries=[]
		@isIdent=false
	end
	@polarity=0
end

Instance Attribute Details

#caseTypeObject (readonly)

【String】格助詞 or nil



66
67
68
# File 'lib/nysol/chunk.rb', line 66

def caseType
  @caseType
end

#cEntriesObject (readonly)

【ComplexEntry_Class Array】複合エントリ配列(なければnil)



71
72
73
# File 'lib/nysol/chunk.rb', line 71

def cEntries
  @cEntries
end

#deniedObject (readonly)

【Fixnum】このchunkもしくは係り先のchunkが否定表現であれば-1



72
73
74
# File 'lib/nysol/chunk.rb', line 72

def denied
  @denied
end

#dummyObject (readonly)

【Token_Class】tokenの双方向リスト用terminal



68
69
70
# File 'lib/nysol/chunk.rb', line 68

def dummy
  @dummy
end

#evalChunkIDObject (readonly)

chunk極性を評価する元になった文節ID



89
90
91
# File 'lib/nysol/chunk.rb', line 89

def evalChunkID
  @evalChunkID
end

#evalPhraseObject (readonly)

chunk極性を評価する元になった文節文字列



90
91
92
# File 'lib/nysol/chunk.rb', line 90

def evalPhrase
  @evalPhrase
end

#evalSentenceIDObject (readonly)

chunk極性を評価する元になった文ID



88
89
90
# File 'lib/nysol/chunk.rb', line 88

def evalSentenceID
  @evalSentenceID
end

#idObject (readonly)

【String】ChunkのID(cabochaが設定したID)



57
58
59
# File 'lib/nysol/chunk.rb', line 57

def id
  @id
end

#isConjunctionObject (readonly)

【Bool】接続助詞を含むかどうか=>同定対象chunkの判定時に利用



79
80
81
# File 'lib/nysol/chunk.rb', line 79

def isConjunction
  @isConjunction
end

#isDenialObject (readonly)

【Bool】否定表現であるかどうか



82
83
84
# File 'lib/nysol/chunk.rb', line 82

def isDenial
  @isDenial
end

#isIdentObject (readonly)

【Bool】同定対象chunk(entry)かどうか



84
85
86
# File 'lib/nysol/chunk.rb', line 84

def isIdent
  @isIdent
end

#isQuotationObject (readonly)

【Bool】引用表現であるかどうか =>引用であれば用言句と見なさない



80
81
82
# File 'lib/nysol/chunk.rb', line 80

def isQuotation
  @isQuotation
end

#isRevConjunctionObject (readonly)

Chunkの各種属性



78
79
80
# File 'lib/nysol/chunk.rb', line 78

def isRevConjunction
  @isRevConjunction
end

#isValidSEObject (readonly)

【Bool】妥当な評価表現であるかどうか



83
84
85
# File 'lib/nysol/chunk.rb', line 83

def isValidSE
  @isValidSE
end

#isWishObject (readonly)

【Bool】願望表現であるかどうか



81
82
83
# File 'lib/nysol/chunk.rb', line 81

def isWish
  @isWish
end

【Chunk_Class】係り先のchunkオブジェクト



59
60
61
# File 'lib/nysol/chunk.rb', line 59

def link
  @link
end

#linkedObject

【Chunk_Class Array】係り元のchunkオブジェクト配列



60
61
62
# File 'lib/nysol/chunk.rb', line 60

def linked
  @linked
end

#linkIDObject (readonly)

【String】係り先chunkのID



58
59
60
# File 'lib/nysol/chunk.rb', line 58

def linkID
  @linkID
end

#nextObject

【Chunk_Class】双方向リスト次



74
75
76
# File 'lib/nysol/chunk.rb', line 74

def next
  @next
end

#phraseObject (readonly)

【String】チャンクのフレーズ(おかしい!!2011/03/02))



61
62
63
# File 'lib/nysol/chunk.rb', line 61

def phrase
  @phrase
end

#phraseOrgObject (readonly)

【String】チャンクのフレーズ(数字変換前)



64
65
66
# File 'lib/nysol/chunk.rb', line 64

def phraseOrg
  @phraseOrg
end

#phraseTokObject (readonly)

【String】チャンクのフレーズ



62
63
64
# File 'lib/nysol/chunk.rb', line 62

def phraseTok
  @phraseTok
end

#phraseTypeObject (readonly)

【String】フレーズタイプ(用言句 or 格助詞句 or nil)



65
66
67
# File 'lib/nysol/chunk.rb', line 65

def phraseType
  @phraseType
end

#polarityObject (readonly)

以下動的に決定される属性



87
88
89
# File 'lib/nysol/chunk.rb', line 87

def polarity
  @polarity
end

#prevObject

【Chunk_Class】双方向リスト前



75
76
77
# File 'lib/nysol/chunk.rb', line 75

def prev
  @prev
end

#rawPhraseObject (readonly)

【String】助詞など一切省略なしの元チャンク



63
64
65
# File 'lib/nysol/chunk.rb', line 63

def rawPhrase
  @rawPhrase
end

#revPolObject

【Fixnum】逆接接続助詞の相対的反転性(+1 or -1)



73
74
75
# File 'lib/nysol/chunk.rb', line 73

def revPol
  @revPol
end

#sentenceObject (readonly)

【Sentence_Class】このchunkが属するsentence



69
70
71
# File 'lib/nysol/chunk.rb', line 69

def sentence
  @sentence
end

#sEntryObject (readonly)

【SimpleEntry_Class】単純エントリ(なければnil)



70
71
72
# File 'lib/nysol/chunk.rb', line 70

def sEntry
  @sEntry
end

#tokensObject (readonly)

【Token_Class Array】token(形態素)配列



67
68
69
# File 'lib/nysol/chunk.rb', line 67

def tokens
  @tokens
end

Instance Method Details

#coreWords(prohibit = []) ⇒ Object

助詞、助動詞、句点を除いたコア語を得る



465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
# File 'lib/nysol/chunk.rb', line 465

def coreWords(prohibit=[])
	prefixVerb=TRUE
	result = ""
	@tokens.each do |token|
		if token.class1=="名詞" then
			prefixVerb=FALSE
		end
		c1=["助詞","助動詞","記号","接頭詞"].index(token.class1)==nil
		c2=["句点","読点","非自立"]         .index(token.class2)==nil
		c3=(token.class1!="動詞" or prefixVerb)

		c4=(prohibit.index(token.word)==nil)
#puts "       #{c1} #{c2} #{c3} #{c4} #{token.word} #{token.class1} #{token.class2}"
		if c1 and c2 and c3 and c4 then
			if token.word=="" then
				result += token.orgWord
			else
				result += token.word
			end
		end
	end
	result = result.chomp.strip.gsub(",","_")
	
	return result
end

#entryCsvout(fp) ⇒ Object



172
173
174
175
176
177
178
179
180
181
182
# File 'lib/nysol/chunk.rb', line 172

def entryCsvout(fp)
	if phraseType=="用言句" then
		linked.each{|linkedChunk|
			next if linkedChunk.phraseType!="格助詞句"
			fp.print "#{sentence.article.id},#{sentence.id},#{id},"
			fp.print "#{linkedChunk.caseType},"
			fp.print "\"#{linkedChunk.phraseTok}_#{linkedChunk.caseType}\","
			fp.print "\"#{phraseTok}_用言\"\n"
		}
	end
end

#evalPolNext(polarity) ⇒ Object

chunkを後方にたどってchunkのpolarityを設定する。既にpolarityが設定済みであればそれ以降は何も設定せずに戻ってくる。逆接接続詞に出会えば、次のchunkから極性を反転させる ex. AAA(+1) BBBだが(+1) CCC(-1)



358
359
360
361
362
363
364
365
366
# File 'lib/nysol/chunk.rb', line 358

def evalPolNext(polarity)
	return if @id==nil
	return if @polarity!=0
	setPolarity(polarity)
	nextPol = polarity
	nextPol *= (-1) if @isRevConjunction # 逆接接続詞の場合は極性反転
	@next.evalPolNext(nextPol)
	return
end

#evalPolPrev(polarity) ⇒ Object

chunkを前方にたどってchunkのpolarityを設定する。



369
370
371
372
373
374
375
376
# File 'lib/nysol/chunk.rb', line 369

def evalPolPrev(polarity)
	return if @id==nil
	return if @polarity!=0
	setPolarity(polarity)
	@polarity *= (-1) if @isRevConjunction # 逆接接続詞の場合は極性反転
	@prev.evalPolPrev(@polarity)
	return
end

#getSentencePol(dic) ⇒ Object

辞書に登録されているエントリとその辞書上のpolarityから計算される##sentence##のpolarityを返す



379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
# File 'lib/nysol/chunk.rb', line 379

def getSentencePol(dic)
	pols=Array.new
	ents=Array.new
	return pols,ents if @sEntry==nil          # 用言句でない
	return pols,ents if not @isIdent          # 対象用言句でない
	return pols,ents if @sentence.mChunk==nil # 主節がない

	# 単純エントリ
	dsEntry=dic.find(@sEntry)                 # 辞書検索
	if dsEntry!=nil then
		# 記事におけるentryのiterNoと極性更新
		if @sEntry.iterNo==-1 then
			@sEntry.iterNo   = dsEntry.iterNo
			@sEntry.polarity = dsEntry.polarity
		end

		# 文極性判定(主節の極性を調べる)
		# ....株価は下降していないが、.....景気は悪化している。
		#                   isDenial
		# ....株価は上昇しているが、.....景気は悪化している。
		#         @revPol=+1    ~~          @revPol=-1
		sPol =dsEntry.polarity                         # 辞書極性
		sPol*=-1 if isDenial                           # そのchunkが否定なら極性反転
		sPol*=-1 if @sentence.mChunk.revPol != @revPol # 主節のchunkの接続詞関係について極性が一致しなければ極性反転
		# 登録
		ents << dsEntry
		pols << sPol
	end

	# 複合エントリ
	@cEntries.each{|cEntry|
		dcEntry=dic.find(cEntry)
		if dcEntry!=nil then
			# 記事におけるentryのiterNoと極性更新
			if cEntry.iterNo==-1 then
				cEntry.iterNo   = dcEntry.iterNo
				cEntry.polarity = dcEntry.polarity
			end

			# 文極性判定
			cPol=dcEntry.polarity
			cPol*=-1 if isDenial
			cPol*=-1 if @sentence.mChunk.revPol != @revPol
			# 登録
			ents << dcEntry
			pols << cPol
		end
	}
	return pols,ents
end

#phraseCsvout(fp) ⇒ Object



149
150
151
152
# File 'lib/nysol/chunk.rb', line 149

def phraseCsvout(fp)
	fp.print "#{sentence.article.id},#{sentence.id},#{id},"
	fp.print "\"#{@phraseTok}\"\n"
end

#phraseDObject



212
213
214
215
216
217
218
219
# File 'lib/nysol/chunk.rb', line 212

def phraseD
	# チャンクの否定語付きフレーズの設定
	if @isDenial then
		return @phraseTok+":否"
	else
		return @phraseTok
	end
end

#phraseEntryCsvout(fp) ⇒ Object



154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
# File 'lib/nysol/chunk.rb', line 154

def phraseEntryCsvout(fp)
	# 格フレームでない場合
     if phraseType==""
		fp.print "#{sentence.article.id},#{sentence.id},#{id},"
		fp.print ","
		fp.print "\"#{phraseTok}\"\n"

	# 格フレームの場合
	elsif phraseType=="用言句" then
		linked.each{|linkedChunk|
			next if linkedChunk.phraseType!="格助詞句"
			fp.print "#{sentence.article.id},#{sentence.id},#{id},"
			fp.print "#{linkedChunk.caseType},"
			fp.print "\"#{linkedChunk.phraseTok}_#{linkedChunk.caseType} #{phraseTok}_用言\"\n"
		}
	end
end

#setAttributesObject

chunkに関する各種属性を調べ、それぞれの判定メンバ変数にbool値をセットする



224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
# File 'lib/nysol/chunk.rb', line 224

def setAttributes
	return false if @tokens.size==0

	# 後ろ二つのtokenをセット
	token1=token2=@dummy
	endByTokusyu=false
	i=0
	@tokens.reverse.each {|token|
		if token.class1 == "特殊" then # 句読点
			endByTokusyu=true if i==0
			i+=1
			next
		end
		token1 = token
		token2 = token.prev
		break
	}

	# 否定であるかどうか
	@isDenial=FALSE
	dFlg=1
	@tokens.each {|token|
		if (token.class1=="接尾辞" and (token.word=="ない" or token.word=="" or token.word=="" or token.word=="かねる")) or (token.class1=="形容詞" and token.word=="ない") or (token.class1=="助動詞" and token.word=="") then
			dFlg *= -1
		end
	}
	@isDenial=TRUE  if dFlg==-1

	# 逆接接続詞かどうか
	@isRevConjunction=false
	if (token1.class1=="接続詞" or token1.class2=="接続助詞") and ["一方","しかし","しかしながら","ところが","それでいて","なのに","それどころか","","だが","けれども","けれど","ながら","ものの"].index(token1.word) then
		@isRevConjunction=true
	elsif token1.orgWord=="" and token2.orgWord=="もの" then
		@isRevConjunction=true
	elsif token1.orgWord=="" and token2.orgWord=="ながら" then
		@isRevConjunction=true
	elsif token1.orgWord=="のに" and token1.class1=="助動詞" and endByTokusyu then
		@isRevConjunction=true
	elsif token1.orgWord=="のに" and token2.orgWord=="" then
		@isRevConjunction=true
	elsif token1.orgWord=="対し" and token2.word=="" then
		@isRevConjunction=true
	elsif token1.word.index("にもかかわらず") and token1.class1=="接続詞" then
		@isRevConjunction=true
	elsif token1.orgWord=="" and token2.orgWord=="かかわら" then
		@isDenial=false
		@isRevConjunction=true
	end

	# 接続詞かどうか
	@isConjunction=false
	@isConjunction=true  if token1.class2=="接続助詞"
	
	# 引用の用言であるかどうか(直前のchunkの最後のwordが引用格助詞かどうかを判定する)
	# ex.
	# 三越伊勢丹ホールディングスの石塚邦雄社長は「最悪な景気感が二年は続くと思って経営にあたる」という。
	# 続く「と」思って,「と」いう。
	#@isQuotation=false
	#@isQuotation=true if @prev.tokens.last.class2=="格助詞" and @prev.tokens.last.class3=="引用"

	# 仮定形のchunkかどうか
	# 例1)
	# する,する,動詞,自立,*,*,サ変・スル,基本形
	# なら,だ,助動詞,*,*,*,特殊・ダ,仮定形
	# 例2)
	# 増やせ,増やす,動詞,自立,*,*,五段・サ行,仮定形
	# ば,ば,助詞,接続助詞,*,*,*,*
	#@isConditional=false
	#@isConditional=true if  token1.form2=="仮定形" and (token1.orgWord=="なら" || token1.orgWord=="たら")
	#@isConditional=true if  token2.form2=="仮定形" and (token1.word=="ば"      || token1.word=="と")

	# 願望のchunkかどうか
	# 怠ら,怠る,動詞,自立,*,*,五段・ラ行,未然形
	# ない,ない,助動詞,*,*,*,特殊・ナイ,基本形
	# よう,よう,名詞,非自立,助動詞語幹,*,*,*
	# に,に,助詞,格助詞,一般,*,*,*
	# し,する,動詞,自立,*,*,サ変・スル,連用形
	# たい,たい,助動詞,*,*,*,特殊・タイ,基本形
	# 。,。,記号,句点,*,*,*,*
	#@isWish=false
	#@isWish=true if token2.form2=="連用形" and token1.word=="たい"
	#@isWish=true if token2.class1=="接尾辞" and token1.word=="ほしい"

	# chunkが評価表現の同定対象として有効かどうか
	@isValidSE = true
	@isValidSE = false if @sEntry==nil or @isConditional or @isWish
end

#setCandidate(cand) ⇒ Object

候補辞書candにentryを@polarity極性にて登録する。015_gendic->sentence.setCandidateから呼ばれる



434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
# File 'lib/nysol/chunk.rb', line 434

def setCandidate(cand)
	return if @sEntry==nil     # 用言句でない
	return if not @isIdent     # 同定対象用言句でない

	# 以下の一文は、MP対応にするまではコメントアウトしていたが復活させた。
	# コメントアウトしていた理由は、トータル件数をカウントするためである。
	# ただ、その為に全エントリが候補としてあがることになり、非常に効率が悪かった。
	# そこで、トータル件数は別の場所(genDic.rb)でセットすることでこの問題を回避することとした。
	return if @polarity==0     # chunk極性が評価されていない

	# 以下をコメントアウトするのは、辞書に既に登録されているエントリも候補として処理するため。
#			return if @sEntry.polarity!=0 # このchunkのpolarityが評価済み

	pol=@polarity
	pol*=(-1) if @isDenial

	cand.add(@sEntry,pol)
	@cEntries.each{|cEntry|
		cand.add(cEntry,pol)
	}
end

#setEntryObject

chunkが用言句であればEntry(極性は0)を登録する。



315
316
317
318
319
320
321
322
323
324
325
# File 'lib/nysol/chunk.rb', line 315

def setEntry
	return if @phraseType!="用言句"
	dPhrase = DeclinedPhrase.new(self)
	@sEntry = SimpleEntry.new(dPhrase,0)
	@linked.each{|from|
		pPhrase = ParticlePhrase.new(from)
		next nil if pPhrase.word==nil
		@cEntries << ComplexEntry.new(dPhrase,pPhrase,0)
	}
	return true
end

#setIdentChunkObject

同定対象chunkかどうかを判定し、isIdent変数をセットする



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
# File 'lib/nysol/chunk.rb', line 330

def setIdentChunk
	return if @id==nil

	#「〜と思う。」などの引用表現の場合は、一つ前の用言句を対象とする。
	if isQuotation then
		@isIdent=false
		prev.setIdentChunk
		return
	end

	if isValidSE then
		@isIdent=true
	else
		@isIdent=false
	end

	@isIdent=true
	@linked.each{|from|
		if from.isConjunction then
			from.setIdentChunk
		end
	}
end

#setPolarity(pol) ⇒ Object

chunkのpolarityをセットする(同時にpolarityが決まったchunk数カウンタをupする)



93
94
95
# File 'lib/nysol/chunk.rb', line 93

def setPolarity(pol)
	@polarity=pol
end

#show(simple = false, fp = STDERR) ⇒ Object



184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# File 'lib/nysol/chunk.rb', line 184

def show(simple=false, fp=STDERR)
	if simple then
			@tokens.each{|token|
			fp.print "#{token.word} "
		}
		fp.puts ""
	else
		fp.print "\t\t"
		fp.print "Chunk #{@phraseTok}(#{@phraseType}:#{@caseType}) ATT:rc#{@isRevConjunction ?1:0},cj#{@isConjunction ?1:0},qt#{@isQuotation ?1:0},co#{@isConditional ?1:0},wi#{@isWish ?1:0},de#{@isDenial ?1:0},vs#{@isValidSE ?1:0},id#{@isIdent ?1:0}"
		fp.print " PO#{@polarity},RP#{@revPol}"
		fp.print ",Eval#{@evalSentenceID}-#{@evalChunkID}(#{@evalPhrase})" if @evalSentenceID!=nil
		fp.print " id=#{@id}(#{sentence.id}) to=#{linkID}("
		@linked.each{|chunk| fp.print "#{chunk.id},"}
		fp.print ") "
		@sEntry.show(fp) if @sEntry!=nil
		if @cEntries!=nil then
			@cEntries.each{|cEntry|
				fp.print " "
				cEntry.show(fp)
			}
		end
		fp.puts ""
			@tokens.each{|token|
			token.show(fp)
		}
	end
end

#tokenCsvout(fp) ⇒ Object



143
144
145
146
147
# File 'lib/nysol/chunk.rb', line 143

def tokenCsvout(fp)
	@tokens.each{|token|
		token.tokenCsvout(fp)
	}
end

#wordsObject



456
457
458
459
460
461
462
# File 'lib/nysol/chunk.rb', line 456

def words
	result = ""
	@tokens.each do |token|
		result += token.word
	end
	return result
end