Connected to Python 3.13.7

In [ ]:
import pandas as pd
import re
from pathlib import Path
from fugashi import Tagger # type: ignore
import unicodedata
from sudachipy import Dictionary, SplitMode

tokenizer = Dictionary().create()
tagger = Tagger('-Owakati')


def cleanse_text_all(text: str) -> str:
    """root_to_text()した後のテキストを正規化する。
    1.nfkc
    2.記号の一部を大文字に揃える
    3.~~数字を0にする~~
    4.連続する空白を削除する (改行は残す、空白を完全に削除しないほうがよさげ)
    """
    def cleanse_normalise(text: str) -> str:
        """文字列の正規化
        まず、記号とかをすべて半角にした後、それっぽいものは全角にする。
        (全角にする意味ある? 全角のやつがnfkc適用されずに残っているときある。)
        ただし、数字と空白以外"""
        text = unicodedata.normalize("NFKC", text)
        # いくつかの文字を全角にする。nfkcしているから半角への変換はいらんと思う。
        tostr = "!”#$%’()*+,-./:=?@[¥]^_`{|};〜。、・「」"
        fromstr = "!\"#$%\'()*+,-./:=?@[¥]^_`{|};~。、・「」"
        pt = re.compile('([{}]+)'.format(fromstr))
        text = text.translate(text.maketrans(fromstr, tostr)) if pt.search(text) else text
        return text

    def cleanse_number(text: str, zero_all=False) -> str:
        """text (string) の前処理
        zero_all: true: 数字をすべて0にする、連続する0を一つの0にする
        covid-19とかiso14000とかも巻き込まれる。0に置換しない方が形態素解析がうまくいくかも
        単位区切りの,.は削除してもいい。sudachipyなら問題ないが、fugashiなら区切られてしまう。
        """
        if zero_all:
            # 連続数字を0に
            text = re.sub(r"\d+", "0", text)
            # 桁区切り、小数点のある数字を0に
            text = re.sub(r"0[,.]0", "0", text)
        else:
            # 桁区切り、小数点を削除
            text = re.sub(r"(\d)[,.](\d)", r"\1\2", text)
        return text

    def cleanse_space(text: str) -> str:
        """textの前処理
        連続する空白を削除する。
        """
        text = text.replace(" ", " ")
        # # [^\S\n]は改行以外の空白
        text = re.sub(r"[^\S\n]+", " ", text)
        return text

    text = cleanse_normalise(text)
    text = cleanse_number(text)
    text = cleanse_space(text)

    return text
In [ ]:
data_dir = Path("../_data")
vtt_files = sorted(data_dir.glob("*.vtt"))

rows = []
for vtt_file in vtt_files:
    text = vtt_file.read_text(encoding="utf-8")
    # VTTブロックを正規表現でパース
    pattern = re.compile(
        r"(\d{2}:\d{2}:\d{2}\.\d{3})\s*-->\s*(\d{2}:\d{2}:\d{2}\.\d{3})\n(.+)"
    )
    for m in pattern.finditer(text):
        start, end, content = m.group(1), m.group(2), m.group(3).strip()
        # 「発話者: 発言内容」の形式を分離
        if ": " in content:
            speaker, utterance = content.split(": ", 1)
        else:
            speaker, utterance = "", content
        rows.append({
            "file_name": vtt_file.name,
            "start_time": start,
            "end_time": end,
            "speaker": speaker,
            "text": utterance,
        })

df = pd.DataFrame(rows)
print(f"全{len(df)}行, ファイル数: {df['file_name'].nunique()}")
df.head(2)
全1911行, ファイル数: 2
Out[ ]:
file_name start_time end_time speaker text
0 GMT20260217-234927_v2.vtt 00:06:20.650 00:06:21.809 カワイ 戻るんですか?
1 GMT20260217-234927_v2.vtt 00:10:10.460 00:10:14.739 天王寺 おはようございます。今秋田さん入られます。お待ちください。
In [ ]:
df.value_counts("speaker")
Out[ ]:
speaker
砂糖     368
橋本     277
スズキ    175
平山     126
山下     124
下川     107
カワイ     99
井上      95
上西      92
西野      78
野村      53
村田      50
淀屋橋     45
所沢      43
沢井      43
本町      40
なんば     28
日本橋     28
天王寺     19
夕日      16
昭和       5
Name: count, dtype: int64
In [ ]:
def wakati(text, pos_filter=None):
    """
    textを分かち書きする
    pos_filter: 文字列 ("名詞") なら単一品詞、リスト (["名詞", "助詞"]) なら複数品詞を残す。Noneなら全て残す。
    """
    # # fugashi
    # return [word for word in tagger(text)]
    # # sudachi
    # morphemes = tokenizer.tokenize(text, SplitMode.C)
    if pos_filter is None:
        return [m.dictionary_form() for m in tokenizer.tokenize(text, SplitMode.C)]
    if isinstance(pos_filter, str):
        pos_filter = [pos_filter]
    return [m.dictionary_form() for m in tokenizer.tokenize(text, SplitMode.C) if m.part_of_speech()[0] in pos_filter]
