20190417のPythonに関する記事は30件です。

supervisordでpythonのpyramidフレームワークをデーモン化する

supervisord

知っていますか。
デーモン化するやつです。
これでスタートとかすると、起動します。
ストップとかすると止まります。
なんと、スーパーユーザじゃなくて出来ます。

手順

今回は、pythonのpyramidフレームワークでWEBアプリを作ってデーモン化します

仮想環境の作成

python3 -m venv env3
source env3/bin/activate

使用するライブラリのインストール

pip install pyramid
pip install mr.laforge
pip install supervisord

使用できるpyramidのテンプレートを確認する

今回はstarterでやろう

pcreate --list-templates
Available scaffolds:
  alchemy:  Pyramid project using SQLAlchemy, SQLite, URL dispatch, and Jinja2
  starter:  Pyramid starter project using URL dispatch and Jinja2
  zodb:     Pyramid project using ZODB, traversal, and Chameleon

プロジェクトの作成してインストール

pcreate -t starter hello
cd hello
pip install -e .

通常起動を確認する

http://localhost:6543にアクセス

pserve development.ini

スクリーンショット 2019-04-17 21.35.56.png

supervisord.conf作成

[supervisord]
childlogdir = log
logfile = supervisord.log
logfile_maxbytes = 50MB
logfile_backups = 10
loglevel = info
pidfile = supervisord.pid
minfds = 1024
umask = 022
nodaemon = false
nocleanup = false

[inet_http_server]
port = 127.0.0.1:7001
username =
password =

[supervisorctl]
serverurl = http://localhost:7001
username =
password =

[ctlplugin:laforge]
supervisor.ctl_factory = mr.laforge.controllerplugin:make_laforge_controllerplugin

[rpcinterface:supervisor]
supervisor.rpcinterface_factory=supervisor.rpcinterface:make_main_rpcinterface

[program:hello]
command = /Users/xxx/env3/bin/pserve /Users/xxx/hello/development.ini
process_name = hello
directory = /Users/xxx/hello/
priority = 10
numprocs = 1
redirect_stderr = true
autostart = false

supervisorの起動

こちらでsupervisordが立ち上がります

suppervisord -c supervisord.conf

supervisorctlの対話モードに入ります

supervisorctl

supervisorctlの使い方

これで、デーモン化した、pyramidが起動します。http://localhost:6543/

supervisor> start hello

これで、デーモン化した、pyramidが終了します。

supervisor> stop hello

対話型supervisorctlから抜けます。

supervisor> exit

これで、supervisorctlを終了します。

supervisor> shutdown
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

おしゃれ並列Grid Search

Joblibでぱぱっと書きました

def job(X, y, params):
    ...

def grid_search(X, y, search_space, n_jobs=-1):
    search_space = [[(k, v) for v in space]
                    for k, space in search_space.items()]

    tasks = []
    for params in product(*search_space):
        tasks.append({
            'job': delayed(job)(X, y, *[p for _, p in params]),
            **dict(params)
        })

    with Parallel(n_jobs=n_jobs) as p:
        results = p([task.pop('job') for task in tasks])

    results = [{**result, **task} for task, result in zip(tasks, results)]
    results = pd.DataFrame(results)
    return results

X, y = get_data()

search_space = {
    'param_a': [1, 3, 5, 7],
    'param_b': ['a', 'b', 'c'],
    ...,
}

results = grid_search(X, y, search_space)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

量子テレポーテーション、やってみた

$$
\def\bra#1{\mathinner{\left\langle{#1}\right|}}
\def\ket#1{\mathinner{\left|{#1}\right\rangle}}
\def\braket#1#2{\mathinner{\left\langle{#1}\middle|#2\right\rangle}}
$$

自作の量子計算シミュレータを使って、量子テレポーテーション、やってみたよ。

はじめに

「量子テレポーテーション」のお勉強です。以下を参考にさせていただきました。

量子テレポーテーションというのは、量子もつれを利用して、ある量子状態をそのまま他方に転送することを言います。「テレポーテーション」といっても物体が瞬間移動するわけではありませんし、光速を超えて情報伝達がなされるわけでもありません。

いま、送信者をAlice、受信者をBobと呼ぶことにします。まず、2つの「量子(例えば、光子)」をもつれさせて、一方をAlice、他方をBobに渡します。光子は電子スピンと同様、2つの状態の重ね合わせで表現できる「量子」なので、スピンのように、もつれさせることができます(と思ってください)。

Aliceは、もう一つ別の「量子」をもっていて、これを適当な重ね合わせ状態にします。この量子状態をBobに転送(テレポート)することを考えます。どうやるかというと、、、

Aliceは転送したい「量子」ともつれている片割れの「量子」の2つを合わせて「ベル測定」という特別な測定を行います。ベル測定というのは、2つの量子状態を一度に測定するもので、結果は4つの状態のいずれかになります。

AliceはBobに、この測定結果を通常の通信路で伝達します。Bobはそれ受け取り、その測定結果に応じて、自分がもっている、もつれている片割れの「量子」に、ある操作(量子ゲート)を適用します。そうすると、あーら不思議、Bobがもっている「量子」が、Aliceが転送したかった量子状態そのものにすり替わっているではありませんか!驚き!となります。

ざっくり、文書で書くと以上のようなことなのですが、なぜこんなことになるのか、次に、数式で確認してみましょう。

原理

3つの量子ビットを用意します。0番目をAliceがBobに送信したい量子ビットとします。1番目と2番目はもつれさせて、1番目をAliceに渡し、2番目をBobに渡すものとします。

0番目(AliceがBobに送信したいもの)を、とりあえず、

\ket{\psi} = \alpha \ket{0} + \beta \ket{1}

と書いておきます(後述するシミュレータではX軸周りとZ軸周りの回転ゲートで、適当な量子状態を作成して、$\alpha$と$\beta$を決めています)。

1番目と2番目は、以下のようにアダマールゲートと制御NOTゲートを通して、もつれさせます。

q1 |0> ----H--*---
q2 |0> -------CX--

そうすると、1番目と2番目の量子ビットに関して、以下の量子状態ができます。

\frac{1}{\sqrt{2}} (\ket{0}_{1}\ket{0}_{2} + \ket{1}_{1}\ket{1}_{2})

先程の0番目と合わせると、トータルで以下のような状態になります。

\frac{1}{\sqrt{2}} \ket{\psi}_{0} (\ket{0}_{1}\ket{0}_{2} + \ket{1}_{1}\ket{1}_{2}) \tag{1}

ここで、Aliceが「ベル測定」を行うのですが、その説明をします。いま、2量子系を考えているので、その測定は、数学的には4つの基底への射影演算をやることに相当します。ベル測定とは、以下の4つの基底への射影演算として定義されます。

\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{00} + \ket{11}) \\
\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} (\ket{00} - \ket{11}) \\
\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} (\ket{01} + \ket{10}) \\
\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} (\ket{01} - \ket{10})

定義がわかったので、(1)式の0番目と1番目の量子ビットに対してベル測定をやってみます。射影演算は4つあります。各々、測定後の結果を列挙します。

  • $\ket{\Phi^{+}}$への射影
\begin{align}
&\frac{1}{\sqrt{2}} \ket{\Phi^{+}}_{01} \bra{\Phi^{+}}_{01} \ket{\psi}_{0} (\ket{0}_{1}\ket{0}_{2} + \ket{1}_{1}\ket{1}_{2}) \\
&= \frac{1}{\sqrt{2}} \ket{\Phi^{+}}_{01} (\alpha \bra{0}_{1} + \beta\bra{1}_{1}) (\ket{0}_{1} \ket{0}_{2} + \ket{1}_{1} \ket{1}_{2}) \\
&= \frac{1}{\sqrt{2}} \ket{\Phi^{+}}_{12} (\alpha \ket{0}_{2} + \beta \ket{1}_{2}) \tag{2}
\end{align}\\

同様にして、他の3つも計算できます。

  • $\ket{\Phi^{-}}$への射影
\begin{align}
&\frac{1}{\sqrt{2}} \ket{\Phi^{-}}_{01} \bra{\Phi^{-}}_{01} \ket{\psi}_{0} (\ket{0}_{1}\ket{0}_{2} + \ket{1}_{1}\ket{1}_{2}) \\
&= \frac{1}{\sqrt{2}} \ket{\Phi^{-}}_{01} (\alpha \ket{0}_{2} - \beta \ket{1}_{2}) \tag{3}
\end{align}
  • $\ket{\Psi^{+}}$への射影
\begin{align}
&\frac{1}{\sqrt{2}} \ket{\Psi^{+}}_{01} \bra{\Psi^{+}}_{01} \ket{\psi}_{0} (\ket{0}_{1}\ket{0}_{2} + \ket{1}_{1}\ket{1}_{2}) \\
&= \frac{1}{\sqrt{2}} \ket{\Psi^{+}}_{01} (\beta \ket{0}_{2} + \alpha \ket{1}_{2}) \tag{4}
\end{align}
  • $\ket{\Psi^{-}}$への射影
\begin{align}
&\frac{1}{\sqrt{2}} \ket{\Psi^{-}}_{01} \bra{\Psi^{-}}_{01} \ket{\psi}_{0} (\ket{0}_{1}\ket{0}_{2} + \ket{1}_{1}\ket{1}_{2}) \\
&= \frac{1}{\sqrt{2}} \ket{\psi^{-}}_{01} (-\beta \ket{0}_{2} + \alpha \ket{1}_{2}) \tag{5}
\end{align}

上の4つの式を眺めてみると、どうでしょう。なんとなく2番目の量子ビットの状態が、もともとAliceが設定した状態に似ていることがわかると思います((2)式はそのものです)。2番目の量子ビットは、Bobに渡してあったものなのですが、Aliceが測定することで、遠隔地にいるBobが持っている量子に影響を及ぼすことができる、というのが量子もつれの不思議なところであり、量子テレポーテーションの肝でもあります。

さて、あとはBobがもっている2番目の量子ビットを操作して、Aliceの最初の0番目の状態に完全に一致させることを考えます。これは、Aliceからベル測定の結果が何だったかを教えてもらえれば、簡単で、

  • $\ket{\Phi^{+}}$の場合
q2 --I-- # 何もしない
  • $\ket{\Phi^{-}}$の場合
q2 --Z--
  • $\ket{\Psi^{+}}$の場合
q2 --X--
  • $\ket{\Psi^{-}}$の場合
q2 --X--Z--

という量子ゲートに通してあげれば、Aliceが転送したかった状態を2番目の量子ビットに完全再現することができる、というわけです。

シミュレータで実行(その1)

では、シミュレータで、以上のことが本当にできるか確認してみましょう。が、ちょっと待ってください。ベル測定ってシミュレータでどうやるんでしたっけ?という疑問がわいてきますよね。

実は、普通の測定(Z方向の測定)でベル測定できるようにするために、ちょっとした工夫が必要になります。具体的には、以下の回路を通してあげます。

q0 --*---H--M  -> b0
q1 --CX-----M  -> b1

この制御NOTゲートとアダマールゲートの組み合わせで、通常の基底からベル基底に変換することができるのです(ここで、b0,b1は最後の測定結果に応じて0/1の値が格納される古典レジスタです)。

ベル基底の4つの状態を上の回路に(頭の中で!?)通してみれば、すぐにわかります(以下、正規化の係数はいちいち書くのが面倒なので省略しました)。

\begin{align}
\ket{\Phi^{+}} &= \ket{00} + \ket{11} \\
&\rightarrow (\ket{0} + \ket{1}) \ket{0} + (\ket{0} - \ket{1}) \ket{0} = \ket{00} \\
\ket{\Phi^{-}} &= \ket{00} - \ket{11} \\
&\rightarrow (\ket{0} + \ket{1}) \ket{0} - (\ket{0} - \ket{1}) \ket{0} = \ket{10} \\
\ket{\Psi^{+}} &= \ket{01} + \ket{10} \\
&\rightarrow (\ket{0} + \ket{1}) \ket{1} + (\ket{0} - \ket{1}) \ket{1} = \ket{01} \\
\ket{\Psi^{-}} &= \ket{01} - \ket{10} \\
&\rightarrow (\ket{0} + \ket{1}) \ket{1} - (\ket{0} - \ket{1}) \ket{1} = \ket{11} \\
\end{align}

となって、ベル基底とb0,b1の値のセットとが対応づけられるようになります。つまり、b0,b1の観測をすることが、すなわちベル測定したことになる、という寸法です。

さて、ようやくシミュレーションの準備が整いました。
qlazyで実行します。測定結果に応じて、適用する量子回路を変えないといけないので、Linuxコマンドではちょっとやりにくいです。なので、Pythonでやってみます。コードは、以下の通りです。

from qlazypy import QState

qs = QState(3)

# prepare qubit (id=0) that Alice want to send to Bob by rotating around X,Z
qs.ry(0,phase=0.3).rz(0,phase=0.4)

# make entangled 2 qubits (id=1 for Alice, id=2 for Bob)
qs.h(1).cx(1,2)

# initial state (before teleportation)
print("== Alice (initial) ==")
qs.show(id=[0])
print("== Bob (initial) ==")
qs.show(id=[2])

# Alice execute Bell-measurement to her qubits 0,1
qs.cx(0,1).h(0)
b0 = qs.m(id=[0],shots=1).lst
b1 = qs.m(id=[1],shots=1).lst
print("== Bell measurement ==")
print("b0,b1 = ", b0,b1)

# Bob operate his qubit (id=2) according to the result
if b0 == 0 and b1 == 0:  # phi+
    pass
elif b0 == 0 and b1 == 1:  # psi+
    qs.x(2)
elif b0 == 1 and b1 == 0:  # psi-
    qs.z(2)
elif b0 == 1 and b1 == 1:  # phi-
    qs.x(2).z(2)

# final state (before teleportation)
print("== Alice (final) ==")
qs.show(id=[0])
print("== Bob (final) ==")
qs.show(id=[2])

qs.free()

これを実行すると、

== Alice (initial) ==
c[0] = +0.8910+0.0000*i : 0.7939 |+++++++++
c[1] = +0.1403+0.4318*i : 0.2061 |+++
== Bob (initial) ==
c[0] = +0.0000+0.0000*i : 0.0000 |
c[1] = +1.0000+0.0000*i : 1.0000 |+++++++++++
== Bell measurement ==
b0,b1 =  1 0
== Alice (final) ==
c[0] = +0.0000+0.0000*i : 0.0000 |
c[1] = +1.0000+0.0000*i : 1.0000 |+++++++++++
== Bob (final) ==
c[0] = +0.8910+0.0000*i : 0.7939 |+++++++++
c[1] = +0.1403+0.4318*i : 0.2061 |+++

となり、確かに、最初Aliceが持っていた量子状態が、きちんとBobの量子ビットに乗り移っていることがわかります。めでたしめでたし!

シミュレータで実行(その2)

ここで、説明を終了しても良いのですが、もうひとつの実行例を掲載しておきます。実は、ベル測定そのものを実装したので、その動作も確認してみました。mb()というメソッドでベル測定を実行できます。コードは以下の通りです。

from qlazypy import QState

BELL_PHI_PLUS  = 0
BELL_PHI_MINUS = 3
BELL_PSI_PLUS  = 1
BELL_PSI_MINUS = 2

qs = QState(3)

# prepare qubit (id=0) that Alice want to send to Bob by rotating around X,Z
qs.ry(0,phase=0.3).rz(0,phase=0.4)

# make entangled 2 qubits (id=1 for Alice, id=2 for Bob)
qs.h(1).cx(1,2)

# initial state (before teleportation)
print("== Alice (initial) ==")
qs.show(id=[0])
print("== Bob (initial) ==")
qs.show(id=[2])

# Alice execute Bell-measurement to her qubits 0,1
print("== Bell measurement ==")
result = qs.mb(id=[0,1],shots=1).lst

# Bob operate his qubit (id=2) according to the result
if result == BELL_PHI_PLUS:
    print("result: phi+")
elif result == BELL_PSI_PLUS:
    print("result: psi+")
    qs.x(2)
elif result == BELL_PSI_MINUS:
    print("result: psi-")
    qs.x(2).z(2)
elif result == BELL_PHI_MINUS:
    print("result: phi-")
    qs.z(2)

# final state (before teleportation)
print("== Alice (final) ==")
qs.show(id=[0])
print("== Bob (final) ==")
qs.show(id=[2])

qs.free()

これを実行すると、

== Alice (initial) ==
c[0] = +0.8910+0.0000*i : 0.7939 |+++++++++
c[1] = +0.1403+0.4318*i : 0.2061 |+++
== Bob (initial) ==
c[0] = +1.0000+0.0000*i : 1.0000 |+++++++++++
c[1] = +0.0000+0.0000*i : 0.0000 |
== Bell measurement ==
result: psi-
== Alice (final) ==
c[0] = +1.0000+0.0000*i : 1.0000 |+++++++++++
c[1] = +0.0000+0.0000*i : 0.0000 |
== Bob (final) ==
c[0] = +0.8910+0.0000*i : 0.7939 |+++++++++
c[1] = +0.1403+0.4318*i : 0.2061 |+++

となり、こちらも無事テレポーテーション成功です!

以上

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

備忘録③ URLの規則性を見つけてページ遷移してスクレイピング

初めに

サイト全体をわざわざクローリングしてまでページ遷移するのはめんどくさいですね(やったことないけど)

例えばサイト情報をスクレイピングするとき
ページのURLの変化に規則性があれば、次のコードが使えるかもしれません

コード 例

https://gigazine.net
の2~6ページのサイトコードをスクレイピングしてみます

pages
import requests

for n in range(1,5):
    page=requests.get("https://gigazine.net/P"+str(n*40)) #規則性#
    page.encoding = page.apparent_encoding
    print (page.text)

