Python×医療事務(×トロント)

#医療 / #医療事務 / #IT / #トロント / #歯科助手 / #のんびり / #備忘録 / #趣味

今後の指標

傷病名マスター|社会保険診療報酬支払基金

 

医科電子点数表の活用手引き

https://www.ssk.or.jp/seikyushiharai/tensuhyo/ikashika/index.files/tensuhyo_01.pdf

 

レセプト電算処理システム
電子レセプトの作成手引き

https://www.ssk.or.jp/seikyushiharai/rezept/iryokikan/iryokikan_02.files/jiki_i01.pdf#search=電子カルテ

 

 

レセ電コード情報ファイル記録条件仕様      医科

https://www.ssk.or.jp/seikyushiharai/rezept/iryokikan/iryokikan_02.files/jiki_i01.pdf

 

www.kartemaker.com

 

オンライン又は光ディスク等による
請求に係る記録条件仕様(医科用)

https://www.mhlw.go.jp/seisakunitsuite/bunya/kenkou_iryou/iryouhoken/reseputo/pdf/kirokusiyou_1.pdf

 


個人情報消去集計ソフト

https://hodanren.doc-net.or.jp/asp/11manual.pdf

 

 

診療報酬情報提供サービス

医科診療行為マスター検索

診療報酬情報提供サービス

 

 

 

レセプト電算処理システム マスターファイル仕様説明書

https://shinryohoshu.mhlw.go.jp/shinryohoshu/file/spec/22rec.pdf

 

電子カルテチェッカーに良さげ

Reactで「CSV一括登録機能」 を開発した話 - Qiita

qiita.com

GitHub - old-stone/easy-rezept-viewer: 簡単なレセプトビューワー

erv.oldst.one

Google Cloud Platform  APIを使いOCR

Google Cloud Platformにアクセス

「無料トライアル」⇢Googleのアカウントでログイン⇢情報を入力⇢「同意して続行」⇢情報の入力

(このときにクレジット情報を求められる。住所や名前は適当に現存しないものでも認証される。しかし、クレジット情報はきちんと入力しないと次に進めない)

やむなくクレジット情報入力し登録。従量課金制と書いているのでビクビクしながらも登録

「無料トライアルを開始」

上の検索枠にてCloud Vision APIとCloud Natural Language を検索

f:id:chocolate22554:20210312211810p:plain

              ↓

f:id:chocolate22554:20210312211851p:plain

 

               ↓

f:id:chocolate22554:20210312211918p:plain

「有効にする」を選択  Natural Language APIも。

 

 

APIキーを取得

APIとサービス→認証情報

f:id:chocolate22554:20210312212109p:plain

→認証情報を作成→APIキーを選択

f:id:chocolate22554:20210312212150p:plain

         ↓

         ↓

f:id:chocolate22554:20210312212246p:plain

VisionAPI=画像内容を理解=画像分類、顔認識、テキストの検出Natural Language API=感情分析、カテゴリごとに分類し意味づけ

 

 

 

テキストエディタで下記コードを実装

import base64
import requests
import json

def ocr(image_file, api_key=""):
with open(image_file, 'rb') as image:
base64_image = base64.b64encode(image.read()).decode()

 

#<ocr関数内部で、受け取った画像ファイルを読み込み、base64エンコードを行っている>

url = 'https://vision.googleapis.com/v1/images:annotate?key={}'.format(api_key)
header = {'Content-Type': 'application/json'}
body = {
'requests': [{
'image': {
'content': base64_image,
},
'features': [{
'type': 'TEXT_DETECTION',
'maxResults': 1,
}]

}]
}

 

#変数body=パラメータを設定。'type'⇢TEXT_DETECTIONに。OCR(光学文字認識)以外にも、顔検出やラベル検出、不適切コンテンツ検出など可能。


response = requests.post(url, headers=header, json=body).json()
# jsonで吐き出し response
# fw = open('vision_response.json','w')
# json.dump(response,fw,indent=4)  #JSON形式にエンコード

APIキーとヘッダ情報を付与して、POSTでAPIを実行(リクエスト)

# print("responseの値は?" + str(response))  
text = response['responses'][0]['textAnnotations'][0]['description'] if len(response['responses'][0]) > 0 else ''
print("textの値は?" + str(text))
return text

# imgの画像ファイルのあるPATH↓
img = "/Users/Desktop/ocr/test.png"
key = "ここにGoogle Cloud PlatformのKeyを貼り付け"
data = ocr(img, key)
print(data)

 

今回は下記画像を 「img」と命名

f:id:chocolate22554:20210314103002p:plain

 

コマンドにて img画像と上記コードを記載したテキストがあるファイルに移動

f:id:chocolate22554:20210314103320p:plain

 

python  テキスト名(ここではAPIS)で実行

上手く読み取れた模様

f:id:chocolate22554:20210314103427p:plain

時々同じような手順でもPC開きっぱなしだと反応しないことがあるので再起動したところ出来た

 

 

カメラ映像から顔認識

https://aiacademy.jp/texts/show/?context=subject-images&id=426

 

カメラ映像から顔認識

カスケードファイルをダウンロード

ターミナルorコマンドにて

wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml

↓ダウンロードされた

f:id:chocolate22554:20210308204118p:plain

 

texteditorにて「カメラ映像で」というドキュメント名で上のxmlファイルもあるフォルダ内に作成

f:id:chocolate22554:20210308210220p:plain

 

 

import cv2


cascade_path = "/Users/cyberbrain/Desktop/haarcascade_frontalface_alt.xml"(# wgetコマンドでダウンロードしたカスケードファイルの絶対パスに変更)

cascade = cv2.CascadeClassifier(cascade_path)
color = (255, 255, 255) # 検出した顔を囲む矩形の色 (白色)

# VideoCapture オブジェクトを取得
cap = cv2.VideoCapture(0)

while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rect = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30))

if len(rect) > 0:
for x, y, w, h in rect:
cv2.rectangle(frame, (x, y), (x+w, y+h), color)

cv2.imshow('video capture', frame)
# 1ミリ秒待機
k = cv2.waitKey(1)
# ESCキーで終了
if k == 27:
break

cap.release() # 動画ファイル閉じる。(キャプチャデバイスを終了。)
cv2.destroyAllWindows()

 

上記のプログラムを  コマンドorターミナルにて実行
この場合 python 顔認識  で実行
 
カメラが起動

f:id:chocolate22554:20210308210335p:plain

常時許可していないとこのようなものが出るためエラーが出る

f:id:chocolate22554:20210308210438p:plain

 
許可しない  でなく  ok を押して許可
再度チャレンジ!
 
進んだ

f:id:chocolate22554:20210308210721p:plain

しかし暗いからか同じ文章が永遠に出る

f:id:chocolate22554:20210308210757p:plain

解決策↓

QtとOpenCVの両方をインストールするとエラーが発生する[Python] n++

 

ターミナル or コマンドにて

  opencv-python をアンインストール

pip uninstall -y opencv-python

 

f:id:chocolate22554:20210308213602p:plain

ターミナル or コマンドにて
GUI機能を含まない、OpenCVのヘッドレス版をインストール
pip install opencv-python-headless

f:id:chocolate22554:20210308213704p:plain

 
テキストエディタで記載していた下記コードを
ターミナル or コマンドにて
python  カメラ映像で    にて実行! 
 

import cv2


cascade_path = "/Users/cyberbrain/Desktop/haarcascade_frontalface_alt.xml"(# wgetコマンドでダウンロードしたカスケードファイルの絶対パスに変更)

cascade = cv2.CascadeClassifier(cascade_path)
color = (255, 255, 255) # 検出した顔を囲む矩形の色 (白色)

# VideoCapture オブジェクトを取得
cap = cv2.VideoCapture(0)

while True:
ret, frame = cap.read()
gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
rect = cascade.detectMultiScale(gray, scaleFactor=1.1, minNeighbors=2, minSize=(30, 30))

if len(rect) > 0:
for x, y, w, h in rect:
cv2.rectangle(frame, (x, y), (x+w, y+h), color)

cv2.imshow('video capture', frame)
# 1ミリ秒待機
k = cv2.waitKey(1)
# ESCキーで終了
if k == 27:
break

cap.release() # 動画ファイル閉じます。(キャプチャデバイスを終了させます。)
cv2.destroyAllWindows()

 

 

カメラが起動

自分の顔が写り自分の顔が認識され四角い枠に囲まれた

 

 

 

 

 

今度は応用して 色々してみたい↓

 

iPhoneでバーコードリーダーでISBNを読み取ってサーバーに送る - argius note

 

Hello Absurd World! pythonでバーコードリーダーの導入(import zbar on python2.6)

 

 

OpenCVによる顔認識

https://aiacademy.jp/texts/show/?id=135&context=subject-images

 

コマンドorターミナルにて

python

 

>>>  が出てきたら

 

import cv2  と打つ

 

exit()で終了

 

対象の画像を予め 「 test.jpg」で対象フォルダに保存しておく

f:id:chocolate22554:20210307201607p:plain

私の場合このようなフォルダ名をつけた

f:id:chocolate22554:20210307201700p:plain



そして下記を実行しようとしたが出来ない

wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml

 

 

qiita.com

コマンドorターミナル にて

install wget

 

 

f:id:chocolate22554:20210307195135p:plain

⇑上では無理だった

 

エラー内容は下記↓

f:id:chocolate22554:20210307195746p:plain

 

↓こちらでチャレンジ

Mac - wgetコマンドをインストール(使えるようにする) - 開発メモ - Webkaru

コマンドorターミナル にて

brew install wget

 

↓Homebrewのアップデートが何故か始まった・・

f:id:chocolate22554:20210307195926p:plain

 

↓errorが出ている気もするがアップデートが来ていた?ようでアップデート&ダウンロードが始まった

f:id:chocolate22554:20210307200027p:plain

f:id:chocolate22554:20210307200042p:plain

 

xmlファイルのダウンロード

コマンドorターミナル にて実行

wget https://raw.githubusercontent.com/opencv/opencv/master/data/haarcascades/haarcascade_frontalface_alt.xml

 

f:id:chocolate22554:20210307201501p:plain

 

今度は成功! Homebrewのアップデートがされていなかったからの模様?

 

顔認識プログラムの実行

text editorにて下記コードを作成

 

import cv2

# カスケードパスは各々のパスに必ず変更してください。
# 次のxmlファイルを探してそのファイルがあるパスを指定してください。 haarcascade_frontalface_alt.xml
# cascade_path = "/Users/cyberbrain/Desktop/haarcascade_frontalface_alt.xml"
# cascade_path = "/usr/local/opt/opencv/share/OpenCV/haarcascades/haarcascade_frontalface_alt.xml"

# Google Colabで実行の場合
cascade_path = './haarcascade_frontalface_alt.xml'

image_path = "test.jpg"
color = (255, 255, 255) # 白

#ファイル読み込み
image = cv2.imread(image_path)
#グレースケール変換
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)


#カスケード分類器の特徴量を取得する
cascade = cv2.CascadeClassifier(cascade_path)
# 顔認識の実行
facerect = cascade.detectMultiScale(image_gray, scaleFactor=1.1, minNeighbors=1, minSize=(1, 1))

print("face rectangle")
print(facerect) # 検出した顔の座標の出力

if len(facerect) > 0:
#検出した顔を囲む矩形の作成
for rect in facerect:
# thicknessは 線や円などの太さです。デフォルト値は1ですが、値を大きくする事で太くなります。
# 例えば円などの図形に対し -1 が指定された場合,そのオブジェクトは塗りつぶされます。
cv2.rectangle(image, tuple(rect[0:2]),tuple(rect[0:2]+rect[2:4]), color, thickness=2)
# 下記のコードと同じ意味です。
# cv2.rectangle(image, (186, 98),(280, 192),(255,255,255), thickness=2)

#認識結果の保存
cv2.imwrite("detected.jpg", image)

 

 

======

 

 

今回 「kao」というドキュメント?名にした

コマンドorターミナル にて  「python  kao 」と実行

f:id:chocolate22554:20210307202050p:plain

フォルダに「detected.jpg」という名前で保存され 顔部分が□で囲まれている

f:id:chocolate22554:20210307202135p:plain

 

 

株価予測の基礎 RNN/LSTMによる時系列データ

 

https://aiacademy.jp/texts/show/?context=subject-nn_deep&id=48

 

 

①sin波の計算及びsin波にノイズをのせる

Sin波=正弦波

 

f:id:chocolate22554:20210304165705p:plain

https://www.google.com/url?sa=t&rct=j&q=&esrc=s&source=web&cd=&cad=rja&uact=8&ved=2ahUKEwjFgZjClJbvAhXYc3AKHXmeD1kQFjABegQIAhAD&url=http%3A%2F%2Fwww.wakariyasui.sakura.ne.jp%2Fp%2Fwave%2Fhadou%2Fseigennha.html&usg=AOvVaw0HgKEciI6DI1KFMg5mKm9u    など

# パラメータの定義
random.seed(0)
# 乱数の係数
random_factor = 0.05
# サイクルあたりのステップ数
steps_per_cycle = 80
# 生成するサイクル数
number_of_cycles = 50
# 入力の長さ
length_of_sequences = 100
# 入力値・出力値の次元の大きさ
in_out_neurons = 1
# 隠れ要素のニューロン
hidden_neurons = 300

 

乱数セットの設定

 

# 乱数のシード値固定
random.seed(0)

 

0であれば0、100であれば100の乱数が生成



0から4000までのsinの各値を入れる箱(セル)を作成

np_ary = np.arange(steps_per_cycle<サイクルあたりのステップ数> * number_of_cycles <サイクル数>+ 1)  <=4000個のデータ>
df = pd.DataFrame(np_ary, columns=["x"]<カラム名(列名)>)

 

作ったデータフレームの箱(セル)の中にsinのステップ数に応じたデータを入力

 

pi_t <円をsteps_per_cycleで分割した値>

= 2 * math.pi / steps_per_cycle

df["sin(x)"]  <←pandasのカラムを事前に作らずとも指定>

= df.x.apply <←データフレームのカラム「x」の各セルを()の中に入力する>(lambda t:<←入力されるtを:から定義している> 

sinθのθの中にこれらの値+ノイズ>

math.sin(t * pi_t +

random.uniform(-1.0, +1.0) <小数点を含むA(-1.0)以上B(+1.0)以下の乱数を生成>

* random_factor<ノイズの大きさを調整>))

 

 

作ったデータフレームをグラフに出力

df"sin(x)".head(steps_per_cycle * 2<sinの2周期分のsin波のデータを取得> ).plot()<その値をグラフに>
plt.show()

f:id:chocolate22554:20210304180115p:plain

 

②入力データ及び正解データそれぞれのリストを作成する。

データを学習モデルに入れられる形にする

正解データの作成

def Input_Ans_Extract(data, input_num = 100):

# 空リスト作成
InputList, AnsList = ,

 

# 0から(len(data)- input_num)だけの整数が配列としてある
for i in range(len(data) - input_num):#3501個のデータ分

 

#doc配列にi個目からi+100番目のデータを行列の形にして入れていく
# InputData = data.iloc[i:i+input_num].as_matrix()#3501~3601
InputData = data.iloc[i:i+input_num].values#3501~3601

 

# AnsData = data.iloc[i+input_num].as_matrix()
AnsData = data.iloc[i+input_num].values
InputList.append(InputData)
AnsList.append(AnsData)

 

# numpyで扱えるように行列をその形にして再定義
InputList_np = np.array(InputList)
AnsList_np = np.array(AnsList)
return InputList_np, AnsList_np

 

用意した空のリスト

f:id:chocolate22554:20210304180437p:plain

numpy形式の各行列データを入力

f:id:chocolate22554:20210304180611p:plain

values

を使うことでそのデータの形式をnumpyの行列に

 

 

③ データを学習用とテスト用に分ける。

def Data_Split(df, test_size=0.1<1割>, input_num = 100):
train_size = round<()中の値の小数点以下を四捨五入する関数>(len(df) * (1 - test_size<9割>))

#3601個

train_size = int(train_size)

#学習データは0-3601

Input_train, Ans_train = Input_Ans_Extract(df.iloc[0:train_size], input_num)
#テストデータは3601〜

Input_test, Ans_test = Input_Ans_Extract(df.iloc[train_size:], input_num)
return (Input_train, Ans_train), (Input_test, Ans_test)

 

 

(Input_train, Ans_train), (Input_test, Ans_test) = Data_Split(df"sin(x)", input_num = length_of_sequences)

 

 

④学習モデルの構築及び学習を実行する

model = Sequential()
model.add(LSTM(hidden_neurons, batch_input_shape=(None<Noneとすることで値を指定せず、任意の数でバッチサイズをきめることができる> , length_of_sequences, in_out_neurons<出力の数>), return_sequences=False))
# 一つの入力で100のリスト

 

# 入力値の個数に対して1つの出力
model.add(Dense(in_out_neurons))


# 活性化関数linear
model.add(Activation("linear"))


# コンパイル
model.compile<書き上げたモデルを構築>(loss="mean_squared_error<誤差逆順伝番法>", optimizer="rmsprop"<勾配法の一種>)

 

#fitの中にも学習と検証データが必要

model.fit<学習アルゴリズムを指定>(Input_train<入力リスト>, Ans_train<正解リスト><=学習を実行>, batch_size=60<一回の学習に60個のデータセット, epochs=3, validation_split=0.05<全データの内0.05(5%)が検証用>)

 


# model.fit(Input_train, Ans_train, batch_size=60, nb_epoch=3<学習データを使い切る回数>, validation_split=0.05)


predicted = model.predict(Input_test) 

 

手順②からのコードで実行 下記出現↓

f:id:chocolate22554:20210304183626p:plain

↓完了

f:id:chocolate22554:20210304183811p:plain

モデルの保存

学習した後にモデルを保存しておく事で、読み込んで使う事が出来る
 

 

モデルの読み込み

kerasで作成したモデルを読み込む

 

from keras.models import model_from_json
modelname = input("モデルファイル = 「model.json」")
paramname = input("学習ファイル = 「weights.hdf5」")
json_string = open(modelname).read()
model = model_from_json(json_string)
model.load_weights(paramname)

# predicted = model.predict(Input_test)

 

 

 

⑤学習を終えたモデルをテストし、そのテスト結果を表示する

 

↓実行!

dataf = pd.DataFrame(predicted[:200])
dataf.columns = ["predict"]
dataf.plot()
dataf["answer"] = Ans_test[:200]
dataf.plot()
plt.show()

 

 

ノイズが消え、ほぼsin波と同じ形状のグラフ

sin波の 動き をうまく学習

f:id:chocolate22554:20210304184045p:plain

 

 

 

すべてのコード↓

import pandas as pd
import numpy as np
import math
import random
from keras.models import Sequential
from keras.layers.core import Dense, Activation
from keras.layers.recurrent import LSTM
import matplotlib.pyplot as plt
# 警告文の非表示
import warnings
warnings.simplefilter('ignore')
# パラメータの定義
random.seed(0)
# 乱数の係数
random_factor = 0.05
# サイクルあたりのステップ数
steps_per_cycle = 80
# 生成するサイクル数
number_of_cycles = 50
# 入力の長さ
length_of_sequences = 100
# 入力値・出力値の次元の大きさ
in_out_neurons = 1
# 隠れ要素のニューロン
hidden_neurons = 300
# 乱数のシード値固定
random.seed(0)

np_ary = np.arange(steps_per_cycle * number_of_cycles + 1)
df = pd.DataFrame(np_ary, columns=["x"])
pi_t = 2 * math.pi / steps_per_cycle
df["sin(x)"] = df.x.apply(lambda t: math.sin(t * pi_t + random.uniform(-1.0, +1.0) * random_factor))
df[["sin(x)"]].head(steps_per_cycle * 2).plot()
plt.show()


def Input_Ans_Extract(data, input_num = 100):
# 空リスト作成
InputList, AnsList = ,
# 0から(len(data)- input_num)だけの整数が配列としてある
for i in range(len(data) - input_num):#3501個のデータ分
#doc配列にi個目からi+100番目のデータを行列の形にして入れていく
# InputData = data.iloc[i:i+input_num].as_matrix()#3501~3601
InputData = data.iloc[i:i+input_num].values#3501~3601
# AnsData = data.iloc[i+input_num].as_matrix()
AnsData = data.iloc[i+input_num].values
InputList.append(InputData)
AnsList.append(AnsData)
# numpyで扱えるように行列をその形にして再定義
InputList_np = np.array(InputList)
AnsList_np = np.array(AnsList)
return InputList_np, AnsList_np

def Data_Split(df, test_size=0.1, input_num = 100):
train_size = round(len(df) * (1 - test_size))#3601個
train_size = int(train_size)
#学習データは0-3601
Input_train, Ans_train = Input_Ans_Extract(df.iloc[0:train_size], input_num)
#テストデータは3601〜
Input_test, Ans_test = Input_Ans_Extract(df.iloc[train_size:], input_num)
return (Input_train, Ans_train), (Input_test, Ans_test)

(Input_train, Ans_train), (Input_test, Ans_test) = Data_Split(df[["sin(x)"]], input_num = length_of_sequences)



model = Sequential()
model.add(LSTM(hidden_neurons, batch_input_shape=(None, length_of_sequences, in_out_neurons), return_sequences=False))
# Noneとすることで値を指定せず、任意の数でバッチサイズをきめることができる
# 一つの入力で100のリスト
#in_out_neuronsは出力の数

# 入力値の個数に対して1つの出力
model.add(Dense(in_out_neurons))
# 活性化関数linear
model.add(Activation("linear"))
model.compile(loss="mean_squared_error", optimizer="rmsprop")

model.fit(Input_train, Ans_train, batch_size=60, epochs=3, validation_split=0.05)
# model.fit(Input_train, Ans_train, batch_size=60, nb_epoch=3, validation_split=0.05)
predicted = model.predict(Input_test)


json_string = model.to_json()
open('model.json', 'w').write(json_string)
model.save_weights('weights.hdf5')


dataf = pd.DataFrame(predicted[:200])
dataf.columns = ["predict"]
dataf.plot()
dataf["answer"] = Ans_test[:200]
dataf.plot()
plt.show()