ミスチルで一番ポジティブな曲とネガティブな曲は?【日本語評価極性辞書でネガポジ分析】

私はミスチルが20年前から好きで、ミスチルの歌詞で一番ポジティブな曲とネガティブな曲をPythonを使用して分析してみることにしました。

分析には、「形態素分析」と「日本語評価極性辞典」を使用します。

形態素解析とは、文章を意味のある最小の単語に分割することができる技術です。

形態素解析については、下記の記事で詳しく書いていますので参考にしてください。

ミスチルの歌詞をJanomeで解析してWordCloudで可視化してみた

極性辞書は、単語を「ポジティブ」「ネガティブ」などに分類して収録しています。

日本語の極性辞書で有名なのは「日本語評価極性辞書」です。

日本語評価極性辞書は、東北大学 乾・岡崎研究室のホームページで公開されており、クレジットを明記すれば商用利用も可能なので、今回はこちらを利用させていただきます。

極性辞書については、下記の記事で詳しく書いていますので参考にしてください。

ミスチルの歌詞全てを対象に、最も使われているポジティブな単語や、もっとも使われているネガティブな単語を集計してみました。

ミスチルの歌詞をネガポジ分析してみた【日本語評価極性辞書】

今回は、ミスチルの曲ごとにネガポジ分析を行い、歌詞目線で一番ポジティブな曲とネガティブな曲が何かを分析してみました。

ポジティブな曲ランキング

早速結果ですが、以下がポジティブな曲であると分析した上位10曲です。

順位曲名スコア
1位思春期の夏 ~君との恋が今も牧場に~0.213
2位Drawing0.190
3位ありふれた Love Story ~男女問題はいつも面倒だ~0.183
4位 himawari0.164
5位 放たれる0.161
6位 Documentary film0.158
6位 HERO0.158
8位 彩り0.153
9位 【es】~Theme of es~0.143
10位 PADDLE0.141

ポジティブ!と思っていた曲(個人的にはPADDLE)も入っていますが、ん?と思う曲(Drawing)なども入っています。

スコアの算出方法については、後で説明します。とりあえず上位3曲について詳しく歌詞を見てみます。

1位: 思春期の夏 ~君との恋が今も牧場に~

まさかの曲が1位でした!

この曲はドラムの鈴木英哉(JEN)がボーカルの数少ない曲です(もう1曲は逃亡者)。

作詞は桜井和寿・小林武史、作曲は鈴木英哉・ 小林武史 です。

曲調はポップで、ライブで一度だけ聞いたことがあって(Thanksgiving 25の時)、盛り上がっていたのを覚えています。

歌詞のざっくりした内容は(個人の解釈)、昔の片思い(場所は牧場)を回想しているという内容です。

曲調はポップですが、歌詞はそこまでポジティブというわけではないと思います。

なぜ1位になっているかは後で確認します。

2位: Drawing

こちらは全くポジティブな印象はありません。

私が初めて買ったオリジナルアルバム「IT’S A WONDERFUL WORLD」に収録されている曲で、何回も聞いた曲ですが、曲調は暗めです。

個人的な解釈としては、いつも「君」のことを考えていて永遠に一緒にいたいけど、永遠は無くいつかは終わる、というような儚い歌詞だと思います。

ポジティブではないと思うので、分析ミスと感じます。

3位:ありふれた Love Story ~男女問題はいつも面倒だ~

この曲は曲調が好きで、昔よく聞きました。

ポップな曲です。

歌詞は、都会のビジネスマンと田舎から都会に出たきたばかりの女性が付き合い始めて、一緒に住み始めて、そのうちうまくいかなくなって、別れたという曲です。

最終的に「男女問題っていつも面倒だな」という結論で終わります。ポジティブではないですね。。。


「PADDLE」や「HERO」、「彩り」などかなりポジティブだなと思う曲も入っていますが、ポジティブとはいいがたい曲もいくつか入っています。

分析内容については、後で詳細を説明します。

ネガティブな曲ランキング

続いて、ネガティブな曲であると分析した上位10曲です。

