[[ノート/テキストマイニング]]~
訪問者数 &counter(); 最終更新 &lastmod();~
> [[ノート/テキストマイニング]]~
> [[ノート/テキストマイニング/テキストマイニングとシソーラス]]~
> [[ノート/テキストマイニング/PubMed解析]]
> [[ノート/テキストマイニング/PubMed解析]]~
> [[ノート/テキストマイニング/NLTK]]~
***シソーラスMeSHの扱い [#y5be46a7]
-[[MeSHのトップ:http://www.nlm.nih.gov/mesh/meshhome.html]]
-[[XMLタグの解説:http://www.nlm.nih.gov/mesh/xmlmesh.html]]
-[[ダウンロード:http://www.nlm.nih.gov/mesh/filelist.html]]
-[[テキスト形式のサンプル:http://www.nlm.nih.gov/mesh/xml2008sample.txt]]
[[XMLの解説:http://www.nlm.nih.gov/mesh/xmlmesh.html]]によると、3層構造
Descriptor
Concept
Term
になっている。Conceptが概念定義で中心になり、Termは同義語(同じ概念を表す
複数の言葉)が入る。Descriptorはまだよくわからない。
同ページの例で見ると、
<DescriptorRecord ...><!-- Descriptor -->
<DescriptorUI>D000005</DescriptorUI>
<DescriptorName><String>Abdomen</String></DescriptorName>
<Annotation> region & abdominal organs...
</Annotation>
<ConceptList>
<Concept PreferredConceptYN="Y"><!-- Concept -->
<ConceptUI>M0000005</ConceptUI>
<ConceptName><String>Abdomen</String></ConceptName>
<ScopeNote> That portion of the body that lies
between the thorax and the pelvis.</ScopeNote>
<TermList>
<Term ... PrintFlagYN="Y" ... ><!-- Term -->
<TermUI>T000012</TermUI>
<String>Abdomen</String><!-- String = the term itself -->
<DateCreated>
<Year>1999</Year>
<Month>01</Month>
<Day>01</Day>
</DateCreated>
</Term>
<Term IsPermutedTermYN="Y" LexicalTag="NON">
<TermUI>T000012</TermUI>
<String>Abdomens</String>
</Term>
</TermList>
</Concept>
</ConceptList>
</DescriptorRecord>
のようになっている。[[テキスト形式のサンプル:http://www.nlm.nih.gov/mesh/xml2008sample.txt]]を、上記のように圧縮してみると、
<DescriptorRecordSet>
<DescriptorRecord DescriptorClass = "1">
<DescriptorUI>D000001</DescriptorUI>
<DescriptorName>
<String>Calcimycin</String>
</DescriptorName>
<AllowableQualifiersList>
<AllowableQualifier>
<QualifierReferredTo>
<QualifierUI>Q000008</QualifierUI>
<QualifierName>
<String>administration & dosage</String>
</QualifierName>
</QualifierReferredTo>
<Abbreviation>AD</Abbreviation>
</AllowableQualifier>
あと詳細は略。内容は
<QualifierName> <String>adverse effects</String> </QualifierName>
<QualifierName> <String>analogs & derivatives</String> </QualifierName>
<QualifierName> <String>analysis</String> </QualifierName>
<QualifierName> <String>antagonists & inhibitors</String> </QualifierName>
後は省略
</AllowableQualifiersList>
<PharmacologicalActionList>
</PharmacologicalActionList>
<ConceptList>
<Concept PreferredConceptYN="Y">
<ConceptUI>M0000001</ConceptUI>
<ConceptName>
<String>Calcimycin</String>
</ConceptName>
<TermList>
<Term ConceptPreferredTermYN="Y" IsPermutedTermYN="N" LexicalTag="NON" PrintFlagYN="Y" RecordPreferredTermYN="Y">
<TermUI>T000002</TermUI>
<String>Calcimycin</String>
</Term>
</TermList>
</Concept>
<Concept PreferredConceptYN="N">
<ConceptUI>M0353609</ConceptUI>
<ConceptName>
<String>A-23187</String>
</ConceptName>
<TermList>
<Term ConceptPreferredTermYN="Y" IsPermutedTermYN="N" LexicalTag="LAB" PrintFlagYN="N" RecordPreferredTermYN="N">
<TermUI>T000001</TermUI>
<String>A-23187</String>
</Term>
<Term ConceptPreferredTermYN="N" IsPermutedTermYN="Y" LexicalTag="LAB" PrintFlagYN="N" RecordPreferredTermYN="N">
<TermUI>T000001</TermUI>
<String>A 23187</String>
</Term>
<Term ConceptPreferredTermYN="N" IsPermutedTermYN="N" LexicalTag="LAB" PrintFlagYN="N" RecordPreferredTermYN="N">
<TermUI>T000004</TermUI>
<String>A23187</String>
</Term>
<Term ConceptPreferredTermYN="N" IsPermutedTermYN="N" LexicalTag="NON" PrintFlagYN="N" RecordPreferredTermYN="N">
<TermUI>T000003</TermUI>
<String>Antibiotic A23187</String>
</Term>
<Term ConceptPreferredTermYN="N" IsPermutedTermYN="Y" LexicalTag="NON" PrintFlagYN="N" RecordPreferredTermYN="N">
<TermUI>T000003</TermUI>
<String>A23187, Antibiotic</String>
</Term>
</TermList>
</Concept>
</ConceptList>
</DescriptorRecord>
</DescriptorRecordSet>
要するに
Descriptor Calcimycin
Concept Calcimycin
Term Calcimycin
Concept A-23187
Term A-23187
Term A 23187
Term A23187
Term Antibiotic A23187
Term A23187, Antibiotic
という構造になっている。
方針:
-MeSHの階層関係をコンパクトな表にする
-Termレベルで出現頻度を集計する
-Descriptorレベルで出現頻度を集計する
***MeSHからDescriptor-Concept-Termを抽出する [#s7f8866d]
MeSH2008をxml形式でダウンロードした。
Expatを使ってXMLを解析。1行にDescriptor, Concept, Termを書く形で出力。
プログラムは、およそこんな感じで書いた。
# -*- coding: utf-8 -*-
import xml.parsers.expat
import codecs
# Expat handler functions
def start_element(name, attrs):
global level, s
global meshDescriptor, meshConcept, meshTerm
if name.encode('ascii')=='DescriptorRecordSet':
meshDescriptor = "\'\'"
if name.encode('ascii')=='DescriptorRecord':
meshConcept = "\'\'"
meshTerm = "\'\'"
s = ''
level.append(name.encode('ascii'))
def end_element(name):
global level, s
global meshDescriptor, meshConcept, meshTerm
if name.encode('ascii')=='Term':
s = meshDescriptor + ", " + meshConcept + ", " + meshTerm
print s
# cur.execute(s)
level.pop()
def char_data(data):
global level, s
global meshDescriptor, meshConcept, meshTerm
if (len(level)<=2) :
pass;
elif (level[len(level)-3]=='DescriptorRecord') \
&(level[len(level)-2]=='DescriptorName')\
&(level[len(level)-1]=='String'):
meshDescriptor = repr(data.encode('ascii', 'ignore'))
elif (level[len(level)-3]=='Concept')\
&(level[len(level)-2]=='ConceptName')\
&(level[len(level)-1]=='String'):
meshConcept = repr(data.encode('ascii', 'ignore'))
elif (level[len(level)-3]=='TermList')\
&(level[len(level)-2]=='Term')\
&(level[len(level)-1]=='String'):
meshTerm = repr(data.encode('ascii', 'ignore'))
### Now Main Part ###
# Setup to run expat XML parser
p = xml.parsers.expat.ParserCreate()
p.StartElementHandler = start_element
p.EndElementHandler = end_element
p.CharacterDataHandler = char_data
# Other initialization
f = open('mesh2008.xml')
#f = open('meshsample.xml')
level = []
# Now Start the parser
for line in f.readlines():
p.Parse(line)
出力結果は181847行。出力結果の一部。Descriptor, Concept, Termの順。
'Calcimycin', 'Calcimycin', 'Calcimycin'
'Calcimycin', 'A-23187', 'A-23187'
'Calcimycin', 'A-23187', 'A 23187'
'Calcimycin', 'A-23187', 'Antibiotic A23187'
'Calcimycin', 'A-23187', 'A23187, Antibiotic'
'Calcimycin', 'A-23187', 'A23187'
'Temefos', 'Temefos', 'Temefos'
'Temefos', 'Difos', 'Difos'
'Temefos', 'Temephos', 'Temephos'
'Temefos', 'Abate', 'Abate'
'Abattoirs', 'Abattoirs', 'Abattoirs'
'Abattoirs', 'Abattoirs', 'Abattoir'
'Abattoirs', 'Abattoirs', 'Slaughterhouses'
'Abattoirs', 'Abattoirs', 'Slaughterhouse'
'Abbreviations as Topic', 'Abbreviations as Topic', 'Abbreviations as Topic'
'Abbreviations as Topic', 'Acronyms as Topic', 'Acronyms as Topic'
'Abdomen', 'Abdomen', 'Abdomen'
'Abdomen', 'Abdomen', 'Abdomens'
'Abdomen, Acute', 'Abdomen, Acute', 'Abdomen, Acute'
'Abdomen, Acute', 'Abdomen, Acute', 'Abdomens, Acute'
'Abdomen, Acute', 'Abdomen, Acute', 'Acute Abdomen'
'Abdomen, Acute', 'Abdomen, Acute', 'Acute Abdomens'
'Abdominal Injuries', 'Abdominal Injuries', 'Abdominal Injuries'
'Abdominal Injuries', 'Abdominal Injuries', 'Injuries, Abdominal'
'Abdominal Injuries', 'Abdominal Injuries', 'Abdominal Injury'
'Abdominal Injuries', 'Abdominal Injuries', 'Injury, Abdominal'
'Abdominal Neoplasms', 'Abdominal Neoplasms', 'Abdominal Neoplasms'
'Abdominal Neoplasms', 'Abdominal Neoplasms', 'Abdominal Neoplasm'
'Abdominal Neoplasms', 'Abdominal Neoplasms', 'Neoplasm, Abdominal'
'Abdominal Neoplasms', 'Abdominal Neoplasms', 'Neoplasms, Abdominal'
'Abdominal Muscles', 'Abdominal Muscles', 'Abdominal Muscles'
'Abdominal Muscles', 'Abdominal Muscles', 'Abdominal Muscle'
'Abdominal Muscles', 'Abdominal Muscles', 'Muscle, Abdominal'
'Abdominal Muscles', 'Abdominal Muscles', 'Muscles, Abdominal'
ここに出てくる句の中で、たとえばAbdomen, AcuteとかInjuries, Abdominal
といった、コンマのある句は、解析対象の文の中にはこの形では現れない。
どうハンドルするのがいいか?
MeSHの中では、同義語としてAcute Abdomenが入っているので、単純にコンマのある
レコードは無視してしまってよいのではないか?~
逆に、こういうレコードはどう使うのだろう? 更に勉強すること。
ここでは無視することにする。そのために、コンマのある行を取り除くプログラム。
import codecs
import re
#f = open('meshtablesample.txt', 'r')
f = open('meshtable.txt', 'r')
for line in f.readlines():
output = 1
# s = "\'(\S+)\', \'(\S+)\', \'(\S+)\'" # \Sだと不可。'と'の間にスペースがあるとダメだから
s = "\'([^\']+)\', \'([^\']+)\', \'([^\']+)\'"
pattern = re.compile(s)
sresult = pattern.search(line)
if sresult:
g1 = sresult.group(1)
g2 = sresult.group(2)
g3 = sresult.group(3)
### print '[' + g1 + '] | [' + g2 + '] | [' + g3 + ']'
for term in [g1, g2, g3]:
t = "([^,]+),([^\n]+)"
pattern2 = re.compile(t)
tresult = pattern2.search(term)
if tresult:
output = 0
else:
pass
if output==1:
print line.strip("\n") # これは入力のlineの最後の\nを取り除くため。printでまた付けてしまう
結果は、
'Calcimycin', 'Calcimycin', 'Calcimycin'
'Calcimycin', 'A-23187', 'A-23187'
'Calcimycin', 'A-23187', 'A 23187'
'Calcimycin', 'A-23187', 'Antibiotic A23187'
'Calcimycin', 'A-23187', 'A23187'
'Temefos', 'Temefos', 'Temefos'
'Temefos', 'Difos', 'Difos'
'Temefos', 'Temephos', 'Temephos'
'Temefos', 'Abate', 'Abate'
'Abattoirs', 'Abattoirs', 'Abattoirs'
'Abattoirs', 'Abattoirs', 'Abattoir'
'Abattoirs', 'Abattoirs', 'Slaughterhouses'
'Abattoirs', 'Abattoirs', 'Slaughterhouse'
'Abbreviations as Topic', 'Abbreviations as Topic', 'Abbreviations as Topic'
'Abbreviations as Topic', 'Acronyms as Topic', 'Acronyms as Topic'
'Abdomen', 'Abdomen', 'Abdomen'
'Abdomen', 'Abdomen', 'Abdomens'
'Abdominal Injuries', 'Abdominal Injuries', 'Abdominal Injuries'
'Abdominal Injuries', 'Abdominal Injuries', 'Abdominal Injury'
元のデータは(コンマが入っているもの)
'Calcimycin', 'Calcimycin', 'Calcimycin'
'Calcimycin', 'A-23187', 'A-23187'
'Calcimycin', 'A-23187', 'A 23187'
'Calcimycin', 'A-23187', 'Antibiotic A23187'
'Calcimycin', 'A-23187', 'A23187, Antibiotic'
'Calcimycin', 'A-23187', 'A23187'
'Temefos', 'Temefos', 'Temefos'
'Temefos', 'Difos', 'Difos'
'Temefos', 'Temephos', 'Temephos'
'Temefos', 'Abate', 'Abate'
'Abattoirs', 'Abattoirs', 'Abattoirs'
'Abattoirs', 'Abattoirs', 'Abattoir'
'Abattoirs', 'Abattoirs', 'Slaughterhouses'
'Abattoirs', 'Abattoirs', 'Slaughterhouse'
'Abbreviations as Topic', 'Abbreviations as Topic', 'Abbreviations as Topic'
'Abbreviations as Topic', 'Acronyms as Topic', 'Acronyms as Topic'
'Abdomen', 'Abdomen', 'Abdomen'
'Abdomen', 'Abdomen', 'Abdomens'
'Abdomen, Acute', 'Abdomen, Acute', 'Abdomen, Acute'
'Abdomen, Acute', 'Abdomen, Acute', 'Abdomens, Acute'
'Abdomen, Acute', 'Abdomen, Acute', 'Acute Abdomen'
'Abdomen, Acute', 'Abdomen, Acute', 'Acute Abdomens'
'Abdominal Injuries', 'Abdominal Injuries', 'Abdominal Injuries'
'Abdominal Injuries', 'Abdominal Injuries', 'Injuries, Abdominal'
'Abdominal Injuries', 'Abdominal Injuries', 'Abdominal Injury'
'Abdominal Injuries', 'Abdominal Injuries', 'Injury, Abdominal'
で、これを使って、《Termが出てきたら、Descriptorをカウントアップ》とすればよい。