In [ ]:
# ! text列を分かち書きする
df["wakati"] = df["text"].apply(wakati)
# df["wakati"] = df["text"].apply(lambda x: wakati(x, "名詞"))
In [ ]:
# ! とりあえず一人だけ取り出して
tmp = df.loc[df["speaker"] == "砂糖"]
In [ ]:
word_counts = tmp["wakati"].explode().value_counts()
word_counts.head(20)
Out[ ]:
wakati
、     369
。     329
と     221
の     193
か     191
だ     180
ます    157
て     140
で     127
です    126
って    106
は     106
する    105
た     100
も      99
に      94
が      93
いう     92
?      82
てる     73
Name: count, dtype: int64
In [ ]:
# ! text列をtokenizeしてpart_of_speech()の6要素を列に展開する
def tokenize_pos(text):
    morphemes = tokenizer.tokenize(text, SplitMode.C)
    return [(m.dictionary_form(), *m.part_of_speech()) for m in morphemes]


POS_COLUMNS = ["品詞", "品詞細分類1", "品詞細分類2", "品詞細分類3", "活用型", "活用形"]
df["pos_list"] = df["text"].apply(tokenize_pos)

# 全話者版 (補助記号のみ除外、長さ制限なし): 助詞・感動詞の分析に使う
df_all = df.explode("pos_list").reset_index(drop=True)
df_all[["dic_form"] + POS_COLUMNS] = pd.DataFrame(
    df_all["pos_list"].tolist(), index=df_all.index
)
df_all = df_all.drop(columns=["pos_list", "wakati", "text"])
df_all["len"] = df_all["dic_form"].str.len()
df_all = df_all.loc[df_all["品詞"] != "補助記号"]

# 砂糖さん単独版 (既存フィルタそのまま)
df_morphemes = df.loc[df["speaker"] == "砂糖"]
df_morphemes = df_morphemes.explode("pos_list").reset_index(drop=True)
df_morphemes[["dic_form"] + POS_COLUMNS] = pd.DataFrame(
    df_morphemes["pos_list"].tolist(), index=df_morphemes.index
)
df_morphemes = df_morphemes.drop(columns=["pos_list", "wakati", "text"])
df_morphemes["len"] = df_morphemes["dic_form"].str.len()

# ? filter
# # 補助記号 (。)、接頭辞 (3つくらいしかない)、一文字、です、ます、する
df_morphemes = df_morphemes.loc[-df_morphemes["品詞"].str.contains("補助記号|接頭")]
df_morphemes = df_morphemes.loc[df_morphemes["len"] >= 2]
df_morphemes.head()
Out[ ]:
file_name start_time end_time speaker dic_form 品詞 品詞細分類1 品詞細分類2 品詞細分類3 活用型 活用形 len
0 GMT20260218-044829_v2.vtt 00:11:58.950 00:12:00.310 砂糖 お疲れ様 名詞 普通名詞 形状詞可能 * * * 4
1 GMT20260218-044829_v2.vtt 00:11:58.950 00:12:00.310 砂糖 です 助動詞 * * * 助動詞-デス 終止形-一般 2
3 GMT20260218-044829_v2.vtt 00:12:00.580 00:12:02.569 砂糖 あれ 代名詞 * * * * * 2
4 GMT20260218-044829_v2.vtt 00:12:00.580 00:12:02.569 砂糖 聞こえる 動詞 一般 * * 下一段-ア行 連用形-一般 4
5 GMT20260218-044829_v2.vtt 00:12:00.580 00:12:02.569 砂糖 てる 助動詞 * * * 下一段-タ行 連用形-一般 2
In [ ]:
df_morphemes["品詞"].value_counts()
# 前処理前
# 助詞      12718
# 名詞       8530
# 動詞       5724
# 補助記号     5558
# 助動詞      5192
# 副詞       2291
# 感動詞      2039
# 連体詞       856
# 代名詞       741
# 形容詞       702
# 接尾辞       626
# 接頭辞       318
# 形状詞       315
# 接続詞       293
# 記号          2
Out[ ]:
品詞
名詞     853
動詞     788
助動詞    435
副詞     277
助詞     275
感動詞    218
代名詞    113
形容詞    105
連体詞    104
接尾辞     63
形状詞     46
接続詞     30
Name: count, dtype: int64
In [ ]:
# ! 頻出単語
min_df = 0.001
max_df = 0.20
df_docs = pd.DataFrame(df_morphemes.value_counts("dic_form")).reset_index()
df_docs["proportion"] = df_docs["count"] / df_docs.shape[0]
df_docs.loc[
    (df_docs["proportion"] >= min_df) &
    (df_docs["proportion"] <= max_df)
]
Out[ ]:
dic_form count proportion
1 です 126 0.175732
2 って 106 0.147838
3 する 105 0.146444
4 いう 92 0.128312
5 てる 73 0.101813
... ... ... ...
712 木札 1 0.001395
713 そろそろ 1 0.001395
714 ばええ 1 0.001395
715 内容 1 0.001395
716 しか 1 0.001395

716 rows × 3 columns