順位曲名スコア
1位タダダキアッテ-0.138
2位Simple-0.130
3位FIGHT CLUB-0.127
4位 It’s a wonderful world-0.125
4位 Surrender-0.125
6位 -0.121
7位 シーソーゲーム ~勇敢な恋の歌~-0.107
8位 So Let’s Get Truth-0.104
9位 タガタメ-0.100
10位 マーマレード・キッス-0.095

こちらも上位3曲について詳しく歌詞を見てみます。

1位: タダダキアッテ

タガタメの原曲です。

子供に関する事件に関して、書かれていると思います。

曲調は暗めで、メッセージ性が強い曲なのでネガティブな単語が多く含まれていると思います。

ちなみにタガタメと歌詞は同じです(歌詞の順序は違う所がありますが)。

しかしタガタメは9位です。後で詳細を確認します。

2位: Simple

結婚式で使えるのではと思うくらいの曲です。

曲調は穏やかですが、サビの歌詞はプロポーズのような内容です。

しかし、歌い出しが「マイナス思考」で始まるように、主人公の思考がネガティブに感じる点も多くあります。

3位: FIGHT CLUB

ブラッド・ピットが主人公の映画「ファイトクラブ」に憧れていた過去を回想する歌詞。

ネガティブな単語は多く出てくるかもしれないですが、ネガティブな曲というわけではないと思います。

分析手順

上記の分析結果を出した手順について説明します。

  1. ミスチルの全歌詞を収集(2021年9月時点)
  2. 全歌詞を形態素解析で単語に分割
  3. 分割した単語が極性辞書にあるかを確認。ポジティブ・ネガティブを振り分ける
  4. 曲ごとにポジティブ・ネガティブの単語の割合を算出しスコア化

①については、スクレイピングで収集しました。

詳細については以下の記事に詳しく書いています。

ミスチルの歌詞をスクレイピングで取得してみた【Beautiful Soup】

②については、以下の記事で詳しく書いています。

形態素解析で単語を分割した後、WordCloudで頻出単語を画像で表示しています。

下記のような画像です。

ミスチルの歌詞をJanomeで解析してWordCloudで可視化してみた

③の極性辞書の詳細な内容やいろいろな使い方は下記の記事で詳しく書いています。

ミスチルの歌詞をネガポジ分析してみた【日本語評価極性辞書】

今回は、④について詳しく書いていきます。

ただし、①~③についても簡単に説明していきます。

HANABIのネガポジ分析を行ってみる

例として、HANABIのネガポジ分析の流れを説明します。

HANABIを選んだ理由は、「有名」であることと、「説明がしやすそうな分析結果だったから」です。

形態素解析で単語を分割する

まずは、形態素解析で歌詞を単語に分割します。

形態素解析には、Pythonのライブラリ「Janome」を使用しました。

今回は名詞のみを抽出しました。

名詞のみを抽出した理由は、

  • 日本語評価極性辞書が「名詞編」と「用言編」に分かれており、「名詞編」の方が単語の収録数が多い。
  • 両方の極性辞書を使うのが面倒であった。
  • 動詞のみ、形容詞のみでも同じ分析を行ってみたが、形態素解析で分類した単語数が少なく、分析結果がいまいちであった。

ということです。

HANABIを形態素解析し、分類した名詞を抽出すると全部で「89」となりました。

HANABIの形態素解析結果

‘どれ’, ‘値打ち’, ‘僕’, ‘今’, ‘世界’, ‘すべて’, ‘無意味’, ‘手’, ‘もの’, ‘引き換え’, ‘いくつ’, ‘輝き’, ‘平和’, ‘世の中’, ‘理想’, ‘希望’, ‘答えよう’, ‘日常’, ‘君’, ‘柔らか’, ‘笑顔’, ‘僕’, ‘憂鬱’, ‘花火’, ‘光’, ‘一回’, ‘一回’, ‘一回’, ‘一回僕’, ‘手’, ‘誰’, ‘皆’, ‘悲しみ’, ‘素敵’, ‘明日’, ‘臆病風’, ‘波風’, ‘世界’, ‘どれ’, ‘すぎ’, ‘言葉’, ‘自分’, ‘不器用さ’, ‘嫌い’, ‘妙’, ‘器用’, ‘自分’, ‘それ以上’, ‘平等’, ‘時’, ‘未来’, ‘僕ら’, ‘声’, ‘今’, ‘君’, ‘さよなら’, ‘最初’, ‘一回’, ‘一回’, ‘一回’, ‘一回何度’, ‘君’, ‘世界’, ‘想像’, ‘単純’, ‘君’, ‘水’, ‘心’, ‘とき’, ‘分’, ‘とき’, ‘分’, ‘一回’, ‘一回’, ‘一回’, ‘一回君’, ‘誰’, ‘皆’, ‘問題’, ‘素敵’, ‘明日’, ‘臆病風’, ‘波風’, ‘世界’, ‘どれ’, ‘一回’, ‘一回’, ‘一回’, ‘一回’

