作成日:2023/12/15

寄稿・コラボ / 奮闘記

データサイエンティスト奮闘記 Vol.2
– Pythonを用いた基礎率集計編 –
(難易度★☆☆)

こんにちは。DeSCヘルスケア(以下、DeSC)データサイエンス部の小林と申します。
第2回目となる今回は、Python初心者で生保数理の知識もなかった私が、Pythonを用いて基礎率を集計できるようになるまでの奮闘をまとめました。

Pythonを用いて基礎率を集計できるようになるまで

この記事は約10分で読めます

  1. 基礎率ってなに?
  2. Pythonがはじめてで不安・・・

Pythonを用いて基礎率を集計できるようになるまで

基礎率ってなに?

生命保険会社向けのデータ分析をするにあたってまず要になるのが、”基礎率”の考え方であると思います。基礎率は保険料計算の際に基礎となる数値です。保険会社は、過去実績の支払データ・公的統計・外部データなどから得られた死亡率、入院・手術の発生率などを基に、保険料算定の基礎となる死亡率や給付発生率を作成します。これらをまとめて「基礎率」と呼んでいます。

レセプトデータ等を用いて基礎率を集計する準備として、基礎率の計算式や計算方法について社内レクチャーを受けました。


基礎率集計用サンプルデータ


この基礎率の計算方法を実際の健保・国保・後期高齢データに適用することでそれぞれのデータにおける基礎率を算出することができます。

最初は基礎率と聞くと、基礎の率?なんだろう?という難しい印象を受けましたが実際に基礎率について学習し、この算出した数値が生命保険の保険料率の見直しなどに役立っていると思うと、とても興味深くなりました。様々な保険商品の約款の給付条件や告知書の告知要件によって若干の抽出条件が変わればもちろん値も変わるので、奥が深い計算であることが分かりました。

また、前職での製薬会社向けの解析でも基礎率と似たような集計をしていることに気づきました。人年法と呼ばれる分析で、例えばある薬剤を使ったときの副作用発生率を調べたいとき、「副作用の発生件数 ÷ 総観察期間(人年)」で発生率を求めます。これは薬剤の安全性を評価する指標となります。扱っているデータは異なるものの似たような計算法を用いて、分析が行われていることに気づきました。

基礎率算出については、こちらのページにも詳細な説明がまとめられています。よろしければ、あわせてご覧ください。

  • 分析白書(DeSCデータ分析事例)
  • Pythonがはじめてで不安・・・

    さて、基礎率の知識も身につけたところで、いざPythonを用いて基礎率を集計しよう!と思いましたが・・・実は、今まで主にSAS言語を使用しており、Pythonでプログラムを書いたことがありませんでした。Pythonで集計ができるようになるまで、3つの学びがありました。

    1. 実際に手を動かしてみる!

    まず、DeSC社員である青木が執筆したこちらの書籍を読んで勉強を始めました。こちらの書籍には、公的データを用いてレセプトデータを擬似生成し、基礎率を集計する実際のPythonスクリプトや考え方がまとめられています。Pythonを知っている友人からは、シンプルに書くことができるし、応用幅の広い言語だよ!と聞いてはいたものの・・・まずは書籍のスクリプトを書き写す作業からでした。

    書き写している最中も最初は、pandas?NumPy?頭にハテナ?がたくさん浮かぶ中での作業で、初めて見る表現ばかりであったため、下記の1〜3の作業を繰り返し、進めていきました。

    この作業を繰り返し、書籍の第2章まで進めると

    データを集計する→発生率を求める→ グラフを描く
    という一連の流れについて、Pythonで実装するイメージを掴むことができました。

    2. エラーメッセージの内容を調べること

    最初は書籍から書き写したコードを実行しエラーが出ても、エラーの内容を読み解くことも難しく、チームメンバーに質問してばかりでした。

    第1章(P.3)の冒頭で、満年齢と保険年齢の関係を表す数直線を描くスクリプトを書き写していると、いきなりエラーが出てしまいました。

    実際のJupyter画面(スクリプト修正前)

    インターネット検索してみたものの分からず、チームメンバーと画面を見ながら検証することにしました。メンバーから「指定している引数が異なっている。Pythonではライブラリ(今回はmatplotlib)の仕様変更に伴い、引数名が変更されることがある」と教えてもらい、下図の青枠箇所を修正することで解決したのを覚えています。

    実際のJupyter画面(スクリプト修正後)

    また、そのときチームメンバーからあったアドバイスは、「エラーを調べることも学習の一つになるので、日本語で調べても分からなかった場合は、さらに英語の文献を見てみたほうが良い」というアドバイスでした。メンバーに質問をして解決するのではなく、実行しつつ、エラーを調べながら進めると、次第に質問する回数も減っていき、Pythonで実行することの特徴を掴めるようになりました。

    3. データの中身を確認すること

    書籍の第2章まで終わったところで、実際にレセプトデータを用いて基礎率の集計をすることになりました。過去にチームメンバーが作成したPythonのスクリプトから少し仕様を変更し、改修して作成するというフローでした。

    スクリプトを書き終え実行をしたところ、エラーが出てしまいました。エラー箇所を探ってみると、pivot_table関数を用いて、各個人IDごとにClaimが発生した月(=診療月)に1を立てるというクロス集計をする処理の際、エラーが出ていることに気づきました。

    サンプルデータにて実際のエラー画面を再現

    print(data)

    というコードを追加し、エラーが出ている「data」の中身を見てみることにしました。すると、診療月がすべてNULLになっていました。

    修正前のdata


    「data」にはデータベース上のレセプトデータテーブルから抽出した結果を格納していたのですが、抽出する際に英語名のカラムを日本語の『診療月』にrenameする処理を同時に行っていました。レセプトデータにおいて診療月がNULLになることは考えられないことから、renameする前のカラムに参照ミスがあるのではないか、と気づきました。

    処理の流れを表した図


    ここまでの経緯をメンバーに相談したところ、想定通り診療月として参照するカラムが誤っていたことがわかり、正しいカラムに書き換えて修正すると、無事に実行することができました。

    修正後のdata

    修正後のdataで実行したcross_table


    最後までエラーなく実行を終え基礎率の結果を得ることができたとき、あきらめず粘り強く原因を探りデータの中身を確認することが大切だと思いました。

    ここまでがPythonを用いて初めて基礎率を集計を行うまでの奮闘記です。次回はPythonをもう少し深掘り、Pythonを用いて分析し感じた特徴などを綴りたいと思います。




    これらの内容は、あくまでも個人的な意見でありますが、皆様のお役に立てれば幸いです。また、DeSCデータについて、詳細な情報が知りたい方はお問い合わせボタンよりお問い合わせください。