![]() |
ノート/テキストマイニング/MeSHhttps://pepper.is.sci.toho-u.ac.jp:443/pepper/index.php?%A5%CE%A1%BC%A5%C8%2F%A5%C6%A5%AD%A5%B9%A5%C8%A5%DE%A5%A4%A5%CB%A5%F3%A5%B0%2FMeSH |
![]() |
ノート/テキストマイニング
訪問者数 3521 最終更新 2008-06-23 (月) 11:06:13
> ノート/テキストマイニング
> ノート/テキストマイニング/テキストマイニングとシソーラス
> ノート/テキストマイニング/PubMed解析
> ノート/テキストマイニング/NLTK
XMLの解説によると、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>
のようになっている。テキスト形式のサンプルを、上記のように圧縮してみると、
<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
という構造になっている。
方針:
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をカウントアップ》とすればよい。