In [ ]:
# ============================================================
# ! 話者ごとの言葉遣いの違いを3側面で見る
#   (A) 話題の違い: 内容語 Top-N
#   (B) 文体の違い: 助詞・助動詞の使用率
#   (C) フィラー/相槌: 感動詞
# ============================================================

# 主要話者 (形態素数 上位) を抽出
top_speakers = (
    df_all.groupby("speaker").size()
    .sort_values(ascending=False).head(6).index.tolist()
)
print(top_speakers)
['橋本', '砂糖', 'カワイ', '下川', '平山', 'スズキ']
In [ ]:
def _hms_to_sec(t):
    h, m, s = t.split(":")
    return int(h) * 3600 + int(m) * 60 + float(s)

df["duration_sec"] = df["end_time"].map(_hms_to_sec) - df["start_time"].map(_hms_to_sec)
speaker_summary = pd.DataFrame({
    "発話回数": df.groupby("speaker").size(),
    "発話時間_秒": df.groupby("speaker")["duration_sec"].sum().round(1),
    "形態素数": df_all.groupby("speaker").size(),
})
speaker_summary["形態素/分"] = (
    speaker_summary["形態素数"] / speaker_summary["発話時間_秒"] * 60
).round(1)
speaker_summary["形態素/回"] = (
    speaker_summary["形態素数"] / speaker_summary["発話回数"]
).round(1)
speaker_summary = speaker_summary.sort_values("形態素数", ascending=False)
# 正規化の分母 (話者の総形態素数)
speaker_totals = df_all.groupby("speaker").size()
speaker_summary.reset_index()
Out[ ]:
speaker 発話回数 発話時間_秒 形態素数 形態素/分 形態素/回
0 橋本 277 2185.9 7168 196.8 25.9
1 砂糖 368 1638.7 5558 203.5 15.1
2 カワイ 99 994.5 3539 213.5 35.7
3 下川 107 1008.3 3452 205.4 32.3
4 平山 126 767.8 2611 204.0 20.7
5 スズキ 175 781.1 2528 194.2 14.4
6 山下 124 764.8 2460 193.0 19.8
7 西野 78 611.5 2098 205.9 26.9
8 上西 92 457.5 1607 210.8 17.5
9 井上 95 389.9 1332 205.0 14.0
10 所沢 43 347.1 1232 213.0 28.7
11 村田 50 394.4 1080 164.3 21.6
12 本町 40 209.0 957 274.7 23.9
13 野村 53 336.3 951 169.7 17.9
14 日本橋 28 275.2 865 188.6 30.9
15 淀屋橋 45 219.3 755 206.6 16.8
16 沢井 43 215.5 641 178.5 14.9
17 夕日 16 164.0 577 211.1 36.1
18 なんば 28 177.8 540 182.2 19.3
19 天王寺 19 100.4 311 185.9 16.4
20 昭和 5 35.8 85 142.5 17.0
In [ ]:
def top_words_by_speaker(df, speakers, pos=None, n=15, min_len=2, stopwords=None):
    """話者 × 頻出語 Top-N の横並び表。
    pos=None で絞らず、pos='名詞' 等で品詞1種に絞る。
    stopwords: 除外する dic_form の集合。None なら除外しない。
    """
    d = df[df["speaker"].isin(speakers)]
    if pos is not None:
        d = d[d["品詞"] == pos]
    if min_len:
        d = d[d["dic_form"].str.len() >= min_len]
    if stopwords:
        d = d[~d["dic_form"].isin(stopwords)]
    out = {}
    for sp in speakers:
        vc = d.loc[d["speaker"] == sp, "dic_form"].value_counts().head(n)
        out[sp] = vc.reset_index().apply(
            lambda r: f"{r['dic_form']} ({r['count']})", axis=1
        )
    return pd.concat(out, axis=1)


def top_words_rate_by_speaker(df, speakers, totals, pos=None, n=15, min_len=2, stopwords=None):
    """Top-N を "word (X.XX‰)" で表示。
    ‰ = 話者の総形態素数 (totals[speaker]) に対する千分率 = 発話量コントロール後の出現率。
    件数ランクと同じ順位 (話者内で単調変換) だが、値が比率なので話者間で直接比較できる。
    stopwords: 除外する dic_form の集合。None なら除外しない。
    """
    d = df[df["speaker"].isin(speakers)]
    if pos is not None:
        d = d[d["品詞"] == pos]
    if min_len:
        d = d[d["dic_form"].str.len() >= min_len]
    if stopwords:
        d = d[~d["dic_form"].isin(stopwords)]
    out = {}
    for sp in speakers:
        vc = d.loc[d["speaker"] == sp, "dic_form"].value_counts().head(n)
        rate = vc / totals[sp] * 1000
        out[sp] = pd.Series(
            [f"{w} ({r:.2f}‰)" for w, r in zip(vc.index, rate.values)],
            name=sp,
        )
    return pd.concat(out, axis=1)


