ノート/テキストマイニング
訪問者数 2540      最終更新 2008-06-23 (月) 11:06:13
> ノート/テキストマイニング
> ノート/テキストマイニング/テキストマイニングとシソーラス
> ノート/テキストマイニング/PubMed解析
> ノート/テキストマイニング/NLTK

シソーラスMeSHの扱い

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 &amp; dosage</String>
      </QualifierName>
    </QualifierReferredTo>
    <Abbreviation>AD</Abbreviation>
   </AllowableQualifier>
   あと詳細は略。内容は
     <QualifierName> <String>adverse effects</String> </QualifierName>
     <QualifierName> <String>analogs &amp; derivatives</String> </QualifierName>
     <QualifierName> <String>analysis</String> </QualifierName>
     <QualifierName> <String>antagonists &amp; 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からDescriptor-Concept-Termを抽出する

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をカウントアップ》とすればよい。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2008-06-23 (月) 11:06:13 (3439d)