極性辞書で単語をポジティブ、ネガティブに分類する

上記で抽出した単語が「日本語評価極性辞書(名詞編)」に収録されているか確認します。

日本語評価極性辞書(名詞編)は単語を「p(ポジティブ)」、「n(ネガティブ)」、「e(ニュートラル:どちらとも言い難い)」で分類しています。

もし、単語が収録されていない場合は「None(未収録)」として記録しておきます。

上記で分類した名詞の中で、ポジティブに分類されたのは下記の「14語」です。

ポジティブに分類された単語

‘値打ち’, ‘輝き’, ‘平和’, ‘理想’, ‘希望’, ‘笑顔’, ‘光’, ‘素敵’, ‘明日’, ‘器用’, ‘平等’, ‘未来’, ‘素敵’, ‘明日’

ネガティブに分類されたのは下記の「7語」です。

ネガティブに分類された単語

‘無意味’, ‘憂鬱’, ‘悲しみ’, ‘波風’, ‘嫌い’, ‘問題’, ‘波風’

ニュートラルに分類されたのは下記の「14語」です。

ニュートラルに分類された単語

‘今’, ‘世界’, ‘手’, ‘手’, ‘皆’, ‘世界’, ‘自分’, ‘妙’, ‘自分’, ‘今’, ‘世界’, ‘単純’, ‘皆’, ‘世界’

辞書に未収録で分類できなかったのは、残りの「54語となりました。

ポジティブ度、ネガティブ度をスコア化する

上記で分類した単語数からスコアを算出します。

スコアは2種類算出します。

  • 未分類の単語を含まないスコア1
  • 未分類の単語を含むスコア2

未分類の単語を含んで計算する場合と含まずに計算する場合の違いを確認します。

未分類の単語を含まないスコア

未分類の単語を含まないスコアは下記のように計算しました。

未分類の単語を含まないスコア1

$$score1 \ = \ pの割合 \ – \ nの割合$$

$$pの割合 \ = \ \frac{pの単語数}{ (pの単語数 \ + \ nの単語数 \ + \ eの単語数)}$$

$$nの割合 \ = \frac{ nの単語数 }{ (pの単語数 \ + \ nの単語数 \ + \ eの単語数) } $$

$$p:ポジティブに分類された単語$$

$$n:ネガティブに分類された単語$$

$$e:ニュートラルに分類された単語$$

$$score1: -1 \leq score1 \leq1$$

$$pの割合:0 \leq p \leq1$$

$$nの割合:0 \leq n \leq1$$

スコア1は 1 に近いほどポジティブ、-1 に近いほどネガティブです。

HANABIのスコア1は下記のようになります。

若干ポジティブよりではありますが、ほぼニュートラルです。

HANABIのスコア1

\begin{align} score1 &= \frac{14}{14 \ + \ 7 \ + \ 14} \ – \frac{7}{14 \ + \ 7 \ + \ 14} \\[10px] &= 0.200 \end{align}

未分類の単語を含むスコア

未分類の単語を含むスコアは下記のように計算しました。

未分類の単語を含むスコア2

$$score2 \ = \ pの割合 \ – \ nの割合$$

$$pの割合 \ = \frac{pの単語数}{ (pの単語数 \ + \ nの単語数 \ + \ eの単語数 + \ 未分類の単語数)}$$

$$= \ \frac{pの単語数}{全単語数} $$

$$nの割合 \ = \frac{nの単語数}{ (pの単語数 \ + \ nの単語数 \ + \ eの単語数 + \ 未分類の単語数)}$$

