目次
- はじめに
- 本記事での検証について
- 検証:感情分析
- 結論
- 感想
1. はじめに
※このブログはAidemy Premiumのカリキュラムの一環で、受講修了条件を満たすために公開しています。
プログラミングとは全く縁がなかった私ですが、今後のキャリアを考え、無謀にもAIの世界に飛び込み、現在Aidemyにて自然言語処理を学んでいます。
今回は、講座で学んだ内容をもとに、太宰治作品を分析しく所存です。
20代後半から病気が徐々に回復したことから法学を学び始め、現在は某システム開発を行っている企業で法務事務を担当しています。
もっとも、システム開発には全く携わったことがないIT完全初心者です。
今後、法務の分野にもAIが大幅に導入されることが想定されることから、少しでも時代についていけるようリスキリングを決意。Aidemyの講座と並行して高校数学を学び、今に至ります。
2. 本記事での検証について
開発環境
Google Colaboratoryにて開発を行います。 使用するプログラミング言語はpythonです。検証内容 〜感情分析〜
感情辞書を用いた小説の感情分析を行います。
この感情分析を用いて私が検証してみたいことは以下の2つです。
そこで、今回は、東北大の乾・岡崎研究室が公開している「日本語評価極性辞書」を用いて、文学の持つ情緒や感情値をどこまで分析することができるのか、検証してみたいと思います。
各作品には、太宰の男性観、女性観が大きく反映されていると思うので、それぞれを感情分析してデータとして比較し、
① 両者にどのような違いがあるか
② 各作品のあらすじの印象と一致するか
を、検証してみたいと思います。
感情分析の方法
-
太宰の3作品の感情分析を行う
・章ごとの感情値を合計したものをグラフにし、可視化。(x軸が各章、y軸が感情値。)
・ポジティブ値とネガティブ値の2つに分けてグラフを描画し、再検証する。
・ポジティブ値の単語数とネガティブ値の単語数の割合を考慮して感情値を算出する。
- 上記でグラフ化した男性一人称の作品と、女性一人称の作品の感情値の推移を比較する。
3. 検証 : 感情分析
さて、分析を始めていきます。- 男性の一人称:『人間失格』
- 女性の一人称:『ヴィヨンの妻』『斜陽』
- あらすじ
- 生きづらさを抱えつつも社会に適応するため道化を演じる葉蔵は、苦しみから逃れようと酒や女遊びを覚え堕落します。女給との心中未遂、未亡人との同棲の後に内縁の妻を得て、ようやく自分も人間らしいものになれるのではと思ったのも束の間、心のバランスを崩し、ついに「人間失格」となったのでした。
-
はしがき →'hashigaki'
「私は、その男の写真を三葉、見たことがある」から始まり、第三者の男の目線で語られます。男は葉蔵の写真について語りますが、1枚目の幼少期、2枚目の青年期、そして3枚目の年齢の分からない白髪姿の葉蔵は、いずれも気味の悪い人間として男の目に映ります。
そして男は葉蔵について、「私はこれまで、こんな不思議な男の顔を見た事が、やはり、いちども無かった」と述べています。
-
第一の手記 →'dai_1'
ここからは、葉蔵自身の視点で語られます。幼いころから「人間の生活というものが、見当つかないのです」と語り、自分は異質だと思って生きてきた葉蔵は、他者とつながるために 「道化」として生きることを覚えました。
そんな葉蔵は女中や下男に「哀しい事を教えられ」(おそらく性的虐待のこと)ても誰にも言い出せず、ただ笑って過ごすことしかできませんでした。
-
第二の手記 →'dai_2'
「道化」を演じる幼少期の葉蔵でしたが、それを唯一見破ったのが竹一でした。やがて竹一と親しくなった葉蔵は、洋画を「お化けの絵」と称した彼に「僕も画くよ。お化けの絵を画くよ」と告げます。葉蔵はそれらの絵を、「人間という化け物に傷(いた)めつけられ、おびやかされた揚句の果、(略)それを道化などでごまかさず、見えたままの表現に努力したのだ」と感じて「将来の自分の、仲間がいる」と興奮します。
やがて成長した葉蔵は美術学校への進学を希望しますが、父親にそれを言い出せず、東京の高等学校を受験します。進学とともに上京した葉蔵は、そこで堀木正雄と出会いました。
堀木と飲み歩くようになった葉蔵は、カフェで女給をしているツネ子と関係を持ちます。しかしそれを知らない堀木に彼女を「貧乏くさい女」と称され、葉蔵は初めて「微弱ながら恋の心の動く」のを感じます。そして葉蔵とツネ子は入水(じゅすい)し、葉蔵だけが生き残ったのでした。
-
第三の手記 →'dai_3'
生き残った葉蔵は、高等学校から追放されてしまいます。葉蔵は堀木のもとで知り合った未亡人シヅ子の家に身を寄せ、漫画家になります。シヅ子の娘にも「お父ちゃん」と呼ばれて慕われますが、堀木に「お前の、女道楽もこのへんでよすんだね。これ以上は、世間が、ゆるさないからな」と言われたことから、「世間というものは、個人ではなかろうか」と思いはじめます。やがて「自分という馬鹿者が、この二人(シヅ子とシヅ子の娘)のあいだにはいって、いまに二人を滅茶苦茶にするのだ」と考えるようになった葉蔵は、シヅ子の元を去りました。
その後はバーのマダムのもとで生活するようになった葉蔵ですが、ひょんなことから向かいの煙草屋の、人を疑うことを知らない純粋なヨシ子を内縁の妻とします。
ようやく平和な日々を手に入れたかに見えた葉蔵ですが、ヨシ子は出入りの商人に関係を強要されてしまいます。それを知った葉蔵は精神を病み、ヨシ子が隠していた睡眠薬で自殺を図ります。
一命をとりとめた葉蔵でしたが、地獄のような日々は続きます。酒と薬に溺れ、金を苦心するためについに父親にすべてを告白する手紙を出した後、脳病院に連れ込まれ、「人間、失格」と悟る のです。
やがて父が死ぬと、葉蔵は療養として田舎へ連れ戻されます。そしてそこで、「いまは自分には、幸福も不幸もありません」 と語ったのでした。
-
あとがき →'atogaki'
ここで語り手はまた第三者の男に戻ります。男はあるとき、バーのマダムから葉蔵の手記と前述の写真を見せられたことを語ります。葉蔵に興味を持った男でしたが、マダムも葉蔵の現在の居場所は知らず、近況についても知りませんでした。生死もわからなくなった葉蔵のことを、マダムは「人間も、ああなっては、もう駄目ね」と言いながら、最後には「神様みたいないい子でした」と振り返るのでした。
-
はしがき →'hashigaki'
-
一 →'one'
戦後の日本。さっちゃん(私)は夫と2歳になる息子と暮らしています。しかし、夫の大谷は一度出かけたら3~4日帰ってこないこともあり、たまに帰ってきても泥酔している状態です。
その夜も、大谷は酔って帰ってきました。すると、玄関から大谷を呼ぶ声が聞こえます。大谷が出ていき、さっちゃんは彼らの会話を寝室で聞いていました。
口論に発展したため、さっちゃんが出ていくと、すきを突いた大谷は逃げてしまいました。さっちゃんは仕方なく、家に来た50歳過ぎくらいの男性と40歳前後の女性を家に入れました。
彼らは、大谷が馴染みにしている「椿屋」という小料理屋の主人とその奥さんでした。そして、普段から飲み代を踏み倒されているのに加えて、今夜は5千円を盗んだため、家まで取り立てに来たのだと言います。
さっちゃんは、「後の始末は私が引き受けます」と言って、彼らに引き取ってもらいました。 -
二 →'two'
翌朝、後始末は引き受けるとは言ったものの、なんの当てもないさっちゃんは途方に暮れてしまいました。ところが、仕方なく椿屋に出向いたさっちゃんは、別人のように振舞います。
さっちゃんは、椿屋の勝手口から店に入ると、昨日家に来た女性に「お金は返せそうです」と思ってもいない嘘をすらすらと言いました。
そして、そのまま椿屋で従業員として働き始めます。すると、タイミングよく1人の女性を連れた大谷が店にやって来ました。そして、大谷と椿屋の主人が店の外に出ていくのを見たさっちゃんは、ほっと胸をなでおろします。 -
三 →'three'
30分ほど経って椿屋の主人が店に戻り、「金は返してもらった」とさっちゃんに告げました。
それから、「椿屋のさっちゃん」という名前で通るようになりました。
さっちゃんは、椿屋での仕事の帰りに客としてきた大谷と一緒に帰ることもあり、とても幸せでした。
その頃、さっちゃんは椿屋に来る人が1人残らず犯罪者だということに気がつきます(椿屋では、闇ルートで仕入れた酒を扱っていました)。
かく言うさっちゃんも、ある夜椿屋に訪れた客に犯されてしまいました。さっちゃんは、人は罪を犯さずには生きていけないと悟ります。
次の日、さっちゃんはいつもと同じように椿屋に出勤しました。そこには、大谷の姿がありました。
そこで彼は、自分が新聞で人非人(にんぴにん。ひとでなし)と書かれていることを嘆きますが、さっちゃんは「人非人でもいいじゃないの。私たちは、生きていさえすればいいのよ」と言いました。 - ヴィヨンの妻 予想
-
一 →'ichi'
(母の病気)
華族のかず子(私)は気品のある母と二人暮らし。
父は10年前に死去、弟の直治は徴兵に取られたっきり帰ってこない。
かず子本人は一度結婚したが離婚した出戻り。
終戦で東京の屋敷を売り払い、伊豆に引越し小さな家に二人で住んでいる。 -
二 →'ni'
(かず子と男性)
屋敷ではボヤ騒ぎを起こして近所に迷惑をかける。
しかし、近所の人と親しむことができて、いっしょに畑仕事が出来るようになる。
華族といっても戦時徴用はあった。立川の山奥でヨウトマケ(土木作業)をした。若い将校に親切にしたもらった。ほかに戦争中の思い出はない。
母は日に日に弱る。
弟の直治が生きているらしい。 -
三 →'san'
(直治の手記)
弟は心配していた麻薬中毒もなく帰ってきた。彼のノート「夕顔日記」を盗み読みすると、麻薬中毒中の苦しさが描かれている。
私も弟の借金返済に困って、弟の師匠上原を尋ねたことがあった。
上原は麻薬から酒に転換する戦術を教えてくれて、不意に私にキスをした。
そんなこんなで、私の結婚は破綻した。 -
四 →'yon'
(かず子から上原へのラブレター)
1、相談がある。M.C.という人が恋しい。M.C.に打診して欲しい。M.C.(マイチエホフ)
2、ずるい手紙を見破られた。返事はもらえなかったが、私にも縁談がある。60過ぎたお爺ちゃん。子供が欲しいから断った。あなたの子供が欲しい
3、返事がもらえなかった。ならば直治が東京に出張している際に伊豆にきてください。はばむ道徳を押しのけられませんか?、M.C.(マイチャイルド) -
五 →'go'
(母の死)
手紙に結局返事はなかった。失恋だ。それならばと上京支度を始めていると、母の具合が悪くなった。医者に見せると心配ないと言う。しかし夢で和服の男性から、「お母様はもう墓の下」と言われる。看病のつれづれに、直治の経済学の本を読む。社会主義のレーニンなどだ。昔友人から薦められていたが、その時は結局読まなかった。今はわかる。人間は革命と恋のために生まれてきたのだ。
10月、母の手が浮腫み、肺結核が診断された。やがて母は死んだ。 -
六 →'roku'
(かず子と上原)
戦闘開始。こうなれば直接押しかける。
東京に出てゆき、上原宅を探していると鼻緒が切れた。こまってい偶然たどり着いた家が上原宅だった。
奥様が鼻緒を直して、上原の行く場所を教えてくれた。奥様に申し訳ないが、恋を貫徹したい。
最終的に西荻のチドリという飲み屋で上原一行に出会えた。同席の知人たちは、ギロチンギロチンなどと歌いながら酒を飲み、大金を浪費している。狂っているが、それでしか生きられないのだろう。
上原に送られて知人宅に泊めてもらい、結局結ばれた。幸福だった。上原が「もう遅いなあ、黄昏だ」と言い、私は「朝ですわ」と答えた。
その日、弟の直治は自殺していた。 -
七 →'nana'
(直治の遺書)
先に行く。なぜ生きなければいけないかわからない。
軍隊で入手した楽に死ねる薬がある。貴族だったからジェラシーを受けた。
苦しかった。遊んでも楽しくなかった。
ただ秘めた恋があった。ある画家の奥さんに恋をしていた。彼女の名前はスガちゃん。
夜が明ける、さようなら。 -
八 →'hachi'
(かず子から上原への手紙)
私は捨てられたようです。でも妊娠できているようです。
戦争や平和や貿易や組合がなんのために存在しているかご存知ですか?それは女が子供を生むためです。だから戦いには勝ちました。これから私生児と母、太陽のように生きます。
最後にお願いがあります。生まれた子を奥さんに一度抱かせて、「これは直治がある女の人に生ませた子です」といいたいのです。なぜだからわからないがそうしたいのです。捨てられた女の最後の嫌がらせです。M.C.(マイコメディアン) - 斜陽の感情推移の予想
- 名詞
- 形容詞
- 動詞
- 副詞
-
①-1 各感情値の合計を各感情値の出現単語数で割って平均値を算出したもの
-
①-2 各感情値の平均値を合計したもの
:各章の感情値の単純な平均値をデータ -
②各章の出現単語数の合計と、各感情値の出現単語数の割合を考慮して感情値を算出したもの
:各章の感情(ポジネガ)の印象を大きく掴む事ができる?データ - 1. 既存の感情辞書で文学をどこまで分析できるか。
-
ネガポジ分析をすることで、物語の大まかな展開や起承転結の転換点の読み取りができることはあるようである。
-
覚悟はしていたものの、文学は表現は奥深く、単語単位でポジネガ値を見るだけでは、感情値を正確に把握することは難しい。
-
既存の感情辞書で、小説の感情値を正確に把握することは難しく、より精度の高い感情分析を行うためには、分析の対象となる作品の内容に合うよう既存の感情辞書を一部改編等する必要があると思われる。
- 2.太宰作品の男性一人称・女性一人称作品の感情値の推移を検証する
-
男性一人称では、感情値の出し方にもよるが、大方の予想通り、全体的にネガティブに偏っており、クライマックスにかけてネガティブ値が大きくなっていくようである。(どの数値の出し方でも、ポジティブ値を示すことはほとんどなかった。)
-
女性一人称では、こちらも感情値の出し方にもよるが、大方の予想通り、極端にポジティブ値に偏るということはないものの、各章に感情値の波が見えた。そして、クライマックスにかけてネガティブ値が小さくなり、ポジティブ値に転換していくようである。
-
以上から、太宰の男性観・女性観を、感情分析という手法を用いて垣間見ることができた部分があったといえる。
-
しかし、検証方法によって結果に疑義が生じる部分があったことから、1.に記載した通り、既存の感情辞書で各作品の感情値を正確に把握することは難しく、精度の高い感情分析を行うためには、分析の対象となる作品の内容に合う感情辞書を作成する必要があると思われる。
データ
青空文庫から作品を取得します。 今回は、太宰の以下の作品をチョイスしました。各作品のあらすじと感情推移の予想
各作品の章ごとのあらすじに沿って、感情推移の結果の予想をしました。 この結果予想と、感情分析後の結果を比較し、感情辞書の汎用性を検証していきます。〜男性一人称〜
『人間失格』
主人公:葉蔵
(太宰そのものといわれている)
検証結果の予想
主人公:葉蔵が、その生き様をつ浮いて、人間失格と堕ちていく様を描いた作品ですね
物語を通して見るに ・・・まさに、救いのない作品といえるでしょう。
章ごとの感情値の推移としては、『葉蔵』(主人公)が語り手となる第一の手記・第二の手記・第三の手記に主眼を置きます。
・第一の手記
幼いころから「人間の生活というものが、見当つかない」と語る葉蔵は、自分は異質だと思って生きてきた。
他者とつながるために 「道化」として生きることを覚え、 女中や下男に「哀しい事を教えられ」ても誰にも言い出せず、ただ笑って過ごすことしかできまなかった。
・第二の手記
「道化」を演じる幼少期の葉蔵だったが、同級生の竹一にそれを見破られる。
竹一の存在に希望を抱いた葉蔵だったが、美術学校に行くと父親に言い出せず、東京の高等学校へ。そこで堀木と出会い、飲み歩くようになる。
そこでツネ子と出会い、初めて僅かな恋心を抱く。ツネ子と入水自殺を図るが、葉蔵だけが生き残る。
・第三の手記
死にきれなかった葉蔵は高等学校を追放される。
純粋なヨシ子を内縁の妻とし平和な日々を手に入れたかに見えたが、ヨシ子は出入りの商人に関係を強要されてしまう。そして、それを知った葉蔵は精神を病み、睡眠薬で自殺を図る。
一命をとりとめた葉蔵だったが、地獄のような日々は続き、父親に脳病院に連れ込まれ、ついに「人間失格」と悟る。
・・・これだけをみても、第一の手記から第三の手記にかけて、ネガティブ値が右肩上がりの展開です。
各章を通じて、ポジティブに振れることは想定できず、徐々にネガティブに下がり切っていく結果が予想されます。
むしろそれ以外の展開が考えられない。
一方、第三者語りの はしがき 、あとがき は、主人公が語り手となる本編と比してネガティブ値が低くなるとなる予想されます。内容が内容だけにネガポジ値がフラットになるはいえませんが、本編と比べてネガティブ値が落ち着くことでしょう。
グラフの推移(形)としてはこんな感じでしょうか。
〜女性一人称〜
『ヴィヨンの妻』
〜甲斐性なし夫と、それを支える妻〜
さっちゃんは、夫のどうしようもなさや、現実(人は罪を犯さずには生きていけないこと)を目の当たりにしながらも、小さな幸せを見つけ、現実を受け入れていきます。
一では、家族を顧みない夫(大谷)が盗みを働いていたことが発覚。
夫の愚行に「わけのわからぬ可笑しさがこみ上げて来まして、私は声を挙げて笑ってしま」うさっちゃん。そんなネガティブな事態から物語は始まります。
二で、さっちゃんは、あてのない返済の猶予を得るため、苦肉の策として、椿屋で働き始めます。さっちゃんの存在によって活気付くクリスマス前夜の椿屋。不幸中の幸い(奇蹟)とはこのことかと、さっちゃんは不思議な感覚に陥ります。
三、仕事の帰りに椿屋に客としてきた大谷と一緒に帰ることもあり、とても幸せなさっちゃん。
もっとも、椿屋に訪れた客に犯され、さっちゃんは、人は罪を犯さずには生きていけないと悟ります。
人非人と揶揄されて嘆く大谷に対し、「人非人でもいいじゃないの。私たちは、生きていさえすればいいのよ」とさっちゃんは言う・・・
以上を見るに、1章が最もネガティブ値が大きく、転じて、2章では「椿屋のさっちゃん」の誕生というポジティブな展開となり、第3章では、「生きてさえいればいい」という幸・不幸ではない悟りに似た境地に至る・・・
これをグラフにすると、こんな感じでしょうか。
波がありながらも、最後はネガティブに陥る印象ではないですね。
『斜陽』
〜華族の没落を描いた作品〜
第1章〜4章は大きな動きや偏りはなく、第5章の母の死、そして第7章の直治の遺書で大きくマイナスに揺れると予想。
クライマックスの第8章では、母や弟を失い、上原に捨てられたと自覚するも、かず子なりの悟りと宿った命と太陽のように生きるという決意をするという描写から、一転ポジティブに振れると思われました。
予想推移は以下の通り。
こちらも波があるものの、クライマックスに向けて、ポジティブな強さが垣間見えると考えます。
男性一人称と女性一人称作品にどのような違いがあるか 〜予想〜
ヴィヨンの妻に、太宰の男性観・女性観を表していると思われる下記のような会話があります。
女「なぜ、はじめからこうしなかったのでしょうね。とっても私は幸福よ」
男「女には、幸福も不幸も無いものです」
女「そうなの? そう言われると、そんな気もして来るけど、それじゃ、男の人は、どうなの?」
男「男には、不幸だけがあるんです。いつも恐怖と、戦ってばかりいるのです」
女「わからないわ、私には。でも、いつまでも私、こんな生活をつづけて行きとうございますわ。椿屋のおじさんも、おばさんも、とてもいいお方ですもの」
確かに、女性一人称の2作品のあらすじを通してみるに、主人公(語り手)の苦難に負けない気丈さ・強かさを感じます。
結末にかけて、現実は容赦なく主人公を打ちのめしますが、そんな中でも自分なりの希望を見出し、生きていこうとする姿勢に、幸せや不幸とは違う次元のポジティブさがあるように思います。
おそらく、女性一人称作品の感情値の推移も、現実の波に揺られながら、クライマックスにかけてネガティブ値が小さくなっていくのではないでしょうか。
他方で、男性一人称「人間失格」では、「不幸だけがある」男がただ堕ちていく様を断続的なネガティブ値として垣間見れるのでは・・・と考えます。
コーパス作成
さあ、検証していきます。
自然言語処理の検証には、コーパス(まとまった量のテキスト)が必要になります。
そのため、『青空文庫』から作品を取得し、コーパス用に加工していきます。
ファイルを取得して本文のみ抽出していきます
まずは男性一人称の人間失格から行っていきましょう。
# 各種モジュールのインポート
import re
import zipfile
import urllib.request
import os.path
import glob
# ファイルパスの取得
URL1 = 'https://www.aozora.gr.jp/cards/000035/files/301_ruby_5915.zip'
# zipファイルを取得・解凍する
def download(URL):
zip_file = re.split(r'/', URL)[-1]
urllib.request.urlretrieve(URL, zip_file)
dir = os.path.splitext(zip_file)[0]
with zipfile.ZipFile(zip_file) as zip_object:
zip_object.extractall(dir)
os.remove(zip_file)
path = os.path.join(dir,'*.txt')
list = glob.glob(path)
return list[0]
ファイルを読み込み、ノイズを削除し、本文を抽出していきます。
# ファイル読み込み・本文を抽出する
def convert(download_text):
data = open(download_text, 'rb').read()
text = data.decode('shift_jis')
# 本文抽出
text = re.split(r'\-{5,}', text)[2]
text = re.split(r'底本:', text)[0]
text = re.split(r'[#改ページ]', text)[0]
# ノイズ削除
text = re.sub(r'《.+?》', '', text)
text = re.sub(r'[#.+?]', '', text)
text = re.sub(r'|', '', text)
text = re.sub(r'\r\n', '', text)
text = re.sub(r'\u3000', '', text) #
return text
ファイルを取得して、本文抽出の実行をします
download_file = download(URL1)
text1 = convert(download_file)
print(text1)
テキストとして抽出ができました。
今回は章ごとに感情分析を行なっていくので、抽出したテキストを章ごとに分けて作成し、読み込んでいきます。
# 〜テキストの読み込み〜
# はしがきの読み込み
textfile1_1 = open('/content/drive/MyDrive/KADAI/data/ningenshikkaku/hashigaki.txt', encoding="UTF-8")
hashigaki = textfile1_1.read()
# 第一の手記
textfile1_2 = open('/content/drive/MyDrive/KADAI/data/ningenshikkaku/dai_1.txt', encoding="UTF-8")
dai_1 = textfile1_2.read()
# 第二の手記
textfile1_3 = open('/content/drive/MyDrive/KADAI/data/ningenshikkaku/dai_2.txt', encoding="UTF-8")
dai_2 = textfile1_3.read()
# 第三の手記
textfile1_4 = open('/content/drive/MyDrive/KADAI/data/ningenshikkaku/dai_3.txt', encoding="UTF-8")
dai_3 = textfile1_4.read()
# あとがき
textfile1_5 = open('/content/drive/MyDrive/KADAI/data/ningenshikkaku/atogaki.txt', encoding="UTF-8")
atogaki = textfile1_5.read()
感情分析(ネガポジ分析)
感情分析の準備をしていきます。
今回は、東北大の乾・岡崎研究室が公開されている「日本語評価極性辞書」 を使用することにします。
# 極性辞書の読み込み
polarity_dict = pd.read_csv('/content/drive/MyDrive/KADAI/siryou/pn_ja.dic.txt', sep=':', header=None, names=['Word', 'Pos', 'Score'], encoding='shift_jis')
# 極性辞書を辞書型に変換
polarity_dict = dict(zip(polarity_dict['Word'], polarity_dict['Score']))
形態素解析とネガポジ判定
読み込んだ章ごとのテキストについて、形態素解析を行います。今回は、「品詞」の中から、テキストの内容を端的に表していると考えられる
# 形態素解析を行い、基本形の単語を抽出する関数
def tokenize(text, mecab):
node = mecab.parseToNode(text)
words = []
while node:
if node.feature.split(",")[0] in ["名詞", "形容詞", "動詞", "副詞"]:
words.append(node.feature.split(",")[6]) # 基本形を抽出
node = node.next
return words
上記で抽出したテキストの単語ごとに感情分析を行うための関数を作成します。
・感情値が0より大きい場合は、「positive_score」
・感情値が0より小さい場合は、「negative_score」
として結果(数値)を返すようにします。
def analyze_sentiment(text, mecab, polarity_dict):
words = tokenize(text, mecab)
positive_score = 0
negative_score = 0
for word in words:
score = polarity_dict.get(word, 0)
if score > 0:
positive_score += score
elif score < 0:
negative_score += score
return positive_score, negative_score
感情値の推移を可視化してみる
それでは、章ごとに感情値を分析して、その推移を見ていきましょう。
まずは、章ごとに感情分析を行い、ポジティブとネガティブに分けて章ごとにリストに格納していきます。
# 章ごとに感情分析を行い、ポジティブとネガティブに分けて章ごとにリストに格納
# はしがき〜感情分析
positive_scores1_1 = []
negative_scores1_1 = []
positive_score, negative_score = analyze_sentiment(hashigaki, mecab, polarity_dict)
positive_scores1_1.append(positive_score)
negative_scores1_1.append(negative_score)
# 第一の手記〜感情分析
positive_scores1_2 = []
negative_scores1_2 = []
positive_score, negative_score = analyze_sentiment(dai_1, mecab, polarity_dict)
positive_scores1_2.append(positive_score)
negative_scores1_2.append(negative_score)
# 第二の手記〜感情分析
positive_scores1_3 = []
negative_scores1_3 = []
positive_score, negative_score = analyze_sentiment(dai_2, mecab, polarity_dict)
positive_scores1_3.append(positive_score)
negative_scores1_3.append(negative_score)
# 第三の手記〜感情分析
positive_scores1_4 = []
negative_scores1_4 = []
positive_score, negative_score = analyze_sentiment(dai_3, mecab, polarity_dict)
positive_scores1_4.append(positive_score)
negative_scores1_4.append(negative_score)
# あとがき〜感情分析
positive_scores1_5 = []
negative_scores1_5 = []
positive_score, negative_score = analyze_sentiment(atogaki, mecab, polarity_dict)
positive_scores1_5.append(positive_score)
negative_scores1_5.append(negative_score)
# 章ごとの感情値をポシティブとネガティブに分けて一つのリストに格納
positive_scores_list = [positive_scores1_1, positive_scores1_2, positive_scores1_3, positive_scores1_4, positive_scores1_5]
negative_scores_list = [negative_scores1_1, negative_scores1_2, negative_scores1_3, negative_scores1_4, negative_scores1_5]
pn_score = 0
# 章ごとの各感情値をリストに格納する
chapter_pn_score_list = []
for i in range(len(positive_scores_list)):
pn_list = positive_scores_list[i] + negative_scores_list[i]
chapter_pn_score_list.append(pn_list)
もっとも、章ごとに各感情値の出現単語数は異なるため、単純に単語数が多いことで数値が大きくなってしまいます。
このことから、各章の感情値の合計を出現単語数で割って平均値を出す必要がありそうです。
そのため、各章の出現単語数をカウントしていきます。
まずは合計の平均値から算出していきましょう。
各章の形態素解析した各章のテキストを「chapter_text」リストに格納し、カウントした単語数を「chapter_words」リストに格納します。
chapter_text = [hashigaki, dai_1, dai_2, dai_3, atogaki]
chapter_count_words =[]
for i in range(len(chapter_text)):
count_words = len(tokenize(chapter_text[i], mecab))
chapter_count_words.append(count_words)
# 各章の単語数
[503, 2414, 7307, 8788, 537]
次に、各章の感情値の合計を、各章の単語数で割って、その平均値を「chapter_average_score」に格納します。
# 章ごとの感情値の合計を算出し、リストに格納する。
chapter_sum_score = []
for i in range(len(chapter_pn_score_list)):
pn_score = sum(chapter_pn_score_list[i])
chapter_sum_score.append(pn_score)
# 各章の単語数で割って平均値を算出
chapter_average_score = []
average_pn_score = 0
for i in range(len(chapter_sum_score)):
average_pn_score = chapter_sum_score[i] / chapter_count_words[i] chapter_average_score.append(average_pn_score)
さあ、結果をグラフにしてみましょう!
折れ線グラフで可視化していきます。
# 章ごとの感情値の合計の平均値をグラフで可視化
chapter = ["hashigaki", "dai_1", "dai_2", "dai_3", "atogaki"]
plt.plot(chapter, chapter_average_score)
plt.xlabel('Chapter')
plt.ylabel('Scores')
plt.title('Sentiment Analysis per Chapter Average')
plt.grid(True)
plt.show()
[-0.3494668260039762, -0.28399461136702564, -0.2820026769522386, -0.27348849287209925, -0.2537366085661079]
おっと・・・感情値としては物語を通してずっとマイナス値を指しているものの、葉蔵視点の第一の手記〜第三の手記にかけて、わずかにマイナス値が軽減していますね・・・
かつ、全体に右肩上がりでネガティブ値が軽減している・・・(予想外)
ですが、これにはポジティブ値の値の推移も関係しているかもしれないので、次は、ポジティブ値とネガティブ値に分けてグラフ化してみます。
まず、各章の単語を各感情値で分けて、「positive_word_list」と「negative_word_list」に格納します。
# 単語を感情値で分けるための関数を定義
def analyze_sentimental_words(text, mecab, polarity_dict):
positive_word_list = []
negative_word_list = []
words = tokenize(text, mecab)
for word in words:
score = polarity_dict.get(word, 0)
if score > 0:
positive_word_list.append(word)
elif score < 0:
negative_word_list.append(word)
return positive_word_list, negative_word_list
# 各章のポジティブ値の単語・ネガティブ値の単語をそれぞれリストに格納する
# はしがき
positive_word_list, negative_word_list = analyze_sentimental_words(hashigaki, mecab, polarity_dict)
hashigaki_positive_list = positive_word_list
hashigaki_negative_list = negative_word_list
# 第一の手記
positive_word_list, negative_word_list = analyze_sentimental_words(dai_1, mecab, polarity_dict)
dai_1_positive_list = positive_word_list
dai_1_negative_list = negative_word_list
# 第二の手記
positive_word_list, negative_word_list = analyze_sentimental_words(dai_2, mecab, polarity_dict)
dai_2_positive_list = positive_word_list
dai_2_negative_list = negative_word_list
# 第三の手記
positive_word_list, negative_word_list = analyze_sentimental_words(dai_3, mecab, polarity_dict)
dai_3_positive_list = positive_word_list
dai_3_negative_list = negative_word_list
# あとがき
positive_word_list, negative_word_list = analyze_sentimental_words(atogaki, mecab, polarity_dict)
atogaki_positive_list = positive_word_list
atogaki_negative_list = negative_word_list
次に、章ごとのポジティブ値の単語、ネガティブ値の単語を、それぞれ「chapter_count_positive_words」「chapter_count_negative_words」リストに格納していきます。
chapter_count_positive_words =[]
chapter_count_negative_words =[]
for i in range(len(positive_word_lists)):
count_words = len(positive_word_lists[i])
chapter_count_positive_words.append(count_words)
print(chapter_count_positive_words)
for i in range(len(negative_word_lists)):
count_words = len(negative_word_lists[i])
chapter_count_negative_words.append(count_words)
各章のポジティブ値・ネガティブ値の合計を、各章のポジティブ値の単語・ネガティブ値の単語の数で割って平均値を出していきます。
chapter_positive_average_score = []
chapter_negative_average_score = []
average_pn_score = 0
for i in range(len(chapter_count_positive_words)):
average_pn_score = positive_scores_list[i] / chapter_count_positive_words[i]
chapter_positive_average_score.append(average_pn_score)
print(chapter_positive_average_score)
for i in range(len(chapter_count_negative_words)):
average_pn_score = negative_scores_list[i] / chapter_count_negative_words[i]
chapter_negative_average_score.append(average_pn_score)
print(chapter_negative_average_score)
さあ、グラフにしてみます。
# ポジティブ値
[0.5225885008695653, 0.580082611, 0.6559165994238685, 0.7282812854948801, 0.6146204875]
# ネガティブ値
[-0.7238495738775511, -0.6936582430903787, -0.6864433409506964, -0.7074330962006893, -0.6376947509090902]
各章を通して、わずかにネガティブ値の値が大きいものの、ポジ・ネガ値の絶対値にあまり差異はないのようです。
ネガティブ値だけを見ると、予想通り、第三の手記が最もネガティブ値が大きくなっていますが、ポジティブ値最も大きくなっています。
各感情値を合計すると、
[-0.2012610730079858, -0.11357563209037869, -0.030526741526827883, 0.020848189294190855, -0.023074263409090245]
なんと、第一の手記から第三の手記まで右肩上がりでネガティブ値が小さくなり、さらには、主人公が人間失格と自覚する第三の手記が唯一ポジティブ値を示しています。。
あらすじからも、この作品の一般的な印象からも、この結果は納得がいかないものではないでしょうか。。
もっとも、一点気になることが。
# ポジティブ値の単語数
[26, 110, 264, 306, 18]
# ネガティブ値の単語数
[267, 1102, 3299, 3781, 236]
どの章も、それぞれの各感情値の単語数に約10倍の差があることが判明。
各感情値の出現数が全く異なる → 出現単語数が多い感情値の印象が強くなる のではないか?
例:
「死にたい。だけど、明日は良い事があると信じたい。希望はある。」 ⇨ポジティブな印象。
「死にたい。明日は良い事があると信じていた。でも、絶望に負けてしまうそうだ。」⇨ネガティブな印象。
と思われるため、各感情値の合計を出現単語数で割って平均値を出すだけでは、各章の感情値を検証し切れないのではないか?と考えました。
そのため、各章の出現単語数の合計と、各感情値の出現単語数の割合を考慮して感情値を算出して、各章の大きな印象をデータとして可視化してみます。
各感情値の平均値 × 各感情値の出現単語数/出現単語の合計
# 章ごとに、各感情値にかかる単語の出現回数の割合を考慮し、各感情値を算出する
chapter_positive_average_score_new = []
chapter_negative_average_score_new = []
average_pn_score_new = 0
for i in range(len(chapter_count_positive_words)):
average_pn_score_new = (positive_scores_list[i] / chapter_count_positive_words[i]) * (chapter_count_positive_words[i] / (chapter_count_positive_words[i] + chapter_count_negative_words[i]))
chapter_positive_average_score_new.append(average_pn_score_new)
for i in range(len(chapter_count_negative_words)):
average_pn_score_new = (negative_scores_list[i] / chapter_count_negative_words[i]) * (chapter_count_negative_words[i] / (chapter_count_positive_words[i] + chapter_count_positive_words[i]))
chapter_negative_average_score_new.append(average_pn_score_new)
#ポジティブ値
[0.04743357378839592, 0.052473937871287124, 0.047572243693516696, 0.053948434120381666, 0.04546934173228346]
#ネガティブ値
[-3.6476894346153856, -3.405279111545454, -4.22366186509471, -4.287425041846419, -4.105715877777776]
ポジティブ値が0の真上でほぼ直線に・・・!
(先日の通り、ネガティブ値の単語と比べてポジティブ値の単語の出現数が少なすぎるため、このような結果になりました。)
他方、期待のネガティブ値は、第二の手記から第三の手記にかけてもっとも大きく、かつ常にネガティブ値に留まっているという予想に近い数値となりました。
(第一の手記が最もネガティブ値が低いのは少し予想外といえますが・・・)
もしかしたら、このやり方によって、作品の各章全体のポジネガの印象を数値として可視化できるのではないかと考えました。
検証に用いる感情値
上記で検証した結果、
この2つの数値が最も信頼できると考えられたので、この数値を用いて検証を続けていきます。
女性一人称作品の感情値
女性の一人称作品でも、感情値の推移(①と②)を見ていきます。
ヴィヨンの妻
①-1 各感情値の合計を各感情値の出現単語数で割って平均値を算出したもの
# ポジティブ値
[0.6350399652631578, 0.7209727727272728, 0.7187392112500002]
# ネガティブ値
[-0.6793343601931974, -0.6797035983783788, -0.7060510761194027]
[-0.044294394930039616, 0.04126917434889399, 0.012688135130597522]
第1章が最もネガティブ値が大きく、第2章でポジティブに転じ、第3章ではほぼ0に近づく・・・という予想に近いグラフとなりました。
②各章の出現単語数の合計と、各感情値の出現単語数の割合を考慮して感情値を算出したもの
# ポジティブ値
[0.04343325896328293, 0.027489429809358753, 0.049912445225694456]
# ネガティブ値
[-4.626624537315776, -8.573534025000004, -4.730542209999998]
# ポジティブの値の単語数
[95, 22, 40]
# ネガティブの値の単語数
[1294, 555, 536]
ですが、こちらではポジティブ値の単語数の圧倒的な少なさから、ポジティブ値は終始0に近い数値となり、かつ、私の予想や①の結果に反して2章が最もネガティブ値が低いという結果になりました。
斜陽
①-1 各感情値の合計を各感情値の出現単語数で割って平均値を算出したもの
# ポジティブ値
[0.6341329728260874, 0.6610461950537635, 0.6429143561481477, 0.744052286330275, 0.6992816445185183, 0.7493105600000003, 0.7249150485840709, 0.8225168965517243]
# ネガティブ値
[-0.7001698017363344, -0.692066942160203, -0.6898394136393443, -0.6948190037037023, -0.7099689494239637, -0.6814962270943382, -0.6520365025510192, -0.6756075917721515]
[-0.06603682891024698, -0.03102074710643954, -0.046925057491196576, 0.04923328262657267, -0.01068730490544545, 0.06781433290566208, 0.07287854603305166, 0.14690930477957287]
単純な平均値では、全体的にポジティブな値を示しており、クライマックスにかけて最もポジティブ値が大きくなっています。
序盤が最もポジティブ値が低いのは予想外でしたが、4章以降は、予想のグラフと似通っている部分が多いですね。
②各章の出現単語数の合計と、各感情値の出現単語数の割合を考慮して感情値を算出したもの
# ポジティブ値
[0.03542212112932607, 0.036901138139255704, 0.05228520366265057, 0.06385960567716534, 0.050455917696419, 0.05743844013937284, 0.0749454716285453, 0.12755609625668454]
# ネガティブ値
[-5.917195878804347, -5.852802688268814, -3.896315206666667, -3.700389281192653, -4.564837393333337, -4.1044659131818095, -2.8274149225663665, -1.840448267241378]
# ポジティブの値の単語数
[92, 93, 135, 109, 135, 110, 113, 29]
# ネガティブの値の単語数
[1555, 1573, 1525, 1161, 1736, 1325, 980, 158]
こちらも、ポジティブ値の単語の出現数が少なく、ボジティブ値がほとんど0に近い数字となっているものの、クライマックスにかけて僅かですがポジティブ値が大きくなっていますね。
また、ネガティブ値のグラフの推移も、クライマックスにかけてネガティブ値が小さくなっています。大まかではありますが、あらすじの印象と一致している部分が多いように思いました。
疑い
上記の検証から、太宰作品に限らず、小説自体にポジティブ値を示す単語が使われること自体が少ないのではないか?という疑問が湧きました・・・そのため、前向きな印象の強い作品
「銀河鉄道の夜」 (全9章) の感情値を見てみようと思います。
①-1 各感情値の合計を出現単語数で割って平均値を算出したもの
# ポジティブ値
[0.8181559, 0.5522425, 0.6434683000000001, 0.6215364545454546, 0.975939, 0.8315443124999999, 0.8126652666666667, 0.7288009375, 0.6489979731200001]
# ネガティブ値
[-0.6986432752475242, -0.6866568861788617, -0.6695590825812501, -0.7525334469381443, -0.7434202378151257, -0.7219414822134391, -0.707749087560975, -0.735301106544502, -0.7257137425723118]
[0.11951262475247582, -0.1344143861788617, -0.02609078258124997, -0.1309969923926897, 0.23251876218487433, 0.10960283028656082, 0.10491617910569173, -0.006500169044502013, -0.07671576945231173]
ポジティブ値の揺れ幅があり、最も値が大きいep5では「0.975939」という1に近い数字を出していますね。
銀河鉄道の夜のイメージに近い数値となったように思いました。
しかし・・・
②各章の出現単語数の合計と、各感情値の出現単語数の割合を考慮して感情値を算出したもの
# ポジティブ値
[0.047714551282051286, 0.03070228787878788, 0.035355401098901104, 0.027150594594594592, 0.010280415384615386, 0.04801115533980582, 0.03927416367521368, 0.030043126361655775, 0.04426156735034803]
# ネガティブ値
[-5.352348414285712, -7.089995533333334, -5.66131086065, -8.354861594964285, -22.990624949999997, -5.067349602500005, -6.4164209770833285, -7.931592392499993, -4.79043544655742]
# ポジティブの値の単語数
[14, 6, 10, 14, 2, 20, 24, 20, 148]
# ネガティブの値の単語数
[220, 126, 172, 319, 128, 289, 444, 439, 2007]
やはり、各感情値の単語数を見ると、ポジティブ値を示す単語が圧倒的に少ないことから、こちらでは太宰作品と同じように0に近い位置で一直線上になってしまうという結果に・・・
平均値では最もポジティブ値が大きかったep5については、ポジティブ値の単語が2つしかなく、かつネガティブ値の単語が128であることから、極端にマイナス値に傾いています。
以上から、やはり、小説にポジティブ値に該当する単語が使われること自体が少ないように思えました。
4. 結論
以上で検証した結果をまとめると・・・
5. 感想
今回、仕事が急に忙しくなったり、体調不良で寝込んでしまったりと、思わぬハプニングがありましたが、どうにか一度完成することができました。 ただ、感情分析のみの検証でなかなかの長編となってしまい、他の検証ができなかったことが悔やまれます・・・。ですが、日本文学という身近なテキストを用いた検証だったことから、数学に疎い私でも比較的楽しく課題に取り組むことが出来ました。
サポートしてくださった皆様に感謝します。
受講期間の残り2ヶ月弱、この課題ではタッチできなかった教師あり学習や教師なし学習、TF-IDFなどを用いて新たなテーマで検証を行なっていこうと思います。
引き続き、私なりに学習を進めていき、自然言語処理という技術を身近に感じられるようにしていきたいと心から思いました。
改めて、ここまで(無駄に長い文章を)お読みいただきありがとうございました。