2018年12月29日土曜日

KH Coderで国会会議録を対応分析する

KH Coderはテキストデータを統計的に分析できるフリーソフトウェアで、共起ネットワークやクラスター分析などさまざま分析ができる(KH Coderでツイートを分類するなど)。そのKH Coderでできる分析のひとつに対応分析というものがあるので、国会会議録の発言テキストを使って分析してみる。


環境


国会会議録取得

Ubuntu 16.04(WSL)とPython3.5.2。
他にPythonライブラリのPandasも使うのでインストールしておく。


KH Coder

Windows10(1803/April 2018 Update)
Windows版 KH Coder Version 3.Alpha.13g


対応分析とは


そもそも対応分析とはなんぞやというところから。コレスポンデンス分析と呼ばれることもあり、ググると、「名義尺度水準のデータを数量化し散布図で表現する分析手法」のような説明が見つかる。KH CoderのホームページのRを用いた多変量解析と可視化にも説明がある。

さらに、対応分析と似た分析手法として主成分分析がある。この2つの分析手法の違いは、コーパス言語学研究における多変量解析手法の比較 : 主成分分析 vs. コレスポンデンス分析に説明がある。

2 つの手法の大きな違いは,対象とするデータの前提条件であり,コレスポンデンス分析は質的データ(名義尺度,順序尺度)を扱い,主成分分析では量的データ(間隔尺度,比率尺度)を扱う

加えて以下のような記述も。

できるだけ元の情報を圧縮したものを作り上げることにあるならば主成分分析がすぐれており,差異(類似)を見つけ出すことが目的なのであれば,コレスポンデンス分析が適していると考えられる


分析対象テキスト


Pythonで国会会議録からワードクラウドを作成すると同様に、国会会議録APIで最新の国家基本政策委員会合同審査会(党首討論)の会議録を取得する。各発言の先頭の「~君」などの発言者は同様に正規表現で取り除く。KH Coderで読み込むために今回はcsvで保存する。その部分を修正したコードは以下の通り。結果は1人の発言ごとにdebate.csvというファイルに保存される。ただし、鉢呂委員長は会議の進行役なので取得対象から除外する。

from urllib.request import Request, urlopen
from urllib.parse import quote
from urllib.error import URLError, HTTPError
import re
import pandas as pd
import xml.etree.ElementTree as ET
import codecs
import csv

def create_query():
    """
    リクエストクエリの作成
    """
    # 国家基本政策委員会合同審査会(党首討論)1回分の発言を取得する
    params = {
        'nameOfMeeting': '国家基本政策委員会合同審査会',
        'maximumRecords': 1
        }

    return '&'.join(['{}={}'.format(key, value) for key, value in params.items()])

def parse_xml(res_xml):
    root = ET.fromstring(res_xml)

    try:
        # 取得したデータはPandasのデータフレームにする
        header = ['Date', 'Meeting', 'Speaker', 'Speech']
        df = pd.DataFrame(columns=header)

        for record in root.findall('./records/record/recordData/meetingRecord'):
            # 会議録情報の取得
            nameOfMeeting = record.find('nameOfMeeting').text
            issue = record.find('issue').text
            meeting = '{} {}'.format(nameOfMeeting, issue)
            date = record.find('date').text
            for speechRecord in record.findall('speechRecord'):
                # 発言者と発言の取得
                speaker = speechRecord.find('speaker').text
                speech = speechRecord.find('speech').text
                if speaker is not None:
                    # 先頭のspeechRecord(speechOrder=0)は出席者一覧などの会議録情報なのでスキップ

                    # 話者(speaker)を除去
                    # (拍手)など括弧でかこまれた箇所を除去
                    # 他人の発言中の発言〔~〕を除去
                    # 全角空白を除去(先頭に全角空白がある文がある)
                    speech = re.sub(r'\A○.*?君()|) |(.*?)|〔.*?〕| ', '', speech)

                    # データフレームに1行ずつ追加していく
                    row = [date, meeting, speaker, speech]
                    df.loc[len(df.index)] = row

        # 会議録の発言などをcsvに保存
        # 鉢呂委員長は進行役なので除外
        with codecs.open('debate.csv', 'w', 'shift_jis', 'ignore') as cf:
            # quoting=csv.QUOTE_NONNUMERICで文字列をダブルクォートで囲む
            df[df['Speaker'] != '鉢呂吉雄'].to_csv(cf, header=True, index=False, quoting=csv.QUOTE_NONNUMERIC)
    except ET.ParseError as e:
        print('ParseError: {}'.format(e.code))

def main():
    # クエリはパーセントエンコードしておく
    request_url = 'http://kokkai.ndl.go.jp/api/1.0/meeting?' + quote(create_query())

    req = Request(request_url)

    try:
        with urlopen(req) as res:
            res_xml = res.read().decode('utf8')
    except HTTPError as e:
        print('HTTPError: {}'.format(e.reason))
    except URLError as e:
        print('URLError: {}'.format(e.reason))
    else:
        parse_xml(res_xml)

if __name__ == '__main__':
    main()

作成したcsvの中身は以下のようになる。


対応分析をする


作成したdebate.csvをKH Coderで読み込んで対応分析をやってみる。KH Coderの新規プロジェクトで、「分析対象とする列」は「Speech」を選択する。形態素解析エンジンはChaSenでもいいが、ここではMeCabを選択する。MeCabの辞書は、もう少し簡単にKH Coderで新語に対応するためにmecab-ipadic-NEologdを使うのようにmecab-ipadic-NEologdに変更済み。

前処理を実行したら、[ツール]>[抽出語]>[対応分析]で対応分析を行う。設定は、「抽出語X外部変数」で「Speaker」を選択し、「バブルプロット」をチェックした以外はデフォルト。


対応分析の結果


以下のような結果になった。データから抽出された成分1と成分2に対する語と発言者とが図示されている。この成分が何を表すかは分析者が推測することになるが、今回はそこまではやらない。各成分のとなりの数字、32%と24%は各成分の寄与率で、全データのうちその成分で説明できている割合。



KH Coder開発者の樋口先生が対応分析のプロット図に軸についてで対応分析の解釈の仕方を説明している。
解釈のしかた、書き方としては、「布置された場所が近いかどうか」ではなく「原点からの方向や距離」に注目するのが正しいのです。
図では「言う」の当たりに原点があるが、ここから離れているほど成分1、2において特徴的ということになる。図では、共産党の志位委員長の発言が他の党首に比べて特徴的ということになる。


対応分析その2


対応分析の図をみると、「言う」とか「考える」など、分析に関係なさそうな語がけっこう含まれている。テキスト分析では分析に関係のない語を除外することでよい結果が得られることがあり、除外する語をストップワードという。KH Coderでも特定の語を分析から除外できる。

まずは、以下のようなストップワードのリストをテキストファイルにする(---cell---は常に必要)。


[前処理]>[語の取捨選択]>[使用しない語の指定]で、「ファイルから読み込み」をチェックして、作成したストップワードのテキストファイルを指定する。

前処理の実行を行い、再度対応分析をする。前回の設定に加えて、今回は最小出現数を8にして表示される語を増やしてみる。

結果は以下の通り。各党首間の位置関係がけっこう変わった。



0 件のコメント:

コメントを投稿