$$= \ \frac{nの単語数}{全単語数} $$

$$p:ポジティブに分類された単語$$

$$n:ネガティブに分類された単語$$

$$e:ニュートラルに分類された単語$$

$$score2: -1 \leq score1 \leq1$$

$$pの割合:0 \leq p \leq1$$

$$nの割合:0 \leq n \leq1$$

スコア2もスコア1同様、 1 に近いほどポジティブ、-1 に近いほどネガティブです。

HANABIのスコア2は下記のようになります。

先ほどよりもスコアが0に近づきました。

未分類が多いほど、スコアが0に近づいてしまいます

HANABIのスコア2

\begin{align} score2 &= \frac{14}{89} \ – \frac{7}{89} \\[10px] &= 0.079 \end{align}

ちなみに上記のランキングは、スコア2を使っています。理由は後で説明します。

全曲のネガポジ度を確認する

各曲に含まれている「ポジティブ」、「ネガティブ」、「ニュートラル」、「未分類」の個数と、上記の方法で2つのスコアを算出した結果を表したのが以下のグラフです。

上記では見にくいので、各項目を見ていきます。

上記のグラフはこちらで詳しく見ることができます。

項目を一つずつ確認したり、表示範囲を変更したりできます。

スマホの場合は横画面の方が見やすいです。

ポジティブな単語数

ポジティブな単語数を多い順に並べたグラフです。

上位10曲は以下です。

順位曲名ポジティブ
単語数
ネガティブ
単語数
スコア2スコア2での順位
(ポジティブ順)
1位ありふれた Love Story ~男女問題はいつも面倒だ~1630.1833位
2位PIANO MAN1540.10326位
3位HANABI1470.07953位
4位 彩り1300.1538位
4位 くるみ1360.10129位
4位 くるみ -for the Film- 幸福な食卓1360.10129位
4位 ニシエヒガシエ1380.08542位
8位 I’LL BE12100.018144位
8位 Drawing1210.1902位
8位 放たれる1220.1615位
20位思春期の夏 ~君との恋が今も牧場に~1000.2131位

ポジティブな単語数が多かったとしても、ネガティブな単語数が多いとスコアは下がります。

また、単純に歌詞の中に単語数が多い方がポジティブな単語数で比べると上位になります。

ポジティブなスコアで1位の「 思春期の夏 ~君との恋が今も牧場に~」は、ポジティブな単語数は比較的多くないですが、ネガティブな単語が含まれていないためスコアで1位になっています。

ネガティブな単語数

ネガティブな単語数を多い順に並べたグラフです。

上位10曲は以下です。

順位曲名ネガティブ
単語数
ポジティブ
単語数
スコア2スコア2での順位
(ネガティブ順)
1位マシンガンをぶっ放せ148-0.06916位
2位シーソーゲーム ~勇敢な恋の歌~134-0.1077位
3位終わりなき旅127-0.06318位
4位 雨のち晴れ114-0.07712位
5位 I’LL BE10120.01898位
5位 Any105-0.07613位
5位 Everything (It’s you)105-0.07613位
5位 FIGHT CLUB102-0.1233位
5位 タガタメ101-0.1009位
5位 タダダキアッテ101-0.1381位
11位Simple92-0.1302位

「タガタメ」と「タダダキアッテ」は「ネガティブ」と「ポジティブ」の単語数が同じなのでスコア2が違うのは、「未分類の単語数」が「タガタメ」の方が多いからです。

「タガタメ」の形態素解析結果