def usage_rate_by_speaker(df, speakers, pos, top_k=20, stopwords=None):
    """話者 × dic_form の使用率 (%) 表。
    その話者の pos 総数に対する割合として正規化。
    stopwords: 除外する dic_form の集合。None なら除外しない。
    """
    d = df[(df["speaker"].isin(speakers)) & (df["品詞"] == pos)]
    if stopwords:
        d = d[~d["dic_form"].isin(stopwords)]
    tab = (
        d.groupby(["speaker", "dic_form"]).size()
        .groupby(level=0).apply(lambda s: s / s.sum() * 100)
        .droplevel(0)
        .unstack("speaker", fill_value=0)
    )
    tab = tab.loc[tab.sum(axis=1).sort_values(ascending=False).head(top_k).index]
    return tab.round(2)
In [ ]:
stopwords = {
    "する", "ます", "です"
}

# 以下、各Top-Nは 件数版と‰版の2種類を出す
#     件数版: たくさん話す情報を残す。
#     ‰版: 話者の総形態素数で割って、発話量コントロール後の比較。
In [ ]:
top_words_by_speaker(df_all, top_speakers, pos=None, n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 ええ (249) って (106) えー (131) えー (129) ええ (54) いう (53)
1 あの (123) いう (92) いう (79) いう (68) てる (46) ない (52)
2 いう (108) てる (73) あの (48) って (47) まあ (44) って (42)
3 ない (106) さん (57) ええ (46) ない (46) いう (40) てる (33)
4 って (98) はい (54) ない (39) ところ (40) ある (31) こと (23)
5 てる (92) ない (54) って (39) ある (36) あの (29) ちょっと (21)
6 まあ (91) あの (50) ところ (33) こと (31) ない (27) もう (20)
7 ある (69) えっと (46) ちょっと (32) てる (29) ちょっと (26) やる (18)
8 こう (65) けど (42) なる (31) やっぱり (27) って (21) ある (17)
9 ちょっと (63) ある (42) ある (31) から (26) けれど (20) 思う (16)
10 思う (61) ちょっと (40) てる (31) たり (23) 思う (20) けど (16)
11 けれど (58) どう (38) けど (25) いる (19) えっと (19) アクションプラン (16)
12 そう (52) これ (38) けれど (23) ちょっと (19) そう (19) あの (15)
13 なる (49) 思う (36) まあ (21) そこ (19) はい (18) これ (14)
14 さん (39) ところ (35) 思う (21) えっと (18) たり (18) いい (13)
In [ ]:
top_words_rate_by_speaker(df_all, top_speakers, speaker_totals, pos=None, n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 ええ (34.74‰) って (19.07‰) えー (37.02‰) えー (37.37‰) ええ (20.68‰) いう (20.97‰)
1 あの (17.16‰) いう (16.55‰) いう (22.32‰) いう (19.70‰) てる (17.62‰) ない (20.57‰)
2 いう (15.07‰) てる (13.13‰) あの (13.56‰) って (13.62‰) まあ (16.85‰) って (16.61‰)
3 ない (14.79‰) さん (10.26‰) ええ (13.00‰) ない (13.33‰) いう (15.32‰) てる (13.05‰)
4 って (13.67‰) はい (9.72‰) ない (11.02‰) ところ (11.59‰) ある (11.87‰) こと (9.10‰)
5 てる (12.83‰) ない (9.72‰) って (11.02‰) ある (10.43‰) あの (11.11‰) ちょっと (8.31‰)
6 まあ (12.70‰) あの (9.00‰) ところ (9.32‰) こと (8.98‰) ない (10.34‰) もう (7.91‰)
7 ある (9.63‰) えっと (8.28‰) ちょっと (9.04‰) てる (8.40‰) ちょっと (9.96‰) やる (7.12‰)
8 こう (9.07‰) けど (7.56‰) なる (8.76‰) やっぱり (7.82‰) って (8.04‰) ある (6.72‰)
9 ちょっと (8.79‰) ある (7.56‰) ある (8.76‰) から (7.53‰) けれど (7.66‰) 思う (6.33‰)
10 思う (8.51‰) ちょっと (7.20‰) てる (8.76‰) たり (6.66‰) 思う (7.66‰) けど (6.33‰)
11 けれど (8.09‰) どう (6.84‰) けど (7.06‰) いる (5.50‰) えっと (7.28‰) アクションプラン (6.33‰)
12 そう (7.25‰) これ (6.84‰) けれど (6.50‰) ちょっと (5.50‰) そう (7.28‰) あの (5.93‰)
13 なる (6.84‰) 思う (6.48‰) まあ (5.93‰) そこ (5.50‰) はい (6.89‰) これ (5.54‰)
14 さん (5.44‰) ところ (6.30‰) 思う (5.93‰) えっと (5.21‰) たり (6.89‰) いい (5.14‰)
In [ ]:
top_words_by_speaker(df_all, top_speakers, pos="名詞", n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 こと (27) ところ (35) ところ (33) ところ (40) こと (9) こと (23)
1 あと (23) こと (30) こと (19) こと (31) お客様 (7) アクションプラン (16)
2 一回 (13) お客さん (16) 一応 (10) 感じ (9) 単価 (6) もの (12)
3 もの (13) 本店 (14) 本店 (8) もの (9) 売り上げ (5) 具体的 (7)
4 本店 (12) 店長 (12) 業者 (6) 共有 (9) 客数 (5) 問題 (7)
5 ところ (11) 店舗 (11) もの (6) パック (7) 切手 (5) メニュー (6)
6 売り上げ (10) あと (11) 白山 (5) ふう (6) 年間 (5) とんかつ (6)
7 店舗 (10) 商品 (10) ふう (5) 主任 (6) 原価 (4) 改善 (6)
8 お客様 (9) ごめん (9) あと (5) 全体 (6) ところ (4) ところ (5)
9 集客 (9) 状況 (9) 管理 (5) 灰皿 (6) 北山 (4) 現場 (5)
10 清水 (8) 売り上げ (9) スタッフ (5) オペレーション (5) 一度 (4) 声がけ (4)
11 意見 (8) 部長 (9) お客様 (5) 基本的 (5) 感じ (4) スタッフ (4)
12 みんな (7) 一応 (8) 課題 (5) あと (5) 仕入れ (3) 一回 (4)
13 先ほど (7) さん付け (8) トイレ (5) 目標 (5) 来店 (3) 職人 (4)
14 スタッフ (7) 渡辺 (7) 一回 (5) 今月 (5) 平均 (3) 部分 (4)
In [ ]:
top_words_rate_by_speaker(df_all, top_speakers, speaker_totals, pos="名詞", n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 こと (3.77‰) ところ (6.30‰) ところ (9.32‰) ところ (11.59‰) こと (3.45‰) こと (9.10‰)
1 あと (3.21‰) こと (5.40‰) こと (5.37‰) こと (8.98‰) お客様 (2.68‰) アクションプラン (6.33‰)
2 一回 (1.81‰) お客さん (2.88‰) 一応 (2.83‰) 感じ (2.61‰) 単価 (2.30‰) もの (4.75‰)
3 もの (1.81‰) 本店 (2.52‰) 本店 (2.26‰) もの (2.61‰) 売り上げ (1.91‰) 具体的 (2.77‰)
4 本店 (1.67‰) 店長 (2.16‰) 業者 (1.70‰) 共有 (2.61‰) 客数 (1.91‰) 問題 (2.77‰)
5 ところ (1.53‰) 店舗 (1.98‰) もの (1.70‰) パック (2.03‰) 切手 (1.91‰) メニュー (2.37‰)
6 売り上げ (1.40‰) あと (1.98‰) 白山 (1.41‰) ふう (1.74‰) 年間 (1.91‰) とんかつ (2.37‰)
7 店舗 (1.40‰) 商品 (1.80‰) ふう (1.41‰) 主任 (1.74‰) 原価 (1.53‰) 改善 (2.37‰)
8 お客様 (1.26‰) ごめん (1.62‰) あと (1.41‰) 全体 (1.74‰) ところ (1.53‰) ところ (1.98‰)
9 集客 (1.26‰) 状況 (1.62‰) 管理 (1.41‰) 灰皿 (1.74‰) 北山 (1.53‰) 現場 (1.98‰)
10 清水 (1.12‰) 売り上げ (1.62‰) スタッフ (1.41‰) オペレーション (1.45‰) 一度 (1.53‰) 声がけ (1.58‰)
11 意見 (1.12‰) 部長 (1.62‰) お客様 (1.41‰) 基本的 (1.45‰) 感じ (1.53‰) スタッフ (1.58‰)
12 みんな (0.98‰) 一応 (1.44‰) 課題 (1.41‰) あと (1.45‰) 仕入れ (1.15‰) 一回 (1.58‰)
13 先ほど (0.98‰) さん付け (1.44‰) トイレ (1.41‰) 目標 (1.45‰) 来店 (1.15‰) 職人 (1.58‰)
14 スタッフ (0.98‰) 渡辺 (1.26‰) 一回 (1.41‰) 今月 (1.45‰) 平均 (1.15‰) 部分 (1.58‰)
In [ ]:
top_words_by_speaker(df_all, top_speakers, pos="動詞", n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 いう (108) いう (92) いう (79) いう (68) いう (40) いう (53)
1 ある (65) ある (42) なる (31) ある (35) ある (30) やる (18)
2 思う (61) 思う (36) ある (29) いる (19) 思う (20) ある (16)
3 なる (49) なる (30) 思う (21) やる (13) いく (14) 思う (16)
4 いく (38) 願う (26) いる (19) なる (13) いただく (13) 言う (12)
5 おる (27) やる (24) いただく (15) 言う (9) おる (12) いく (10)
6 やる (26) 思る (23) できる (13) いく (9) やる (12) 思る (10)
7 願う (21) ござる (21) 来る (11) 行く (8) なる (11) なる (10)
8 いただく (19) いる (19) いく (10) おる (8) できる (10) 出す (9)
9 思る (17) 行く (16) やる (10) よる (7) 関する (9) くる (9)
10 ござる (16) いく (15) 願う (8) 思う (7) もらう (9) いただく (7)
11 くる (16) 見る (15) 思る (8) できる (7) いる (7) わかる (7)
12 できる (15) 言う (14) 使う (8) くる (6) ござる (6) 出る (7)
13 いる (14) 上がる (12) わかる (8) 出す (5) くる (6) できる (6)
14 言う (13) いただく (11) いただける (8) 来る (5) 言う (6) 回す (6)
In [ ]:
top_words_rate_by_speaker(df_all, top_speakers, speaker_totals, pos="動詞", n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 いう (15.07‰) いう (16.55‰) いう (22.32‰) いう (19.70‰) いう (15.32‰) いう (20.97‰)
1 ある (9.07‰) ある (7.56‰) なる (8.76‰) ある (10.14‰) ある (11.49‰) やる (7.12‰)
2 思う (8.51‰) 思う (6.48‰) ある (8.19‰) いる (5.50‰) 思う (7.66‰) ある (6.33‰)
3 なる (6.84‰) なる (5.40‰) 思う (5.93‰) やる (3.77‰) いく (5.36‰) 思う (6.33‰)
4 いく (5.30‰) 願う (4.68‰) いる (5.37‰) なる (3.77‰) いただく (4.98‰) 言う (4.75‰)
5 おる (3.77‰) やる (4.32‰) いただく (4.24‰) 言う (2.61‰) おる (4.60‰) いく (3.96‰)
6 やる (3.63‰) 思る (4.14‰) できる (3.67‰) いく (2.61‰) やる (4.60‰) 思る (3.96‰)
7 願う (2.93‰) ござる (3.78‰) 来る (3.11‰) 行く (2.32‰) なる (4.21‰) なる (3.96‰)
8 いただく (2.65‰) いる (3.42‰) いく (2.83‰) おる (2.32‰) できる (3.83‰) 出す (3.56‰)
9 思る (2.37‰) 行く (2.88‰) やる (2.83‰) よる (2.03‰) 関する (3.45‰) くる (3.56‰)
10 ござる (2.23‰) いく (2.70‰) 願う (2.26‰) 思う (2.03‰) もらう (3.45‰) いただく (2.77‰)
11 くる (2.23‰) 見る (2.70‰) 思る (2.26‰) できる (2.03‰) いる (2.68‰) わかる (2.77‰)
12 できる (2.09‰) 言う (2.52‰) 使う (2.26‰) くる (1.74‰) ござる (2.30‰) 出る (2.77‰)
13 いる (1.95‰) 上がる (2.16‰) わかる (2.26‰) 出す (1.45‰) くる (2.30‰) できる (2.37‰)
14 言う (1.81‰) いただく (1.98‰) いただける (2.26‰) 来る (1.45‰) 言う (2.30‰) 回す (2.37‰)
In [ ]:
top_words_by_speaker(df_all, top_speakers, pos="形容詞", n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 ない (50) ない (33) ない (14) ない (25) ない (8) ない (16)
1 ええ (41) いい (31) いい (9) いい (6) ええ (6) いい (13)
2 いい (12) よろしい (8) 多い (5) すごい (6) すごい (4) ほしい (6)
3 多い (5) 多い (5) ええ (4) 多い (4) いい (3) 美味しい (1)
4 すごい (3) 難しい (4) 高い (4) ええ (4) 少ない (2) すごい (1)
5 よろしい (3) すごい (4) 難しい (3) 少ない (2) 多い (2) ええ (1)
6 寂しい (3) ほしい (3) 大きい (1) 大きい (2) 低い (1) ものすごい (1)
7 新しい (2) うまい (2) 遅い (1) おいしい (2) 新しい (1) 新しい (1)
8 高い (2) ええ (2) おかしい (1) 早い (2) ほしい (1) 限りない (1)
9 悪い (2) 長い (2) 欲しい (1) 若い (1) 細かい (1) 近い (1)
10 硬い (2) 高い (2) 早い (1) 遅い (1) 嬉しい (1) 悪い (1)
11 正しい (1) 良い (2) すごい (1) 忙しい (1) 厳しい (1) 少ない (1)
12 目新しい (1) 少ない (1) 四角い (1) 深い (1) NaN 辛い (1)
13 細かい (1) よい (1) 悪い (1) 高い (1) NaN NaN
14 欲しい (1) 小さい (1) 面白い (1) はええ (1) NaN NaN
In [ ]:
top_words_rate_by_speaker(df_all, top_speakers, speaker_totals, pos="形容詞", n=15, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 ない (6.98‰) ない (5.94‰) ない (3.96‰) ない (7.24‰) ない (3.06‰) ない (6.33‰)
1 ええ (5.72‰) いい (5.58‰) いい (2.54‰) いい (1.74‰) ええ (2.30‰) いい (5.14‰)
2 いい (1.67‰) よろしい (1.44‰) 多い (1.41‰) すごい (1.74‰) すごい (1.53‰) ほしい (2.37‰)
3 多い (0.70‰) 多い (0.90‰) ええ (1.13‰) 多い (1.16‰) いい (1.15‰) 美味しい (0.40‰)
4 すごい (0.42‰) 難しい (0.72‰) 高い (1.13‰) ええ (1.16‰) 少ない (0.77‰) すごい (0.40‰)
5 よろしい (0.42‰) すごい (0.72‰) 難しい (0.85‰) 少ない (0.58‰) 多い (0.77‰) ええ (0.40‰)
6 寂しい (0.42‰) ほしい (0.54‰) 大きい (0.28‰) 大きい (0.58‰) 低い (0.38‰) ものすごい (0.40‰)
7 新しい (0.28‰) うまい (0.36‰) 遅い (0.28‰) おいしい (0.58‰) 新しい (0.38‰) 新しい (0.40‰)
8 高い (0.28‰) ええ (0.36‰) おかしい (0.28‰) 早い (0.58‰) ほしい (0.38‰) 限りない (0.40‰)
9 悪い (0.28‰) 長い (0.36‰) 欲しい (0.28‰) 若い (0.29‰) 細かい (0.38‰) 近い (0.40‰)
10 硬い (0.28‰) 高い (0.36‰) 早い (0.28‰) 遅い (0.29‰) 嬉しい (0.38‰) 悪い (0.40‰)
11 正しい (0.14‰) 良い (0.36‰) すごい (0.28‰) 忙しい (0.29‰) 厳しい (0.38‰) 少ない (0.40‰)
12 目新しい (0.14‰) 少ない (0.18‰) 四角い (0.28‰) 深い (0.29‰) NaN 辛い (0.40‰)
13 細かい (0.14‰) よい (0.18‰) 悪い (0.28‰) 高い (0.29‰) NaN NaN
14 欲しい (0.14‰) 小さい (0.18‰) 面白い (0.28‰) はええ (0.29‰) NaN NaN
In [ ]:
usage_rate_by_speaker(df_all, top_speakers, pos="助詞", top_k=20, stopwords=stopwords)
Out[ ]:
speaker カワイ スズキ 下川 平山 橋本 砂糖
dic_form
の 12.01 12.00 15.30 13.54 11.58 10.97
て 12.90 12.48 7.65 13.18 14.47 7.96
と 10.16 11.02 11.87 9.31 8.82 12.56
は 8.92 6.49 9.94 5.20 5.93 6.03
か 5.92 6.49 5.72 6.77 6.29 10.86
も 9.63 6.24 3.78 6.05 8.82 5.63
に 5.12 6.73 7.30 6.89 6.38 5.34
が 4.33 5.51 8.18 6.05 4.04 5.29
で 6.10 5.02 4.84 3.87 5.79 6.03
って 3.45 5.02 4.13 2.54 4.50 6.03
を 2.56 5.75 5.63 3.99 3.26 2.50
ん 4.06 3.43 1.58 5.93 5.42 3.18
ね 1.50 1.35 1.76 1.69 1.93 3.52
けど 2.21 1.84 1.58 1.81 0.92 2.39
な 2.47 0.61 0.79 1.93 1.56 1.93
から 0.88 0.98 2.29 1.57 1.47 1.88
けれど 2.03 0.73 0.00 2.30 2.62 0.17
たり 0.71 0.24 2.02 2.18 0.83 1.14
よ 0.27 2.82 1.23 0.60 0.37 1.42
ば 1.24 0.98 0.09 0.36 0.83 0.80
In [ ]:
usage_rate_by_speaker(df_all, top_speakers, pos="助動詞", top_k=20, stopwords=stopwords)
Out[ ]:
speaker カワイ スズキ 下川 平山 橋本 砂糖
dic_form
だ 41.54 39.00 42.45 39.85 40.92 40.27
た 21.92 21.62 26.98 21.46 21.93 22.37
てる 11.92 12.74 10.43 17.62 15.06 16.33
ない 9.62 13.90 7.55 7.28 9.17 4.70
たい 3.46 3.86 1.44 4.98 3.11 3.58
れる 1.15 2.70 2.88 2.68 3.93 2.91
ぬ 2.69 2.70 0.72 0.38 1.15 1.34
せる 1.92 0.77 2.16 2.30 1.31 0.22
られる 1.54 0.00 0.36 1.15 0.16 0.45
り 0.38 0.00 1.08 1.15 0.82 0.00
や 0.00 1.16 0.00 0.00 0.16 1.34
とる 0.38 0.00 0.00 0.00 0.00 2.01
てく 0.00 0.39 0.36 0.00 0.00 1.57
ず 0.38 0.00 0.72 0.38 0.33 0.00
む 0.00 0.39 0.00 0.77 0.00 0.45
けり 0.00 0.00 0.00 0.00 1.15 0.22
させる 1.15 0.00 0.00 0.00 0.00 0.00
てらっしゃる 0.77 0.00 0.00 0.00 0.00 0.22
き 0.00 0.00 0.72 0.00 0.16 0.00
てえ 0.00 0.00 0.72 0.00 0.16 0.00
In [ ]:
top_words_by_speaker(df_all, top_speakers, pos="感動詞", n=15, min_len=0, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 ええ (208) はい (54) えー (131) えー (129) ええ (48) えー (8)
1 え (99) えっと (46) ええ (42) え (31) え (46) はい (6)
2 はい (22) えー (33) え (31) えっと (18) えっと (19) あ (4)
3 あ (17) えっ (32) ま (24) はい (15) はい (18) ええ (3)
4 ありがとう (10) ありがとう (21) はい (7) えーとー (12) えっ (7) ええと (3)
5 ま (8) あ (10) あ (7) えっ (12) ありがとう (6) え (3)
6 えー (7) え (7) えっ (6) ええ (5) いや (4) えっと (3)
7 あの (6) ええと (7) えっと (4) ありがとう (5) えー (3) ありがとう (1)
8 う (4) えーと (6) あのー (3) えーと (4) ええと (2) さ (1)
9 まあ (4) えっとー (5) おー (2) ま (4) あ (2) あのー (1)
10 ああ (3) あれ (4) うー (2) まー (4) ああ (2) うー (1)
11 おはようございます (2) ま (2) んー (2) えっとー (2) ま (1) いや (1)
12 えっと (2) あっ (2) あの (2) あ (2) えーと (1) ええー (1)
13 へえ (2) あのー (2) う (1) あー (2) あの (1) あー (1)
14 よし (1) えーとー (1) まー (1) あの (2) まあ (1) えーと (1)
In [ ]:
top_words_rate_by_speaker(df_all, top_speakers, speaker_totals, pos="感動詞", n=15, min_len=0, stopwords=stopwords)
Out[ ]:
橋本 砂糖 カワイ 下川 平山 スズキ
0 ええ (29.02‰) はい (9.72‰) えー (37.02‰) えー (37.37‰) ええ (18.38‰) えー (3.16‰)
1 え (13.81‰) えっと (8.28‰) ええ (11.87‰) え (8.98‰) え (17.62‰) はい (2.37‰)
2 はい (3.07‰) えー (5.94‰) え (8.76‰) えっと (5.21‰) えっと (7.28‰) あ (1.58‰)
3 あ (2.37‰) えっ (5.76‰) ま (6.78‰) はい (4.35‰) はい (6.89‰) ええ (1.19‰)
4 ありがとう (1.40‰) ありがとう (3.78‰) はい (1.98‰) えーとー (3.48‰) えっ (2.68‰) ええと (1.19‰)
5 ま (1.12‰) あ (1.80‰) あ (1.98‰) えっ (3.48‰) ありがとう (2.30‰) え (1.19‰)
6 えー (0.98‰) え (1.26‰) えっ (1.70‰) ええ (1.45‰) いや (1.53‰) えっと (1.19‰)
7 あの (0.84‰) ええと (1.26‰) えっと (1.13‰) ありがとう (1.45‰) えー (1.15‰) ありがとう (0.40‰)
8 う (0.56‰) えーと (1.08‰) あのー (0.85‰) えーと (1.16‰) ええと (0.77‰) さ (0.40‰)
9 まあ (0.56‰) えっとー (0.90‰) おー (0.57‰) ま (1.16‰) あ (0.77‰) あのー (0.40‰)
10 ああ (0.42‰) あれ (0.72‰) うー (0.57‰) まー (1.16‰) ああ (0.77‰) うー (0.40‰)
11 おはようございます (0.28‰) ま (0.36‰) んー (0.57‰) えっとー (0.58‰) ま (0.38‰) いや (0.40‰)
12 えっと (0.28‰) あっ (0.36‰) あの (0.57‰) あ (0.58‰) えーと (0.38‰) ええー (0.40‰)
13 へえ (0.28‰) あのー (0.36‰) う (0.28‰) あー (0.58‰) あの (0.38‰) あー (0.40‰)
14 よし (0.14‰) えーとー (0.18‰) まー (0.28‰) あの (0.58‰) まあ (0.38‰) えーと (0.40‰)
In [ ]:
usage_rate_by_speaker(df_all, top_speakers, pos="感動詞", top_k=15, stopwords=stopwords)
Out[ ]:
speaker カワイ スズキ 下川 平山 橋本 砂糖
dic_form
えー 49.06 20.0 50.19 1.85 1.72 13.87
ええ 15.73 7.5 1.95 29.63 51.23 0.42
え 11.61 7.5 12.06 28.40 24.38 2.94
はい 2.62 15.0 5.84 11.11 5.42 22.69
えっと 1.50 7.5 7.00 11.73 0.49 19.33
えっ 2.25 0.0 4.67 4.32 0.25 13.45
あ 2.62 10.0 0.78 1.23 4.19 4.20
ありがとう 0.37 2.5 1.95 3.70 2.46 8.82
ま 8.99 0.0 1.56 0.62 1.97 0.84
ええと 0.00 7.5 0.00 1.23 0.25 2.94
えーと 0.00 2.5 1.56 0.62 0.00 2.52
いや 0.00 2.5 0.39 2.47 0.00 0.42
あのー 1.12 2.5 0.39 0.00 0.25 0.84
えーとー 0.00 0.0 4.67 0.00 0.00 0.42
あー 0.37 2.5 0.78 0.62 0.00 0.42