DPCデータの分析とかやるブログ

DPCデータの分析なんかをテキトーにやってます。

全自動BIツールとしてのGoogleスプレッドシート

前回の記事から二ヶ月ぶりくらいです。
放置しててすみません。私事ですが、色々ドタバタしていたもので……
さて、今日のお題はGoogleスプレッドシートです。

そもそもGoogleスプレッドシートって?

「あのGoogleExcelパクったやつでしょ?」と思ったあなた、まあ、そんなに間違ってはいません。 関数とか、かなり完コピしてますし、一見してとても、その、すごくExcelです……

ですが、このスプレッドシートExcelには無い素晴らしい機能があります。

サジェスト型BIツール

試しに、機械学習のお題によく使われる、irisデータセットを貼り付けてみました。

docs.google.com

すると、画面右下に「データ探索」というボタンが出現し、クリックすれば……あら不思議。
Google先生が、私の代わりに散布図やらヒストグラムを描いてくれ、あれこれデータについて教えてくれます。
上記リンクのシートでは、散布図とヒストグラムを載せていますが、これはサジェストされたものを1クリックで載せたものです。
所要時間は、せいぜい30秒くらいでしょう。

BIツールの現状と問題点

データの可視化に活躍するBIツール。
ですが、当然ながら、ユーザーは可視化について、ある程度の前提知識を求められます。 そして困ったことに、そんなことは学校教育で教わりません。
(理系に進んで研究をやっていれば別なんでしょうけど、私文系だったので……)

Googleスプレッドシートは、「何の可視化をすべきか」「データの要点は何か」を、向こうからサジェストしてくれます。
ユーザーは与えられた選択肢から選ぶだけです。まあ、的外れなサジェストもありますが、兎に角形にしてくれるわけです。

もし職場で、手っ取り早くデータ分析を広めたいのなら、Googleスプレッドシートは最適な入り口でしょう。
Excelのように煩雑なグラフ作成手順を踏む必要はありませんし、BIツールのように前提知識を求めません。 まあ、そのうちMicrosoftも似たような機能を載せてきそうですが、現状ではGoogleに一日の長がありますね。

DPCチェッカー ver0.4を公開しました

github.com

修正内容

  • 問い合わせ結果がゼロ件だった場合、何の表示もなかったので、データなしと表示するように修正
  • レイアウトが崩れていたのを修正

現在の開発状況

現在、手探りでElectronを書いてますが、流石に限界なのでボイラープレートに乗っかろうと思ってます。
Electron-vueという、素晴らしいテンプレートがありますので、それを使おうかなあ……

導入 · electron-vue

Electron周辺は、とにかく動きが早くて追いかけるのが大変ですが、日々便利なツールが増えていく状況は楽しいですね!
JavaScriptの世界には、他には無い熱さがあります。

平成30年度改定について

ざっと見たところ、EF/Dファイルには大きな変更は無さそうなので、このまま走ると思います。
ただ、実運用してみて変なバグが見つかったら、順次修正する予定です。

DPCチェッカー書き直しました

github.com

