[[ノート/テキストマイニング]]~
訪問者数 &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 &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の階層関係をコンパクトな表にする
-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をカウントアップ》とすればよい。

トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS