liblinear の切片を忘れていませんか?
背景
liblinear の学習で、切片を忘れているのを見た。幸いプロダクトではない。
切片とは、英語で言うと intercept (知っとるわw)
このページを見に来た人は特に切片の説明自体はしなくてもよいと思う。どのように取得するのかは、
scikit-learn だと、
sklearn.linear_model.LogisticRegression — scikit-learn 0.19.0 documentation
Attributes という項目にあるので、忘れないように。
intercept_ : array, shape (1,) or (n_classes,) Intercept (a.k.a. bias) added to the decision function. If fit_intercept is set to False, the intercept is set to zero. intercept_ is of shape(1,) when the problem is binary.
とある。どのように使うかはいい例が見つからなかったので書かないが、切片の意味が分かっていれば特に必要ないと思う。
python ライブラリの gcloud(google.cloud) の storage の blob_name とは
背景
python ライブラリの gcloud(google.cloud) の storage の get_blob において、
とあるが、試してみると、google cloud storage 上の
gs://my-bucket
に、/path/to/blob.txt
は存在するのに、なぜか、 None
が返ってくる。ほえ?
blob_name
には 始めのスラッシュはいりません
すなわち、blob_name
は
path/to/blob.txt
ということです。だったらそのように例を(次のように)
>>> from google.cloud import storage >>> client = storage.Client() >>> bucket = client.get_bucket('my-bucket') >>> print(bucket.get_blob('path/to/blob.txt')) <Blob: my-bucket, path/to/blob.txt> >>> print(bucket.get_blob('does-not-exist.txt')) None
と書いてよ、と思う。
sklearn にて `class_weight` が `balanced` か「なし」の探索
背景
sklearn の GridSearchCV
はパラメータサーチに利用される。
sklearn.model_selection.GridSearchCV — scikit-learn 0.19.0 documentation
ところが、パラメータなし、の設定例はみつからない。
sklearn.linear_model.LogisticRegression — scikit-learn 0.19.0 documentation
には、dict か "balanced"
かと書いてある。
パラメータなしは、None
class_weight
が balanced
か「なし」の探索
"class_weight": ["balanced", None]
Arduino (Uno R3互換)を Mac でLチカくらいまで。
準備
購入したもの
マニュアル
CD 内の K4 というマニュアル/K4/k4 Japanese tutorial.doc
ダウンロード
インストール
本体の準備
本体(UNO R3)をUSBケーブルで接続。緑LEDの点灯を確認。
ソフトのセットアップ
- 上記のファイルをダウンロード後、解凍し、起動。
- 次にメニュー、ツール→ボード→Arduino/Genuino Uno を選択。
- 次にメニューの、ツール→シリアルポート→
/dev/cu.usbmodemFD131 (Arduino/Genuino Uno)
を選択 - 次にメニューの、ツール→ボード情報を取得 で無事表示されれば準備完了。
Lチカ
Lチカとは、LEDチカチカの略であるが、次のようにまず example から blink を選ぶ
そして、画像のように、左から二個目のボタンを押すと
USBケーブルを通じて、Arduino に書き込まれ、リスタートして、Lチカが始まる。 もしかしたら、初期状態でもLEDが1秒毎に点滅していたので、Lチカが動いていたのかもしれない。
その他
チュートリアルはマニュアルが雑で、画像が間違ったポート番号に刺さっていたりとか普通にあるので注意した方がいいし、
マニュアル中のコードは word 上で貼り付けられているので、インデントが死んでいるし、//
のコメント行の最後に改行した後に書かれなければならない、}
が書かれていたりするので、
そのままだとコンパイルできないことがあったりするが、C言語をやったことがある人なら、それくらいのノイズは大したことなく、こなせることであろう。
CDの K4
の中に、code
というフォルダがあるので、その中にまともなコードが有るかと思ったら、pde ってなんだろう。
シンギュラリティは永久機関のようなもの
背景
社員旅行の夜、シンギュラリティについて質問された。 それまであまりよく考えたことがなかったけど、このときに自分の中でかなり整理された。
無限に賢くなる?
シンギュラリティの主張は、
- AIがもっと賢いAIを作る。
- これを繰り返す。
- 最終的に圧倒的に人より賢いAIが作られる。
確かにこれを聞けばすごくAIは賢くなる気がする。
賢さとは何か?
賢さとは何なのか。考えてみる。
- 計算スピード。すでにコンピュータのほうが早い。でも人間より賢いわけではない。
- 記憶力。コンピュータの方が多く記憶できるし、早く記憶できる。でも人間より賢いわけではない。
賢さの要素となるものは既に人間より上回っているにも関わらず、賢いとはいえないわけである。
学習の性能とその上限
今シンギュラリティが話題となっている背景に、深層学習のような機械学習のブレイクスルーがあるので、(機械)学習の枠組みで賢さを考える。 (機械)学習の評価尺度に正解率というものがある。特に重要なのが、汎化性能とよばれる未知の問題に対する正解率である。
この未知の問題に対する正解率には実は上限がある。どんなに優れた機械学習手法においてもこの上限を超えることはできない。
例えば、
- サイコロの目の数の予測
であるが、どのように優れた機械学習の手法を用いても正解率は6分の1を超えることはできない。
無限に賢くなる手法というのが提案されたとしても(事実Boostingは「訓練事例に対しては」無限に正解率が上がる)、アキレスと亀のように上限を超えることはできない。
賢い人が教えたらもっと賢い人になるか?
機械学習は新しいアルゴリズムを生成するものではない。だから、機械学習によって直にもっと賢い機械学習ができるわけではない。 ただし、機械学習のパラメータを効率よくチューニングするような話(メタ学習とよばれる)もないわけではない。 また機械学習のアルゴリズムを一つの推論とみなすとき、強化学習のような方法で効率よく学習が出来るようになるかもしれない。 ところが、強化学習やメタ学習による機械学習手法が代表的な一手法として確立してない現状をみると、 この強化学習やメタ学習にブレイクスルーがなければ、将来的にもその可能性は低いと考えられる。
そもそも賢い人が教えたらもっと賢い人になるという前提自体が根拠が不明である。賢い人自身がもっと賢くなることはあっても。
計算複雑性理論は越えられない
また例えそうだったとしても、計算複雑性理論の上限を超えることは出来ないだろう。もちろん量子コンピュータなどの新しい可能性もあるが、賢さのみでハードウェアを構築することは出来ないし、 人間もそうだが、どんなに賢くても無限のリソースが手に入るわけでもない。物理的な制約まで賢さが克服する根拠はない。
結局、シンギュラリティは計算機科学における永久機関
結局、シンギュラリティに到達するには様々な制約があり、それが克服される技術的・科学的な根拠はまだない。 よって、個人的には永久機関のようなものと考えている。
json ぽいデータを引き抜くクソクエリ
背景
json に対応していない mysql 5.7 未満のシステムに、json で値が格納されている。
対応
クソにはクソで。 LOCATE
と、SUBSTRING
を駆使し、抽出を試みる。
ここに書かれているは方法は、「一般的に」JSONをパースして抽出する方法でなく、利用範囲が限られるアドホックな方法であること(だからクソ)に注意されたい。
戦略
SUBSTR
は、
SUBSTRING(文字列, 開始位置, 文字数)
で開始位置から文字数分、文字列を抽出できる。よって、 抽出したい文字列の開始位置 と 抽出したい文字列の文字数 が分かればいいことになる。
多くの場合は、抽出対象となる文字列は ..., <key>: <value>, ...
みたいな形式になっており、抽出したい文字列自体(ここでは、<value>
とする)は不定で、<key>
をヒントに、「<key>
の後のコロンの後に続く文字列」であることが多い。ここでは、これを例として話をすすめる。
抽出したい文字列の開始位置
とりあえず、
LOCATE("<key>:", 非抽出カラム名)
で取れる。よってこれに <key>:
の長さを追加すれば、「LENGTH("<key>:")
と計算してもいいし、自分で数えても良い。
空白の有無はそこはデータ依存によるが、後で TRIM
を使うのであれば、空白が含まれていても問題ないだろう。
よって抽出したい文字列の開始位置は、
LOCATE("<key>:", 被抽出カラム名) + LENGTH("<key>:")
となる。
抽出したい文字列の文字数
抽出したい文字列の文字数は次のように求められる。
抽出したい文字列の文字数 = (抽出したい文字列の先頭からの文字列における)抽出したい文字列の次の文字列の位置 -1
である。ここで、 抽出したい文字列の先頭からの文字列 は次のようして求まる。
SUBSTRING(被抽出カラム名, LOCATE("<key>:", 被抽出カラム名) + LENGTH("<key>:"))
よって、LOCATEを使い、 (抽出したい文字列の先頭からの文字列における)抽出したい文字列の次の文字列の位置 は、
LOCATE(",", SUBSTRING(被抽出カラム名, LOCATE("<key>:", 被抽出カラム名) + LENGTH("<key>:")))
となる。
まとめると
最後にすべてまとめると、
SUBSTRING(被抽出カラム名, 抽出したい文字列の開始位置, 抽出したい文字列の文字数)
に、抽出したい文字列の開始位置 を代入すると、
SUBSTRING(被抽出カラム名, LOCATE("<key>:", 被抽出カラム名) + LENGTH("<key>:"), 抽出したい文字列の文字数)
となり、ここに、抽出したい文字列の文字数 を代入すると、
SUBSTRING(被抽出カラム名, LOCATE("<key>:", 被抽出カラム名) + LENGTH("<key>:"), LOCATE(",", SUBSTRING(被抽出カラム名, LOCATE("<key>:", 被抽出カラム名) + LENGTH("<key>:")))-1)
となる。クソクエリの完成である。
まとめ
テンプレートを作った。
SUBSTRING(column,LOCATE(prefix, column)+LENGTH(prefix),LOCATE(suffix,SUBSTRING(column,LOCATE(prefix, column)+LENGTH(prefix)))-1)
ここで、column: 被抽出カラム名、prefix: 抽出したい文字列の前に来る文字列、suffix: 抽出したい文字列の次に来る文字列 である。
ただし、これは抽出したい文字列の次に来る文字列が固定されている場合に限定されるクエリである。最後にカンマがあったりなかったりするとうまくいかない。クソクエリだからである。
luigi で パラメータで与えられた日付をtimedelta を使って増減させたい
背景
luigi にて、パラメータで与えられた日付に対して、固定日分前(例えば一週間など)を求めたい。
from datetime import timedelta import luigi class MyTask(luigi.Task): date = luigi.DateParameter() start_date = date - timedelta(days=7)
と書くと、次のようなエラー。
unsupported operand type(s) for -: 'DateParameter' and 'datetime.timedelta'
確かに、date はDateParameter
なので、エラーの通りなのだが。
での、回答者のコメントでは、 “DateParameter
returns a value that is a python date. ” といってるので、半分信じてしまった。
ちなみにこのQAは役立たない。なぜならデフォルト値の計算をしたいわけではないから。
クラス変数とインスタンス変数の違い
関数の中の、self.date
はクラス変数と思っていたが、間違いだ。これはインスタンス変数だ。
厄介なことに、 self.date
の表記は python 的にはクラス変数でもインスタンス変数にもなるらしい。
インスタンス変数として「初期化」すれば、クラス変数は隠蔽され以後インスタンス変数として扱われる。
ただ参照するだけならば、クラス変数として扱われる。
結局、self.date
がインスタンス変数ということは、親のクラスのインスタンス初期化の処理などで、クラス変数の設定通りの動作が行われ、self.date
というインスタンス変数に値がセットされたのだろう。
解決
from datetime import timedelta import luigi class MyTask(luigi.Task): date = luigi.DateParameter() def requires(self): start_date = self.date - timedelta(days=7)
もし、固定の日でなく、パラメータで与えたいのであれば、TimeDeltaParameter
を使おう。
http://luigi.readthedocs.io/en/stable/api/luigi.parameter.html#luigi.parameter.TimeDeltaParameter