‘どれ’, ‘値打ち’, ‘僕’, ‘今’, ‘世界’, ‘すべて’, ‘無意味’, ‘手’, ‘もの’, ‘引き換え’, ‘いくつ’, ‘輝き’, ‘平和’, ‘世の中’, ‘理想’, ‘希望’, ‘[‘ディカプリオ’, ‘出世作’, ‘さっき僕’, ‘録画’, ‘話’, ‘星’, ‘君’, ‘僕’, ‘あと何人’, ‘人’, ‘人’, ‘キス’, ‘子供ら’, ‘被害者’, ‘加害者’, ‘街’, ‘何’, ‘?’, ‘被害者’, ‘加害者’, ‘とき’, ‘涙’, ‘瞼’, ‘ほか’, ‘?タダタダダキアッテ\u3000(‘, ‘)カタタタキダキアッテ\u3000(肩叩き’, ‘)テヲトッテダキアッテ\u3000(手’, ‘)左’, ‘人’, ‘右’, ‘人’, ‘場所’, ‘片一方’, ‘僕ら’, ‘連鎖’, ‘生き物’, ‘世界’, ‘怒り’, ‘悲しみ’, ‘あと何度’, ‘それ’, ‘?明日’, ‘公園’, ‘手’, ‘犬’, ‘何’, ‘タタカッテ’, ‘タタカッテ\u3000(‘, ‘)タガタメ’, ‘タタカッテ\u3000(誰’, ‘)タタカッテ’, ‘ダレ’, ‘カッタ\u3000(‘, ‘誰’, ‘?)タガタメダ’, ‘タガタメダ\u3000(誰’, ‘?\u3000誰’, ‘?)タガタメ’, ‘タタカッタ\u3000(誰’, ‘?)子供ら’, ‘被害者’, ‘加害者’, ‘街’, ‘何’, ‘?’, ‘被害者’, ‘加害者’, ‘とき’, ‘性懲り’, ‘こと以外’, ‘タダタダダキアッテ\u3000(‘, ‘)カタタタキダキアッテ\u3000(肩叩き’, ‘)テヲトッテダキアッテ\u3000(手’, ‘)タダタダタダ\u3000(‘, ‘)タダタダタダ\u3000(‘, ‘)タダタダキアッテイコウ\u3000(ただ’, ‘)タタカッテ’, ‘タタカッテ\u3000(‘, ‘)タガタメ’, ‘タタカッテ\u3000(誰’, ‘)タタカッテ’, ‘ダレ’, ‘カッタ\u3000(‘, ‘誰’, ‘?)タガタメダ’, ‘タガタメダ\u3000(誰’, ‘?\u3000誰’, ‘?)タガタメ’, ‘タタカッタ\u3000(誰’, ‘?)’

「 タダダキアッテ 」の形態素解析結果

‘ディカプリオ’, ‘出世作’, ‘さっき僕’, ‘録画’, ‘話’, ‘星’, ‘君’, ‘僕’, ‘あと何人’, ‘人’, ‘人’, ‘キス’, ‘世界’, ‘怒り’, ‘悲しみ’, ‘あと何度’, ‘それ’, ‘?明日’, ‘公園’, ‘手’, ‘犬’, ‘何’, ‘左’, ‘人’, ‘右’, ‘人’, ‘場所’, ‘片一方’, ‘僕ら’, ‘連鎖’, ‘生き物’, ‘子供ら’, ‘被害者’, ‘加害者’, ‘街’, ‘何’, ‘?’, ‘被害者’, ‘加害者’, ‘とき’, ‘涙’, ‘瞼’, ‘ほか’, ‘?’, ‘肩叩き’, ‘手’, ‘子供ら’, ‘被害者’, ‘加害者’, ‘街’, ‘何’, ‘?’, ‘被害者’, ‘加害者’, ‘とき’, ‘性懲り’, ‘こと以外’, ‘肩叩き’, ‘手’, ‘誰’, ‘誰’, ‘?誰’, ‘?\u3000誰’, ‘?誰’, ‘?’

「タガタメ」の方が「タタカッテ」などのカタカナが多く入っています。

辞書にこれらのカタカナは入っていないので、Noneの分類結果が多くなっています。

「タダダキアッテ」の方は、上記のカタカナ部分はひらがなで歌詞に記載されています。

ひらがなの「ただ」は、分析に含まないように前処理していたので、このような差が出ています。

また、「\u3000」(全角スペース)が多く含まれているせいで分析が上手くいっていない部分もあると思います。

前処理で消しておかないといけませんでした。

スコア1( 未分類の単語を含まない )

スコア1( 未分類の単語を含まない )をスコアが高い順に並べたグラフです。

スコアは第2軸(右側)です。

ポジティブな上位10曲

ポジティブな上位10曲を確認します。

曲名 スコア1 スコア1順位
(ポジティブ順)
スコア2スコア2順位
(ポジティブ 順)
未分類単語数未分類単語割合
思春期の夏 ~君との恋が今も牧場に~0.6671位0.2131位3268.1%
Drawing0.6112位0.1902位4069.0%
口がすべって0.6003位0.12513位3879.2%
風と星とメビウスの輪0.6003位0.11518位2180.8%
Documentary film0.5635位0.1586位4171.2%
himawari0.5635位0.1634位3970.9%
君が好き0.5387位0.11717位4778.3%
I’m sorry0.5008位0.10425位3879.2%
忙しい僕ら0.5008位0.09538位1781.0%
風と星とメビウスの輪(Single Version)0.5008位0.08344位2083.3%

風と星とメビウスの輪(Single Version)」を確認してみると、スコア1が8位に対して、スコア2が44位になっています。

未分類の単語の割合を見てみると83.3%もあります。

逆に考えると、分類には16.7%しか使えていないということです。

「 風と星とメビウスの輪(Single Version) 」の未分類単語

”君’, ‘僕’, ‘メビウス’, ‘輪’, ‘上’, ‘時流(とき)’, ‘一歩’, ‘心’, ‘風’, ‘唄’, ‘心’, ‘一歩’, ‘心’, ‘星’, ‘頼り’, ‘君’, ‘僕’, ‘メビウス’, ‘輪’, ‘上’

今回の分類全体で、未分類の単語の割合は73.0%です。

つまり、全体の27.0%しか分類に使えていないということになります。

分類精度を上げるには、辞書を更新して未分類の単語を減らさないといけません。

ネガティブな上位10曲

ネガティブな上位10曲を確認します。

曲名 スコア1 スコア1順位
(ネガティブ順)
スコア2スコア2順位
( ネガティブ 順)
未分類単語数未分類単語割合
かぞえうた-1.0001位-0.03337位2996.7%
-0.6672位-0.1216位2781.8%
マーマレード・キッス-0.5713位-0.09510位3583.3%
君の事以外は何も考えられない-0.5004位-0.02345位4295.4%
タガタメ-0.4745位-0.1009位7178.9%
深海-0.4296位-0.08611位2880.0%
タダダキアッテ-0.4296位-0.1381位4467.7%
Simple-0.4128位-0.1302位3768.5%
FIGHT CLUB-0.3819位-0.1273位4266.7%
It’s a wonderful world-0.37510位-0.1254位1666.7%

「かぞえうた」を見てみると、スコア1が-1.000になっています。

つまり、分類済みの全単語がネガティブな単語という分析結果です。

ただし、未分類の単語の割合は96.7%になっており、ほとんど分類できていません。

「 かぞえうた 」の形態素解析結果

‘うた’, ‘なに’, ‘なに’, ‘やみ’, ‘ひとつふたつ’, ‘ひとつ’, ‘こころ’, ‘あなた’, ‘なん’, ‘かなしみ’, ‘ひとつふたつ’, ‘ひとつ’, ‘ぼう’, ‘うた’, ‘むりなんかしなくてもひとりふたりもうひとりと’, ‘いつか’, ‘ょにうたいたいなえがおのうた僕ら’, ‘以上’, ‘風’, ‘稲穂’, ‘なに’, ‘ひとつふたつ’, ‘ひとつ’, ‘あなた’, ‘ぼう’, ‘うたひとつふたつ’, ‘ひとつ’, ‘びににたきえない’, ‘ぼう’, ‘うた’

このうち、分類できたのは「かなしみ」のみで、ネガティブに分類されています。

このように、歌詞がほとんど平仮名では正常に分析できていないので、辞書にフリガナを追加するなどの対処が必要かもしれません。

スコア2( 未分類の単語を含む)

上記ような問題があるため、今回はスコア2を最終的な分析結果としました。

上位10件については、記事冒頭に示しています。

以下が、スコア1とスコア2を比較したグラフです。

未分類が多いので、スコア2は全体的に0に近づいています。

分析の課題

今回分析を行って、歌詞のネガポジ度を数値化することで曲の特徴をいつもとは違った視点でわかりやすく示すことができたと思います。

曲調でポジティブな印象を持っていても、歌詞を見てみると案外ネガティブな内容だったということもありました。

しかし、分類精度が低いので精度を上げるためには以下のような対応が必要であると考えます。

  • 形態素解析の精度を上げる
  • 極性辞書を分析対象に合わせて自作・更新する(ネガポジの精度向上・未分類率の低下)

上記のような課題があると思いますが、日本語は本当に複雑で、同じような言葉が少し変わるだけで全く違う意味になったり、同じ意味でもいくつもの形があったりと、大変分析が難しいです。

極性辞書を使用する他の方法で、Googleの「Natural Cloud Language API」を使用する方法があります。

こちらはとても簡単にネガポジ分析ができるので、お手軽でおすすめです。

ミスチルの「終わりなき旅」を 「Natural Cloud Language API」 で分析してみた結果を以下の記事に書いているので、気になる方は見てください。

ミスチルの終わりなき旅をCloud Natural Language APIで感情分析してみた

コード

最後に、今回作成したコードを載せておきます。

使用しているライブラリの説明や、歌詞データの内容については冒頭に載せた関連記事に記載している内容と同じです。

import pandas as pd
import collections
from janome.analyzer import Analyzer
from janome.charfilter import *
from janome.tokenfilter import *
import plotly.graph_objects as go

# カラム名と値の位置ずれを制御
pd.set_option('display.unicode.east_asian_width', True)

# csvファイルを読み込み
df_dic = pd.read_csv('pn.csv.m3.120408.trim', sep='\t', names=("名詞", "判定", "詳細"), encoding='utf-8')

# p,n,eの判定値の項目のみ取り出し
df_dic = df_dic[(df_dic["判定"] == 'p') | (df_dic["判定"] == 'e') | (df_dic["判定"] == 'n')]

# 名詞と判定値のみ取り出し
df_dic = df_dic.iloc[:,0:2]

keys = df_dic["名詞"].tolist()
values = df_dic["判定"].tolist()
dic = dict(zip(keys, values))

# 歌詞の名詞を読み込む
# csvファイルを読み込み
df_file = pd.read_csv('mrchildren-lyrics.csv', encoding='utf-8')

# 歌詞をデータフレームからリストに変換
song_info = df_file[["曲名", "歌詞"]]

song_list = []
for song_name, song_lyrics in zip(song_info['曲名'], song_info['歌詞']):

    # 複合名詞化
    a = Analyzer(token_filters=[CompoundNounFilter()])
    result = [token.base_form for token in a.analyze(song_lyrics) if token.part_of_speech.split(',')[0] in ['名詞']]
    result_list = [song_name, result]
    song_list.append(result_list)


# 削除するワードをリスト化
stopwords = ['ん', 'よう', 'の', 'こと', 'さ', 'そう', 'まま', 'はず', 'ため']
for song in song_list:
    for stopword in stopwords:
        song[1] = [i for i in song[1] if i != stopword]
    song_word_num = len(song[1])
    song.append(song_word_num)

    # 辞書で判定
    results = []
    for sentence in song[1]:
        word_score = []
        score = dic.get(sentence)
        word_score = (sentence, score)
        results.append(word_score)

    # 判定を曲情報に追加
    song.append(results)

    # それぞれの曲の単語をp,n,e,Noneに分けてリストに格納
    p_lists = []
    n_lists = []
    e_lists = []
    None_lists = []
    for result in results:
        if result[1] == 'p':
            p_lists.append(result[0])
        elif result[1] == 'n':
            n_lists.append(result[0])
        elif result[1] == 'e':
            e_lists.append(result[0])
        else:
            None_lists.append(result[0])

    # それぞれのリストを曲情報に追加
    song.append(p_lists)
    song.append(len(p_lists))
    song.append(n_lists)
    song.append(len(n_lists))
    song.append(e_lists)
    song.append(len(e_lists))
    song.append(None_lists)
    song.append(len(None_lists))

    # p/(p+n+e) の割合を計算
    try:
        p_ratio1 = len(p_lists) / (len(p_lists) + len(n_lists) + len(e_lists))
    except ZeroDivisionError:
        p_ratio1 = 0
    song.append(p_ratio1)

    # p/全単語数 の割合を計算
    try:
        p_ratio2 = len(p_lists) / (song_word_num)
    except ZeroDivisionError:
        p_ratio2 = 0
    song.append(p_ratio2)

    # n/(p+n+e) の割合を計算
    try:
        n_ratio1 = len(n_lists) / (len(p_lists) + len(n_lists) + len(e_lists))
    except ZeroDivisionError:
        n_ratio1 = 0
    song.append(n_ratio1)

    # n/全単語数 の割合を計算
    try:
        n_ratio2 = len(n_lists) / (song_word_num)
    except ZeroDivisionError:
        n_ratio2 = 0
    song.append(n_ratio2)

    # ポジティブ - ネガティブのスコア1を算出
    score1 = p_ratio1 - n_ratio1
    song.append(score1)
    # ポジティブ - ネガティブのスコア2を算出
    score2 = p_ratio2 - n_ratio2
    song.append(score2)

# グラフ作成
graph_data_list1 = []
graph_data_list2 = []
graph_data_list3 = []
graph_data_list4 = []
graph_data_list5 = []
graph_data_list6 = []
for song in song_list:
    # ポジティブの単語数
    graph_data1 = [song[0], song[5]]
    graph_data_list1.append(graph_data1)
    # ネガティブの単語数
    graph_data2 = [song[0], song[7]]
    graph_data_list2.append(graph_data2)
    # ニュートラルの単語数
    graph_data3 = [song[0], song[9]]
    graph_data_list3.append(graph_data3)
    # 未分類の単語数
    graph_data4 = [song[0], song[11]]
    graph_data_list4.append(graph_data4)
    # スコア1
    graph_data5 = [song[0], song[16]]
    graph_data_list5.append(graph_data5)
    # スコア2
    graph_data6 = [song[0], song[17]]
    graph_data_list6.append(graph_data6)

graph_list1 = dict(graph_data_list1)
graph_list2 = dict(graph_data_list2)
graph_list3 = dict(graph_data_list3)
graph_list4 = dict(graph_data_list4)
graph_list5 = dict(graph_data_list5)
graph_list6 = dict(graph_data_list6)

# plotlyでグラフ化
graphtitle = "ミスチル ネガポジ分析"
fig = go.Figure()
fig.add_trace(go.Bar(x=list(graph_list1.keys()), y=list(graph_list1.values()), name = 'ポジティブ単語数',  yaxis='y1'))
fig.add_trace(go.Bar(x=list(graph_list2.keys()), y=list(graph_list2.values()), name = 'ネガティブ単語数',  yaxis='y1'))
fig.add_trace(go.Bar(x=list(graph_list3.keys()), y=list(graph_list3.values()), name = 'ニュートラル単語数',  yaxis='y1'))
fig.add_trace(go.Bar(x=list(graph_list4.keys()), y=list(graph_list4.values()), name = '未分類の単語数',  yaxis='y1'))
fig.add_trace(go.Scatter(x=list(graph_list5.keys()), y=list(graph_list5.values()), name = 'スコア1',  yaxis='y2', mode='markers'))
fig.add_trace(go.Scatter(x=list(graph_list6.keys()), y=list(graph_list6.values()), name = 'スコア2',  yaxis='y2', mode='markers'))
fig.update_layout(title={'text': graphtitle})
fig.update_layout(xaxis={'categoryorder':'total descending'})
fig.update_layout(yaxis1=dict(side='left'),
                  yaxis2=dict(side='right',
                              showgrid=False,                              
                              overlaying='y'))
fig.show()
# グラフをhtml形式で保存。
filename = "mrchildren-negaposi"
with open(filename + '.html', 'w') as f:
    f.write(fig.to_html(include_plotlyjs='cdn'))

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

CAPTCHA


検索

アーカイブ

プロフィール

プロフィール背景画像
プロフィール画像

チャベス

機械機器メーカーで研究開発をしている機械系エンジニアです。 Notion、SANGO(WordPress)、Pythonが好きです。 詳細プロフィールはこちらnoteにNotionの記事も書いています。 Notion公式資格のNotion Essentials Badge取得。

WP-Searchにサイト事例として掲載されています。