[PYTHON] Visualize details of life insurance company complaints

Introduction

Visualization of the number of complaints from life insurance companies continued

import pathlib
from urllib.parse import urljoin

import pandas as pd
import pdfplumber
import requests
from bs4 import BeautifulSoup


def fetch_file(url, dir="."):

    r = requests.get(url)
    r.raise_for_status()

    p = pathlib.Path(dir, pathlib.PurePath(url).name)
    p.parent.mkdir(parents=True, exist_ok=True)

    with p.open(mode="wb") as fw:
        fw.write(r.content)
    return p


url = "https://www.seiho.or.jp/member/complaint/"

headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64; Trident/7.0; rv:11.0) like Gecko"
}

r = requests.get(url, headers=headers)
r.raise_for_status()

soup = BeautifulSoup(r.content, "html.parser")

dfs = []

for tag in soup.select("div.headMod04.mt30"):

    name = tag.h3.get_text(strip=True).replace("Co., Ltd.", "")

    href = (
        tag.find_next_sibling("table", class_="mt10")
        .find("a", text="Details of the breakdown of complaints")
        .get("href")
    )

    link = urljoin(url, href)

    p = fetch_file(link)

    with pdfplumber.open(p) as pdf:

        p0 = pdf.pages[0]

        table = p0.extract_table()

    df0 = pd.DataFrame(table)

    #Remove line breaks, whitespace and commas
    df0 = df0.applymap(lambda s: "".join(s.split()).replace(",", "") if s else None)
    df0 = df0.mask(df0.isna())

    df0.iloc[0] = df0.iloc[0].fillna(method="ffill")
    df0.iloc[:, 0] = df0.iloc[:, 0].fillna(method="ffill")

    #DataFrame cannot be converted well, so convert it to CSV once

    p_csv = p.with_suffix(".csv")
    df0.to_csv(p_csv, index=False, header=False)

    df1 = (
        pd.read_csv(p_csv, index_col=[0, 1], header=[0, 1])
        .loc[:, pd.IndexSlice[:, "Total"]]
        .droplevel(level=1, axis=1)
    )

    df2 = df1.reindex(df1.index.drop("Total", level=1, errors="raise"))

    df2[name] = df2.sum(axis=1)

    dfs.append(df2[name])

df = pd.concat(dfs, axis=1)

