LEFT OUTER JOINの評価
LEFT OUTER JOINの評価
一瞬で終わる。メモリも食わない。
UNIQUE属性付けておくとさらに早い。
実施内容
データのテーブルと、クラス分け結果のテーブルのJoin。
クラス分け結果は適当に%演算で作った。
ソースコード
import sqlite3 from faker import Faker import random from datetime import datetime tic0 = datetime.now() con = sqlite3.connect(":memory:") con.isolation_level = None # None で自動コミットモード cur = con.cursor() cur.execute('PRAGMA temp_store=MEMORY;') cur.execute('PRAGMA journal_mode=MEMORY;') #cur.execute('PRAGMA rock_mode=OFF;') listsize = 100000 classsize= 128 sql_create_data = "CREATE TABLE data(number INTEGER UNIQUE, name TEXT, score REAL)" sql_create_class = "CREATE TABLE class(number INTEGER UNIQUE, label INTEGER)" sql_instert_data = "INSERT INTO data VALUES(?,?,?)" sql_instert_class = "INSERT INTO class VALUES(?,?)" sql_select_join = "SELECT data.number, data.name, data.score, class.label FROM data LEFT OUTER JOIN class ON data.number = class.number" sql_select_join_cl1 = "SELECT data.number, data.name, data.score, class.label FROM data LEFT OUTER JOIN class ON data.number = class.number WHERE class.label = 1 " #list_data = [[None] for i in range(listsize)] list_data = [None] * listsize list_class = [None] * listsize fake = Faker() print("データ準備 開始") for i in range(listsize): list_data[i] = [i, fake.name(), random.random()] list_class[i] = [i, i%classsize] print("データ準備 完了") cur.execute(sql_create_data) cur.execute(sql_create_class) print("テーブルの定義を表示") table_defs = cur.execute("SELECT * FROM sqlite_master WHERE type='table'") for item in table_defs: print(item) print("データの挿入") cur.executemany(sql_instert_data, list_data) cur.executemany(sql_instert_class, list_class) # ここからjoin時間計測 tic = datetime.now() cur.execute(sql_select_join) toc = datetime.now() print("テーブルの中身を表示") print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print("classが1のテーブルの中身を表示") cur.execute(sql_select_join_cl1) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print("join {0}件 処理時間 {1}".format(listsize, toc-tic)) print("全体処理時間 {0}件 処理時間 {1}".format(listsize, datetime.now()-tic0)) con.close()
結果
(base) C:\dev\SampleCodes\hello_sqlite>python outerjoin.py データ準備 開始 データ準備 完了 テーブルの定義を表示 ('table', 'data', 'data', 2, 'CREATE TABLE data(number INTEGER UNIQUE, name TEXT, score REAL)') ('table', 'class', 'class', 4, 'CREATE TABLE class(number INTEGER UNIQUE, label INTEGER)') データの挿入 テーブルの中身を表示 (0, 'Troy Wagner', 0.44436625795068907, 0) (1, 'Lee Robertson', 0.8527352596455694, 1) (2, 'Mark Franco', 0.9942993187450221, 2) (3, 'Joel Sandoval', 0.9462360044917911, 3) (4, 'Katherine Ho', 0.6177953257612685, 4) (5, 'Shannon Adams', 0.6044842942129696, 5) (6, 'Jacob Wong', 0.4513990366427033, 6) (7, 'Howard Bennett', 0.6643356684420646, 7) (8, 'Scott Mitchell', 0.5792325135939987, 8) (9, 'Joshua Tyler', 0.4882390253804837, 9) (10, 'Steven Day', 0.03463822764171387, 10) (11, 'Heather Hughes', 0.888992343863056, 11) (12, 'Margaret Thomas DDS', 0.402020535579534, 12) (13, 'David Rosario', 0.8354810420435498, 13) classが1のテーブルの中身を表示 (1, 'Lee Robertson', 0.8527352596455694, 1) (129, 'April Pittman', 0.48442848761646606, 1) (257, 'Mercedes Gallagher', 0.9811398290695581, 1) (385, 'Xavier Harvey', 0.39333389385880146, 1) (513, 'Laura Powell', 0.11691465694144565, 1) (641, 'Mrs. Lori Gibbs MD', 0.13424141037411286, 1) (769, 'Christina Jacobson', 0.7144345369983663, 1) (897, 'Gregory Lowe', 0.2939644032693347, 1) (1025, 'Michael Santos', 0.9319930754332403, 1) (1153, 'Olivia Montgomery', 0.3756360549631732, 1) (1281, 'Joseph Eaton', 0.7451317465818261, 1) (1409, 'Julia Adams', 0.5858535015316725, 1) (1537, 'George Kelley', 0.12250922691704258, 1) (1665, 'Patricia Johnson DVM', 0.09949616494939173, 1) join 100000件 処理時間 0:00:00 全体処理時間 100000件 処理時間 0:00:14.371519
Neural Network ConsoleのCrossEntropy損失関数(ロス関数)の使い方
Neural Network Consoleの損失関数(ロス関数)の使い方の記録。
画像処理系はSquareErrorでもいいが、カテゴリ系はそんなわけにもいかないので。
入力データ次第で、ある程度決まった形になるので、記録として残しておく。
CategoricalCrossEntropyを使う場合
ラベルは、複数値のカテゴリインデックス。1列。
affineで適当な列数に変換した後、softmax -> CategoricalCrossEntropy
BinaryCrossEntropyを使う場合
ラベルは1か0の2値。
OneHot形式の2列の場合、affineで2列に変換した後、softmax -> BinaryCrossEntropy
1列の0/1の場合、affineで1列に変換した後、sigmoid(softmaxからsigmoidに訂正) -> BinaryCrossEntropy
補足
参考資料。softmaxではなくsigmoidの例。
レイヤーの層を単純に深くしても、精度は向上しないことを確認する/Neural Network Consoleの使い方 - "BOKU"のITな日常
sqlite3のexecutemanyの動作確認
1回で10万件を挿入するのに、0.35秒。
別実行した1件ソートの繰り返しでは0.42秒。大した差ではないが、ループを組まなくていいメリットあり。
値を埋めたいところは、"INSERT INTO users VALUES(?,?,?)" のようにハテナにしておく。
リストのリストや、タプルのリストにしておけば、全件Insertしてくれるようす。
プログラム
import sqlite3 from faker import Faker import random from datetime import datetime con = sqlite3.connect(":memory:") con.isolation_level = None # None で自動コミットモード cur = con.cursor() cur.execute('PRAGMA temp_store=MEMORY;') cur.execute('PRAGMA journal_mode=MEMORY;') listsize = 100000 sql_create = "CREATE TABLE users(number INTEGER, name TEXT, score REAL)" sql_instert = "INSERT INTO users VALUES(?,?,?)" sql_select = "SELECT number,name,score FROM users ORDER BY number LIMIT 3" sql_select_last = "SELECT number,name,score FROM users ORDER BY number LIMIT 3 OFFSET {0}".format(listsize-3) list1 = [None] * listsize fake = Faker() print("データ準備 開始") for i in range(listsize): list1[i] = [i, fake.name(), random.random()] print("データ準備 完了") cur.execute(sql_create) print("テーブルの定義を表示") tmp = cur.execute("SELECT * FROM sqlite_master WHERE type='table'").fetchall() print(tmp) # ここからexecutemany時間計測 tic = datetime.now() print("データの挿入") cur.executemany(sql_instert, list1) # executemany時間計測終わり toc = datetime.now() cur.execute(sql_select) print("テーブルの中身を表示") print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print() cur.execute(sql_select_last) print(cur.fetchone()) print(cur.fetchone()) print(cur.fetchone()) print() print("executemany {0}件 処理時間 {1}".format(listsize, toc-tic)) con.close()
実行結果
(base) C:\dev\SampleCodes\hello_sqlite>python execmeny.py データ準備 開始 データ準備 完了 テーブルの定義を表示 [('table', 'users', 'users', 2, 'CREATE TABLE users(number INTEGER, name TEXT, score REAL)')] データの挿入 テーブルの中身を表示 (0, 'Dawn West', 0.5244752623689407) (1, 'Marvin Chambers', 0.8354440852719125) (2, 'Clinton Lowe', 0.4116042084368037) (99997, 'Aaron Conley', 0.795391969430207) (99998, 'Alyssa Brooks', 0.17316654138026266) (99999, 'Marisa Peterson', 0.018786705346994004) executemany 100000件 処理時間 0:00:00.350097
sqlite3とpandasの連動確認
やっていること
0. sqliteのDB(インメモリ)の用意
1. データ準備
2. sqliteのDB(インメモリ)に書き込み
3. sqliteのDB(インメモリ)のテーブル定義を確認
4. sqliteのDB(インメモリ)のテーブルの内容を確認 ORDER BY numberでソート。
5. fillnaでNaN値を補完
6. ソートしなおして、NaNを補完した値で、sqliteに書き込み&内容確認
ソースコード
import sqlite3 import pandas as pd con = sqlite3.connect(":memory:") con.isolation_level = None # None で自動コミットモード cur = con.cursor() cur.execute('PRAGMA temp_store=MEMORY;') cur.execute('PRAGMA journal_mode=MEMORY;') list1 = [[1, 'alpha', 10.0], [2, 'Bravo', None], [3, 'Charlie', 8.5], [5, 'Echo', 9.8], [4, 'Delta', 3.6]] #list1 = [[1,'alpha', 10],[2,'Bravo', None],[3,'Charlie', 8], [5,'Foxtrot', 9],[None,'Echo', 3]] #list1 = [[1,'alpha', 10],[2,'Bravo', 7],[3,'Charlie', 8], [5,'Foxtrot', 9],[4,'Echo', 3]] df1 = pd.DataFrame(list1, columns=['number', 'name', 'score']) print(df1) print(df1.dtypes) # sqliteに書き込み df1.to_sql(name='users', con=con, index=False, schema='number INTEGER, name TEXT, score REAL') tmp = cur.execute("SELECT * FROM users").fetchall() print(tmp) # schemaに'number TEXT, name TEXT, score REAL'を指定しても、 # 'number TEXT, name TEXT, score REAL'になるので、dataframeの設定が優先される様子。 # 値にNoneがあると、INTEGERではなくREALになる。 tmp = cur.execute("SELECT * FROM sqlite_master WHERE type='table'").fetchall() print(tmp) # read_sql_table only supported for SQLAlchemy connectable. df2 = pd.read_sql(sql='SELECT * FROM users ORDER BY number', con=con) # df3.to_sql(・・・,if_exists="replace")を実行したとき、 # pandas.io.sql.DatabaseError: Execution failed on sql 'DROP TABLE "users"': database table is locked # になることがある。再実行するか、curを閉じるとよい。 print(df2) print(df2.dtypes) df3 = df2.fillna(method="ffill") print(df3) df3.to_sql(name='users', con=con, index=False, schema='number INTEGER, name TEXT, score REAL', if_exists="replace") tmp = cur.execute("SELECT * FROM users").fetchall() cur.close() print(tmp) con.close()
実行結果
number name score 0 1 alpha 10.0 1 2 Bravo NaN 2 3 Charlie 8.5 3 5 Echo 9.8 4 4 Delta 3.6 number int64 name object score float64 dtype: object [(1, 'alpha', 10.0), (2, 'Bravo', None), (3, 'Charlie', 8.5), (5, 'Echo', 9.8), (4, 'Delta', 3.6)] [('table', 'users', 'users', 2, 'CREATE TABLE "users" (\n"number" INTEGER,\n "name" TEXT,\n "score" REAL\n)')] number name score 0 1 alpha 10.0 1 2 Bravo NaN 2 3 Charlie 8.5 3 4 Delta 3.6 4 5 Echo 9.8 number int64 name object score float64 dtype: object number name score 0 1 alpha 10.0 1 2 Bravo 10.0 2 3 Charlie 8.5 3 4 Delta 3.6 4 5 Echo 9.8 [(1, 'alpha', 10.0), (2, 'Bravo', 10.0), (3, 'Charlie', 8.5), (4, 'Delta', 3.6), (5, 'Echo', 9.8)]
可変引数のテスト**kwargs
可変引数のテスト
プログラム
def func1(**kwargs): print(kwargs) # キーに一致する値の取得。キーがない場合はNoneになる。 print(kwargs.get("a")) print(kwargs.get("b")) print(kwargs.get("c")) print(kwargs.get("key1")) print(kwargs.get("key2")) print(kwargs.get("key3")) print("func1(key1=1, key2=2)の場合") func1(key1=1, key2=2) # 辞書を引数として渡せる print("func1(**dict1)の場合") dict1 = {"a": 1, "b": "bb"} func1(**dict1)
実行結果
func1(key1=1, key2=2)の場合 {'key1': 1, 'key2': 2} None None None 1 2 None func1(**dict1)の場合 {'a': 1, 'b': 'bb'} 1 bb None None None None
pythonでyamlファイルの読み込み(コンフィグファイルとして)
yamlに書いた内容が、文字列や数値がその型で取得できる。
辞書型と、リストにはいった辞書のyamlの書き方を追記。
import yaml import os import pprint # yamlファイルは、このhello_yaml.pyと同じディレクトリにある想定 default_yaml_filename = "config.yaml" class config(): def __init__(self): self.foo = None self.bar = None self.hoge = None self.piyo = None self.dics = None self.dics_list=None self.default_yaml_fullpath = os.path.dirname( os.path.abspath(__file__)) + os.sep + default_yaml_filename self.load() def load(self): try: # 念のため絶対パスでアクセス with open(self.default_yaml_fullpath,"r",encoding="utf-8") as f: y = yaml.load(stream=f, Loader=yaml.SafeLoader) self.foo = y.get("foo") self.bar = y.get("bar") self.hoge = y.get("hoge") self.piyo = y.get("piyo") self.dics = y.get("dics") self.dics_list = y.get("dics_list") except: print("error", self.default_yaml_fullpath) raise config = config() print("config.foo: {0} {1}".format(config.foo, type(config.foo))) print("config.bar: {0} {1}".format(config.bar, type(config.bar))) print("config.hoge: {0} {1}".format(config.hoge, type(config.hoge))) print("config.piyo: {0} {1}".format(config.piyo, type(config.piyo))) print("config.dics: {0} {1}".format(config.dics, type(config.dics))) pprint.pprint(config.dics) print("config.dics_list: {0} {1}".format(config.dics_list, type(config.dics_list))) pprint.pprint(config.dics_list)
config.yamlファイル(ソースコードと同じディレクトリ)
foo: foo1 bar: 100 hoge: 3.14 piyo: - piyo1 - piyo2 - 100 - 3.14 dics: x: 100 y: 200 dics_list: - a: 1111 b: 2222 - c: 3333 d: 4444
実行結果
> >python hello_yaml.py config.foo: foo1 <class 'str'> config.bar: 100 <class 'int'> config.hoge: 3.14 <class 'float'> config.piyo: ['piyo1', 'piyo2', 100, 3.14] <class 'list'> config.dics: {'x': 100, 'y': 200} <class 'dict'> {'x': 100, 'y': 200} config.dics_list: [{'a': 1111, 'b': 2222}, {'c': 3333, 'd': 4444}] <class 'list'> [{'a': 1111, 'b': 2222}, {'c': 3333, 'd': 4444}]
補足
Loader指定のないyaml.load(f)は推奨されない。y = yaml.load(stream=f, Loader=yaml.SafeLoader)に変更。
C:\dev\SampleCodes\hello_yaml\hello_yaml.py:20: YAMLLoadWarning: calling yaml.load() without Loader=... is deprecated, as the default Loader is unsafe. Please read https://msg.pyyaml.org/load for full details. y = yaml.load(f)
Visual Studio Code & Anaconda環境構築
最近、VSCodeでPython環境を作るとデバッグ実行がうまくいかないことがあるので、試行錯誤のメモ。
path(ユーザーの環境変数)に以下を追加
C:\Users\<ユーザー名>\Anaconda3\Scripts
C:\Users\<ユーザー名>\Anaconda3\
anacondaの初期設定
「CommandNotFoundError: Your shell has not been properly configured to use 'conda activate'.」と言われたときは、「conda init」を実行してみるとよい。
(base) C:\Users\<ユーザー名>>conda init
no change C:\Users\<ユーザー名>\Anaconda3\Scripts\conda.exe
no change C:\Users\<ユーザー名>\Anaconda3\Scripts\conda-env.exe
no change C:\Users\<ユーザー名>\Anaconda3\Scripts\conda-script.py
no change C:\Users\<ユーザー名>\Anaconda3\Scripts\conda-env-script.py
no change C:\Users\<ユーザー名>\Anaconda3\condabin\conda.bat
no change C:\Users\<ユーザー名>\Anaconda3\Library\bin\conda.bat
no change C:\Users\<ユーザー名>\Anaconda3\condabin\_conda_activate.bat
no change C:\Users\<ユーザー名>\Anaconda3\condabin\rename_tmp.bat
no change C:\Users\<ユーザー名>\Anaconda3\condabin\conda_auto_activate.bat
no change C:\Users\<ユーザー名>\Anaconda3\condabin\conda_hook.bat
no change C:\Users\<ユーザー名>\Anaconda3\Scripts\activate.bat
no change C:\Users\<ユーザー名>\Anaconda3\condabin\activate.bat
no change C:\Users\<ユーザー名>\Anaconda3\condabin\deactivate.bat
modified C:\Users\<ユーザー名>\Anaconda3\Scripts\activate
modified C:\Users\<ユーザー名>\Anaconda3\Scripts\deactivate
modified C:\Users\<ユーザー名>\Anaconda3\etc\profile.d\conda.sh
modified C:\Users\<ユーザー名>\Anaconda3\etc\fish\conf.d\conda.fish
no change C:\Users\<ユーザー名>\Anaconda3\shell\condabin\Conda.psm1
modified C:\Users\<ユーザー名>\Anaconda3\shell\condabin\conda-hook.ps1
modified C:\Users\<ユーザー名>\Anaconda3\Lib\site-packages\xonsh\conda.xsh
modified C:\Users\<ユーザー名>\Anaconda3\etc\profile.d\conda.csh
modified C:\Users\<ユーザー名>\Documents\WindowsPowerShell\profile.ps1
modified HKEY_CURRENT_USER\Software\Microsoft\Command Processor\AutoRun
「Missing required dependencies ['numpy']」と言われたら以下。
ファイルのありか Python Extension Packages for Windows - Christoph Gohlke
参考サイトscipyが突然読み込まれなくなった話 - Qiita
pip install C:\Users\<ユーザー名>\Downloads\numpy-1.16.2+mkl-cp37-cp37m-win_amd64.whl
PowerShellを管理者として実行
Set-ExecutionPolicy -ExecutionPolicy RemoteSigned