Gigazinでは、次のページに行くごとにベースのURL(https://gigazine.net/)に
Pと40×(ページの遷移した数)が後に続きます

終わり

サクッとデータ収集する時に使えそうな感
これに加えて例外を飛ばしたり
BeautifulSoup でもう少し具体化して収集してPandasとかでデータを整形できるようになりたい

備忘録④ 予定

後記

その後のコードの発展形を備忘録していきます
アイディア・指摘・コメントでください

Gigazin_links
#2~6ページの記事リンク取得

import requests
from bs4 import BeautifulSoup

for n in range(1,5):
    page=requests.get("https://gigazine.net/P"+str(n*40))
    page.encoding = page.apparent_encoding
    #print (page.text)

    soup = BeautifulSoup(page.text, 'html.parser')
    #print(soup.title)

    imgs = soup.find(class_="content")

    for i in imgs.find_all("img"):
        print(i.get("data-src"))

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

くまのプーさんの名言「何もしないをしよう」の類似表現を機械学習(Doc2vec)で探す

目的

日常を生きていると、常に「何かをしなければ」と思ってしまいがちです。
しかしながら、「何かをすること」が必ずしも本当に重要な事に繋がっていない事もしばしばあります。
この場合は「何もしない」をすることが実は自分を客観的に見直せるきっかけになることを、
くまのプーさんは教えてくれています。

pooh_serifu_do_nothing-min.jpg

なのですが、
結構「何もしないをする」の抽象度が高く、自分なりに都合よく解釈しがちなのも事実だと思います。
従いまして、客観的に上記の意味を捉えるため、機械学習(Doc2vec)を用いて類似表現を探したいと思います。

準備

1.Doc2vecをインストールする。

下記を参照してインストールします。

Doc2Vecを使用するまでの環境構築手順

2.Doc2vecの学習済みモデルを取得する。

下記サイト""よりダウンロードさせて頂きます。

日本語WIKIPEDIAで学習したDOC2VECモデル
dbow300d

解凍

$ tar zxvf jawiki.doc2vec.dbow300d.tar.bz2

3.機械学習用コード作成
 下記3step.で処理します。コードは後述。
 step1.学習モデルのロード(Doc2vec.load)
 step2.入力テキストの構文解析(Mecab.tagger)
 step3.テキストから類似表現取得(docvecs.most_similar)

コード

# -*- coding: utf-8 -*-                                                                                             

from gensim.models.doc2vec import Doc2Vec
import MeCab
import numpy as np


def tokenize(text):
    wakati = MeCab.Tagger("-O wakati")
    wakati.parse("")
    return wakati.parse(text).strip().split()

model = Doc2Vec.load("jawiki.doc2vec.dbow300d.model")

text="何もしないをしよう"
out=model.docvecs.most_similar([model.infer_vector(tokenize(text))])
print( out );

text="自分を変えるものは、自分で作るものだ。"
out=model.docvecs.most_similar([model.infer_vector(tokenize(text))])
print( out );

text="君が100まで生きるなら、 僕は君より1日少なく生きたいよ。 だって、君がいない人生なんて、 無いのと同じだからね。"
out=model.docvecs.most_similar([model.infer_vector(tokenize(text))])
print( out );

テスト

「何もしないをしよう」
4-8.jpg

[('虜', 0.6765191555023193), 
('岡田淮一', 0.6655471324920654), 
('レイノルド・シルキー', 0.6532681584358215), 
('ミラノ・フプツェイ', 0.6495197415351868), 
('フォレスト・ガンダー', 0.6368730068206787), 
('タックス・ヘブン', 0.6367721557617188), 
('バルタサー・ハブマイヤー', 0.6332018971443176), 
('ボルトネック', 0.6331052780151367), 
('官弊社', 0.6319104433059692), 
('上諏訪市', 0.6254733800888062)]

→虜なんですね!

「自分を変えるものは、自分で作るものだ。」
Cgj553KUcAASj_b.jpg-large.jpeg

[('オオツヤヒサシサイカブト', 0.6657865643501282), 
('虜', 0.6558833122253418), 
('オキサリルジヒドラジド', 0.6334289312362671), 
('足型', 0.6331846714019775), 
('マックロ', 0.6315746307373047), 
('的 (曖昧さ回避)', 0.625438392162323), 
('バルタサー・ハブマイヤー', 0.6228896975517273), 
('レイノルド・シルキー', 0.6207892894744873), 
('フォレスト・ガンダー', 0.6185415387153625), 
('上諏訪市', 0.6169095039367676)]

→「オオツヤヒサシサイカブト」はカブトムシですね。

「君が100まで生きるなら、 僕は君より1日少なく生きたいよ。 だって、君がいない人生なんて、 無いのと同じだからね。」
スクリーンショット 2019-04-17 20.48.02.png

[('ミラノ・フプツェイ', 0.678257167339325), 
('桑田圭祐', 0.6598429679870605), 
('レイノルド・シルキー', 0.6597413420677185), 
('岡田淮一', 0.650931179523468), 
('楠正成', 0.6494807004928589), 
('上諏訪市', 0.6473155617713928), 
('ボトムネック', 0.646905779838562), 
('聴きたかったダンスミュージック、リキッドルームに', 0.6437188386917114), 
('碓井峠', 0.6405103206634521), 
('クリスタルカイザー', 0.638593852519989)

→やはり、桑田佳祐ですね!

TSUNAMIが聴きたくなってきました。
参考文献にも記載がある通り、何もないよりはよいですが、
doc2vecを使いこなすのであれば、学習モデルをもう少しドメイン寄りのものにした方が良さそうです。

CodingError対策

ModuleNotFoundError: No module named 'numpy.core._multiarray_umath'

ネットで調べたらnumpyと他ライブラリの順序関係が影響しているらしく、numpyを再インストールしたら解決。
$ sudo pip uninstall numpy
$ pip install numpy
Successfully installed numpy-1.16.2

参考

くまのプーさん(ディズニー)-wikipedia
Doc2Vecを使用するまでの環境構築手順
日本語WIKIPEDIAで学習したDOC2VECモデル

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Leapmotion のサンプルプログラムを動かすためにやったこと ubuntu18.04

これはためになった

まず、leapmotionを使うためには環境を整える必要があり、以下のサイトが参考になった。基本的には以下2つのサイト通りなのだが、エラーが出てしまうらしい。
第302回 Ubuntuで3Dモーションセンサ『Leap Motion』を使う
Leap Motion + Ubuntu16.04 + Unity(ゲームエンジン)
ダウンロードしたもの:V2 Tracking

エラーが出たために参考にしたもの。

以下のサイトにあるようにファイルを追加することで、うまく行くらしい
Ubuntu 16.04にLeapMotion導入
Ubuntuに Leap Motion SDKをインストールした作業メモ

pythonのサンプルコードを走らせるときに見たもの

Leap Motion を Pythonから使う方法を調べた

使わなくてもできるけど参考までに

PythonでLeapMotionのデータを取得する。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ROS(Robot Operating System)について学ぶべき全てのことがここにあります

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CentOS7で共有ライブラリを追加する

概要

CentOS7では、デフォルトで/libと/usr/lib以下のファイルは、共有ライブラリとして含まれています。
それ以外のディレクトリのライブラリを追加したい場合は、以下のいずれかの方法で設定する必要があります。

  1. 特定のユーザーのみが使えるようにする方法
  2. システム全体で永続的に使いたい場合

OpenSSLのインストール

今回は例として、OpenSSLを共有ライブラリに追加するため、インストールをします。

参考:CentOS7にOpenSSL1.1.1をインストール

特定のユーザーのみが使えるようにする方法

LD_LIBRARY_PATHは、/etc/ld.so.confで定義されたパスよりも優先されます。

設定したいディレクトリ以下のライブラリを全て参照するようになります。

$ LD_LIBRARY_PATH=/usr/local/openssl-1.1.1/lib; export LD_LIBRARY_PATH

設定したいディレクトリが複数ある場合は、:で区切って設定します。

$ LD_LIBRARY_PATH=/usr/local/lib:/usr/lib; export LD_LIBRARY_PATH

ちなみに、LD_LIBRARY_PATHの設定を以下で定義しても反映されません。

  • $HOME/.profile
  • /etc/profile
  • /etc/environment

参考:EnvironmentVariables - Community Help Wiki

LD_LIBRARY_PATH についての説明から抜粋
Note: You can only set this environment variable inside an interactive shell. Since Ubuntu 9.04 Jaunty Jackalope, LD_LIBRARY_PATH cannot be set in $HOME/.profile, /etc/profile, nor /etc/environment files. You must use /etc/ld.so.conf.d/*.conf configuration files. See Launchpad bug #366728 for more information.

参考:LD_LIBRARY_PATH を設定しても反映されないことがある

システム全体で永続的に使いたい場合

追加するライブラリ

今回は例として、以下のopensslのライブラリ群を追加します。

$ sudo ls -l /usr/local/openssl-1.1.1/lib
total 10432
drwxr-xr-x 2 root root      39 Apr 17 04:12 engines-1.1
-rw-r--r-- 1 root root 5599274 Apr 17 04:12 libcrypto.a
lrwxrwxrwx 1 root root      16 Apr 17 04:12 libcrypto.so -> libcrypto.so.1.1
-rwxr-xr-x 1 root root 3370584 Apr 17 04:12 libcrypto.so.1.1
-rw-r--r-- 1 root root 1019068 Apr 17 04:12 libssl.a
lrwxrwxrwx 1 root root      13 Apr 17 04:12 libssl.so -> libssl.so.1.1
-rwxr-xr-x 1 root root  685240 Apr 17 04:12 libssl.so.1.1
drwxr-xr-x 2 root root      61 Apr 17 04:12 pkgconfig

共有ライブラリとして認識されているパスの確認

以下コマンドで読み込まれているパスを確認できます。

$ sudo ldconfig -p

ライブラリ追加前の状態を確認します。ssl関係のライブラリは/lib64のもののみ認識されています。

$ sudo ldconfig -p | grep libssl
        libssl3.so (libc6,x86-64) => /lib64/libssl3.so
        libssl.so.10 (libc6,x86-64) => /lib64/libssl.so.10

ライブラリを追加する

システム全体に永続的にライブラリを追加したい場合は、/etc/ld.so.confに定義します。
実際にファイルの中を見てみると、以下のようになっています。

$ sudo cat /etc/ld.so.conf
include ld.so.conf.d/*.conf

/etc/ld.so.confで直接定義することもできますが、/etc/ld.so.conf.dの下にファイルを作成して定義することを推奨します。 

/etc/ld.so.conf.d/openssl-1.1.1.confを作成して、以下を定義します。

/etc/ld.so.conf.d/openssl-1.1.1.conf
/usr/local/openssl-1.1.1/lib

キャッシュファイルを更新

OSはライブラリを検索する際に、/etc/ld.so.confを直接参照するのではなく、/etc/ld.so.cacheというキャッシュファイルを参照するため、以下のコマンドでこのキャッシュファイルを更新します。

$ sudo ldconfig

ライブラリが追加されたことを確認

以下コマンドで/usr/local/openssl-1.1.1/lib以下のライブラリが追加されたことを確認できます。

$ sudo ldconfig -p | grep libssl
        libssl3.so (libc6,x86-64) => /lib64/libssl3.so
        libssl.so.10 (libc6,x86-64) => /lib64/libssl.so.10
+       libssl.so.1.1 (libc6,x86-64) => /usr/local/openssl-1.1.1/lib/libssl.so.1.1
+       libssl.so (libc6,x86-64) => /usr/local/openssl-1.1.1/lib/libssl.so

関連記事

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CentOS7でldconfigを使って共有ライブラリを追加する

概要

CentOS7では、デフォルトで/libと/usr/lib以下のファイルは、共有ライブラリとして含まれています。
それ以外のディレクトリのライブラリを追加したい場合は、以下のいずれかの方法で設定する必要があります。

  1. 特定のユーザーのみが使えるようにする方法
  2. システム全体で永続的に使いたい場合

OpenSSLのインストール

今回は例として、OpenSSLを共有ライブラリに追加するため、インストールをします。

参考:CentOS7にOpenSSL1.1.1をインストール

特定のユーザーのみが使えるようにする方法

LD_LIBRARY_PATHは、/etc/ld.so.confで定義されたパスよりも優先されます。

設定したいディレクトリ以下のライブラリを全て参照するようになります。

$ LD_LIBRARY_PATH=/usr/local/openssl-1.1.1/lib; export LD_LIBRARY_PATH

設定したいディレクトリが複数ある場合は、:で区切って設定します。

$ LD_LIBRARY_PATH=/usr/local/lib:/usr/lib; export LD_LIBRARY_PATH

ちなみに、LD_LIBRARY_PATHの設定を以下で定義しても反映されません。

  • $HOME/.profile
  • /etc/profile
  • /etc/environment

参考:EnvironmentVariables - Community Help Wiki

LD_LIBRARY_PATH についての説明から抜粋
Note: You can only set this environment variable inside an interactive shell. Since Ubuntu 9.04 Jaunty Jackalope, LD_LIBRARY_PATH cannot be set in $HOME/.profile, /etc/profile, nor /etc/environment files. You must use /etc/ld.so.conf.d/*.conf configuration files. See Launchpad bug #366728 for more information.

参考:LD_LIBRARY_PATH を設定しても反映されないことがある

システム全体で永続的に使いたい場合

追加するライブラリ

今回は例として、以下のopensslのライブラリ群を追加します。

$ sudo ls -l /usr/local/openssl-1.1.1/lib
total 10432
drwxr-xr-x 2 root root      39 Apr 17 04:12 engines-1.1
-rw-r--r-- 1 root root 5599274 Apr 17 04:12 libcrypto.a
lrwxrwxrwx 1 root root      16 Apr 17 04:12 libcrypto.so -> libcrypto.so.1.1
-rwxr-xr-x 1 root root 3370584 Apr 17 04:12 libcrypto.so.1.1
-rw-r--r-- 1 root root 1019068 Apr 17 04:12 libssl.a
lrwxrwxrwx 1 root root      13 Apr 17 04:12 libssl.so -> libssl.so.1.1
-rwxr-xr-x 1 root root  685240 Apr 17 04:12 libssl.so.1.1
drwxr-xr-x 2 root root      61 Apr 17 04:12 pkgconfig

共有ライブラリとして認識されているパスの確認

以下コマンドで読み込まれているパスを確認できます。

$ sudo ldconfig -p

ライブラリ追加前の状態を確認します。ssl関係のライブラリは/lib64のもののみ認識されています。

$ sudo ldconfig -p | grep libssl
        libssl3.so (libc6,x86-64) => /lib64/libssl3.so
        libssl.so.10 (libc6,x86-64) => /lib64/libssl.so.10

ライブラリを追加する

システム全体に永続的にライブラリを追加したい場合は、/etc/ld.so.confに定義します。
実際にファイルの中を見てみると、以下のようになっています。

$ sudo cat /etc/ld.so.conf
include ld.so.conf.d/*.conf

/etc/ld.so.confで直接定義することもできますが、/etc/ld.so.conf.dの下にファイルを作成して定義することを推奨します。 

/etc/ld.so.conf.d/openssl-1.1.1.confを作成して、以下を定義します。

/etc/ld.so.conf.d/openssl-1.1.1.conf
/usr/local/openssl-1.1.1/lib

キャッシュファイルを更新

OSはライブラリを検索する際に、/etc/ld.so.confを直接参照するのではなく、/etc/ld.so.cacheというキャッシュファイルを参照するため、以下のコマンドでこのキャッシュファイルを更新します。

$ sudo ldconfig

ライブラリが追加されたことを確認

以下コマンドで/usr/local/openssl-1.1.1/lib以下のライブラリが追加されたことを確認できます。

$ sudo ldconfig -p | grep libssl
        libssl3.so (libc6,x86-64) => /lib64/libssl3.so
        libssl.so.10 (libc6,x86-64) => /lib64/libssl.so.10
+       libssl.so.1.1 (libc6,x86-64) => /usr/local/openssl-1.1.1/lib/libssl.so.1.1
+       libssl.so (libc6,x86-64) => /usr/local/openssl-1.1.1/lib/libssl.so

関連記事

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

CentOS7にOpenSSL1.1.1をインストール

概要

Python3.7のインストール時に、OpenSSL1.0.2以上のインストールを求められたので1.1.1を入れた。
この記事ではその時の手順をまとめた。

関連記事

OpenSSLの各versionのサポート状況

1.0.2は2019-12-31にEOL。
https://www.openssl.org/policies/releasestrat.html

The next version of OpenSSL will be 3.0.0.
Version 1.1.1 will be supported until 2023-09-11 (LTS).
Version 1.1.0 will be supported until 2019-09-11.
Version 1.0.2 will be supported until 2019-12-31 (LTS).
Version 1.0.1 is no longer supported.
Version 1.0.0 is no longer supported.
Version 0.9.8 is no longer supported.

OpenSSLのインストール

依存関係のインストール

$ sudo yum install -y zlib-devel perl-core make gcc

OpenSSLのダウンロード

以下のサイトからインストールしたいバージョンをダウンロード。
https://www.openssl.org/source/

ここでは1.1.1をインストールする。

$ sudo curl https://www.openssl.org/source/openssl-1.1.1.tar.gz -o /usr/local/src/openssl-1.1.1.tar.gz

OpenSSLのインストール

$ cd /usr/local/src
$ sudo tar xvzf openssl-1.1.1.tar.gz
$ cd openssl-1.1.1/
$ sudo ./config --prefix=/usr/local/openssl-1.1.1 shared zlib
$ sudo make depend
$ sudo make
$ sudo make test
$ sudo make install

インストールされたことを確認

以下にインストールされる。

$ sudo ls -l /usr/local/openssl-1.1.1
total 0
drwxr-xr-x 2 root root  37 Apr 17 05:57 bin
drwxr-xr-x 3 root root  21 Apr 17 05:57 include
drwxr-xr-x 4 root root 159 Apr 17 05:57 lib
drwxr-xr-x 4 root root  28 Apr 17 05:58 share
drwxr-xr-x 5 root root 140 Apr 17 05:57 ssl

OpenSSLを共有ライブラリに追加する

下記ページの、「システム全体で使いたい場合」以降を実施してください。
これを行わないとOpenSSLを利用できません。

動作確認

以下コマンドで動作確認をする。TLSv1.3に対応していることがわかる。

$ sudo /usr/local/openssl-1.1.1/bin/openssl ciphers -v TLSv1.3
TLS_AES_256_GCM_SHA384  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(256) Mac=AEAD
TLS_CHACHA20_POLY1305_SHA256 TLSv1.3 Kx=any      Au=any  Enc=CHACHA20/POLY1305(256) Mac=AEAD
TLS_AES_128_GCM_SHA256  TLSv1.3 Kx=any      Au=any  Enc=AESGCM(128) Mac=AEAD

関連記事

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Python2to3アップデート方法】Python3系のインストール

目次

概要

Python2系を3系にアップデートする手順や、バージョンについて説明する。

インストール方法

ここでは、以下の3つのインストール方法を紹介する。

方法 version 備考
CentOS:7.5にyumでインストール 3.6 yumでは3.6までしかインストールできない
ubuntu:18.04にapt-getでインストール 3.7 apt-get-で3.7をインストール可能
ソースファイルをコンパイルしてインストール 3.7 -

CentOS7にyumで3.6をインストール

CentOS7のyumでは、Python3.6が最新なので3.6をインストールする。

レポジトリを追加

$ sudo yum install -y https://centos7.iuscommunity.org/ius-release.rpm

インストール

$ sudo yum install -y python36u python36u-libs python36u-devel python36u-pip

インストールすると、python関連のコマンドが以下のように増える。
python3.6mとは、--with-pymallocオプションが設定されたもの。
pymallocについては、こちらを参照。

/usr/bin/pydoc
/usr/bin/python
/usr/bin/python2.7
/usr/bin/python3.6-config
/usr/bin/python3.6m-config
/usr/bin/pyvenv-3.6
/usr/bin/pydoc3.6
/usr/bin/python2
/usr/bin/python3.6
/usr/bin/python3.6m
/usr/bin/python3.6m-x86_64-config

シンボリックリンクを貼る

pythonコマンドでpython3.6を実行できるようにする。

$ sudo ln -s /usr/bin/python3.6 /usr/local/bin/python
$ python --version
Python 3.6.7

pipについて

python36u-pipをインストールした直後では、pipコマンドはpip3.6のみが存在している。

$ which pip3.6
/usr/bin/pip3.6

pip3.6コマンドを実行すると、pipをupgradeしろと出るのでupgradeする。

You are using pip version 9.0.1, however version 19.0.3 is available.
You should consider upgrading via the 'pip install --upgrade pip' command.
$ pip3.6 install --upgrade pip

そうすると、pipコマンドが以下の3つに増える。

-rwxr-xr-x 1 root root 218 Apr 18 01:54 /usr/bin/pip
-rwxr-xr-x 1 root root 218 Apr 18 01:54 /usr/bin/pip3
-rwxr-xr-x 1 root root 218 Apr 18 01:54 /usr/bin/pip3.6

ただし、全て同じ場所を参照しているようなので、全て同じだと思われる。

$ python3.6 -m pip -V
pip 19.0.3 from /usr/lib/python3.6/site-packages/pip (python 3.6)
$ pip -V
pip 19.0.3 from /usr/lib/python3.6/site-packages/pip (python 3.6)
$ pip3 -V
pip 19.0.3 from /usr/lib/python3.6/site-packages/pip (python 3.6)
$ pip3.6 -V
pip 19.0.3 from /usr/lib/python3.6/site-packages/pip (python 3.6)

python36とpython36uの違い

ちなみに、yum searchをすると分かるが、python36python36uの2つのパッケージが用意されている。この2つの違いについて調べてみた。

$ sudo yum search yum search python36
python36.x86_64 : Interpreter of the Python programming language
python36u.x86_64 : Interpreter of the Python programming language

python36uとは一体なんなのか調べてみた。

EPELの後発であるIUSが独自の基準で選んだpythonのリビジョンやらがEPELと違うので同じpackage nameだと不都合だからuをつけたんだろう

CentOS python3 package difference between python36 and python36u

python36u is an alternative build provided by IUS; python36 is an EPEL package.
yum info python36 python36u will show you different repos for the two, and it's likely that the IUS one has a slightly higher minor version number than the EPEL package.

結論としては、提供元が違うだけで、大きな差はなさそう。

Ubuntuのapt-getで3.7をインストール

ちなみに、Ubuntuではあまり動作確認していません。

Python3.7のインストール

$ sudo apt-get install python3.7

pip3のインストール

$ sudo apt-get install python3-pip

ソールファイルをコンパイルして3.7インストール

CentOS7.5でPython3.7をインストールするには、OpenSSL1.02以上が必要となる。
(Python3.6をインストールする場合は現行のversionでOK)

現行もversionでPythonのインストールを続けると、コンパイル時に以下のように、ssl moduleをbuildできないというログが出力される。

Could not build the ssl module!
Python requires an OpenSSL 1.0.2 or 1.1 compatible libssl with X509_VERIFY_PARAM_set1_host().
LibreSSL 2.6.4 and earlier do not provide the necessary APIs, https://github.com/libressl-portable/portable/issues/381

現行のopensslのversionを調べてみると、1.0.2が入っているように見えるが、これでは駄目なようだ。
yum install -y openssl-develをしても結果は変わらなかった。

$ rpm -qa | grep openssl
openssl-libs-1.0.2k-8.el7.x86_64

そのため、OpenSSL1.1.1をインストールすることにする。

OpenSSL-1.0.2は2019-12-31にEOL

また、1.0.2は2019-12-31にEOLなようなので、1.1.1を入れることにする。
https://www.openssl.org/policies/releasestrat.html

The next version of OpenSSL will be 3.0.0.
Version 1.1.1 will be supported until 2023-09-11 (LTS).
Version 1.1.0 will be supported until 2019-09-11.
Version 1.0.2 will be supported until 2019-12-31 (LTS).
Version 1.0.1 is no longer supported.
Version 1.0.0 is no longer supported.
Version 0.9.8 is no longer supported.

OpenSSLのインストール

OpenSSL1.1.1を入れます。以下を参考にしてインストールしてください。
「OpenSSLを共有ライブラリに追加する」も実施してください。(実施しないとpipが使えません。)

参考:CentOS7にOpenSSL1.1.1をインストール

ちなみに、既存のOpenSSLは残したまま、別途1.1.1をインストールするし、Pythonの./configureオプションで1.1.1のライブラリパスを指定するインストール方法を実施する。

依存関係のインストール

以下をインストールする。

$ sudo yum -y install zlib \
                      tk-devel \
                      tcl-devel \
                      ncurses-devel \
                      gdbm-devel \
                      readline-devel \
                      zlib-devel \
                      bzip2-devel \
                      sqlite-devel \
                      openssl-devel \
                      libXext.x86_64 \
                      libSM.x86_64 \
                      libXrender.x86_64 \
                      gcc \
                      gcc-c++ \
                      libffi-devel \
                      python-devel \
                      patch \
                      bzip2 \
                      make

matplotlib使うなら下記もインストールする。
後から追加した場合、Pythonのリビルドが必要となる。

$ sudo yum install -y tk.x86_64 tk-devel.x86_64 tkinter.x86_64

Pythonのダウンロード

以下からインストールするversionを選ぶ。
https://www.python.org/

ここでは3.7をインストールする。

$ sudo curl https://www.python.org/ftp/python/3.7.3/Python-3.7.3.tgz -o /usr/local/src/Python-3.7.3.tgz

Pythonのインストール

--with-openssl=/usr/local/openssl-1.1.1で先程インストールしたOpenSSLのパスを指定する。
--with-ensurepipを付けることでpip3もインストールする。
--enable-optimizationsを付けると、11%ほどパフォーマンスが上がるらしい。ただし、makeにすごく時間がかかる。

$ cd /usr/local/src
$ sudo tar xvfz Python-3.7.3.tgz
$ cd Python-3.7.3
$ sudo ./configure --enable-unicode=ucs4 \
                   --prefix=/usr/local \
                   --with-openssl=/usr/local/openssl-1.1.1 \
                   --with-ensurepip \
                   --enable-optimizations
$ sudo make
$ sudo make altinstall

make altinstallについて

https://docs.python.org/ja/3/using/unix.html#building-python

警告 make install は python3 バイナリを上書きまたはリンクを破壊してしまうかもしれません。そのため、make install の代わりに exec_prefix/bin/pythonversion のみインストールする make altinstall が推奨されています。

インストールされたことを確認

以下にインストールされる。

$ sudo ls -l /usr/local/bin/
total 24644
-rwxr-xr-x 1 root root      101 Apr 17 11:22 2to3-3.7
-rwxr-xr-x 1 root root      241 Apr 17 11:22 easy_install-3.7
-rwxr-xr-x 1 root root       99 Apr 17 11:22 idle3.7
-rwxr-xr-x 1 root root      223 Apr 17 11:22 pip3.7
-rwxr-xr-x 1 root root       84 Apr 17 11:22 pydoc3.7
-rwxr-xr-x 2 root root 12603000 Apr 17 11:22 python3.7
-rwxr-xr-x 2 root root 12603000 Apr 17 11:22 python3.7m
-rwxr-xr-x 1 root root     3105 Apr 17 11:22 python3.7m-config
-rwxr-xr-x 1 root root      441 Apr 17 11:22 pyvenv-3.7

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ライブラリ一覧とバージョンを確認する

はじめに

 インストールしたライブラリとバージョンは次の方法で確認できる。

import pkg_resources
for dist in pkg_resources.working_set:
    print(dist.project_name,dist.version)

出力

zict 0.1.3
xlwt 1.3.0
xlwings 0.11.4
XlsxWriter 1.0.2
xlrd 1.1.0
wrapt 1.10.11
wincertstore 0.2
win-unicode-console 0.5
win-inet-pton 1.0.1
widgetsnbextension 3.0.2
wheel 0.29.0
Werkzeug 0.12.2
webencodings 0.5.1
wcwidth 0.1.7
urllib3 1.22
unicodecsv 0.14.1
typing 3.6.2
traitlets 4.3.2
tornado 4.5.2
toolz 0.8.2
Theano 1.0.1
testpath 0.3.1
tensorflow 1.1.0
tblib 1.3.2
tables 3.4.2
sympy 1.1.1
statsmodels 0.8.0
SQLAlchemy 1.1.13
spyder 3.2.4
sphinxcontrib-websupport 1.0.1
Sphinx 1.6.3
sortedcontainers 1.5.7
sortedcollections 0.5.3
snowballstemmer 1.2.1
six 1.11.0
singledispatch 3.4.0.3
simplegeneric 0.8.1
setuptools 36.5.0.post20170921
seaborn 0.8
scipy 0.19.1
scikit-learn 0.19.1
scikit-image 0.13.0
ruamel-yaml 0.11.14
rope 0.10.5
requests 2.18.4
requests-toolbelt 0.8.0
requests-oauthlib 0.8.0
QtPy 1.3.1
qtconsole 4.3.1
QtAwesome 0.4.4
pyzmq 16.0.2
PyYAML 3.12
pywin32 221
PyWavelets 0.5.2
pytz 2017.2
python-dateutil 2.6.1
pytest 3.2.1
PySocks 1.6.7
pyparsing 2.2.0
pyOpenSSL 17.2.0
pyodbc 4.0.17
pylint 1.7.4
Pygments 2.2.0
pyflakes 1.6.0
pycurl 7.43.0
pycrypto 2.6.1
pycparser 2.18
pycosat 0.6.3
pycodestyle 2.3.1
py 1.4.34
psutil 5.4.0
protobuf 3.5.1
prompt-toolkit 1.0.15
progress 1.3
ply 3.10
pkginfo 1.4.1
pip 9.0.1
Pillow 4.2.1
pickleshare 0.7.4
pep8 1.7.0
patsy 0.4.1
pathlib2 2.3.0
path.py 10.3.1
partd 0.3.8
pandocfilters 1.4.2
pandas 0.20.3
packaging 16.8
openpyxl 2.4.8
olefile 0.44
odo 0.5.1
oauthlib 2.0.6
numpydoc 0.7.0
numpy 1.12.1
numexpr 2.6.2
numba 0.35.0
notebook 5.0.0
nose 1.3.7
nltk 3.2.4
networkx 2.0
nbformat 4.4.0
nbconvert 5.3.1
navigator-updater 0.1.0
multipledispatch 0.4.9
msgpack-python 0.4.8
mpmath 0.19
mistune 0.7.4
menuinst 1.4.14
mccabe 0.6.1
matplotlib 2.1.0
MarkupSafe 1.0
lxml 4.1.0
lockfile 0.12.2
locket 0.2.0
llvmlite 0.20.0
lazy-object-proxy 1.3.1
Keras 2.0.5
jupyterlab 0.27.0
jupyterlab-launcher 0.4.0
jupyter-core 4.3.0
jupyter-console 5.2.0
jupyter-client 5.1.0
jsonschema 2.6.0
Jinja2 2.9.6
jedi 0.10.2
jdcal 1.3
itsdangerous 0.24
isort 4.2.15
ipywidgets 7.0.0
ipython 6.1.0
ipython-genutils 0.2.0
ipykernel 4.6.1
imagesize 0.7.1
imageio 2.2.0
idna 2.6
html5lib 0.999999999
heapdict 1.0.0
h5py 2.7.0
greenlet 0.4.12
glob2 0.5
gevent 1.2.2
flickrapi 2.3.1
Flask 0.12.2
Flask-Cors 3.0.3
filelock 2.0.12
fastcache 1.0.2
et-xmlfile 1.0.1
entrypoints 0.2.3
docutils 0.14
distributed 1.19.1
distlib 0.2.5
decorator 4.1.2
datashape 0.5.4
dask 0.15.3
cytoolz 0.8.2
Cython 0.26.1
cycler 0.10.0
cryptography 2.0.3
contextlib2 0.5.5
conda 4.6.12
conda-verify 2.0.0
conda-build 3.0.27
comtypes 1.1.2
colorama 0.3.9
clyent 1.2.2
cloudpickle 0.4.0
click 6.7
chardet 3.0.4
cffi 1.10.0
certifi 2017.7.27.1
CacheControl 0.12.3
Bottleneck 1.2.1
boto 2.48.0
bokeh 0.12.10
bleach 2.0.0
blaze 0.11.3
bkcharts 0.2
bitarray 0.8.1
beautifulsoup4 4.6.0
backports.shutil-get-terminal-size 1.0.0
astropy 2.0.2
astroid 1.5.3
asn1crypto 0.22.0
anaconda-project 0.8.0
anaconda-navigator 1.6.12
anaconda-client 1.6.5
alabaster 0.7.10
babel 2.5.0
deap 1.2.2

参考文献

  • 『データサイエンティスト養成読本 登竜門編』(2017)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Python 3.7.4 からGC対象オブジェクトのメモリ使用量が8バイト増えるかも

x86-64 の ABI では、 int128 や long double 型は 16byte 境界に配置することになっています。

しかし Python がもっている pymalloc 実装は 8 バイト境界のメモリブロックを返すようになっています。。。大丈夫か?
16byte alignment を要求する型が入った構造体を malloc しようとすると 16byte の倍数になるはずなので、malloc(sizoef(構造体)) ならセーフで、 malloc(sizeof(構造体)+16の倍数じゃないバイト数) みたいなケースでは問題になりそう。

それよりも問題なのがGCヘッダ。64bit環境でのGCヘッダは 24byte です。「ヘッダ」という名前が示すとおり、GC対象オブジェクト(循環参照を構成するかもしれないオブジェクト。tuple,list,dictなど。)の先頭に配置されます。

GC対象オブジェクトを生成するときは、 malloc(sizeof(GCヘッダ) + オブジェクトサイズ) のようにメモリ確保してからGCヘッダ分ずらしたアドレスを PyObject* 型のポインタに利用します。なので malloc が 16byte 境界アドレスを返しても、 +24byte したアドレスに Python オブジェクトが格納されることになり、そのオブジェクトの構造体に int128 や long double 型があると 16byte 境界をまたぐように配置されてしまいます。

最近のコンパイラは実際に 16byte 境界を前提にした命令を利用するようになっているようで、「理論上は違反しているが実際は問題なく動いている」ではなく「本当にセグフォで落ちる」問題になってしまいました。

最近まで気づかなかったのですが、 Python 2.7 で先にこの現象が報告されていて、 2.7.15 でGCヘッダが 24byte から 32byte に増やされていました。 (changelog, commit, issue)

最近 Python 3.7 でも同様の問題が報告された (クラッシュのissue, 昔からあったubsanエラーのissue) ので、ABI互換を破壊しない他の良い方法が見つからない限りは同じ修正を適用するしかなさそうです。 long double とか int128 とかいったレアな型のために、大量にある&それらの型を絶対に入れることがないタプルのメモリ消費を+8バイトしないといけないのは、ケチな私からすると惜しいです。

ところで、Python 3.8 ではGCヘッダの中身を3ワード(64bit環境で24byte)から2ワード(同16byte)に削って、GC対象オブジェクトstr,bytes,int,floatなどは対象外)のメモリ使用量を8バイト削ることに成功していました。そのためこの問題の影響を受けることなく、余計なパディングは必要ありません。結果的に Python 2.7.15 以降や多分 3.7.4 以降に比べると16byteの削減になります。この改善に成功していて本当に良かった。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

PNGからM5Stackで表示できるBitmapのテキストデータに変換するPythonツール

M5Stackを買いました!
どうやら人気らしくネットでの在庫がなくなっているようです。(2019.04現在)
DSC_1633.JPG

何をしてよいのか分からなかったのですが、SDカードに入ったjpeg画像は簡単に表示できるということを知って、早速表示してみました。
ArduinoIDEはすでに入っていたので簡単なスケッチを書くだけです。

void setup(void) {
  M5.begin();
  M5.Lcd.drawJpgFile(SD, "/miku.jpg");
}

DSC_1632.JPG
コードを書くよりも、16GB以下のマイクロSDカードを部屋で探す方が時間がかかりました(笑)

次はM5.LCD.drawRGBBitmapを使って、ドット絵などの小さい画像を表示させます。
画像を切り替えてアニメーションさせるために、SDカードの画像ファイルではなくプログラム内に画像データとして置きます。
M5Stack Animation Test

このときに画像をテキストデータに変換するのですが、適当なツールが見つけられなかったので、簡単なコンバータをPythonで作りました。
ソースコードはこちら。
https://github.com/iikagenlabo/png2img

python png2img.py <pngfile>

とすると、画面にテキストデータが表示されます。
コピペするかリダイレクトでファイルにしてコードに埋め込んでください。

//  例
const unsigned short img0[] = {
  0x0000,0x0000,0x0000,0x3800,0xD800,0xC800,0xC800,0xC800,
  0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,
  0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,
  0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,0xC800,
};
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ROSでのpythonのプログラムからロボットのゴールを指定する。

はじめに

rosで目的地まで自律移動させる際に使っているrvizの「2D Nav Goal」をプログラム上から指定することを目的としています。個人的にpythonで処理をしてから目的地の決定をしたいと思ったのでpythonでやる方法を調査しました。

コード

以下ソースコードです。

sample.py
#!/usr/bin/env python

import rospy
import actionlib
import tf
from nav_msgs.msg import Odometry
import math
from move_base_msgs.msg import MoveBaseAction, MoveBaseGoal

def goal_pose(pose):
    goal_pose = MoveBaseGoal()
    goal_pose.target_pose.header.frame_id = 'map'
    goal_pose.target_pose.pose.position.x = pose[0][0]
    goal_pose.target_pose.pose.position.y = pose[0][1]
    goal_pose.target_pose.pose.position.z = pose[0][2]
    goal_pose.target_pose.pose.orientation.x = pose[1][0]
    goal_pose.target_pose.pose.orientation.y = pose[1][1]
    goal_pose.target_pose.pose.orientation.z = pose[1][2]
    goal_pose.target_pose.pose.orientation.w = pose[1][3]

    return goal_pose


if __name__ == '__main__':
    rospy.init_node('patrol')
    listener = tf.TransformListener()

    client = actionlib.SimpleActionClient('move_base', MoveBaseAction)
    client.wait_for_server()
    listener.waitForTransform("map", "base_link", rospy.Time(), rospy.Duration(4.0))

    pose = [(-24.1430511475,-1.39947879314,0.0),(0.0,0.0,0.712479235583,0.701693194255)]
    goal = goal_pose(pose)
    client.send_goal(goal)

参考

https://github.com/HotBlackRobotics/hotblackrobotics.github.io/blob/master/en/blog/_posts/2018-01-29-action-client-py.md
https://hotblackrobotics.github.io/en/blog/2018/01/29/action-client-py/
https://www.robotech-note.com/entry/2018/04/16/080816

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

ADALINEのまとめ

はじめに

ADALINE を一から実装したのでそのまとめ

ADALINE とパーセプトロンの違い

  • 重みの更新方法

    • パーセプトロンは単位ステップ関数で重みの更新を行います
    • ADALINE は挿入力の高等関数を使う(Hidrow-Hoff 測と呼ばれます)
φ(w^Tx) = w^Tx
  • クラスラベルの予測

    • パーセプトロンは活性化関数をそのまま出力します
    • ADALINE は量子化器を使います

コスト関数の定義

教師あり学習を構成する要素として、最適化される目的関数を定義することがあります。
多くの場合にはこの目的関数は最小化したいコスト関数です。ADALINE ではコスト関数$J(w)$として定義します。
ADALINE の場合計算結果と本当のクラスラベルとの誤差平方和をとります。

J(w) = \frac{1}{2}\sum_i(y^{(i)}-φ(z^{(i)}))^2

重みベクトル$w$の各重み$w_i$は同時に更新され以下の式で表されます。

w_i := w_i + \Delta w_i

$\Delta w_i$の計算は以下のようにされます。

\Delta w_i = \eta(y_i - \breve{y_i})x_i^{(i)}

$\eta$は学習率で$0<\eta<1$です。
$y_i$はトレーニングクラスラベルで$\breve{y_i}$は予測クラスラベルです。

ADALINE の実装

実装環境

  • python 3.6

  • JupyterLab 0.35.4

コード

コスト関数の最小化については勾配降下法を使っています。

class AdalineGD(object):
    """
    パラメータ
    eta:学習率
    n_iter:トレーニング回数

    属性
    w_:一次元配列、適合後の重み
    errors_:リスト、各エポックでの誤分類数
    """
    def __init__(self,eta = 0.01,n_iter = 50):
        self.eta = eta
        self.n_iter = n_iter

    def fit(self,X,y):
        """
        パラメータ
        X:配列のようなデータ構造,shape = {n_sample,n_features}
        n_samplesはサンプルの個数、n_featuresは特徴量の個数
        y:目的変数

        戻り値
        self:object
        """
        self.w_ = np.zeros(1 + X.shape[1])
        self.cost_ = []
        #トレーニング回数分トレーニングデータを反復
        for i in range(self.n_iter):
            #活性化関数の出力の計算
            output = self.net_input(X)
            #誤差の計算
            errors = (y-output)
            #w1以降の更新
            self.w_[1:] += self.eta*X.T.dot(errors)
            #w0の更新
            self.w_[0] += self.eta*errors.sum()
            #コスト関数の計算(勾配降下法)
            cost = (errors**2).sum()/2.0
            #コストの格納
            self.cost_.append(cost)
        return self
    #挿入力の計算
    def net_input(self,X):
        return np.dot(X,self.w_[1:])+self.w_[0]
    #活性化関数の出力を計算
    def activation(self,X):
        return self.net_input(X)
    #1ステップ後のクラスラベルを返す
    def predict(self,X):
        return np.where(self.activation(X) >= 0.0,1,-1)

学習するデータセットはパーセプトロンと同じアヤメのデータセットを使います

#Irisデータセットの入手
import pandas as pd

df = pd.read_csv('https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data',header=None)

散布図を描画します

#グラフの描画
import matplotlib.pyplot as plt
#1-100番目まで目的変数の抽出
y = df.iloc[0:100,4].values
#Iris-setosa を-1 iris-verginica を1に変換
y = np.where(y == 'Iris-setosa',-1,1)
#1-100行目の1,3列めの抽出
X = df.iloc[0:100,[1,3]].values
#グラフのプロット
plt.scatter(X[:50,0],X[:50,1],color = 'red',marker = 'o',label = 'setosa')
plt.scatter(X[50:100,0],X[50:100,1],color = 'blue',marker = '*',label='versicolor')
#軸ラベルの設定
plt.xlabel('speal length [cm]')
plt.ylabel('petal length [cm]')
plt.show()

dataset.png

次に学習率$\eta$を 0.01 と 0.001 に設定してコスト関数とエポック数をプロットします

import matplotlib.pyplot as plt
#描画領域を1行2列に変換
fig,ax = plt.subplots(nrows=1,ncols=2,figsize=(8,4))
#勾配降下法によるAdaLineGDの学習
ada1 = AdalineGD(n_iter=10,eta=0.01).fit(X,y)
#エポック数とコストの関係を示す折れ線グラフのプロット
ax[0].plot(range(1,len(ada1.cost_)+1),np.log10(ada1.cost_),marker='o')
#軸ラベルの設定
ax[0].set_xlabel=('Epochs')
ax[0].set_ylabel=('sum-squared-error')
#タイトルの設定
ax[0].set_title('Adaline - Learning rate 0.01')
#勾配降下法によるAdaLineGDの学習
ada2 = AdalineGD(n_iter=10,eta=0.0001).fit(X,y)
#エポック数とコストの関係を示す折れ線グラフのプロット
ax[1].plot(range(1,len(ada2.cost_)+1),ada2.cost_,marker='o')
#軸ラベルの設定
ax[1].set_xlabel=('Epochs')
ax[1].set_ylabel=('sum-squared-error')
#タイトルの設定
ax[1].set_title('Adaline - Learning rate 0.0001')

plt.show()

error.png

ここで得られたグラフから、右のグラフでは学習率が大きすぎると誤差平方和が増加していることがわかるった。
左のグラフでは、学習率が非常に小さいので収束させるのに相当な数のエポック数が必要になることがわかった。

スケーリングをする

機械学習のアルゴリズムは、最適なパフォーマンスを実現するために何等かの特徴量スケーリングを必要とします。
今回は、標準化というスケーリング手法をとります。

標準化は、各特徴量を 0 として標準偏差を 1 にするというものです。
例えば、$j$番目の特徴量を標準化するには、サンプルの平均$\mu_j$をすべてのトレーニングサンプルから引いて、標準偏差$\sigma_j$で割ります。

x_j = \frac{x_j-\mu_j}{\sigma_j}

この場合に$x_j$はすべてのトレーニングサンプルの$j$番目の特徴量の値からなるベクトルです。
numpyのmeanメソッドstdメソッドを使うと簡単に実装できます。

  • meanメソッド 平均を計算する

  • stdメソッド 標準偏差を計算する

#データのコピー
X_std = np.copy(X)
#各列の標準化
X_std[:,0] = (X[:,0]-X[:,0].mean())/X[:,0].std()
X_std[:,1] = (X[:,1]-X[:,1].mean())/X[:,1].std()

標準化の後に、学習率$\eta = 0.01$を使ってトレーニングして収束することを確認します。

from matplotlib.colors import ListedColormap

def plot_decision_regions(X,y,classifier,resolution = 0.02):
    #マーカーとカラーマップの用意
    markers = ('s','x','o','^','v')
    colors = ('red','blue','lightgreen','gray','cyan')
    cmap = ListedColormap(colors[:len(np.unique(y))])
    #決定領域のプロット
    x1_min,x1_max = X[:,0].min() - 1,X[:,0].max() + 1
    x2_min,x2_max = X[:,1].min() - 1,X[:,1].max() + 1
    #グリッドポイントの作成
    xx1,xx2 = np.meshgrid(np.arange(x1_min,x1_max,resolution),
                         np.arange(x2_min,x2_max,resolution))
    #特徴量を一次元配列に変換して予測を実行する
    Z = classifier.predict(np.array([xx1.ravel(),xx2.ravel()]).T)
    #予測結果をグリッドポイントのデータサイズに変換
    Z = Z.reshape(xx1.shape)
    #グリッドポイントの等高線のプロット
    plt.contourf(xx1,xx2,Z,alpha = 0.4,cmap = cmap)
    #軸の範囲の設定
    plt.xlim(xx1.min(),xx1.max())
    plt.ylim(xx2.min(),xx2.max())
    #クラスごとにサンプルをプロット
    #matplotlibが1.5.0以下ならc = cmapをc=colors[idx]に変更
    for idx,cl in enumerate(np.unique(y)):
        plt.scatter(x=X[y==cl,0],y=X[y == cl,1],alpha=0.8,c = cmap(idx),marker=markers[idx],label=cl)
#勾配降下法によるADALINEの学習(標準化後)
ada = AdalineGD(n_iter=15,eta=0.01)
#モデルの適合
ada.fit(X_std,y)
#境界領域のプロット
plot_decision_regions(X_std,y,classifier=ada)
#タイトルの設定
plt.title('Adaline - Gradient Descent')
#軸ラベルの設定
plt.xlabel('sepal length [standardized]')
plt.ylabel('petal length [standardized]')
#凡例の設定
plt.legend(loc = 'upper left')
# 保存先のファイル名(PNG形式)
fname = "gradient.png"
plt.savefig(fname, dpi = 128, tight_layout = True)
plt.show()

#エポック数とコストの関係性を示す折れ線グラフのプロット
plt.plot(range(1,len(ada.cost_) + 1),ada.cost_,marker='o')
#軸ラベルの設定
plt.xlabel('Epochs')
plt.ylabel('Sum quared error')
# 保存先のファイル名(PNG形式)
fname = "sum_error.png"
plt.savefig(fname, dpi = 128, tight_layout = True)
plt.show()

gradient.png

sum_error.png

グラフからわかったように、データの標準化をすることでADALINEが収束することが分かった。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

蟻本をPythonで (初級編)

はじめに

蟻本(プログラミングコンテストチャレンジブック)は C++ で書かれているので、それを Python で書きました。詳しい解説は本に書いてあるため省略します。また、AtCoder 版!蟻本 (初級編)に載っている類題についても扱います。類題については先にこちらのリンク先で問題を見てから読むことを推奨します。
現在 2-2 までを載せています(少しずつ更新していきます)。

2 初級編

2-1 すべての基本 "全探索"

スタックとキュー

Python では list 型の pop メソッドを使うことで以下のようにスタックとキューを扱うことができます。

# スタック
s = []
s.append(1)  # [1]
s.append(2)  # [1, 2]
s.append(3)  # [1, 2, 3]
s.pop()      # 一番上から取り除く [1, 2, 3] -> [1, 2]
s.pop()      # [1, 2] -> [1]
s.pop()      # [1] -> []


# キュー
q = []
q.append(1)  # [1]
q.append(2)  # [1, 2]
q.append(3)  # [1, 2, 3]
q.pop(0)     # 一番下から取り除く [1, 2, 3] -> [2, 3]
q.pop(0)     # [2, 3] -> [3]
q.pop(0)     # [3] -> []

しかし、list 型だと要素を取り除く際に O(n) かかってしまいます。そこで、この操作を O(1) で行うことができる collections.deque を利用します。

スタック

from collections import deque

s = deque([])
s.append(1)  # [1]
s.append(2)  # [1, 2]
s.append(3)  # [1, 2, 3]
s.pop()      # 一番上から取り除く [1, 2, 3] -> [1, 2]
s.pop()      # [1, 2] -> [1]
s.pop()      # [1] -> []

キュー

スタックと同様に collections.deque で扱うことができます。スタックでは取り除くときに pop だったのが、キューだと popleft になっているだけです。

from collections import deque

q = deque([])
q.append(1)  # [1]
q.append(2)  # [1, 2]
q.append(3)  # [1, 2, 3]
q.popleft()  # 一番下から取り除く [1, 2, 3] -> [2, 3]
q.popleft()  # [2, 3] -> [3]
q.popleft()  # [3] -> []

例題 2-1-1 部分和問題

部分和問題

# i までで sum を作って、残り i 以降を調べる
def dfs(i, sum):
    # n 個決め終わったら、今までの和 sum が k と等しいかを返す
    if i == n:
        return sum == k

    # a[i] を使わない場合
    if dfs(i + 1, sum):
        return True

    # a[i] を使う場合
    if dfs(i + 1, sum + a[i]):
        return True

    # a[i] を使う使わないに拘らず k が作れないので False を返す
    return False


n, k = map(int, input().split())
a = list(map(int, input().split()))

if dfs(0, 0):
    print("Yes")
else:
    print("No")

実はこの問題は再帰以外に bit で解くこともでき、以下のようになります。

n, k = map(int, input().split())
a = list(map(int, input().split()))

# 0 から (2^n)-1 までループ
for bit in range(1 << n):
    sum = 0

    for i in range(n):
        # bit に i 番目のフラグが立っているかどうか
        if bit & (1 << i):
            # フラグが立っているならば sum に加算する
            sum += a[i]

    if sum == k:
        print("Yes")
        exit()

print("No")

bit 全探索についてはビット演算 (bit 演算) の使い方を総特集! 〜 マスクビットから bit DP まで 〜を参考にしました。

ABC 045 C たくさんの数式

・再帰

def dfs(i, f):
    if i == n - 1:
        return sum(list(map(int, f.split("+"))))

    # 式 f の末尾に "+" を追加するかしないかして次の数字を追加
    return dfs(i + 1, f + s[i + 1]) + \
           dfs(i + 1, f + "+" + s[i + 1])


s = input()
n = len(s)

print(dfs(0, s[0]))

・bit

s = input()
n = len(s)

ans = 0

for bit in range(1 << (n - 1)):
    # 各場合で式 f を生成する
    f = s[0]

    for i in range(n - 1):
        if bit & (1 << i):
            # フラグが立っているならば "+" を式の末尾に追加する
            f += "+"
        f += s[i + 1]

    ans += sum(map(int, f.split("+")))

print(ans)

ABC 079 C Train Ticket

ABC 045 C たくさんの数式とほぼ同じです。

・再帰

def dfs(i, f, sum):
    if i == 3:
        if sum == 7:
            # 答えは1つ出力すれば良いので =7 になれば終了
            print(f + "=7")
            exit()

    else:
        # 式 f の末尾に符号と次の数字を追加し、その分 sum に加減する
        dfs(i + 1, f + "-" + s[i + 1], sum - int(s[i + 1]))
        dfs(i + 1, f + "+" + s[i + 1], sum + int(s[i + 1]))


s = input()

dfs(0, s[0], int(s[0]))

・bit

s = input()

for bit in range(1 << 3):
    ans = int(s[0])
    f = s[0]

    for i in range(3):
        # フラグが立っていれば "+" 、なければ "-"
        if bit & (1 << i):
            ans += int(s[i + 1])
            f += "+"
        else:
            ans -= int(s[i + 1])
            f += "-"
        f += s[i + 1]

    if ans == 7:
        print(f + "=7")
        exit()

ABC 104 C All Green

中途半端に解く配点は1種類以下で良いので、各配点について解くか解かないかを決め、その上で G 点に満たなければまだ解いてない配点のうち一番高い配点のものを足りない分解けば良いことになります。

・再帰

# まだ解いてない配点を nokori として持つ
def dfs(i, sum, count, nokori):
    global ans
    if i == d:
        # G 点に満たなければ nokori のうち一番大きいものを解く
        if sum < g:
            use = max(nokori)
            # 解く問題が問題数を超えないように注意
            n = min(pc[use - 1][0], -(-(g - sum) // (use * 100)))
            count += n
            sum += n * use * 100

        if sum >= g:
            ans = min(ans, count)
    else:
        # 総合スコア、解いた問題数、まだ解いてない問題を更新
        dfs(i + 1, sum, count, nokori)
        dfs(i + 1, sum + pc[i][0] * (i + 1) * 100 + pc[i][1], count + pc[i][0], nokori - {i + 1})


d, g = map(int, input().split())
pc = [list(map(int, input().split())) for i in range(d)]

ans = float("inf")

dfs(0, 0, 0, set(range(1, d + 1)))
print(ans)

・bit

d, g = map(int, input().split())
pc = [list(map(int, input().split())) for i in range(d)]

ans = float("inf")

for bit in range(1 << d):
    count = 0
    sum = 0
    nokori = set(range(1, d + 1))

    for i in range(d):
        if bit & (1 << i):
            sum += pc[i][0] * (i + 1) * 100 + pc[i][1]
            count += pc[i][0]
            nokori.discard(i + 1)

    # G 点に満たなければ nokori のうち一番大きいものを解く
    if sum < g:
        use = max(nokori)
        n = min(pc[use - 1][0], -(-(g - sum) // (use * 100)))
        count += n
        sum += n * use * 100

    if sum >= g:
        ans = min(ans, count)

print(ans)

ARC 029 A 高橋君とお肉

・再帰

def dfs(i, a, b):
    global ans
    if i == n:
        ans = min(ans, max(a, b))

    else:
        # a の肉焼き器に乗せるか、 b の肉焼き器に乗せるか
        dfs(i + 1, a + t[i], b)
        dfs(i + 1, a, b + t[i])


n = int(input())
t = [int(input()) for i in range(n)]

ans = float("inf")

dfs(0, 0, 0)
print(ans)

・bit

n = int(input())
t = [int(input()) for i in range(n)]

ans = float("inf")

for bit in range(1 << n):
    a = 0
    b = 0

    for i in range(n):
        # フラグが立っていれば a に、なければ b に乗せる
        if bit & (1 << i):
            a += t[i]
        else:
            b += t[i]

    ans = min(ans, max(a, b))

print(ans)

ABC 002 D 派閥

・再帰

import itertools


# 形成した派閥を group として持つ
def dfs(i, group):
    global ans
    if i == n:
        # group 内の全員が知り合い同士か
        flag = True

        # group 内から2人選ぶ組み合わせのループ
        for i in itertools.combinations(group, 2):
            # 1人でも知り合いでなければ終了
            if friend[i[0]][i[1]] == 0:
                flag = False
                break

        if flag:
            ans = max(ans, len(group))

    else:
        dfs(i + 1, group)
        dfs(i + 1, group + [i])


n, m = map(int, input().split())
friend = [[0] * n for i in range(n)]
for i in range(m):
    x, y = map(int, input().split())
    x -= 1
    y -= 1
    friend[x][y] = 1
    friend[y][x] = 1

ans = 0

dfs(0, [])
print(ans)

・bit

import itertools

n, m = map(int, input().split())
friend = [[0] * n for i in range(n)]
for i in range(m):
    x, y = map(int, input().split())
    x -= 1
    y -= 1
    friend[x][y] = 1
    friend[y][x] = 1

ans = 0

for bit in range(1 << n):
    group = []

    for i in range(n):
        if bit & (1 << i):
            group.append(i)

    # group 内の全員が知り合い同士か
    flag = True

    # group 内から2人選ぶ組み合わせのループ
    for i in itertools.combinations(group, 2):
        # 1人でも知り合いでなければ終了
        if friend[i[0]][i[1]] == 0:
            flag = False
            break

    if flag:
        ans = max(ans, len(group))

print(ans)

例題 2-1-1 Lake Counting (POJ No.2386)

Lake Counting (POJ No.2386)

# 現在位置 (x, y)
def dfs(x, y):
    # 今いるところを . に置き換える
    field[x][y] = "."

    # 移動する8方向をループ
    for dx in range(-1, 2):
        for dy in range(-1, 2):
            # x, y 方向それぞれに dx, dy 移動した場所を (nx, ny) とする
            nx = x + dx
            ny = y + dy

            # nx と ny が庭の範囲内かどうかと field[nx][ny] が水溜りかどうかを判定
            if 0 <= nx and nx < n and 0 <= ny and ny < m and field[nx][ny] == "W":
                dfs(nx, ny)


n, m = map(int, input().split())
field = [list(input()) for i in range(n)]

res = 0
for i in range(n):
    for j in range(m):
        if field[i][j] == "W":
            # Wが残っているならそこから dfs をはじめる
            dfs(i, j)
            res += 1
print(res)

ATC 001 A 深さ優先探索

# pythonだとデフォルトの再帰処理回数の上限に引っかかってしまうので、それを変更
import sys
sys.setrecursionlimit(1000000)


def dfs(x, y):
    d[x][y] = 1

    # 移動4方向をループ
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]

        # nx と ny が街の範囲内か、行ったことがないか、塀ではないかを判定
        if 0 <= nx and nx < n and 0 <= ny and ny < m and d[nx][ny] == 0 and c[nx][ny] != "#":
                dfs(nx, ny)


n, m = map(int, input().split())
c = [list(input()) for i in range(n)]

# 到達したかどうか(0は未到達、1は到達済み)
d = [[0] * m for i in range(n)]

# 移動する4方向
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

# スタート地点から dfs を始める
for i in range(n):
    for j in range(m):
        if c[i][j] == "s":
            dfs(i, j)

# ゴール地点に到達したかどうか
for i in range(n):
    for j in range(m):
        if c[i][j] == "g" and d[i][j]:
            print("Yes")
            exit()
print("No")

問題のページにも解説が載っていますが、蟻本の書き方を採用しました。

ARC 031 B 埋め立て

def dfs(x, y):
    field[x][y] = "x"

    # 移動4方向をループ
    for i in range(4):
        nx = x + dx[i]
        ny = y + dy[i]

        # nx と ny が地図の範囲内か、field[nx][ny]が島か判定
        if 0 <= nx and nx < 10 and 0 <= ny and ny < 10 and field[nx][ny] == "o":
                dfs(nx, ny)


A = [list(input()) for i in range(10)]

# 移動する4方向
dx = [1, 0, -1, 0]
dy = [0, 1, 0, -1]

# 埋め立てる1マスを全探索
for p in range(10):
    for q in range(10):
        if A[p][q] == "x":
            # 海だったら A を field にコピーしてそのマスを埋め立てる
            field = [k[:] for k in A]
            field[p][q] = "o"
            count = 0
            # 埋め立てた上で dfs で島の数をカウント
            for i in range(10):
                for j in range(10):
                    if field[i][j] == "o":
                        dfs(i, j)
                        count += 1
            # count (島の数)が1かどうか
            if count == 1:
                print("YES")
                exit()
print("NO")

ARC 037 B バウムテスト

def dfs(now, prev):
    global flag
    # 今いる頂点から行ける頂点を順に next に入れてループ
    for next in g[now]:
        if next != prev:
            if memo[next]:
                # 過去に訪れていれば閉路
                flag = False
            else:
                memo[next] = True
                dfs(next, now)


n, m = map(int, input().split())
g = [[] * n for i in range(n)]
for i in range(m):
    u, v = map(int, input().split())
    u -= 1
    v -= 1
    g[u].append(v)
    g[v].append(u)

# 訪れたことがあるか
memo = [False for i in range(n)]

ans = 0
# 頂点をループ
for i in range(n):
    if not memo[i]:
        flag = True
        dfs(i, -1)
        if flag:
            # 閉路がなければ木である
            ans += 1
print(ans)

例題 2-1-3 迷路の最短路

迷路の最短路

from collections import deque


# (sx, sy) から (gx, gy) への最短距離を求める
# 辿り着けないと INF
def bfs():
    # すべての点を INF で初期化
    d = [[float("inf")] * m for i in range(n)]

    # 移動4方向のベクトル
    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    for i in range(n):
        for j in range(m):
            # スタートとゴールの座標を探す
            if maze[i][j] == "S":
                sx = i
                sy = j
            if maze[i][j] == "G":
                gx = i
                gy = j

    # スタート地点をキューに入れ、その点の距離を0にする
    que = deque([])
    que.append((sx, sy))
    d[sx][sy] = 0

    # キューが空になるまでループ
    while que:
        # キューの先頭を取り出す
        p = que.popleft()
        # 取り出してきた状態がゴールなら探索をやめる
        if p[0] == gx and p[1] == gy:
            break
        # 移動4方向をループ
        for i in range(4):
            # 移動した後の点を (nx, ny) とする
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            # 移動が可能かの判定とすでに訪れたことがあるかの判定
            # d[nx][ny] != INF なら訪れたことがある
            if 0 <= nx and nx < n and 0 <= ny and ny < m and \
                    maze[nx][ny] != "#" and d[nx][ny] == float("inf"):
                # 移動できるならキューに入れ、その点の距離を p からの距離 +1 で確定する
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    return d[gx][gy]


n, m = map(int, input().split())
maze = [list(input()) for i in range(n)]

print(bfs())

ABC 007 C 幅優先探索

蟻本の問題とほぼ全く同じですが、sx と sy 、gx と gy が逆なので注意が必要です。

from collections import deque


def bfs():
    d = [[float("inf")] * c for i in range(r)]

    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    que = deque([])
    que.append((sy, sx))
    d[sy][sx] = 0

    while que:
        p = que.popleft()
        if p[0] == gy and p[1] == gx:
            break
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            if 0 <= nx and nx < r and 0 <= ny and ny < c and\
                maze[nx][ny] != "#" and d[nx][ny] == float("inf"):
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    return d[gy][gx]


r, c = map(int, input().split())
sy, sx = map(int, input().split())
gy, gx = map(int, input().split())
sx -= 1
sy -= 1
gy -= 1
gx -= 1
maze = [list(input()) for i in range(r)]

print(bfs())

JOI 2010 予選 E チーズ

チーズを食べるたびにスタートとゴールが変わる問題です。

from collections import deque


def bfs(sx, sy, gx, gy):
    d = [[float("inf")] * w for i in range(h)]

    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    que = deque([])
    que.append((sx, sy))
    d[sx][sy] = 0

    while que:
        p = que.popleft()
        if p[0] == gx and p[1] == gy:
            break
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            if 0 <= nx and nx < h and 0 <= ny and ny < w and\
                    maze[nx][ny] != "X" and d[nx][ny] == float("inf"):
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    return d[gx][gy]


h, w, n = map(int, input().split())
maze = [list(input()) for i in range(h)]

# 各チーズ工場の座標
g = [0] * n

for i in range(h):
    for j in range(w):
        if maze[i][j] == "S":
            sx = i
            sy = j
        # 書かれているのが数字なら g にその座標を書き込む
        if maze[i][j].isdecimal():
            g[int(maze[i][j]) - 1] = (i, j)

# 1回目は巣をスタート、硬さ1のチーズ工場をゴールにする
ans = bfs(sx, sy, g[0][0], g[0][1])
# それ以降は前回の工場をスタート、次の工場をゴールにする
for i in range(1, n):
    ans += bfs(g[i - 1][0], g[i - 1][1], g[i][0], g[i][1])
print(ans)

ABC 088 D Grid Repainting

最短経路のマス以外は塗ることができるため、白いマスの個数から最短経路のマス分とゴールのマスを引けば求められます。

from collections import deque


def bfs():
    d = [[float("inf")] * w for i in range(h)]

    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    que = deque([])
    que.append((sx, sy))
    d[sx][sy] = 0

    while que:
        p = que.popleft()
        if p[0] == gx and p[1] == gy:
            break
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]

            if 0 <= nx and nx < h and 0 <= ny and ny < w and\
                    maze[nx][ny] != "#" and d[nx][ny] == float("inf"):
                que.append((nx, ny))
                d[nx][ny] = d[p[0]][p[1]] + 1

    return d[gx][gy]


h, w = map(int, input().split())
maze = [list(input()) for i in range(h)]
sx, sy = 0, 0
gx, gy = h - 1, w - 1

# 白いマスを数える
white = 0
for i in range(h):
    for j in range(w):
        if maze[i][j] == ".":
            white += 1

res = bfs()
if 0 < res < float("inf"):
    # 白いマスの数から最短経路でかかるコスト分を引く
    # ゴールを黒いマスに変えることはできないためその分も引く
    print(white - res - 1)
else:
    print(-1)

ARC 005 C 器物損壊!高橋君

壁を壊した回数も含めて考える必要があるため、今までの d[x][y] を d[x][y][t](t は壊した回数) として解きます。また、 Python だと BFS で解くと TLE になってしまうため、今回は DFS (deque の popleft を pop に変えただけです)を使いました。 BFS で解けた方いましたら教えていただけると嬉しいです。

from collections import deque


def dfs():
    d = [[[False] * 3 for j in range(w)] for i in range(h)]

    dx = [1, 0, -1, 0]
    dy = [0, 1, 0, -1]

    for i in range(h):
        for j in range(w):
            if maze[i][j] == "s":
                sx = i
                sy = j
            if maze[i][j] == "g":
                gx = i
                gy = j

    que = deque([])
    # 3つ目は壊した回数
    que.append((sx, sy, 0))
    # 座標と壊した回数ごとに行ける行けないを持つ
    d[sx][sy][0] = True

    while que:
        # ここが popleft ではなく pop になっているためスタックになり、これはDFSです
        p = que.pop()
        if p[0] == gx and p[1] == gy:
            break
        for i in range(4):
            nx = p[0] + dx[i]
            ny = p[1] + dy[i]
            t = p[2]

            if not (0 <= nx and nx < h and 0 <= ny and ny < w):
                continue
            # すでに2回壊してる状態で壁に当たると進めない
            if t == 2 and maze[nx][ny] == "#":
                continue
            if d[nx][ny][t]:
                continue
            # 壁なら壊して進む
            if maze[nx][ny] == "#":
                que.append((nx, ny, t + 1))
                d[nx][ny][t + 1] = True
            else:
                que.append((nx, ny, t))
                d[nx][ny][t] = True

    # ゴールの座標を壊した回数でループ
    for i in range(3):
        if d[gx][gy][i]:
            return True


h, w = map(int, input().split())
maze = [list(input()) for i in range(h)]

if dfs():
    print("YES")
else:
    print("NO")

例題 2-1-4 特殊な状態の列挙

特殊な状態の列挙

Python には順列や組み合わせを列挙することのできる itertools というライブラリがあります。

import itertools


# 順列
# permutations(list, n) で list から n 個選んで並べる
for i in itertools.permutations([0, 1, 2], 3):
    print(i)
# (0, 1, 2)
# (0, 2, 1)
# (1, 0, 2)
# (1, 2, 0)
# (2, 0, 1)
# (2, 1, 0)


# 組み合わせ
# combinations(list, n) で list から n 個選ぶ
for i in itertools.combinations([0, 1, 2], 2):
    print(i)
# (0, 1)
# (0, 2)
# (1, 2)

ABC 054 C One-stroke Path

import itertools

n, m = map(int, input().split())

path = [[False] * n for i in range(n)]
for i in range(m):
    a, b = map(int, input().split())
    a -= 1
    b -= 1
    path[a][b] = True
    path[b][a] = True

ans = 0

# 頂点を並び替える順列を生成してループ
for i in itertools.permutations(range(n), n):
    # 頂点1が始点
    if i[0] == 0:
        # 生成した順列の中をさらにループ
        for j in range(n):
            # n - 1 まで続いたら条件を満たすパスが存在する
            if j == n - 1:
                ans += 1
                break
            # i[j] から i[j + 1] に行くパスがなければ終了
            if not path[i[j]][i[j + 1]]:
                break

print(ans)

JOI 2009 予選 D カード並べ

import itertools

n = int(input())
k = int(input())
card = [input() for i in range(n)]

# set を使うと重複せずに数えられる
number = set()
# card から k 個選んで並び替える
for i in itertools.permutations(card, k):
    # 並び替えたものを繋げて1つの文字列にする
    number.add("".join(i))

print(len(number))

2-2 猪突猛進! "貪欲法"

例題 2-2-1 硬貨の問題

硬貨の問題

c = list(map(int, input().split()))
a = int(input())

# コインの金額
v = [1, 5, 10, 50, 100, 500]
ans = 0

for i in range(1, 7):
    t = min(a // v[-i], c[-i])  # コイン i を使う枚数
    a -= t * v[-i]
    ans += t

print(ans)

JOI 2007 予選 A おつり

「硬貨の問題」の各硬貨を十分にたくさん持っているバージョンです。

# おつりの金額
a = 1000 - int(input())

v = [1, 5, 10, 50, 100, 500]
ans = 0

for i in range(1, 7):
    t = a // v[-i]
    a -= t * v[-i]
    ans += t

print(ans)

例題 2-2-2 区間スケジューリング問題

区間スケジューリング問題

# 多次元リストの sort に使える
from operator import itemgetter

n = int(input())
s = list(map(int, input().split()))
t = list(map(int, input().split()))

st = sorted([(s[i], t[i]) for i in range(n)], key=itemgetter(1))

ans = 0
# 最後に選んだ仕事の終了時間
last = 0

for i in range(n):
    if last < st[i][0]:
        ans += 1
        last = st[i][1]

print(ans)

KUPC 2015 A 東京都

t = int(input())

for i in range(t):
    s = input()
    ans = 0
    j = 0

    while j < len(s) - 4:
        # 前から5文字ずつ見ていく
        if s[j:j + 5] == "tokyo" or s[j:j + 5] == "kyoto":
            ans += 1
            # 一致すれば5文字分進める
            j += 5
        else:
            j += 1

    print(ans)

ABC 103 D - Islands War

from operator import itemgetter

n, m = map(int, input().split())

# 区間の終端でソート
ab = sorted([tuple(map(int, input().split())) for i in range(m)], key=itemgetter(1))
# 前回除いた橋
removed = -1
ans = 0

for a, b in ab:
    # a が removed より大きい = まだ取り除いてない
    if a > removed:
        removed = b - 1
        ans += 1

print(ans)

ABC 038 D プレゼント

解けなくて調べてたら蟻本の中級編に載ってるデータ構造が必要だということがわかったので一旦飛ばします。

例題 2-2-3 Best Cow Line (POJ No.3617)

Best Cow Line (POJ No.3617)

n = int(input())
s = input()

t = ""

a = 0
b = n - 1
while a <= b:
    # 左から見た場合と右から見た場合を比較
    left = False
    i = 0
    while a + i <= b:
        if s[a + i] < s[b - i]:
            left = True
            break
        elif s[a + i] > s[b - i]:
            left = False
            break
        i += 1

    if left:
        t += s[a]
        a += 1
    else:
        t += s[b]
        b -= 1

print(t)

ABC 076 C Dubious Document 2

sd = input()
t = input()

n = len(sd)
m = len(t)
s = []

# sd を後ろから見ていき、 t の入りそうな場所を探す
for i in range(n - m, -1, -1):
    t_kamo = sd[i:i + m]
    for j in range(m + 1):
        # 1文字ずつ順に入りうるか調べ、最後まで入るなら "?" を "a" に置き換えて出力
        if j == m:
            print((sd[:i] + t + sd[i + len(t):]).replace("?", "a"))
            exit()
        if t_kamo[j] == "?":
            continue
        elif t_kamo[j] != t[j]:
            break

print("UNRESTORABLE")

ABC 007 B 辞書式順序

辞書順最小は "a" なので、これを出力すれば良いです。

a = input()
if a == "a":
    print(-1)
else:
    print("a")

ABC 009 C 辞書式順序ふたたび

from collections import Counter

n, k = map(int, input().split())
s = list(input())

s_sort = sorted(s)
t = ""

# 元の位置と違う文字の数
diff = 0
# 見終わったけどまだ使ってない文字
counter = Counter(s[:1])
counts = sum(counter.values())

# 1文字目から順に見ていく
for i in range(n):
    # t + c が可能か調べる
    for c in s_sort:
        # t + c の中で元の位置と違う文字の数
        diff1 = diff + (c != s[i])
        # まだ使ってない文字の中で元の位置と違う文字の数
        diff2 = counts - (counter[c] > 0)

        # 両方を足して k 以下ならば t + c が可能
        if diff1 + diff2 <= k:
            t += c
            s_sort.remove(c)
            diff = diff1
            counter = Counter(s[:i + 2]) - Counter(t)
            counts = sum(counter.values())
            break
print(t)

例題 2-2-4 Saruman's Army (POJ No.3069)

Saruman's Army (POJ No.3069)

n = int(input())
r = int(input())
x = list(map(int, input().split()))

x = sorted(x)

i = 0
ans = 0
while i < n:
    # s はカバーされていない一番左の点の位置
    s = x[i]
    i += 1
    # s から距離 r を超える点まで進む
    while i < n and x[i] <= s + r:
        i += 1

    # p は新しく印を付ける点の位置
    p = x[i - 1]
    # p から距離 r を超える点まで進む
    while i < n and x[i] <= p + r:
        i += 1

    ans += 1

print(ans)

ABC 083 C Multiple Gift

条件を満たすもののうち数列の長さが最大になるのは、 Ai+1 が Ai の2倍になるような数列です。

x, y = map(int, input().split())

ans = 0

while x <= y:
    x *= 2
    ans += 1

print(ans)

ARC 006 C 積み重ね

n = int(input())
w = [int(input()) for i in range(n)]

ans = 0
# 積み重ねた山の一番上のダンボール
top = []

for i in w:
    # 山を順番に見る
    for j in range(len(top) + 1):
        # 載せられる山がなければ新しい山を作る
        if j == len(top):
            ans += 1
            top.append(i)
        # 載せられる山があればそこに載せる
        if top[j] >= i:
            top[j] = i
            break

print(ans)

ABC 005 C おいしいたこ焼きの売り方

t = int(input())
n = int(input())
a = list(map(int, input().split()))
m = int(input())
b = list(map(int, input().split()))

# 各たこ焼きが作られてから経過した時間
takoyaki = []
# 今いる客の数
kyaku = 0

# 100秒目までループ
for i in range(101):
    # 客を待たせてはいけない
    if kyaku:
        print("no")
        exit()

    for j in range(n):
        # i 秒目にたこ焼きが作られていれば takoyaki に追加
        if a[j] == i:
            takoyaki.append(0)
    for k in range(m):
        # i 秒目に客が来ていれば kyaku に加算
        if b[k] == i:
            kyaku += 1

    # 客とたこ焼きがある限り売る
    while takoyaki and kyaku:
        takoyaki.pop(0)
        kyaku -= 1

    x = 0
    while x < len(takoyaki):
        # 各たこ焼きに 1 秒加算する
        takoyaki[x] += 1
        # t 秒を超えたら捨てる
        if takoyaki[x] > t:
            takoyaki.pop(x)
        else:
            x += 1

if kyaku:
    print("no")
else:
    print("yes")

例題 2-2-5 Fence Repair (POJ No.3253)

Fence Repair (POJ No.3253)

n = int(input())
L = list(map(int, input().split()))

ans = 0

# 板が1本になるまで適用
while n > 1:
    # 一番短い板 mii1 、次に短い板 mii2 を求める
    mii1 = 0
    mii2 = 1

    if L[mii1] > L[mii2]:
        mii1, mii2 = mii2, mii1

    for i in range(2, n):
        if L[i] < L[mii1]:
            mii2 = mii1
            mii1 = i
        elif L[i] < L[mii2]:
            mii2 = i

    # それらを併合
    t = L[mii1] + L[mii2]
    ans += t

    if mii1 == n - 1:
        mii1, mii2 = mii2, mii1
    L[mii1] = t
    L[mii2] = L[n - 1]
    n -= 1

print(ans)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Djangoチュートリアル(個人用)その2:django.shortcuts

1. render(request, テンプレート, コンテキスト)

polls/views.py
from django.http import HttpResponse
from django.template import loader

def index(request):
    (中略)
    template = loader.get_template('polls/index.html')
    return HttpResponse(template.render(context, request))

django.http.HttpResponse, django.template.loaderの代わりに、
django.shortcuts.renderを利用することでコンパクトに記述可能。

polls/views.py
from django.shortcuts import render
# ...
def index(request):
    (中略)
    return render(request, 'polls/index.html', context)

2. get_object_or_404(オブジェクト, pk)

polls/views.py
from django.http import Http404
from django.shortcuts import render

from .models import Question
# ...
def detail(request, question_id):
    try:
        question = Question.objects.get(pk=question_id)
    except Question.DoesNotExist:
        raise Http404("Question does not exist")
    return render(request, 'polls/detail.html', {'question': question})

django.http.Http404の代わりに、django.shortcuts.get_object_or_404をインポート。
try~except文を用いた分岐を用いなくても良いので、よりコンパクトな記述が可能となる。

polls/views.py
from django.shortcuts import get_object_or_404, render

from .models import Question
# ...
def detail(request, question_id):
    question = get_object_or_404(Question, pk=question_id)
    return render(request, 'polls/detail.html', {'question': question})

ちなみに、
get_list_or_404()
という関数もあるそうです。
この関数は
get_object_or_404()
と同じように動きますが、
get() ではなく、 filter() を使います。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Djangoチュートリアル(個人用)その1

初投稿&個人用記事なのでショボいです…
Markdownなどの確認も兼ねて記事を作成しています。

polls/template/polls/detail.html
{{ text }}
polls/views.py
from django.shortcuts import render

def detail(request):
    test_text = "abc"
    render(request, "polls/index.html", {"text": test_text})
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Talibで使えるローソク足に関する関数のまとめ (1)

最初に

今はまだβ版での随時更新していくのでよろしくお願いします

ローソク足について

ローソク足とは?

ローソク足とは日本のチャートの代表であり、ローソク足には日足、週足、月足、年足などの種類があります。
上に伸びている線を上ヒゲ。下に伸びている線を下ヒゲ。ヒゲの間にある箱を実体という。実体は始値と終値が一緒の時には存在しなく一本の線で表させれその線を同時線と呼ぶ。

image.png
「陰線」とは始値に対し終値が安い物。多くの書籍では黒いローソク足で書かれることが多い。

image.png

「陽線」とは始値に対して終値が高い物。多くの書籍では白いローソク足で書かれることが多い。
image.png
始値と終値が逆になっている事を注意して欲しい。

短い足のローソク(小陽線・小陰線)

CDLSHORTLINE - Short Line Candle
【小陽線】
image.png
小陽線は、実体が小さく、値幅(高値と安値の価格差)も小さい陽線です。これは、レンジ相場でよく見られるもので、相場が上下どちらに動くか迷っていて、停滞状態にあることを表します。
しかし、停滞状態にある相場は、いつかブレイクします。
特に、小陽線が何本も続いた後に、相場が転換することは非常に多いです。例えば、小陽線が連続した後に大陽線が出た場合は、横ばい相場をブレイクした可能性を想定することができます。
参考サイト
参考サイト
【小陰線】
image.png
小陽線と同じように、横ばい相場の時に多く見られます。小陰線1本だけで、何か大きなシグナルになることはありません。前後のローソク足の連続性と比較して、次の動きに備えておくと良いでしょう。
参考サイト
参考サイト
integer = CDLSHORTLINE(open, high, low, close)
※小陰線や小陽線が連続している停滞状態の時こそ、無理に売買せず、戦略を立ててライバルに差をつけることが大切。

長い足のローソク(大陽線・大陰線)

CDLLONGLINE - Long Line Candle
[買いのサイン]
実体が長く、価格が大きく変動するほど買いの勢いが強いのがわかります。大陽線は非常に強い買いのサインです。底値で大陽線が出た場合は、その後は株価の上昇が期待できます。
また、このローソクを大陽線と呼ぶ。
image.png

[売りのサイン]
実体が長く、価格が大きく変動するほど売りの勢いが強いのがわかります。大陰線は非常に強い売りのサインです。天井圏で大陰線が出た場合は、その後は株価の下落が予想できます。
また、このローソクを大陰線と呼ぶ。
image.png

integer = CDLLONGLINE(open, high, low, close)

丸坊主

CDLMARUBOZU - Marubozu
image.png
[買いのサイン]
黒丸坊主は片側にヒゲのない長い黒い実体です。それは弱気継続パターン、または強気逆転パターンであることが多く、特にダウントレンドに出現します。 長い黒色のろうそく足は強気の大勝利を示します。よってそれはしばしば, 強気特色の多くの逆転パターンの初日に出現します。
[売りのサイン]
白丸坊主は片側に影のない長い白い実体です。これは相場の勢いがひじょうに強いろうそくです。黒丸坊主と違い、しばしば継続の強気相場パターンか弱気逆転パターンで終わります。

integer = CDLMARUBOZU(open, high, low, close)

ハンマー

CDLHAMMER - Hammer
【買いのサイン】
下降トレンドで、ローソク足の終値が始値付近になるか、最高値で終了します。通常、このパターンには陽線(上ヒゲ)がありません。ただし、本体に比べてごく小さいときに限り、ヒゲがあってもかまいません。陽のハンマーが現れると、あるポイントで価格は低下するものの、売り手は価格をさらに押し広げることができず、反発して、終値は安値より上となりました。これは強気反転パターン(リバーサルパターン)です。
image.png

integer = CDLHAMMER(open, high, low, close)
参考サイト

逆ハンマー

CDLINVERTEDHAMMER - Inverted Hammer
【買いのサイン】
逆ハンマーは通常、下降トレンドの終わりに観察されます。ろうそくの実体の上ヒゲにがあり、ろうそくの実体に下ヒゲが少しあるかな?程度です。このパターンはShooting Starに似ており、発生する位置が異なるだけです。
image.png

integer = CDLINVERTEDHAMMER(open, high, low, close)
参考サイト

パターン

CDL2CROWS - Two Crows
【売りのサイン】
カブセ線として知られている
陽線の後に二本の陰線が出てくる二本目の陰線は長く大陽線の次に、その大陽線の終値よりも高く始まったものの、終値では大陽線の実体に入り込んでいる陰線。

integer = CDL2CROWS(open, high, low, close)

CDL3BLACKCROWS - Three Black Crows
【売りのサイン】
三羽烏(黒三兵)そして知られている
三本の長い陰線のロウソク足が続き、二本目が前日のロウソク足の実体の幅で始まる。引きけにかけて前日の終値を下回り、三本目も二本メモ動揺な型のロウソク足を形成したもの。
integer = CDL3BLACKCROWS(open, high, low, close)

CDL3OUTSIDE - Three Outside Up/Down
【買いのサイン】
抱き線(抱きの一本立ち)として知られている
陰線が形成された後、二本目のロウソク足が陽線でかつ一本前の陰線の実体を飲み込む形になっている。
【売りのサイン】
最後の抱き線と知られている
陽線が形成された後、二本目のロウソク足が陰線でかつ一本前の陰線の実体を飲み込む形になっている。
integer = CDL3OUTSIDE(open, high, low, close)

CDL3STARSINSOUTH - Three Stars In The South
【買いのサイン】
1本目の陰線は下ヒゲが長く、実体も長い。また、二番目のロウソクは短く、黒の丸坊主、星で二番目のセッションに関連する
image.png

【売りのサイン】
高い終値の3つの白いろうそく足最初の2つのろうそく足 は長くなっています。
それぞれのろうそく足の始値は前の実体にかぶさっています。
image.png

integer = CDL3STARSINSOUTH(open, high, low, close)

CDL3WHITESOLDIERS - Three Advancing White Soldiers
【買いのサイン】
3つの長い白の ろうそく足が次々と現れ、それぞれの終値は前の終値より高くなっています。
image.png
integer = CDL3WHITESOLDIERS(open, high, low, close)

明けの明星

CDLABANDONEDBABY - Abandoned Baby
【買いのサイン】
一日目に陰線が出現した翌日、それより下に十字星、極性が現れる。その後、三本目のロウソク足はヒゲの間に同じ隙間のある「長い」陽線のろうそく足で、一番目より短くなっています。
image.png

【売りのサイン】
一日目に陽線が出現した翌日、それより上に十字星、極性が現れる。その後、三本目のロウソク足はヒゲの間に同じ隙間のある「長い」陰線のろうそく足で、一番目より短くなっています。
image.png

integer = CDLABANDONEDBABY(open, high, low, close, penetration=0)

CDLADVANCEBLOCK - Advance Block
【買いのサイン】
上昇トレンド内、もしくは下落トレンド内での反発を意味している。
また、陽線の実体はだんだんと短くなっていく。2番目と3番目のキャンドルの開きは、前のキャンドルの実体の中にあります。3つのキャンドルの上のヒゲは次第に高くなります
image.png

integer = CDLADVANCEBLOCK(open, high, low, close)
詳細

CDLBELTHOLD - Belt-hold
【買いのサイン】
レンド方向に大差があるろうそく足のオープン
白ろうそく足(陽の大引け坊主)
白いろうそく足の実体は前のろうそく足の実体よりもずっと大きくなっています。
image.png

【売りのサイン】
レンド方向に大差があるろうそく足のオープン
黒ろうそく足 (陰の大引け坊主)
黒いろうそく足の実体は前のろうそく足の実体よりもずっと大きくなっています。
image.png

integer = CDLBELTHOLD(open, high, low, close)

CDLBREAKAWAY - Breakaway
【買いのサイン】
初日の大きい陰線は今の下落トレンド象徴して、次の日もまた陰線はトレンドの方向に実体の間隔がある。
image.png

【売りのサイン】
初日の大きい陽線は今の下落トレンド象徴して、次の日もまた陽線はトレンドの方向に実体の間隔がある。

image.png

integer = CDLBREAKAWAY(open, high, low, close)

CDLCLOSINGMARUBOZU - Closing Marubozu #talibにないと出るので飛ばす
【買いのサイン】
【】
integer = CDLCLOSINGMARUBOZU()(open, high, low, close)
関連記事

CDLCONCEALBABYSWALL - Concealing Baby Swallow
【買いのサイン】
最初の二本の陰線は丸坊主。
三番目は二番目のろうそく足長さ範囲内で形作られます。それは長い上ヒゲを形成します。
四本目は陰線となり、抱き込む形になる。
image.png
integer = CDLCONCEALBABYSWALL(open, high, low, close)

CDLCOUNTERATTACK - Counterattack
【買いのサイン】
最初は下落トレンドであり、最初のローソク足は陰線で実体が長い。
二本目のローソクは一本目のローソクと同じような大きさで終値が一本目のローソクの終値と近い陽線。今後上昇トレンドに変化する事がある。
image.png
【売りのサイン】
最初は上昇トレンドであり、最初のローソク足は陽線で実体が長い。
二本目のローソクは一本目のローソクと同じような大きさで終値が一本目のローソクの終値と近い陰線。今後下落トレンドに変化する事がある。

image.png

integer = CDLCOUNTERATTACK(open, high, low, close)

詳細
詳細

暗雲

CDLDARKCLOUDCOVER - Dark Cloud Cover
【売りのサイン】
どちらのろうそく足も長くなっています。
黒の ろうそく足の始値は白のろうそく足の高値を上回ります。
※ブルベアの三年間で1〜2回反応する程度
image.png

integer = CDLDARKCLOUDCOVER(open, high, low, close, penetration=0)

同時線

CDLDOJI - Doji
Doji(同時線)とは?
ろうそく足の実体が小さいため、始値と終値が同じであればそれは「同時線」と呼ばれます。
始値と終値の要求が全く同じであり、データに厳しい制約が設けられるので、同時線はほとんど見られません。
始値と終値の差が数個のティック(最小価格変動)を超えることがなければ、これは十分以上です。
image.png

integer = CDLDOJI(open, high, low, close)
詳細

同時線(星)

CDLDOJISTAR - Doji Star
【買いのサイン】
最初は長い陰線となり、二本目はトレンド方向のブレイクがある同時線が出る時。
image.png
【売りのサイン】
最初は長い陽線となり、二本目はトレンド方向のブレイクがある同時線が出る時。
image.png

integer = CDLDOJISTAR(open, high, low, close)

同時線(とんぼ)

CDLDRAGONFLYDOJI - Dragonfly Doji
上ヒゲのない十字線。高値圏に現れれば高値を買い上る勢いが衰えてきたこと、また、底値圏に現れれば押し戻す買い勢力を暗示します。
【買いのサイン】
低値圏(0 > x > -100 [x:自然数])
【売りのサイン】
高値圏(0 < x < 100 [x:自然数])

image.png

integer = CDLDRAGONFLYDOJI(open, high, low, close)

つつみ線

CDLENGULFING - Engulfing Pattern
【買いのサイン】
様々な陰線の黒色のローソクを飲み込んでいるネオンサインのように陽線の白色のローソクが存在している。
これは投資家の心が動いている様子がを凄く簡単に分かるようになっています。いくつかの単純な原因が強気な巻き込みパターンをより説得力のあるものにして、前の日のローソクが飲み込まれるほど、新しいトレンドシグナルはより効果的になります。
image.png
【売りのサイン】
弱気なつつみ線は、これからの低価格を示唆するテクニカルチャートのパターンです。パターンは、陽線のローソク足と、それに続いて小さい陽線のローソクを隠し、大きな陰線のローソク足で構成されています。これは、売り手が買い手を追い越し、買い手がそれを押し上げるよりも積極的に価格を引き下げている(ろうそくを上げている)ことを示しているので重要です。
image.png

integer = CDLENGULFING(open, high, low, close)
詳細

CDLEVENINGDOJISTAR - Evening Doji Star
image.png

integer = CDLEVENINGDOJISTAR(open, high, low, close, penetration=0)

CDLEVENINGSTAR - Evening Star
【買いのサイン】
一番目と三番目のセッションは「長い」ろうそく足です。星のヒゲは短く、色は関係ありません。最初のろうそく足の終値から星は離れています。
三番目のろうそく足は一番目より短くその長さの内側に収まっています。
image.png

【売りのサイン】
一番目と三番目のセッションは「長い」ローソク足です。星のヒゲは短く、色は関係ありません。最初のろうそく足の終値から星は離れています。
三番目のろうそく足は一番目より短くその範囲に収まっています。
image.png

integer = CDLEVENINGSTAR(open, high, low, close,
penetration=0)
参考サイト

長い足の同時線

CDLLONGLEGGEDDOJI - Long Legged Doji
image.png
この長い足がある同時線は強い上昇トレンドや強い下落トレンドで最も重要とされている。
理由は足の長い同時線は、需要と供給の力が均衡に近づいており、トレンドの逆転が起こる可能性があることを示唆しています。
integer = CDLLONGLEGGEDDOJI(open, high, low, close)

CDLKICKING - Kicking
【買いのサイン】
最初に陰線の丸坊主が出てきてその後に陽線の丸坊主が下落トレンドで出てくる。
その時最初のローソクと次のローソクにはギャップアップがあり、ローソクが長ければ逆(今回の場合上昇トレンド)になる信憑性が高くなる。
image.png
ギャップアップとは?

【売りのサイン】
最初に陽線の丸坊主が出てきてその後に陰線の丸坊主が上昇トレンドで出てくる。
その時最初のローソクと次のローソクにはギャップダウンがあり、ローソクが長ければ逆(今回の場合下落トレンド)になる信憑性が高くなる。
image.png
ギャップダウンとは?
integer = CDLKICKING(open, high, low, close)

CDLLADDERBOTTOM - Ladder Bottom
image.png
【買いのサイン】
このパターンは上昇トレンドに反転する時のパターンの一つであり下落トレンド時にでる。
一本、二本、三本目そして四本目のローソクは陰線で長い実体、それぞれの初値と終値は前のローソクの初値と終値の間にある。
四本目の陰線は実体が短く上ヒゲがある。
五本目は前のローソク足の実体を始値が抜いている陽線。

integer = CDLLADDERBOTTOM(open, high, low, close)
参考サイト

CDLMATCHINGLOW - Matching Low
image.png
[買いのサイン]
下落トレンドであり、最初のローソク足は実体が長い陰線であり、二本目のローソクは最初のローソク足の終値がほぼ同じ終値の陰線。2番目のろうそくが1番目のろうそくの終値を下回ることができないということは、強気の逆転に対する支持レベルを生み出します。このパターンは、数期間にわたって価格が下落傾向にある時間帯ではなく、大規模な上昇トレンドに続く一時的な下落に最も適しています。
※[売りのサイン]にもなりうる
integer = CDLMATCHINGLOW(open, high, low, close)
参考サイト

CDLMATHOLD - Mat Hold
[買いのサイン]
強気キッカーローソク足パターンを特定するには、以下の基準を探します。

まず、最初のキャンドルは黒または弱気のローソク足である必要があります。次に、2番目のキャンドル(白または強気)が最初のキャンドルの終点より上に開いている必要があります。第三に、第二のろうそく足の形成中の価格の動きは、第一と第二のろうそくの間に形成されたギャップに決して落ちないはずです。ご想像のとおり、これは2番目のローソク足に一番下の芯があることはめったにないことを意味します。

Bullish Kickerローソク足パターンは、大幅な下落の後に形成する必要はありませんが、多くの場合そうなります。これが起こるとき、態度の突然の変化はたぶんゲームを変えるニュースイベントが原因です。

最後に、もしあなたが反対の形成(白いろうそくとそれに続く隙間に落ちない黒いろうそく)でパターンを見つけるなら、あなたはあなたの手に弱気キッカーがあるかもしれません。それはさらに下向きの動きを予告する弱気な反転信号です。強気のキッカーのように、弱気のキッカーはまれですが信頼できることを証明します
image.png

[売りのサイン]
image.png

integer = CDLMATHOLD(open, high, low, close,penetration=0)

流れ星(Shooting Star)

CDLSHOOTINGSTAR - Shooting Star
【売りのサイン】
上昇トレンドに見れる。上ヒゲは3以下ではなく実体より大きい。
下ヒゲはない、または非常に短い。(ろうそく足範囲の10%以上ではない。)
星と以前のろうそく足間の価格差
image.png

integer = CDLSHOOTINGSTAR(open, high, low, close)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MACでPythonのpsycopg2を使えるように

はじめに

MACのローカル環境でPythonを実行しようとしていました。
そのファイルではpsycopg2をimportしていたので、
homebrew等を使って準備をしていましたが、
いざ、実行しようとすると、下記エラーが。。

  File "sample.py", line 4, in <module>
    import psycopg2
  File "/Users/gouda/.pyenv/versions/anaconda3-4.0.0/lib/python3.5/site-packages/psycopg2/__init__.py", line 50, in <module>
    from psycopg2._psycopg import (                     # noqa
ImportError: dlopen(/Users/gouda/.pyenv/versions/anaconda3-4.0.0/lib/python3.5/site-packages/psycopg2/_psycopg.cpython-35m-darwin.so, 2): Library not loaded: libssl.1.0.0.dylib
  Referenced from: /Users/gouda/.pyenv/versions/anaconda3-4.0.0/lib/python3.5/site-packages/psycopg2/_psycopg.cpython-35m-darwin.so
  Reason: image not found

解決

こちらを参考に、対応しました。

libssl と libcrypto のバージョンが低いのが悪さしているようですね。

$ ln -s /usr/local/Cellar/openssl/1.0.2e/lib/libssl.1.0.0.dylib /usr/local/lib
$ ln -s /usr/local/Cellar/openssl/1.0.2e/lib/libcrypto.1.0.0.dylib /usr/local/lib

こちらを実行することで、解決しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Arxiv API

今や論文公開プラットフォームの代名詞となったコーネル大学のarXivですが,APIはフリーで公開されています.
使い方についてはarXiv API User's Manualに全て書いてありますが,日本語での紹介が見当たらなかったので書き散らしてみます.

基本

一般的なAPIと同じようにhttp://export.arxiv.org/api/queryにクエリーを付加する形となります.

parameters type defaults required
search_query string None No
id_list comma-delimited string None No
start int 0 No
max_results int 10 No

search_queryで任意の単語を含む論文を検索します.
その際,前に修飾子をつけることで検索する範囲を指定できます.

prefix explanation
ti Title
au Author
abs Abstract
co Comment
jr Journal Reference
cat Subject Category
rn Report Number
id Id (use id_list instead)
all All of the above

ソート

  • sortBy
    • "relevance"
    • "lastUpdatedDate"
    • "submittedDate"
  • sortOrder
    • "ascending"
    • "descending"

Category

CATに指定するキーワードです.
各キーワードが論文のカテゴリを表します.

キーワード 説明
astro-ph Astrophysics
astro-ph.CO Cosmology and Nongalactic Astrophysics
astro-ph.EP Earth and Planetary Astrophysics
astro-ph.GA Astrophysics of Galaxies
astro-ph.HE High Energy Astrophysical Phenomena
astro-ph.IM Instrumentation and Methods for Astrophysics
astro-ph.SR Solar and Stellar Astrophysics
cond-mat.dis-nn Disordered Systems and Neural Networks
cond-mat.mes-hall Mesoscale and Nanoscale Physics
cond-mat.mtrl-sci Materials Science
cond-mat.other Other Condensed Matter
cond-mat.quant-gas Quantum Gases
cond-mat.soft Soft Condensed Matter
cond-mat.stat-mech Statistical Mechanics
cond-mat.str-el Strongly Correlated Electrons
cond-mat.supr-con Superconductivity
cs.AI Artificial Intelligence
cs.AR Hardware Architecture
cs.CC Computational Complexity
cs.CE Computational Engineering, Finance, and Science
cs.CG Computational Geometry
cs.CL Computation and Language
cs.CR Cryptography and Security
cs.CV Computer Vision and Pattern Recognition
cs.CY Computers and Society
cs.DB Databases
cs.DC Distributed, Parallel, and Cluster Computing
cs.DL Digital Libraries
cs.DM Discrete Mathematics
cs.DS Data Structures and Algorithms
cs.ET Emerging Technologies
cs.FL Formal Languages and Automata Theory
cs.GL General Literature
cs.GR Graphics
cs.GT Computer Science and Game Theory
cs.HC Human-Computer Interaction
cs.IR Information Retrieval
cs.IT Information Theory
cs.LG Learning
cs.LO Logic in Computer Science
cs.MA Multiagent Systems
cs.MM Multimedia
cs.MS Mathematical Software
cs.NA Numerical Analysis
cs.NE Neural and Evolutionary Computing
cs.NI Networking and Internet Architecture
cs.OH Other Computer Science
cs.OS Operating Systems
cs.PF Performance
cs.PL Programming Languages
cs.RO Robotics
cs.SC Symbolic Computation
cs.SD Sound
cs.SE Software Engineering
cs.SI Social and Information Networks
cs.SY Systems and Control
econ.EM Econometrics
eess.AS Audio and Speech Processing
eess.IV Image and Video Processing
eess.SP Signal Processing
gr-qc General Relativity and Quantum Cosmology
hep-ex High Energy Physics - Experiment
hep-lat High Energy Physics - Lattice
hep-ph High Energy Physics - Phenomenology
hep-th High Energy Physics - Theory
math.AC Commutative Algebra
math.AG Algebraic Geometry
math.AP Analysis of PDEs
math.AT Algebraic Topology
math.CA Classical Analysis and ODEs
math.CO Combinatorics
math.CT Category Theory
math.CV Complex Variables
math.DG Differential Geometry
math.DS Dynamical Systems
math.FA Functional Analysis
math.GM General Mathematics
math.GN General Topology
math.GR Group Theory
math.GT Geometric Topology
math.HO History and Overview
math.IT Information Theory
math.KT K-Theory and Homology
math.LO Logic
math.MG Metric Geometry
math.MP Mathematical Physics
math.NA Numerical Analysis
math.NT Number Theory
math.OA Operator Algebras
math.OC Optimization and Control
math.PR Probability
math.QA Quantum Algebra
math.RA Rings and Algebras
math.RT Representation Theory
math.SG Symplectic Geometry
math.SP Spectral Theory
math.ST Statistics Theory
math-ph Mathematical Physics
nlin.AO Adaptation and Self-Organizing Systems
nlin.CD Chaotic Dynamics
nlin.CG Cellular Automata and Lattice Gases
nlin.PS Pattern Formation and Solitons
nlin.SI Exactly Solvable and Integrable Systems
nucl-ex Nuclear Experiment
nucl-th Nuclear Theory
physics.acc-ph Accelerator Physics
physics.ao-ph Atmospheric and Oceanic Physics
physics.app-ph Applied Physics
physics.atm-clus Atomic and Molecular Clusters
physics.atom-ph Atomic Physics
physics.bio-ph Biological Physics
physics.chem-ph Chemical Physics
physics.class-ph Classical Physics
physics.comp-ph Computational Physics
physics.data-an Data Analysis, Statistics and Probability
physics.ed-ph Physics Education
physics.flu-dyn Fluid Dynamics
physics.gen-ph General Physics
physics.geo-ph Geophysics
physics.hist-ph History and Philosophy of Physics
physics.ins-det Instrumentation and Detectors
physics.med-ph Medical Physics
physics.optics Optics
physics.plasm-ph Plasma Physics
physics.pop-ph Popular Physics
physics.soc-ph Physics and Society
physics.space-ph Space Physics
q-bio.BM Biomolecules
q-bio.CB Cell Behavior
q-bio.GN Genomics
q-bio.MN Molecular Networks
q-bio.NC Neurons and Cognition
q-bio.OT Other Quantitative Biology
q-bio.PE Populations and Evolution
q-bio.QM Quantitative Methods
q-bio.SC Subcellular Processes
q-bio.TO Tissues and Organs
q-fin.CP Computational Finance
q-fin.EC Economics
q-fin.GN General Finance
q-fin.MF Mathematical Finance
q-fin.PM Portfolio Management
q-fin.PR Pricing of Securities
q-fin.RM Risk Management
q-fin.ST Statistical Finance
q-fin.TR Trading and Market Microstructure
quant-ph Quantum Physics
stat.AP Applications
stat.CO Computation
stat.ME Methodology
stat.ML Machine Learning
stat.OT Other Statistics
stat.TH Statistics Theory
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

機械学習用の画像集めに便利な「google-images-download」の使い方

google-images-downloadの使い方

Google画像検索から画像をダウンロードするツール

Google検索から画像を一括でダウンロード出来る。
画像認識のモデルに学習させる時に便利。

参考にしたページ
Googleから画像を一括でダウンロードするツール「google-images-download」 | cupOF Interests

インストール方法

pip install google_images_download

pipでインストールする。

使い方

コマンドラインから簡単にダウンロード出来る。

googleimagesdownload --keywords "リンゴ"

カレントディレクトリに「リンゴ」の検索結果を100件保存。

オプション一覧

オプション ショートカット 説明
keywords k ターゲットとなる画像のキーワード
suffix_keywords sk キーワードを追加する為の接尾辞
('りんご' '赤' など)
limit l 一度にダウンロードする画像数
(デフォルトでは100個)
format f ダウンロードする画像の形式
(jpg, gif, png, bmp, svg, webp, ico)
color co ダウンロードする画像の色を指定
(red, orange, yellow, green, teal,blue,purple,pink, white, gray, black, brown)
color_type ct ダウンロードする画像色のタイプ
(full-color, black-and-white, transparent)
size s ダウンロードする画像のサイズ
(large, medium, icon, >400*300, >640*480,>800*600,>1024*768, >2MP, >4MP, >6MP, >8MP, >10MP)
aspect_ratio a ダウンロードする画像の形。パノラマなど
(tall, square, wide, panoramic)
type t ダウンロードする画像のタイプ。パノラマなど
(face, photo, clip-art, line-drawing,animated)
time w インデックスされた画像の期間を指定 1日以内, 一週間以内など
( past-24-hours, past-7-days)
similar_images si 指定した画像ファイルやURLから、似たイメージをダウンロードします
output_directory o 指定したディレクトリに画像を展開。
デフォルトではコマンドを実行したディレクトリに画像がダウンロードされます
language la 画像を入手するGoogleサービスの言語を指定
指定できる言語一覧Arabic, Chinese (Simplified), Chinese (Traditional), Czech, Danish, Dutch,  English, Estonian. Finnish, French, German, Greek, Hebrew, Hungarian,Icelandic, Italian, Japanese, Korean, Latvianm, Lithuanian, Norwegian, Portuguese, Polish, Romanian, Russian, Spanish, Swedish, Turkish
chromedriver cd 画像を入手するドライバをchromedriverに変更できます。

100件以上のダウンロードには「ChromeDriver」が必要

デフォルトで設定されている100件以上の画像をダウンロードするには「chromeDriver」が必要。

下記URLからダウンロード。
Downloads - ChromeDriver - WebDriver for Chrome

解凍して出てきた「chromedriver.exe」をカレントに置く。

googleimagesdownload -ri -cd "chromedriver.exe" -l 1000  -k "猫"

こんな感じで叩けば出来るっぽい。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pyenv installでコケる(zlib)

pyenvでpythonのバージョンを上げたい

$ pyenv install 3.x.x   // ここで止まる
$ pyenv global 3.x.x

エラー

$ pyenv install 3.x.x
python-build: use openssl from homebrew
python-build: use readline from homebrew

<...>

BUILD FAILED (OS X 10.14.3 using python-build 20180424)

Inspect or clean up the working tree at /var/folders/82/wbj2z1dx1px5tgqszjg3fdt80000gn/T/python-build.20190417125321.77862
Results logged to /var/folders/82/wbj2z1dx1px5tgqszjg3fdt80000gn/T/python-build.20190417125321.77862.log

Last 10 log lines:
  File "/private/var/folders/82/wbj2z1dx1px5tgqszjg3fdt80000gn/T/python-build.20190417125321.77862/Python-3.5.1/Lib/ensurepip/__main__.py", line 4, in <module>
    ensurepip._main()
  File "/private/var/folders/82/wbj2z1dx1px5tgqszjg3fdt80000gn/T/python-build.20190417125321.77862/Python-3.5.1/Lib/ensurepip/__init__.py", line 209, in _main
    default_pip=args.default_pip,
  File "/private/var/folders/82/wbj2z1dx1px5tgqszjg3fdt80000gn/T/python-build.20190417125321.77862/Python-3.5.1/Lib/ensurepip/__init__.py", line 116, in bootstrap
    _run_pip(args + [p[0] for p in _PROJECTS], additional_paths)
  File "/private/var/folders/82/wbj2z1dx1px5tgqszjg3fdt80000gn/T/python-build.20190417125321.77862/Python-3.5.1/Lib/ensurepip/__init__.py", line 40, in _run_pip
    import pip
zipimport.ZipImportError: can't decompress data; zlib not available   ? zlibを入れればええんか?
make: *** [install] Error 1

これで解決しました

$ brew install zlib
$ brew install sqlite
$ export LDFLAGS="${LDFLAGS} -L/usr/local/opt/zlib/lib"
$ export CPPFLAGS="${CPPFLAGS} -I/usr/local/opt/zlib/include"
$ export LDFLAGS="${LDFLAGS} -L/usr/local/opt/sqlite/lib"
$ export CPPFLAGS="${CPPFLAGS} -I/usr/local/opt/sqlite/include"
$ export PKG_CONFIG_PATH="${PKG_CONFIG_PATH} /usr/local/opt/zlib/lib/pkgconfig"
$ export PKG_CONFIG_PATH="${PKG_CONFIG_PATH} /usr/local/opt/sqlite/lib/pkgconfig"
$ pyenv install 3.6.8

参考: https://github.com/jiansoung/issues-list/issues/13#issuecomment-470275744

他に試したこと

$ sudo installer -pkg /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg -target /

-> 同様にfailed

$ brew install zlib

-> zlibだけ入れても意味がなかった

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

pythonでpsycopg2のインストールでエラー出た時の対処法のメモ

pip install django-heroku
を実行した時に

Command "python setup.py egg_info" failed with error code 1
のエラーが出てインストールされない時

brew install postgresql
して

export PATH="/usr/pgsql-9.4/bin:$PATH"

するといける。

参考
http://h2shiki.hateblo.jp/entry/2016/05/05/210738

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【秒速】PythonのPelicanを使ってウェブサイト(Coreserverで)を作ってみる。

Pelicanとは

Python製の静的サイトジェネレータです。Ruby製のJekyllやOctropressに似ていますが、PelicanはPythonだけで動かせます。GitHub Pagesへの公開も非常に簡単です。
公式サイトがとても充実していますが日本語の資料少ない。
Python製 Pelican を使ってサクッとブログを公開する より

前まで自分のウェブサイトをワードプレスで使ったりしていましたが、テック系の記事はQittaに書きますし、ブログはnote、つぶやきはtwitterとそれぞれの役割が分担してきたので定期的にコンテンツを自分で書くウェブサイトはいらないのかなと考えていました。

ただ、自分のホームページはほしいので自己紹介を含めた簡単まとめとしてペリカンで軽くサイトを作ることにしました。

Pythonだし、退屈なことはあとあと自動化しようかと思ってます。

早速サイトを作る!

まず、この記事を使ってCoreserverで体験用ドメインとpythonのセットアップを終えてください。

https://qiita.com/twinoze/items/5bd62a2bc08fee7596f1

次にpipでpelicanとmarkdownします。

$ pip install pelican markdown

サイトを入れるフォルダをどこでもいいので作ってから、そこに入りpelican quick-startを実行します。
初期設定用の質問に答えれば、簡単なデモサイトが出来上がります。

$ mkdir mysite
$ cd mysite

image.png

output内にhtmlファイルがいくつか作られるのですが、これをpublil_htmlに入れることで自分のウェブサイトを公開することができると思います。

毎回、場所を変えるのは面倒なので、viでpelicanconf.pyの最後の行に

OUTPUT_PATH = '../public_html/atomscott.com/'

image.png

をくっつけるとpublic_html直下のatomscott.comフォルダにサイトをoutputしてくれます。

atomscott.comにお邪魔してみると(いまは開発を進めたのでもっとかっこいいサイトが出てくるかもしれません!)こんな画面が!

image.png

楽ですね〜
今日はこれで以上です。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Docker-Composeでコンテナをビルドする際に起こったエラーと解決策まとめ

はじめましての方ははじめまして。

未来電子テクノロジーでインターンをしている<@kento_o>です。

今回は、Quickstart: Compose and Djangoを一通り試してみる中で起こったエラーと解決策をログとして残しておきます。

起こったエラー

・Dockerファイルを誤植した際に起こったエラー
・データベースにコネクトし、ページを表示する際に起こったエラー
1つ目のエラーは至極単純なものですが、2つ目が厄介でした。

Disarrowed?

Screenshot from 2019-04-17 11-22-00.png
このようなエラーが出力されました。
んん?hostが許されていない......?
1時間ほどエラー原因を探してみたところ、どうも「Setting.py」の設定ミスのよう。

setting.py
ALLOWED_HOSTS = []

となっていたので、

setting.py
ALLOWED_HOSTS = ['*']

に変更

解決

django-it-worked.png

やりました,b

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

keras-self-attentionを使ってエンティティタイプを予測

keras-self-attention1 は、self-attentionを簡単に使うためのライブラリです。今回は、このライブラリを使うことによって、エンティティタイプ予測の問題をより汎用的な特徴量から学習させられることを確かめます。

事前準備

pip install keras-self-attention

モデル

model.png

訓練部分のコード

import json
import sqlite3
from random import choice

import numpy as np
import sentencepiece as spm
from keras import optimizers
from keras.callbacks import ModelCheckpoint
from keras.layers import Dense, Input, Embedding, Dropout, concatenate, Flatten
from keras.models import Model
from keras.preprocessing.sequence import pad_sequences
from keras_self_attention import SeqSelfAttention

sp = spm.SentencePieceProcessor()
sp.load("./spmodel/en.wiki.bpe.vs10000.model")


def build_model(num_labels,
                maxlen1=128,
                maxlen2=128,
                max_features=10001,
                dim1=50,
                dim2=50):
    inputs = Input(shape=(maxlen1, ))
    inputs2 = Input(shape=(maxlen2, ))
    emb1 = Embedding(max_features, dim1, input_length=maxlen1)(inputs)
    emb2 = Embedding(max_features, dim2, input_length=maxlen2)(inputs2)
    tmp = concatenate([emb1, emb2])
    att = SeqSelfAttention(attention_activation='sigmoid')(tmp)
    tmp2 = Flatten()(emb1)
    tmp3 = Flatten()(att)
    tmp = concatenate([tmp2, tmp3])
    tmp = Dense(1024, activation="linear")(tmp)
    out = Dropout(0.5)(tmp)
    output = Dense(units=num_labels, activation='softmax')(out)
    model = Model([inputs, inputs2], output)
    opt = optimizers.Adam(lr=0.001, clipvalue=0.5)
    model.compile(loss='categorical_crossentropy',
                  optimizer=opt,
                  metrics=['acc'])
    return model


def preprocessing(texts, sp=sp, maxlen=50):
    return pad_sequences([sp.EncodeAsIds(text) for text in texts],
                         maxlen=maxlen)


def generate_data(data, labels, batch_size=1000):
    X0 = []
    X1 = []
    y = []
    while True:
        for i, d in enumerate(data):
            X0.append(d["entity"].replace("_", " "))
            X1.append(d["definition"])
            label = np.zeros(len(labels.keys()))
            label[int(labels[d["type"]])] = 1.0
            y.append(label)
            if len(X0) > 1000:
                yield [preprocessing(X0, maxlen=128), preprocessing(X1, maxlen=128)], np.array(y)
                X0 = []
                X1 = []
                y = []

def generate_test_data(test, labels):
    X0 = []
    X1 = []
    y = []
    for i, d in enumerate(test):
        X0.append(d["entity"].replace("_", " "))
        X1.append(d["definition"])
        y.append(int(labels[d["type"]]))
    return [preprocessing(X0, maxlen=128), preprocessing(X1, maxlen=128)], np.array(y)


if __name__ == "__main__":
    from sklearn.utils import shuffle
    from sklearn.metrics import classification_report
    with open("./labels.json") as f:
        key2i = json.load(f)[1]

    with open("./wiki_definition.json") as f:
        data = shuffle(json.load(f))

    size = int(len(data) * 0.8)
    train, test = data[:size], data[size:]
    size = int(len(test) * 0.8)
    test, val = test[:size], test[size:]

    model = build_model(len(key2i.keys()))
    callbacks = [
        ModelCheckpoint("model.h5",
                        save_best_only=False,
                        monitor="val_loss",
                        mode="min"),
        ModelCheckpoint("model_best.h5",
                        save_best_only=True,
                        monitor="val_loss",
                        mode="min")
    ]
    model.fit_generator(generate_data(train, key2i),
                        validation_data=generate_data(val, key2i),
                        validation_steps=10,
                        steps_per_epoch=1000,
                        epochs=3,
                        verbose=1,
                        callbacks=callbacks)

    X_test, y_test = generate_test_data(test, key2i)

    y_pred = [np.argmax(x) for x in model.predict(X_test)]

    with open("eval.txt", "w") as f:
        f.write(classification_report(y_test, y_pred))

Note: labels.jsonには、ラベル名とラベルIDの対応が入っています。

Note: wiki_definition.jsonには、定義文、エンティティ名, エンティティタイプが格納されています。

精度

※ スマホなど、ブラウザの横幅が狭い場合は、以下の精度を横にスクロールさせて見てください。

                                             precision recall    f1-score  support   

AcademicConference                           0.71      0.33      0.45      15        
AcademicJournal                              0.92      0.95      0.94      1075      
Actor                                        0.49      0.16      0.24      630       
AdministrativeRegion                         0.84      0.81      0.82      3307      
AdultActor                                   0.76      0.61      0.68      171       
Aircraft                                     0.92      0.96      0.94      1726      
Airline                                      0.96      0.95      0.96      582       
Airport                                      0.97      0.94      0.96      2177      
Album                                        0.96      0.96      0.96      19501     
AmateurBoxer                                 0.29      0.08      0.12      75        
Ambassador                                   0.28      0.36      0.31      83        
AmericanFootballLeague                       0.00      0.00      0.00      10        
AmericanFootballPlayer                       0.80      0.90      0.85      3070      
AmericanFootballTeam                         0.00      0.00      0.00      5         
Amphibian                                    0.91      0.95      0.93      563       
AmusementParkAttraction                      0.76      0.55      0.64      64        
AnatomicalStructure                          0.56      0.64      0.60      268       
Animal                                       0.73      0.83      0.77      1096      
AnimangaCharacter                            0.50      0.05      0.08      22        
Anime                                        0.41      0.10      0.16      161       
Arachnid                                     0.94      0.84      0.89      632       
Archaea                                      0.71      0.56      0.63      27        
Architect                                    0.58      0.34      0.43      457       
ArchitecturalStructure                       0.33      0.05      0.08      43        
Artery                                       1.00      0.83      0.91      52        
ArtificialSatellite                          0.89      0.94      0.91      371       
Artist                                       0.47      0.38      0.42      2267      
ArtistDiscography                            0.98      0.99      0.98      560       
Artwork                                      0.82      0.81      0.82      760       
Asteroid                                     0.00      0.00      0.00      2         
Astronaut                                    0.77      0.79      0.78      104       
Athlete                                      0.81      0.86      0.84      5763      
AustralianFootballLeague                     0.00      0.00      0.00      1         
AustralianFootballTeam                       0.72      0.88      0.79      72        
AustralianRulesFootballPlayer                0.98      0.99      0.98      1959      
AutoRacingLeague                             0.00      0.00      0.00      1         
Automobile                                   0.92      0.86      0.89      887       
AutomobileEngine                             0.87      0.76      0.81      54        
Award                                        0.82      0.93      0.87      788       
Bacteria                                     0.45      0.37      0.41      145       
BadmintonPlayer                              0.96      0.88      0.92      241       
Band                                         0.86      0.79      0.83      5259      
Bank                                         0.72      0.41      0.52      425       
Baronet                                      0.68      0.81      0.74      118       
BaseballLeague                               0.58      0.88      0.70      48        
BaseballPlayer                               0.96      0.98      0.97      3303      
BaseballSeason                               0.96      0.42      0.58      53        
BaseballTeam                                 0.00      0.00      0.00      2         
BasketballLeague                             0.88      0.62      0.73      69        
BasketballPlayer                             0.92      0.94      0.93      1930      
BasketballTeam                               0.87      0.82      0.85      271       
Bay                                          0.00      0.00      0.00      1         
BeachVolleyballPlayer                        0.55      0.43      0.48      28        
BeautyQueen                                  0.87      0.76      0.81      339       
Beverage                                     0.79      0.56      0.66      130       
BiologicalDatabase                           0.66      0.67      0.67      46        
Bird                                         0.98      0.92      0.95      2012      
BodyOfWater                                  0.68      0.45      0.54      195       
Bodybuilder                                  0.90      0.43      0.58      44        
Bone                                         0.65      0.47      0.55      55        
Book                                         0.85      0.90      0.87      5439      
Boxer                                        0.85      0.86      0.85      642       
Brain                                        0.78      0.77      0.77      82        
Brewery                                      0.18      0.07      0.10      43        
Bridge                                       0.85      0.92      0.88      694       
BroadcastNetwork                             0.34      0.28      0.31      197       
Building                                     0.67      0.78      0.72      7466      
BusCompany                                   0.87      0.74      0.80      223       
BusinessPerson                               0.00      0.00      0.00      109       
CanadianFootballLeague                       0.00      0.00      0.00      1         
CanadianFootballTeam                         0.56      0.29      0.38      31        
Canal                                        0.84      0.65      0.73      63        
Canoeist                                     0.90      0.89      0.89      70        
Cardinal                                     0.57      0.35      0.43      117       
Castle                                       0.60      0.72      0.65      232       
Cave                                         0.87      0.67      0.76      89        
Chancellor                                   0.00      0.00      0.00      16        
Cheese                                       0.73      0.71      0.72      42        
Chef                                         0.61      0.50      0.55      90        
ChemicalCompound                             0.86      0.90      0.88      1550      
ChessPlayer                                  0.85      0.80      0.82      226       
ChristianBishop                              0.75      0.77      0.76      1413      
City                                         0.70      0.76      0.73      3115      
ClassicalMusicArtist                         0.00      0.00      0.00      60        
ClassicalMusicComposition                    0.55      0.36      0.44      99        
Cleric                                       0.71      0.48      0.57      414       
ClubMoss                                     0.00      0.00      0.00      17        
College                                      0.86      0.86      0.86      14        
CollegeCoach                                 0.83      0.82      0.83      1053      
Colour                                       0.75      0.63      0.69      38        
Comedian                                     0.49      0.23      0.32      194       
ComedyGroup                                  0.00      0.00      0.00      7         
Comic                                        0.75      0.79      0.77      344       
ComicStrip                                   0.88      0.46      0.61      65        
ComicsCharacter                              0.89      0.84      0.87      620       
ComicsCreator                                0.71      0.55      0.62      426       
Company                                      0.76      0.84      0.80      7920      
ConcentrationCamp                            0.33      0.08      0.13      12        
Congressman                                  0.42      0.47      0.45      493       
Conifer                                      0.86      0.75      0.80      110       
Constellation                                0.90      0.60      0.72      15        
Continent                                    0.00      0.00      0.00      5         
Convention                                   0.58      0.59      0.59      327       
Country                                      0.70      0.52      0.60      475       
Crater                                       0.91      0.81      0.86      103       
CricketGround                                0.90      0.70      0.79      37        
CricketLeague                                0.00      0.00      0.00      1         
CricketTeam                                  0.91      0.83      0.87      113       
Cricketer                                    0.97      0.97      0.97      2926      
Criminal                                     0.66      0.40      0.50      380       
Crustacean                                   0.87      0.83      0.85      433       
CultivatedVariety                            0.97      0.91      0.94      242       
Curler                                       0.90      0.93      0.91      137       
Currency                                     0.92      0.77      0.84      57        
Cycad                                        0.83      0.54      0.65      28        
CyclingRace                                  0.85      0.94      0.89      115       
CyclingTeam                                  0.97      0.74      0.84      47        
Cyclist                                      0.94      0.96      0.95      1745      
Dam                                          0.91      0.86      0.89      516       
DartsPlayer                                  0.97      0.86      0.91      101       
Device                                       0.91      0.83      0.87      196       
Diocese                                      0.98      0.97      0.97      526       
Disease                                      0.95      0.82      0.88      882       
Drug                                         0.88      0.79      0.84      936       
Earthquake                                   0.99      0.98      0.98      129       
Economist                                    0.46      0.20      0.28      188       
EducationalInstitution                       0.84      0.41      0.55      75        
Election                                     1.00      0.71      0.83      17        
Embryology                                   0.39      0.30      0.34      30        
Engineer                                     0.46      0.21      0.29      115       
Entomologist                                 0.56      0.26      0.36      73        
Enzyme                                       0.96      0.96      0.96      786       
EthnicGroup                                  0.87      0.79      0.83      773       
Eukaryote                                    0.62      0.42      0.50      208       
EurovisionSongContestEntry                   0.84      0.86      0.85      179       
Event                                        0.75      0.69      0.72      655       
Fashion                                      0.33      0.02      0.04      50        
FashionDesigner                              0.66      0.35      0.46      130       
Fern                                         0.82      0.80      0.81      165       
FictionalCharacter                           0.77      0.46      0.57      640       
FieldHockeyLeague                            0.00      0.00      0.00      5         
FigureSkater                                 0.97      0.94      0.95      528       
Film                                         0.92      0.93      0.93      16836     
FilmFestival                                 0.91      0.86      0.88      143       
Fish                                         0.95      0.93      0.94      2870      
FloweringPlant                               0.00      0.00      0.00      26        
Food                                         0.89      0.85      0.87      744       
FootballLeagueSeason                         0.93      0.96      0.95      1501      
FootballMatch                                0.96      0.89      0.92      486       
FormulaOneRacer                              0.69      0.47      0.56      120       
FormulaOneTeam                               0.92      0.58      0.71      19        
Fungus                                       0.94      0.96      0.95      1742      
GaelicGamesPlayer                            0.95      0.96      0.96      568       
Galaxy                                       0.94      0.95      0.95      157       
Game                                         0.82      0.67      0.74      228       
Garden                                       0.81      0.42      0.55      50        
Ginkgo                                       0.00      0.00      0.00      2         
GivenName                                    0.90      0.90      0.90      621       
Glacier                                      0.92      0.83      0.87      119       
Gnetophytes                                  0.00      0.00      0.00      3         
GolfCourse                                   0.86      0.74      0.80      50        
GolfLeague                                   0.00      0.00      0.00      3         
GolfPlayer                                   0.97      0.94      0.96      538       
GolfTournament                               0.93      0.97      0.95      269       
GovernmentAgency                             0.72      0.78      0.75      879       
Governor                                     0.43      0.18      0.26      420       
GrandPrix                                    0.97      0.98      0.98      229       
Grape                                        0.93      0.83      0.88      69        
GreenAlga                                    0.48      0.75      0.58      67        
GridironFootballPlayer                       0.69      0.45      0.54      1090      
Guitarist                                    0.00      0.00      0.00      23        
Gymnast                                      0.91      0.80      0.85      333       
HandballLeague                               0.00      0.00      0.00      3         
HandballPlayer                               0.94      0.96      0.95      366       
HandballTeam                                 0.90      0.78      0.84      60        
Historian                                    0.40      0.03      0.06      124       
HistoricBuilding                             0.79      0.81      0.80      1373      
HistoricPlace                                0.66      0.42      0.51      3697      
HockeyTeam                                   0.93      0.90      0.92      374       
Holiday                                      0.75      0.59      0.66      152       
HollywoodCartoon                             0.82      0.83      0.83      241       
HorseRace                                    0.97      0.98      0.98      378       
HorseRider                                   0.76      0.69      0.72      87        
HorseTrainer                                 0.83      0.39      0.54      38        
Hospital                                     0.84      0.90      0.87      474       
Hotel                                        0.68      0.49      0.57      196       
IceHockeyLeague                              0.77      0.82      0.79      44        
IceHockeyPlayer                              0.95      0.97      0.96      2344      
InformationAppliance                         0.80      0.45      0.57      200       
InlineHockeyLeague                           0.00      0.00      0.00      1         
Insect                                       0.98      0.99      0.98      21033     
Island                                       0.76      0.81      0.78      929       
Jockey                                       0.73      0.74      0.73      91        
Journalist                                   0.30      0.12      0.17      230       
Judge                                        0.52      0.30      0.38      430       
LacrosseLeague                               1.00      0.50      0.67      8         
LacrossePlayer                               0.77      0.84      0.81      69        
Lake                                         0.91      0.90      0.91      1516      
Language                                     0.97      0.94      0.95      1191      
LaunchPad                                    1.00      0.86      0.92      14        
LawFirm                                      0.87      0.49      0.62      68        
Legislature                                  0.79      0.85      0.82      287       
Library                                      0.65      0.82      0.73      158       
Ligament                                     0.96      0.79      0.87      29        
Lighthouse                                   0.95      0.87      0.91      287       
Locomotive                                   0.87      0.95      0.91      515       
Lymph                                        0.83      1.00      0.91      10        
Magazine                                     0.90      0.67      0.77      809       
Mammal                                       0.89      0.89      0.89      1260      
Manga                                        0.73      0.55      0.63      491       
MartialArtist                                0.92      0.70      0.79      513       
Mayor                                        0.42      0.41      0.41      266       
Medician                                     0.17      0.01      0.02      76        
MemberOfParliament                           0.52      0.61      0.56      1191      
MilitaryConflict                             0.92      0.92      0.92      2103      
MilitaryPerson                               0.84      0.79      0.81      4300      
MilitaryStructure                            0.64      0.52      0.57      665       
MilitaryUnit                                 0.94      0.93      0.94      2694      
Mineral                                      0.94      0.93      0.93      224       
MixedMartialArtsEvent                        0.95      0.91      0.93      116       
Model                                        0.62      0.46      0.53      252       
Mollusca                                     0.98      0.98      0.98      4271      
Monarch                                      0.49      0.36      0.42      367       
Monument                                     0.56      0.22      0.32      86        
Moss                                         0.85      0.64      0.73      78        
Motorcycle                                   0.84      0.86      0.85      153       
MotorcycleRacingLeague                       0.00      0.00      0.00      4         
MotorcycleRider                              0.86      0.93      0.89      201       
MotorsportSeason                             0.94      0.93      0.94      503       
Mountain                                     0.91      0.88      0.89      2631      
MountainPass                                 0.93      0.88      0.90      160       
MountainRange                                0.91      0.78      0.84      385       
Murderer                                     0.00      0.00      0.00      17        
Muscle                                       0.92      0.77      0.84      44        
Museum                                       0.83      0.68      0.75      874       
MusicFestival                                0.73      0.34      0.47      64        
MusicGenre                                   0.83      0.49      0.62      172       
Musical                                      0.76      0.83      0.79      209       
MusicalArtist                                0.70      0.73      0.71      7874      
MusicalWork                                  0.50      0.14      0.22      43        
MythologicalFigure                           0.73      0.57      0.64      109       
NCAATeamSeason                               1.00      1.00      1.00      2668      
NascarDriver                                 0.64      0.84      0.72      146       
NationalCollegiateAthleticAssociationAthlete 0.00      0.00      0.00      23        
NationalFootballLeagueSeason                 0.96      0.97      0.96      560       
Nerve                                        0.87      0.86      0.86      56        
NetballPlayer                                0.91      0.69      0.78      42        
Newspaper                                    0.85      0.87      0.86      1019      
Noble                                        0.60      0.48      0.53      799       
Non-ProfitOrganisation                       0.30      0.01      0.02      303       
Novel                                        0.00      0.00      0.00      4         
OfficeHolder                                 0.61      0.70      0.65      10451     
OlympicEvent                                 0.98      0.97      0.98      726       
OlympicResult                                0.80      0.99      0.89      113       
Olympics                                     0.75      1.00      0.86      6         
Organisation                                 0.67      0.60      0.63      2759      
Painter                                      0.68      0.35      0.46      402       
Park                                         0.64      0.48      0.55      608       
Person                                       0.59      0.67      0.63      28250     
Philosopher                                  0.41      0.17      0.24      286       
Photographer                                 0.75      0.04      0.08      73        
Place                                        0.68      0.68      0.68      1071      
Planet                                       0.98      0.95      0.96      537       
Plant                                        0.97      0.96      0.96      8292      
Play                                         0.75      0.62      0.68      288       
PlayboyPlaymate                              0.82      0.73      0.78      45        
Poem                                         0.57      0.53      0.55      57        
Poet                                         0.34      0.21      0.26      56        
PokerPlayer                                  0.96      0.94      0.95      130       
PoliticalParty                               0.93      0.84      0.88      1178      
Politician                                   0.75      0.25      0.38      2808      
PoloLeague                                   0.00      0.00      0.00      5         
Pope                                         0.94      0.88      0.91      68        
PowerStation                                 0.83      0.95      0.89      326       
Presenter                                    0.00      0.00      0.00      16        
President                                    0.54      0.14      0.22      321       
PrimeMinister                                0.33      0.06      0.11      203       
Prison                                       0.89      0.89      0.89      199       
ProgrammingLanguage                          0.73      0.55      0.63      148       
ProtectedArea                                0.80      0.85      0.82      1404      
Protein                                      0.81      0.75      0.78      356       
PublicTransitSystem                          0.49      0.68      0.57      252       
Publisher                                    0.81      0.43      0.56      250       
RaceHorse                                    0.97      0.97      0.97      627       
Racecourse                                   0.81      0.57      0.67      51        
RacingDriver                                 0.74      0.73      0.74      388       
RadioHost                                    0.17      0.32      0.22      56        
RadioProgram                                 0.71      0.62      0.66      189       
RadioStation                                 0.96      0.97      0.96      3086      
RailwayLine                                  0.90      0.77      0.83      526       
RailwayStation                               0.93      0.60      0.73      235       
RailwayTunnel                                0.75      0.75      0.75      32        
RecordLabel                                  0.88      0.85      0.86      506       
Religious                                    0.43      0.14      0.21      169       
ReligiousBuilding                            0.59      0.67      0.62      675       
Reptile                                      0.90      0.90      0.90      742       
ResearchProject                              0.00      0.00      0.00      2         
Restaurant                                   0.79      0.63      0.70      175       
River                                        0.96      0.98      0.97      4331      
Road                                         0.95      0.98      0.96      3216      
RoadJunction                                 0.86      0.64      0.73      28        
RoadTunnel                                   0.65      0.84      0.73      43        
Rocket                                       0.78      0.45      0.57      40        
RollerCoaster                                0.87      0.86      0.87      109       
Rower                                        0.75      0.28      0.41      43        
Royalty                                      0.71      0.67      0.69      1580      
RugbyClub                                    0.85      0.89      0.87      366       
RugbyLeague                                  0.77      0.65      0.70      62        
RugbyPlayer                                  0.95      0.97      0.96      2539      
Saint                                        0.75      0.72      0.73      602       
School                                       0.91      0.96      0.93      4936      
Scientist                                    0.51      0.53      0.52      3674      
ScreenWriter                                 0.36      0.03      0.06      118       
Sea                                          0.50      0.14      0.22      7         
Senator                                      0.21      0.16      0.18      115       
Settlement                                   0.88      0.91      0.90      37384     
Ship                                         0.96      0.97      0.97      4584      
ShoppingMall                                 0.86      0.89      0.88      381       
Single                                       0.88      0.93      0.90      7687      
SiteOfSpecialScientificInterest              0.79      0.88      0.83      170       
Skater                                       0.65      0.80      0.72      80        
SkiArea                                      0.85      0.70      0.77      92        
Skier                                        0.77      0.84      0.81      413       
Skyscraper                                   0.00      0.00      0.00      1         
SnookerChamp                                 0.00      0.00      0.00      4         
SnookerPlayer                                0.83      0.95      0.89      61        
SoapCharacter                                0.85      0.84      0.85      418       
SoccerClub                                   0.97      0.94      0.95      3233      
SoccerClubSeason                             0.94      0.99      0.96      1460      
SoccerLeague                                 0.81      0.77      0.79      269       
SoccerManager                                0.82      0.64      0.72      2965      
SoccerPlayer                                 0.93      0.97      0.95      17824     
SoccerTournament                             0.84      0.92      0.88      1079      
SoftballLeague                               0.00      0.00      0.00      2         
Software                                     0.78      0.84      0.81      1716      
SolarEclipse                                 0.98      0.98      0.98      61        
Song                                         0.56      0.29      0.38      941       
SpaceShuttle                                 0.00      0.00      0.00      2         
SpaceStation                                 0.00      0.00      0.00      9         
Species                                      0.79      0.81      0.80      940       
SpeedwayLeague                               0.00      0.00      0.00      3         
SpeedwayRider                                0.95      0.97      0.96      108       
SpeedwayTeam                                 1.00      0.67      0.80      9         
Sport                                        0.38      0.25      0.30      40        
SportsEvent                                  0.84      0.80      0.82      172       
SportsLeague                                 0.31      0.28      0.29      65        
SportsTeam                                   0.63      0.69      0.66      377       
SportsTeamMember                             0.93      0.59      0.72      90        
SquashPlayer                                 0.97      0.94      0.95      65        
Stadium                                      0.62      0.30      0.40      932       
Star                                         0.96      0.96      0.96      469       
Station                                      0.95      0.99      0.97      4268      
Stream                                       0.00      0.00      0.00      7         
SumoWrestler                                 0.97      0.87      0.92      76        
SupremeCourtOfTheUnitedStatesCase            0.97      0.97      0.97      437       
Surname                                      0.14      0.01      0.02      74        
Swimmer                                      0.88      0.82      0.85      919       
TableTennisPlayer                            0.82      0.68      0.74      75        
TelevisionEpisode                            0.93      0.92      0.92      1277      
TelevisionHost                               0.00      0.00      0.00      10        
TelevisionSeason                             0.94      0.88      0.91      569       
TelevisionShow                               0.86      0.83      0.84      5644      
TelevisionStation                            0.91      0.84      0.87      1163      
TennisLeague                                 0.00      0.00      0.00      1         
TennisPlayer                                 0.92      0.97      0.94      810       
TennisTournament                             0.92      0.94      0.93      188       
Theatre                                      0.30      0.24      0.27      115       
Town                                         0.83      0.71      0.76      6528      
TradeUnion                                   0.89      0.73      0.81      248       
Train                                        0.91      0.76      0.83      237       
Tunnel                                       0.00      0.00      0.00      15        
University                                   0.88      0.86      0.87      2900      
Valley                                       0.14      0.07      0.09      15        
Vein                                         0.92      0.94      0.93      35        
Venue                                        0.41      0.67      0.51      889       
VideoGame                                    0.90      0.93      0.92      3038      
Village                                      0.96      0.95      0.95      26308     
VoiceActor                                   0.00      0.00      0.00      28        
Volcano                                      0.68      0.51      0.58      106       
VolleyballCoach                              0.08      0.12      0.10      8         
VolleyballLeague                             0.71      0.38      0.50      13        
VolleyballPlayer                             0.94      0.89      0.91      601       
WaterRide                                    0.00      0.00      0.00      10        
WaterwayTunnel                               1.00      0.50      0.67      2         
Weapon                                       0.90      0.78      0.84      814       
Website                                      0.73      0.29      0.42      548       
WineRegion                                   0.94      0.77      0.85      65        
Winery                                       0.82      0.73      0.77      51        
WomensTennisAssociationTournament            0.91      0.93      0.92      88        
WorldHeritageSite                            0.57      0.07      0.13      107       
Wrestler                                     0.89      0.73      0.80      524       
WrestlingEvent                               0.95      0.91      0.93      173       
Writer                                       0.50      0.33      0.40      4675      
WrittenWork                                  0.66      0.81      0.73      235       
Year                                         0.99      0.97      0.98      247       
YearInSpaceflight                            1.00      0.86      0.92      7         
owl#Thing                                    0.52      0.56      0.54      42119     

micro avg                                    0.81      0.81      0.81      500412    
macro avg                                    0.69      0.61      0.64      500412    
weighted avg                                 0.81      0.81      0.81      500412    
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

kubernetesでPython+MySQL8を使う時にハマった点!

概要

現在、ローカルにvue+djangoの開発環境をkubernetesで構築しようとしているのですが、
mysqlのコンテナを立てる際にハマったことがあったので、情報を共有します。

MySQL8をPythonで使う場合について

MySQLをPythonで使う場合、パッケージにmysqlclientを選択することがあると思います。

ここでMySQL8でmysqlclientを使う場合に注意する点があります。
MySQL8.0.4以降、デフォルトの認証方式が変更され、mysql_native_passwordからcaching_sha2_passwordになりました。しかし、mysqlclientはこのcaching_sha2_passwordに対応していません。
そのため、以下のように、my.cnfを変更するか、もしくはmysqldの実行時に--default-authentication-plugin=mysql_native_passwordオプションをつけて、認証方式をmysql_native_passwordに戻す必要があります。

my.cnf
[mysqld]
default-authentication-plugin = mysql_native_password
mysqld --default-authentication-plugin=mysql_native_password

kubernetesでMySQLをデプロイ

私は、docker-composeにてMySQL8系のコンテナを利用していたこともあり、その際にdocker-compose.ymlからコマンドを上書きして、後者のコマンドにオプションをつけて実行する方法で実行していたため、kubernetesでの実行時も同様の方法を選択しました。

一部抜粋した設定定義ファイルでは以下のように指定していました。

注:ここではローカル環境用の設定定義のため、パスワード等をConfigMapで設定していますが、実際の運用ではSecretを推奨です

mysql-sts.yaml
...
    spec:
      containers:
      - name: mysql
        image: mysql:8.0.15
        # この部分
        command:
          - mysqld
          - --user=root --default-authentication-plugin=mysql_native_password
        env:
          - name: MYSQL_USER
            valueFrom:
              configMapKeyRef:
                name: mysql-cm
                key: MYSQL_USER
          - name: MYSQL_PASSWORD
            valueFrom:
              configMapKeyRef:
                name: mysql-cm
                key: MYSQL_PASSWORD
          - name: MYSQL_DATABASE
            valueFrom:
              configMapKeyRef:
                name: mysql-cm
                key: MYSQL_DATABASE
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
...

しかし、これを用いてリソースを作成するとなぜか初期化の段階でうまくいきません。
これはkubernetesのcommandの仕様が、少し特殊だったことが原因でした。

kubernetesのcommandとENTRYPOINT

結論から言いますと、kubernetesのcommandはCMDだけではなく、ENTRYPOINTも上書きしてしまうことが問題点となっていました。
kubernetes学習番外編 コンテナ起動時のコマンド実行 - そんな今日この頃の技術ネタ

このリソースでは公式のMySQLイメージを利用していますが、公式イメージはイメージ内でENTRYPOINTを利用して初期化をするスクリプトが走っています。
そのため、上記のようにkubernetesのcommandを利用してしまうと、ENTRYPOINTが上書きされてしまい、公式イメージによって自動化されていた初期化のプロセスを実行しなくてはいけないんですが、それをうまく実行できていなかったために、エラーとなっていたようです。

そのため、以下のようにmy.cnfを変更する方法で、認証方式をmysql_native_passwordに戻すことで、エラーを回避することができました。

mysql-sts.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: django-mysql-cm
  labels:
    project: django-vue
    app: mysql
data:
  MYSQL_USER: timer
  MYSQL_PASSWORD: timer
  MYSQL_DATABASE: timer
  MYSQL_HOST: django-mysql-svc
  my.cnf: |-
    [mysqld]
    default-authentication-plugin = mysql_native_password
---
...
      containers:
      - name: mysql
        image: mysql:8.0.15
        env:
          - name: MYSQL_USER
            valueFrom:
              configMapKeyRef:
                name: django-mysql-cm
                key: MYSQL_USER
          - name: MYSQL_PASSWORD
            valueFrom:
              configMapKeyRef:
                name: django-mysql-cm
                key: MYSQL_PASSWORD
          - name: MYSQL_DATABASE
            valueFrom:
              configMapKeyRef:
                name: django-mysql-cm
                key: MYSQL_DATABASE
        ports:
        - containerPort: 3306
          name: mysql
        volumeMounts:
        - name: my-cnf
          mountPath: /etc/my.cnf
          subPath: my.cnf
          readOnly: true
        - name: data
          mountPath: /var/lib/mysql
          subPath: mysql
      volumes:
      - name: my-cnf
        configMap:
          name: django-mysql-cm
          items:
          - key: my.cnf
            path: my.cnf
...

あとがき

今回は思ってもみなかったkubernetesの仕様でかなりの時間対応させられることになってしまいました。
初期化で失敗している時点で、公式イメージの初期化処理が通ってないと気づくのが、もう少し早かったならばと悔やまれます。

現在まだ環境を構築中ですが、開発環境が完成したら、後日公開したいなと思っています。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

TensorFlow2.0でアニメキャラ識別

TensorFrowのチュートリアルパクって参考にしてアニメキャラ識別をしてみました。
解説はチュートリアルに書いてあるのでそちらを見てください。

環境

  • Windows10 (64bit)
  • Python 3.6.8
  • TensorFrow 2.0.0-alpha0

以下のようなフォルダ階層となっている前提で話を進めます。

.
├─mk_DataSet.py
├─Training.py
├─Classifier.py
├─Labels.tsv
└─Anime_Title
   ├─Chara1
   │   └─大量の画像データ
   ├─Chara2
   │   └─大量の画像データ
   ├─Chara3
   │   └─大量の画像データ

学習データ集め

まずは学習用のデータを集めます。使うのはこれ↓だと思いますが、先人たちがいろいろ書いてくれてますので今回は割愛します。
OpenCVによるアニメ顔検出ならlbpcascade_animeface.xml

集めたデータはキャラクターごとに分けてください。
それに合わせてLabels.tsvファイルを作成します。タブ区切りで「id,キャラ名(フォルダ名),イメージカラー」
folder.png

Labels.tsv
0   Lala    (255, 127, 255)
1   Mirei   (255, 127, 127)
2   Sophy   (255, 0, 255)
3   Sion    (0, 255, 0)
4   Dorothy (255, 0, 0)
5   Reona   (0, 0, 255)

データセット作成

学習用とテスト用データセットをつくる。
train.tsvとtest.tsvができます。

mk_DataSet.py
import os
import glob
import numpy as np


imdir = 'PriPara'
idx, labels, col = np.loadtxt('Labels.tsv', delimiter='\t', dtype='i8,S20,S20', unpack=True)


data = []
for i,name in zip(idx,labels):
    lst = glob.glob(os.path.join(imdir, name.decode(), '*.png'))
    print('%s: %d'%(name.decode(), len(lst)))
    for fn in lst:
        data.append([i, fn])

np.random.shuffle(data)
tt = int(len(data)*0.75)
np.savetxt('train.tsv', data[:tt], fmt='%s', delimiter='\t')
np.savetxt('test.tsv',  data[tt:], fmt='%s', delimiter='\t')

学習する

チュートリアルではグレースケール画像ですが,アニメキャラは髪の色で判別してる説があるのでカラー画像で学習します。
画像を読み込むときにいろいろ処理していますが,それっぽいことをしているだけで効果があるかは確認していません。

Training.py
import tensorflow as tf
from tensorflow import keras
import numpy as np
import cv2
import matplotlib.pyplot as plt


idx, labels, col = np.loadtxt('Labels.tsv', delimiter='\t', dtype='i8,S20,S20', unpack=True)
IMG_SHAPE = (50, 64, 3)


def img(fn):
    img = cv2.imread(fn)
    # サイズ調整
    img = cv2.resize(img, (np.max(IMG_SHAPE),np.max(IMG_SHAPE)))
    img = img[:IMG_SHAPE[0],:IMG_SHAPE[1],:]
    # ガウシアンフィルタで平滑化
    img = cv2.GaussianBlur(img, (3,3), 1)
    # 輝度のみ平坦化
    img = cv2.cvtColor(img, cv2.COLOR_BGR2YUV)
    img[:,:,0] = cv2.equalizeHist(img[:,:,0])
    img = cv2.cvtColor(img, cv2.COLOR_YUV2BGR)
    return img

def mk_data(fn):
    print('Loading...', fn)
    labels, lst = np.loadtxt(fn, delimiter='\t', dtype='i8,S50', unpack=True)
    images = np.stack([img(fn.decode()) for fn in lst])
    images = images / 255.0
    return labels, images

try:
    data = np.load('train.npz')
    train_labels = data['lbl']
    train_images = data['img']
    data = np.load('test.npz')
    test_labels = data['lbl']
    test_images = data['img']
    ans = input('Use save data? [Y/n] ')
    if ans in ['N','n','No','no']:
        raise Exception
except:
    train_labels, train_images = mk_data('train.tsv')
    test_labels,  test_images  = mk_data('test.tsv')
    np.savez('train.npz', lbl=train_labels, img=train_images)
    np.savez( 'test.npz',  lbl=test_labels,  img=test_images)


## モデルの構築
# layerの設定
model = keras.Sequential([
    keras.layers.Flatten(input_shape=IMG_SHAPE),
    keras.layers.Dense(256, activation=tf.nn.relu),
    keras.layers.Dense(np.max(idx)+1, activation=tf.nn.softmax)
])

# モデルのコンパイル
model.compile(optimizer=tf.keras.optimizers.Adam(), 
              loss='sparse_categorical_crossentropy',
              metrics=['accuracy'])

## モデルの訓練
model.fit(train_images, train_labels, epochs=20)

## 正解率の評価
test_loss, test_acc = model.evaluate(test_images, test_labels)
print('Test accuracy:', test_acc)

model.save('my_model.h5')




## 予測する
predictions = model.predict(test_images)

def plot_image(i, predictions_array, true_label, img):
    predictions_array, true_label, img = predictions_array[i], true_label[i], img[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    plt.imshow(img, cmap=plt.cm.binary_r)

    predicted_label = np.argmax(predictions_array)
    color = 'blue' if predicted_label == true_label else 'red'

    plt.xlabel("{} {:2.0f}% ({})".format(labels[predicted_label].decode(),
                                    100*np.max(predictions_array),
                                    labels[true_label].decode()),
                                    color=color)

def plot_value_array(i, predictions_array, true_label):
    predictions_array, true_label = predictions_array[i], true_label[i]
    plt.grid(False)
    plt.xticks([])
    plt.yticks([])
    thisplot = plt.bar(range(np.max(idx)+1), predictions_array, color="#777777")
    plt.ylim([0, 1]) 
    predicted_label = np.argmax(predictions_array)

    thisplot[predicted_label].set_color('red')
    thisplot[true_label].set_color('blue')

num_rows = 5
num_cols = 3
num_images = num_rows * num_cols
plt.figure(figsize=(2*2*num_cols, 2*num_rows))
for i in range(num_images):
    plt.subplot(num_rows, 2*num_cols, 2*i+1)
    plot_image(i, predictions, test_labels, test_images)
    plt.subplot(num_rows, 2*num_cols, 2*i+2)
    plot_value_array(i, predictions, test_labels)

plt.show()

精度は95%程度はでる。
最後に学習結果の例が出る。Matplotlibで表示されるのでRとBが逆だけど気にしない。
コメント 2019-04-16 235316.png

識別する

スクショをとって識別してみます。
model = keras.models.load_model('my_model.h5')で保存したモデルごと読み込むだけで使える。

Classifier.py
import tensorflow as tf
from tensorflow import keras
import numpy as np
import cv2
from PIL import ImageGrab


idx, labels, cols = np.loadtxt('Labels.tsv', delimiter='\t', dtype='i8,S20,S20', unpack=True)
IMG_SHAPE = (100, 128, 3)
model = keras.models.load_model('my_model.h5')
print(model.summary())

path = 'C:\\_data_\\lbpcascade_animeface.xml'
cascade = cv2.CascadeClassifier(path)


def predict(img):
    cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
    img = cv2.resize(img, (np.max(IMG_SHAPE),np.max(IMG_SHAPE)))
    img = img[:IMG_SHAPE[0],:IMG_SHAPE[1],:]
    predictions = model.predict(np.expand_dims(img,0))
    return np.argmax(predictions[0]), np.max(predictions[0])

cv2.namedWindow('ret', cv2.WINDOW_NORMAL)
while cv2.waitKey(1)!=27:
    img = ImageGrab.grab(bbox=(50, 100, 1600, 1200))
    img = np.asarray(img)
    img = cv2.cvtColor(img, cv2.COLOR_RGB2BGR)

    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    gray = cv2.equalizeHist(gray)
    faces = cascade.detectMultiScale(gray, minSize=(200,200), scaleFactor=1.05, minNeighbors=5)

    for (x,y,w,h) in faces:
        face = img[y:y+h, x:x+w]
        idx, val = predict(face)
        label = labels[idx].decode()
        col = tuple(map(int, cols[idx][1:-1].decode().split(',')))
        cv2.rectangle(img, (x,y), (x+w,y+h), col, 2)
        cv2.putText(img, '%s:%.3f'%(label,val), (x,y), cv2.FONT_HERSHEY_SIMPLEX, 1.0, col, 2)

    cv2.imshow('ret', img)

結果

コメント 2019-04-17 000957.png
コメント 2019-04-17 001100.png
コメント 2019-04-17 001300.png
コメント 2019-04-17 001405.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む