Pythonで自然言語の行ごとの分析をしてみる

以下のあたりの続きで、行単位でデータを見てみます。

esu-ko.hatenablog.com

esu-ko.hatenablog.com

データの作成1

行単位のデータをつくります。nltk.sent_tokenizeで日本語対応(改行や。での改行化)ができるか調べられなかったので、自前で改行ごとにループを回します。

#janomeでのトークナイズは前回までを確認
#j_tokensがトークンオブジェクト

tmp = []
for i, row in enumerate( " ".join([token.base_form for token in j_tokens]).splitlines()):
  tmp.append(pd.DataFrame(
      {
          "line":i,
          "word":row.split(" ")
      }
    )
  )

sentence = pd.concat(tmp)

データをつくる2

感情辞書をつくります。 今回は短い分なので、こちらも自前で作ります。 まずは出てくる単語のdistinctのリストをつくります。

set([token.base_form for token in j_tokens if token.part_of_speech.split(',')[0] in ['名詞','動詞','形容詞','形容動詞']])

そのあとエクセルとエディタでちまちま辞書をつくり、読み込みます。

sent_row = """word    score
一番    1
余裕    1
好き    1
忘れる -1
感謝    1
憧れる 1
有り難い  1
楽しい 1
死ぬ    -1
満たす 1
煩悩    -1
申し訳 -1
良い    1
騙す    -1
"""
senti = pd.DataFrame([row.split("\t") for row in sent_row.splitlines()][1:],columns = ['word','score'])

集計してみてみる

各データを結合し、行ごとに語彙数と感情を集計してみます。

df = sentence.merge(senti,how='left').fillna("0")

df.assign(
    num=1,
    score = df.score.apply(int)
).groupby('line')['num','score'].sum().plot()

f:id:esu-ko:20200812223117p:plain

なんとなくマイナスには周期性があるような気がします。
またプラス直後にマイナスがくるところが二箇所ほどあるのが、ボケとツッコミのやりとりかもしれません。

語彙数がみにくいので移動平均をとってみます。
7程度の山になるので、比較的長台詞になるのは10弱程で、ここが喋りの見せ場なのかもしれません。前半から中盤の山が高いので状況説明などがこの辺で行っているのかもですね。 f:id:esu-ko:20200812223455p:plain