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

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

レセ電パーサー:破壊的更新を実施しました

こんばんは、スタゲイラです。
今回はレセ電パーサーに破壊的変更を加えました。

github.com

具体的には、患者IDを指定した際の挙動を変えています。
今まではレセオブジェクトを返していましたが、今回からレセオブジェクトのリストを返すようになりました。
こちら、実務で使っていたら『同一患者に複数のレセがある』ケースがあることに今さら気付き、安直に修正した結果となります。
そりゃ、同月に入外受診したり、DPCと出来高が混ざったりすれば、そうなりますよね……

さて、実務でレセ電パーサーを使っていれば、当然分析に応用したくなります。
そこで、レセ電ファイルからデータを抽出するユーティリティを開発中です。
こちらは『点数や食事だけ抽出』とか、『診療行為をリスト化する』とかを考えています。
PandasのDataFrameで吐き出す仕様にしようかなー、と考え中ですので、のんびりお待ちください。

お久しぶりです。レセ電パーサを更新しました

こんばんは、スタゲイラです。
はい、まる2年にわたってブログを放置していました……!  申し開きようもございません。部署異動もあり、医療実務から離れていたら、すっかりモチベーションが続かなくなっていました。
しかし、最近になってDPCデータやレセ電データをいじくる機会もありまして、リハビリがてら再開しようと思います。

まずはレセ電パーサの更新をしてみました。

github.com

以前はデータ行数によってディクショナリが返るか、ディクショナリのリストが返るか、挙動が変わっていました。
自分で使ってみてひどい仕様だと反省し、一貫してディクショナリのリストが返る仕様に変更してます。すみませんでした……

さて、今後なのですが、そろそろDPCデータ分析の基盤を見直すかなーと思っています。
今まで本ブログでは、「Python環境がなくても動く分析ツールを!」という目標を掲げ、Scalaをいじってみたり、PowerShellを書いてみたり、色々迷走していました。
が、どう考えても労力に割に合いませんし、私みたいな一介の事務員がJavaScript + Electronでアプリでっち上げるのも、無理があります。
(いや、書きましたけど、続けられません!/苦笑)

ということで、Pythonを中心に、というかほぼPythonオンリーで環境構築することにします。
今までDPCデータのDB投入も、PostgreSQLのインポートツール使ったりしてましたが、Python経由で投入することにします。
次回以降、色々書いていこうと思いますので、お使い頂ければ幸いです。

Facebookの「Prophet」を使った時系列予測

前の記事から大分時間が空いてしまって、すみません。
私事ですが、転勤などあって、ドタバタしていました。

さて、今日の話題は時系列予測です。
時系列予測を行うには、以下のような方法が挙げられます。

  1. Excel2016の新機能、「予測シート」を使う
  2. Power BIの予測機能を使う
  3. RかPythonで頑張る

さて、1番と2番については、どちらも「指数平滑法」というアルゴリズムを使っています。
3は色々方法がありますが、有名なのはRのforecastパッケージと、pythonstatsmodels.tsaでしょう。
これらの方法には、色々メリットがありますが、今日紹介するのは時系列予測界隈のニューフェイスfacebook製作のProphetライブラリです。

Prophet、素人のための時系列予測ライブラリ

facebook.github.io

煽りっぽい書き方ですが、facebookのページには、時系列予測を扱えるユーザーを広げようと書いてあります。
Prophetのモットー、'Forecasting at scale'とは、ビッグデータを扱おうという意味ではなく、時系列予測を行える人間を増やそうという意味です。
実際、Prophetは使い方にクセがありますが、かなり使いやすいライブラリです。ユーザーが指定しなければならないパラメータを、極力減らしています。

まず、以下のようなデータフレームを用意します。 そう、Pandasのデータフレームを使うことが前提です。

y ds cap
112 1949-01-01 1000
118 1949-02-01 1000
132 1949-03-01 1000
129 1949-04-01 1000
121 1949-05-01 1000

さらに注意すべきは、

  • 予測したい数値はyというカラムに入れる
  • 日付データはdsというカラムに入れる

と、カラム名まで決めうちになっていることです。 こんな風に、データフレームを使うだけではなく、カラム名まで決めうちにするライブラリは珍しいですね。

また、Prophetは「上限値」を設定することが出来ます。capというカラムに指定してください。

from fbprophet import Prophet

m = Prophet(growth='logistic')
m.fit(df)

まず、モデルのインスタンスを作成し、fitメソッドでデータを食わせます。scikit-learnでよく見るスタイルですね。
また、上限値を設定する場合は必ずlogisticモデルを選択しなければいけません。
ちなみに、growthパラメータは'logistic'と'linear'の2択ですので、迷ったら両方試せば良いでしょう。

続いて、未来予測を行います。どれくらいの期間予測するのか設定しましょう。
statsmodelsではパラメータにより予測期間を設定しますが、Prophetでは未来のデータを収めるデータフレームを作ります。
これもかなり特異な部分ですが、ヘルパーメソッドが用意されているので、大して複雑ではありません。

future = m.make_future_dataframe(periods=36,freq='M')
future['cap'] = 1000
forecast = m.predict(future)

今回のデータは月次データなので、freq='M'を指定しました。periods=36となっているので、36ヶ月分のデータを予測することになります。
今回は上限値を設定したいので、futureデータフレームにもcapカラムを用意しています。
なお、capは定数でなくても構いません。 ある時期を境に、上限値が変わることが分かっているなら、そのように設定すれば、モデルはそれを元に予測を行います。賢い!
さて、こうして作られたforecast変数は、予測値の他、トレンドや季節性、信頼区間などのデータが入ったデータフレームです。
データフレームの中身を見てもいいですし、手っ取り早くplotメソッドで可視化も出来ます。

m.plot(forecast)

f:id:stagira:20180623222522p:plain

f:id:stagira:20180623222522p:plain
Prophetで予測を行った結果

結果は上のようになります。上の点線が、設定した上限値です。
あっけないほど簡単に時系列予測が出来てしまいました。
まあ、実際には上限値の設定により予測値が大きくブレることもあったり、注意が必要ですが、かなりお手軽に使えるライブラリです。
Python界隈では、Rのforecastパッケージのような、扱いやすい予測ライブラリがありませんでした。Prophetはかなりいい位置にあるのではないでしょうか。
本家ドキュメントでは、クリスマスのように数値が跳ね上がる瞬間を、上手に扱う方法も紹介されています。極めてビジネス寄りの思想で作られたライブラリですね。

全自動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日かけて突貫で書き上げました。 (ファイル仕様を書き出すのと、サンプルファイルの修正が一番大変でした……) 最低限の機能しか実装していませんので、これから色々拡張していきたいですね。
具体的には、各レセプトごとの情報を統合して見やすく表示する機能とか、全体のサマリを表示する機能とか…