df
('item', 'Contents') AXA Life Insurance AXA Direct Life Insurance Asahi Mutual Life Insurance Company Aflac life insurance Aeon Allianz Life Insurance SBI Life Insurance NN Life Insurance FWD Fuji Life Insurance ORIX Life Insurance Cardif life insurance Japan Post Insurance Crédit Agricole Life Insurance Gibraltar Life Insurance Sumitomo Life Insurance Company Sony life insurance Sony Life with Life Insurance SOMPO Himawari Life Insurance (former Sompo Japan Nipponkoa Himawari Life Insurance) Dai-ichi Life Insurance Daiichi Frontier Life Insurance Taiju Life Insurance (formerly Mitsui Life Insurance) Daido Life Insurance Taiyo Life Insurance Zurich Life Insurance Company Limited T & D Financial Life Insurance Tokio Marine & Nichido Life Insurance Nippon Wealth Life Insurance Nippon Life Insurance Company Neo First Life Insurance Hanasaku Life Insurance Fukoku Life Insurance Company Fukoku Shinrai Life Insurance Prudential Life Insurance PGF Life (Prudential Gibraltar Financial Life Insurance) Manulife life insurance Mitsui Sumitomo Insurance Aioi Life Insurance Mitsui Sumitomo Primary Life Insurance Midori Life Insurance Meiji Yasuda Life Insurance Company MetLife Life Insurance Medicare Life Insurance Lifenet Life Insurance Rakuten Life Insurance
('New contract relationship', 'Inappropriate recruitment') 38 0 82 10 0 1 0 11 7 0 6124 0 64 53 126 3 24 233 10 87 1 20 14 0 138 3 120 3 6 28 1 133 16 10 7 3 64 47 45 8 0 4
('New contract relationship', 'Get inappropriate notifications') 6 0 6 0 0 0 0 0 5 0 91 0 4 4 7 0 5 9 0 3 0 16 11 0 6 0 10 3 3 4 0 6 0 2 5 0 0 4 13 0 0 2
('New contract relationship', 'Inappropriate narration') 7 0 4 4 0 0 0 0 0 0 20827 0 45 3 22 0 1 4 2 1 0 2 0 0 0 0 12 0 1 1 0 26 0 4 1 1 1 10 3 1 0 0
('New contract relationship', 'Insufficient explanation') 160 0 177 104 0 8 3 108 124 0 11660 2 148 233 4 17 67 182 60 205 3 51 78 6 108 6 339 40 11 68 0 45 52 37 14 105 20 92 381 15 12 45
('New contract relationship', 'Careless handling of office work') 32 0 11 486 0 2 2 22 58 0 31 1 11 49 21 0 30 47 62 38 1 9 98 0 71 1 66 10 1 21 0 83 17 7 42 1 7 42 106 62 4 7
('New contract relationship', 'Contract confirmation') 30 2 4 0 0 1 0 4 14 0 686 0 9 22 6 0 1 3 0 1 5 4 5 0 0 0 2 0 1 0 0 5 0 0 3 0 2 12 41 2 1 3
('New contract relationship', 'Contract underwriting relationship') 33 9 17 237 0 12 2 14 734 3 121 1 28 40 9 1 4 28 0 9 30 5 49 2 12 0 13 9 0 12 0 17 17 2 5 0 1 17 208 20 34 17
('New contract relationship', 'Securities not yet arrived') 11 1 5 13 0 0 0 29 16 0 25 0 5 19 10 2 5 7 7 2 0 1 26 0 12 1 21 1 1 3 5 34 0 1 8 2 2 0 107 0 1 0
('New contract relationship', 'その他New contract relationship') 325 28 117 2066 0 14 7 56 692 16 3466 0 64 375 164 1 35 34 135 30 108 305 242 26 85 9 471 43 22 120 26 49 43 23 37 7 15 488 417 21 559 68
('Storage related', 'Collecting money') 0 0 5 0 0 0 0 0 0 0 14 0 5 6 0 0 0 4 0 0 0 0 0 0 0 0 0 0 0 2 0 1 0 1 0 0 0 4 0 0 0 0
('Storage related', 'Direct debit / remittance') 175 11 81 1241 0 2 11 112 368 0 306 0 497 400 336 0 118 103 0 106 72 39 51 3 242 10 319 12 5 256 66 161 27 74 46 0 4 206 874 45 78 87
('Storage related', 'Work area group treatment') 40 0 19 192 0 0 0 0 2 0 38 0 93 43 11 0 1 22 0 15 1 0 0 0 8 0 71 0 0 71 0 2 0 0 3 0 0 77 22 0 0 0
('Storage related', 'Insurance premium payment') 32 0 60 20 0 0 2 1 63 0 134 0 148 95 13 0 5 131 0 26 16 38 53 4 54 2 224 4 0 15 8 50 26 7 10 0 3 79 17 1 0 1
('Storage related', 'Insurance premium transfer loan') 10 0 15 17 0 0 0 2 15 0 0 0 103 101 35 0 11 38 0 13 4 6 0 1 38 6 50 0 0 30 4 32 8 3 4 0 0 23 27 0 0 0
('Storage related', 'Expiration / Resurrection') 33 1 24 161 0 0 5 21 88 0 85 0 110 86 34 0 22 24 0 13 11 15 114 0 34 5 46 1 0 14 3 16 2 21 14 0 1 44 208 12 8 12
('Storage related', 'その他Storage related') 2 0 8 0 0 1 7 0 2 0 123 0 85 105 46 0 18 67 0 15 18 11 70 2 22 1 164 15 8 4 3 3 5 37 0 0 0 200 17 18 2 1
('Conservation relations', 'Dividend details') 9 0 6 0 0 0 0 0 0 0 20 0 16 58 3 0 0 76 0 12 7 3 0 0 2 0 51 0 0 19 45 1 4 0 0 0 0 39 0 0 0 0
('Conservation relations', 'Contractor loan') 156 0 33 82 0 0 10 15 56 0 187 0 469 290 215 0 84 152 0 42 170 10 0 3 124 3 274 0 0 84 12 233 17 19 17 0 0 149 384 0 0 0
('Conservation relations', 'update') 42 7 44 43 0 1 2 7 17 1 0 0 273 155 31 0 13 115 0 74 53 29 69 4 39 3 110 10 0 176 6 12 2 25 3 0 0 143 136 0 16 21
('Conservation relations', 'Contract details change') 87 1 56 209 0 2 3 12 58 0 148 0 149 553 81 0 27 128 1 72 43 27 29 5 44 19 332 2 3 30 24 109 27 39 7 5 0 228 190 2 1 6
('Conservation relations', 'Name change / address change') 148 0 96 347 0 2 6 25 163 1 192 1 363 481 257 7 61 115 26 104 67 21 98 9 155 28 400 5 0 117 29 150 56 31 20 36 0 281 374 31 16 20
('Conservation relations', 'Special contract mid-career addition') 7 2 1 113 0 0 0 3 13 0 76 0 180 21 20 0 4 5 0 9 3 1 13 0 7 0 124 1 0 6 1 6 0 0 3 0 0 7 53 0 0 0
('Conservation relations', 'Cancellation procedure') 437 7 365 1112 0 5 19 37 246 0 686 1 700 956 334 5 134 288 56 166 188 106 75 7 275 18 1023 13 0 261 44 178 82 73 70 18 7 542 902 22 14 54
('Conservation relations', 'Cancellation refund') 21 1 29 228 0 0 2 4 37 1 181 0 263 171 59 98 14 16 12 45 25 9 2 15 50 7 66 4 0 25 4 13 63 12 7 3 3 108 231 0 0 1
('Conservation relations', 'Life insurance card / ATM related') 0 0 9 0 0 0 0 0 0 0 0 0 0 189 0 0 0 54 0 4 0 5 0 0 0 0 485 0 0 75 0 0 0 0 0 0 0 38 0 0 0 0
('Conservation relations', 'その他Conservation relations') 57 0 107 1353 0 0 39 19 421 0 1056 0 912 955 670 7 43 436 24 53 17 84 46 27 152 32 646 8 3 217 14 138 64 14 5 44 3 763 794 3 20 33
('Insurance claims / benefits', 'Maturity insurance, pension, etc.') 65 0 109 76 9 0 5 37 44 0 434 0 835 535 104 12 24 160 24 125 40 63 1 3 53 117 249 0 0 233 183 95 37 30 7 32 20 269 244 0 0 0
('Insurance claims / benefits', 'Death insurance payment procedure') 71 1 60 180 2 0 8 4 127 1 145 1 158 400 48 2 19 98 18 47 41 13 3 12 5 18 167 2 0 30 20 15 80 42 6 26 1 185 235 1 3 8
('Insurance claims / benefits', 'Decided not to pay insurance claims such as death') 5 0 2 23 0 0 1 0 16 0 30 1 6 7 1 0 0 5 0 3 6 4 0 0 1 0 45 0 0 3 0 0 0 0 1 2 1 17 9 0 1 1
('Insurance claims / benefits', 'Hospitalization benefit payment procedure') 766 16 151 2203 0 8 2 203 2116 2 874 0 709 1568 368 0 197 356 0 241 109 111 141 12 150 11 497 57 9 401 7 143 16 82 177 0 0 808 1631 57 68 132
('Insurance claims / benefits', 'Decided not to pay benefits such as hospitalization') 189 5 50 709 0 4 3 20 247 1 330 0 53 101 32 0 25 115 0 46 25 42 30 3 11 1 163 5 2 58 0 5 1 11 53 0 0 197 337 17 14 36
('Insurance claims / benefits', 'その他Insurance claims / benefits') 6 2 15 2 0 0 4 4 46 1 176 0 1 157 18 1 57 153 7 0 5 10 13 8 4 3 245 6 3 0 0 3 8 22 4 0 2 104 183 6 3 25
('Other', 'Attitude and manners of staff') 118 0 305 33 0 4 2 14 48 0 95 2 168 391 106 2 32 1072 26 163 75 96 80 0 162 5 729 22 2 129 0 53 0 58 27 58 8 493 117 16 3 7
('Other', 'Insurance premium deduction') 13 0 3 46 0 0 0 4 14 0 27 0 46 30 22 0 6 12 0 2 3 1 13 0 21 0 52 0 0 18 1 3 2 0 2 0 1 17 43 0 2 1
('Other', 'Personal information handling relationship') 14 0 42 51 0 1 0 22 84 0 14 1 26 80 66 0 15 123 1 32 6 9 9 1 13 0 124 1 0 35 0 45 13 4 4 0 1 101 4 3 1 21
('Other', 'After-sales service') 1689 0 735 957 0 4 18 268 364 0 60 0 933 862 366 29 122 684 93 601 255 51 321 6 641 69 1128 4 1 299 17 138 91 85 144 67 6 636 2273 14 166 53
('Other', 'Other') 107 13 66 444 0 0 1 23 316 4 505 0 132 2155 244 13 53 676 154 120 28 130 50 14 79 7 462 21 5 25 778 60 52 328 22 161 2 684 312 13 89 20
import japanize_matplotlib
import matplotlib as mpl
import matplotlib.pyplot as plt

mpl.rcParams["figure.dpi"] = 200

df.T.plot.barh(stacked=True, figsize=(15, 15))

insurance04.png

Recommended Posts

Visualize details of life insurance company complaints
Visualize the number of complaints from life insurance companies
[Python] Representing the number of complaints from life insurance companies in a bar graph