えーと、今回は64bit版のみのリリースになります。32bi版も追って公開したいな、と思ってますが、ビルドが面倒なもので…(汗

また、ダッシュボード機能は一度取り下げることにしました。
今度はもうちょっと面白いグラフになるようにしたいですね。

で、何をやったのか

完全な書き直しです。
Python版の頃から一貫して、「ローカルでウェブサイトを立ち上げ、それを見る」というアレな設計でしたが、いい加減止めました。
それに伴い、内部のコードは8割方(ひょっとすると、もっと)書き換えてます。中身はほぼ別物です。

こんなことをした理由

幾らなんでも、ローカルでサーバー立ち上げるようなアプリはねーよ、と思いました(遅い
また、今までの実装があまりにもいじり辛く、機能追加も修正も面倒で気が進まないという欠陥がありました。
今回はそれを打破すべく、かなり後付でいじりやすくなっています。
オレオレ版を作りたい、という方はどうぞフォークして作って下さい。

実装よもやま話

SPA

今回、フロントエンドは全てVue.jsで書き直し、SPAにしています。 SPAはシングルページアプリケーションの略で、んーと、単一のindex.htmlをjavascriptがゴニョゴニョやって、あたかも複数のページを移動しているかのごとく振る舞うものです。
10年前にウェブサイトを作った頃は、リンクを踏むと別なhtmlに飛んでましたが、今はjavascriptがhtmlを作るのです!なんという進歩でしょう!(白目

.......正直、絶対近寄りたくないと思ってた分野であります。

……が、えー、Electronでアプリを書くに当たり、色んな記事を読みましたところ、どれもSPAで書くことを前提にしてますね(苦笑
無駄な抵抗を色々やりましたが、結局諦めてSPAを書くことにしました。
例えやりたくない方法でも、何のガイドもない方法を選ぶよりは遥かにマシです。

Vue.js

Vue.jsについては以前ちらっと記事で触れたかも知れません。
データを元に、動的にリストを作成したり、ボタンクリックだの入力だのの操作とデータの接続をよしなにしてくれたり、とっても便利なライブラリです。
まあ、Reactでもいいのですが、私はJSXを見て心が折れました……
そもそも私、病院の事務職で、フロントエンドエンジニアじゃないしー……

Vuetify

VuetifyはVue.jsのライブラリで、お手軽にGoogleっぽいデザインのサイトを作れます。
以前はMaterial Design Liteでゴリゴリ手書きしてましたが、もう疲れました…
<button>タグの変わりに<v-btn>タグを使う、たったそれだけのことで、見れるボタンの出来上がりです!お手軽!

レセ電パーサを公開しました

とても人類には読み取れないレセ電ファイルを読み込むパーサ、Receparserを公開しました。 こちらです。

github.com

現在、医科レセプトファイルと、DPCレセプトファイルに対応しています。
なお、サンプルファイルは支払基金公開しているサンプルを修正したものです。
テスト用にJupyter Notebookファイルも付けておきましたので、ご覧ください。

使い方

from receparser import MonthlyRece,Rece

で、必要なオブジェクトをインポートします。

サンプルファイルを読み込みます。 読み込みの際には、codesオプションに"dpc"か"ika"を指定します。

.keysでカルテ番号の一覧を見ることが出来ます。 ディクショナリのように動きます。.items(),.values()も使えます。

dpc = MonthlyRece('dpcsample.csv',codes="dpc")
dpc.keys()

out: 
dict_keys(['1111', '', '2222', '3333', '4444', '5555', '6666', '8888', '9999', '101010'])

電子レセプトファイルは各行にレコードと呼ばれるアルファベットが振られており、それぞれ異なる内容を持っています。カルテ番号から更に深掘りしてみましょう。

dpc['1111'].keys()

とすると、

dict_keys(['RE', 'HO', 'KO', 'BU', 'SB', 'KK', 'GA', 'HH', 'GT', 'CO', 'SI', 'CD'])

が返ってきます。それぞれの内容を追っていくと…

dpc['1111']['RE']

out:
{'レコード識別番号': 'RE', 'レセプト番号': '1', 'レセプト種別': '1127', '診療年月': '42806', '氏名': 'サンプルDPC01', '男女区分': '1', '生年月日': '3160822', '給付割合': '', '入院年月日': '', '病棟区分': '', '一部負担金区分': '', 'レセプト特記事項': '', 'カルテ番号等': '1111', '割引点数単価': '', 'レセプト総括区分': '0', '明細情報数': '', '検索番号': '', '記録条件仕様年月情報': '', '請求情報': '', '診療科名': '59', '診療科_人体の部位': '', '診療科_性別等': '', '診療科_医学的処置': '', '診療科_特定疾病': ''}

dpc['1111']['HO']

out:
{'レコード識別番号': 'HO',
 '保険者番号': '06132013',
 '合計点数': '57706',
 '職務上の理由': '',
 '被保険者証の番号': '1',
 '被保険者証の記号': '1234567',
 '診療実日数': '5',
 '証明者番号': '',
 '負担金額_医療保険': '44400',
 '負担金額_減免区分': '',
 '負担金額_減額割合': '',
 '負担金額_減額金額': '',
 '食事_合計金額': '2072',
 '食事_回数': '3',
 '食事療養・生活療養_標準負担額': '1080'}

このような感じになります。
何だかんだ、2,3日かけて突貫で書き上げました。 (ファイル仕様を書き出すのと、サンプルファイルの修正が一番大変でした……) 最低限の機能しか実装していませんので、これから色々拡張していきたいですね。
具体的には、各レセプトごとの情報を統合して見やすく表示する機能とか、全体のサマリを表示する機能とか…

2017年振り返りと、2018年の展望

はい、今年の後半は本当にブログ書いてませんでした!ごめんなさい!
暇ができたら、レセ電ファイルを読み取るパーサーでも書こうと思ってましたが……うーん、全然時間が取れませんでしたね。
で、何をやってたかと言うと…

本ばっかり読んでいた

私は読書が趣味です。出身が人文学部なので、とにかく沢山読みます。
元々は西洋哲学や、ヨーロッパ史を中心に読み漁ってましたが、この数年はプログラムの本を読むのが趣味になりました。
ええ、趣味です。結局肝心のコードを書けてないので、実益は(殆ど)ありません。
ということで、以下に最近買った本をつらつらと。

Fluent Python ―Pythonicな思考とコーディング手法

Fluent Python ―Pythonicな思考とコーディング手法

Pythonによるテキストマイニング入門

Pythonによるテキストマイニング入門

基礎からわかる Scala

基礎からわかる Scala

Javaの絵本 第3版 Javaが好きになる新しい9つの扉

Javaの絵本 第3版 Javaが好きになる新しい9つの扉

経済・ファイナンスデータの計量時系列分析 (統計ライブラリー)

経済・ファイナンスデータの計量時系列分析 (統計ライブラリー)

いや、これは無理でしょう

今年の教訓は「自分の頭に入るだけの本を買いなさい」ですね!
どれもすごくいい本で、頭の中が整理されますが(特にFluent Pythonは素晴らしい)、いかんせん数が多すぎます。 途中で止まってる本も多いし……

2018年はどうするか

2016年の終わりには、「Webが全てにやって来るぞ!」と書きました。
マイクロソフトSkypeをElectronで書き直したと聞いた時は、椅子から転げ落ちそうになりましたね。何だかんだ言いつつ、Node.jsは避け得ないものになってますし、Reactは凄い存在感で……ん?

はい。2017年はこのブログが何度も「DPCデータ分析」から脱線しまくった1年でした(白目

2018年はそろそろデータ分析に戻ります……うん、戻る、はず……
ただ、流石にネタ切れなので、ブログのタイトルは変えます。DPCデータ分析=>医療データ分析、くらいに風呂敷を広げるか、もうちょい広い(そしてテキトーな)タイトルにするかも知れません。
一応予定しているリストをば。

  • 時系列分析。本まで買ってますし、記事は書きます。ただ、理解するのにすごい苦労してますが…

  • Pythonをシェル代わりに使おう話。オライリーPython自動化本で、os.walkの使い方を読んだ時は目からウロコでした。

  • 事務仕事はPythonで片付けましょう講座。

結局、機械学習でDPCデータ分析をしよう!という抱負は生煮えで終わってしまったので、2018年こそは何か形にしたいですね。
何だかんだ、グダグダな2017年でありましたが、2018年はブログの名前も変えますし、色々方向を変えようと思っております。
それでは皆様、よいお年を。

ICD10を正規表現でパースする

またもやお久しぶりとなってしまいました… さて、今回のお題はICD10のパースです。以前、「I20$のような、I200~209を指定するケースはどうしよう?」という問題を記事にしました。その時は、ゴリ押しでI200~I209までを連番生成して済ませてます。
が、今回(実際にあった話ですが)、「I20$もしくは、I50$もしくは、I1$のどれかに当てはまる疾患を探してね!」という案件が参りました。うーん、どうしたもんでしょうか。

正規表現を使わざるを得ないとき

問題に直面したとき、ある人々はこう考える……「そうか、正規表現を使うんだ!」そして問題が2つに増える

インターネットには賢者の箴言がありますが、そうも言っていられません。
上記のような問題に出くわしたとき、正規表現ではI20[0-9]|I50[0-9]|I1[0-9]のように表記します。 |はor条件を意味しており、[0-9]は0から9の数字に当てはまるもの、という意味です。 上記ですと、正に「I20$もしくは、I50$もしくは、I1$のどれか」という分けですね。 まあ、実際にはI500だけではなく、I5000にも当てはまっちゃうので、本当にそれでいいのかと言われるとアレですが…(この辺は、ICDのコード体系におんぶに抱っこしてます)

例としてPythonで書くとこんな感じですね。

import re
pattern = r"I20[0-9]|I50[0-9]|I1[0-9]"
re.findall(pattern,"I209,I11,I300")

out: ['I209,'I11']

実務でICD10の抽出をするときは、患者単位であることが殆どです。
その場合、患者別にICDのリストを作るのか(例:['I209','I11','I300'])、複数のICDを連結して文字列にしてしまうか(例:"I209,I11,I300")は、ケースバイケースでしょう。
私が関わった案件では単純に連結してしまいましたが、リストのほうが扱いやすいケースもある筈です。

pandasで移動平均を出してみる

お久しぶりです。
ブログはサボってましたが、仕事はサボれず、色々やっていました。
現在、時系列データに取り組んでいますが、全く経験がないので四苦八苦してます。
単に推移を見るだけならプロットすればオシマイですが、突発的な変動は無視して、傾向を見たいとなると、移動平均というものを扱う必要が出てきます。

エクセルでどうやるのかは知りませんが、pandasなら簡単!

ということで、以下の通りすぐに出来ました。
移動平均は一定期間(例えば3ヶ月毎)の平均を、ずらしながら取っていくという数字です。 統計WEBに記事があります
wikipediaにも記事がありますが……
うーん、これ読むよりはいきなりグラフ描いたほうが分かりやすいかも…
なお、wikipediaで紹介されている指数加重移動平均もpandasに実装されています。
数式の理解はともかく、実際にはどっちも使ってみればいいんじゃないでしょうか。使うのは簡単だし。

Pandas rolling_mean & emma example