情報学部大学生のダラダラ日記

β日記

機械学習や日記っぽいものを書きます

Pythonでcsvを分割して読み込む(改訂版)

はじめに

半年ほど前に似たような記事を書いたのですが、それは自分が使用したコードを貼り付けただけで全く参考にならなさそうだったので簡略化したものをもう一度書くことにしました。

前回の↓

Python3で大容量のcsvファイルを分割して読み込む - 情報学部大学生のダラダラ日記

 

使用するcsvとコード

スクリーンショットで失礼します。以下のcsvを使います。

f:id:Parco1021:20191228182704p:plain

import pandas as pd

reader = pd.read_csv('tagA.csv'chunksize=5)

for r in reader:
    print(r)

chunksizeなどの説明は以前の記事に書いたのでそちらをご覧になってください。簡単に言うとchunksizeで指定した数で分割して読み込みます。なのでこのコードだと5個ずつデータを分割します。そして今回データ数は10個なので10/5で2回に分けて読み込みます。

 

結果

f:id:Parco1021:20191228181452p:plain

ご覧の通り5個ずつ2回に分けて読み込んでいることがわかります。

もう少しいじってみる

分割して読み込んだのはいいとして、これを少しいじってみます。

コード
import pandas as pd

reader = pd.read_csv('tagA.csv'chunksize=5)

for r in reader:
    row = []
    for index,rows in r.iterrows():
        print(rows[1])
        row.append(rows[1])
    print("#分割の区切り")
    print(row)

iterrows()とすることで列ごと見ることができます。具体的にはこのコードにおけるrowsはrow[0]にid、row[1]にはtagが入っています。これをさらに別々に出力させることもでき、今回はリストにも入れてみました。

出力

f:id:Parco1021:20191228185655p:plain

今回はfor文の中でリストを初期化しているのでこのような出力となっていますが、外でやった場合、全データのtagのリストとなります。また、iterrows()をiteritems()とすることで行で見ることができるので用途によって使い分けが必要です。
また、今回出力させていませんが、indexにはインデックス(0,1,...9)が入っています。

さいごに

使用機材のメモリにのらない時に多く使われる印象のあるchunksizeというオプションですが、考えようによっては他にも良い使い方がありそうだな~と思いました。

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

2019年の終わり、それはPython2の終わり。

僕は知らなかったのですが、Python2がサポート終了するのが2020年1月1日に大分前から決まっていたようです。公式のドキュメントはこちら↓

www.python.org

「Python2の日没」ですって。オシャレ。

ドキュメントによると、2000年にPython2が始まり、2006年にPython3が作られた?のですが、初めはPython3がよろしくなかったらしくPython3へ移行する人があまりおらず、結局Python2を使う人とPython3使う人が共存してしまい、両方改良を続けていたようです。

こうなってしまった原因として、2系と3系で互換性がないことが挙げられます。僕も最初ネットを参照しながらPythonを書いていたらネットには2系と3系が混在しており、エラーが無くならず心が折れかけました。例としては2系ではprint "Hello World"であるのに対し、3系ではprint ("Hello World")のようになります。僕は3系しか使ったことがないので他にはわかりませんが、多くの違いがあり、全くの別言語らしいです。

話を戻して、両方改良するのはさすがに公式さんも大変だったらしく、2008年に「2015年にサポートを終了する」というアナウンスをしたそうです。しかし、2014年にそれは厳しいと判断し、2020年に終了すると先延ばしにしました。

今は2019年12月末。あと少しでPython2のサポートが終了します。Python2しか使ってない!って人も、2to3というPython2を3へ変更するモノがあるらしいので応急措置ですが大丈夫です。あくまで応急措置なのでPython3のお勉強をしなければなりませんが…。

あとどれだけでサポートが終了するか示すサイトもあるぽいです。

Python 2.7 Countdown

あと10日と4時間です。

f:id:Parco1021:20191221193057p:plain

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

数値微分法についてまとめてPythonで色々してみる

 勾配法あたりでやたらと見る数値微分法について調査し、まとめてみました。

 今回、理論的なことは以下の書籍を参照し、図とプログラムは1から自作したものであり、特にプログラムは筆者がその場で簡易的に考え実装したものです。変数名などおかしい点がありますがご容赦ください。

数値微分法とは

 勾配法においてはある重み{\displaystyle w_1 }において、誤差関数{\displaystyle E(w) }{\displaystyle w }に関して偏微分したものの符号を入れ変えたもの{\displaystyle -\frac{∂E}{∂w} }の方向に重み{\displaystyle w_1 }を更新します。この偏微分という動作をしなくても近似を使うことによって重みの更新をしちゃおう!というのが数値微分法の目的です。

 

 まず、微分の定義を思い出します。

{\displaystyle \lim_{h \to 0} \frac{f(x+h)-f(x)}{h} }

これが見慣れた形ですが今回は文字を変えて

{\displaystyle \lim_{ε \to 0} \frac{E(w_1+ε)-E(w_1)}{ε} }

とします。

f:id:Parco1021:20191215170236p:plain

余談ですが、式だけだとわかりづらいので僕が誰かに微分の定義を説明する時は上みたいな図を描いてこのεを0にもってくとその点での接線になるでしょ??って言います。

 

まず、数値微分法のうち、2点近似を紹介します。図は↑と同様で、式は

{\displaystyle \frac{E(w_1+ε)-E(w_1)}{ε} }です。

 数値微分法では極限などを使わず、手動で限りなく小さいεを設定することで勾配を近似します。例えばεを0.001と設定し、{\displaystyle E(w)=w^3 }{\displaystyle w_1=3 }とすると、

微分法:{\displaystyle E'(3)=27 }

数値微分法(2点近似):{\displaystyle E'(3)≒27.009001‬ }となり、誤差は約0.01ほどになります。

 

 では、より誤差を減らす方法はないの?と思ったそこの奥様!あります。三点近似(中心差分)という手法です。図は先ほどと異なります。

f:id:Parco1021:20191215173433p:plain

そして式は

{\displaystyle \frac{E(w_1+ε)-E(w_1-ε)}{2ε} }です。

試しに先ほどの2点近似と同様の条件で計算してみると

数値微分法(3点近似):{\displaystyle E'(3)≒27.000001‬‬ }となり、誤差が0.000001にまで減りました。

 

Pythonで観測

式自体は単純なものなので書く必要もないと思いますが、通常の微分したものとの差をグラフに描画するプログラムを書きます。

import matplotlib.pyplot as plt
%matplotlib inline

Ew = lambda w: w**3
Gw = lambda w: 3*w**2
e = 0.001
w = [-10000,-100,0,2,16,64,100,1000,10000]
_two = []
_three = []

def normal(w):
    E_dashn = Gw(w)
    return E_dashn
    
    
def three_point(w,e):
    E_dashth = (Ew(w+e)-Ew(w-e)) / (2*e)
    return E_dashth

def two_point(w,e):
    E_dashtw = (Ew(w+e)-Ew(w)) / e
    return E_dashtw

for i in range(len(w)):
        _two.append(two_point(w[i],e)-normal(w[i]))
        _three.append(three_point(w[i],e)-normal(w[i]))

plt.plot(w,_two,label='2point')
plt.plot(w,_three,label="3point")
plt.show()

プログラムは単純なものです。式Ewとそれを微分した式Gwを用意し、wを変化させた時の2点近似と3点近似と通常微分との値の差を取っています。

 

結果

f:id:Parco1021:20191215192757p:plain

グラフを観ると、2点近似は単調増加しており、3点近似は変化していません。これは今回の{\displaystyle E(w)がw^3}であることと、それぞれの式を観れば自明です。そして2点近似と3点近似の優劣は関数{\displaystyle E(w) }が変わっても変化しないでしょう。よって計算量が増加するというデメリットがありますが、3点近似を使う方がより誤差を減らすことができます。

参考文献

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

2次方程式や3次方程式の解と係数の関係の導出方法

 解と係数の関係、知っていますでしょうか。結構な頻度で使われるので受験を経験した人達は覚えていると思います。しかしセンター試験レベルだとせいぜい使っても2次方程式の解と係数の関係ぐらいなので暗記でも乗り越えられるのですが、突然3次方程式の解と係数の関係を使う問題がでた時に困ります。そんな時に導出方法を知っていると役に立つと思うので知らない受験生は知り得です。

2次方程式の解と係数の関係

2次方程式{\displaystyle ax^2+bx+c=0 }が2つの解{\displaystyle α,β }を持つとき、

{\displaystyle α+β=-\frac{b}{a} }

{\displaystyle αβ=\frac{c}{a} }

が成り立ちます。僕は「マイナス(-)を忘れる奴はば(ba)か(ca)」と覚えろと教わりました。まず、2つの方法で2次方程式における関係を導出してみます。

 

 

1つ目は解の公式を使います。

 x=\frac{-b±\sqrt{b^2-4ac}}{2a}

この場合、解は{\displaystyle α,β }なので

{\displaystyle α+β=\frac{-b+\sqrt{b^2-4ac}}{2a}+\frac{-b-\sqrt{b^2-4ac}}{2a}=\frac{-2b}{2a}=-\frac{b}{a}}

{\displaystyle αβ=\frac{b^2-(b^2-4ac)}{4a^2}=\frac{c}{a} }

となります。

 

2つ目は因数定理を使います。

※因数定理

{\displaystyle f(x)が(x-α)を因数(掛け算として表したときにその個々の数のこと)持つことはf(α)=0となるための必要十分条件である }

 

これを使うことにより

{\displaystyle ax^2+bx+c=0がα,βを解に持つ⇔A(x-α)(x-β)=0 }とすることができます。

右辺を展開すると

{\displaystyle Ax^2-A(α+β)x+Aαβ=0 }となります。そこで元の式と比較すると

{\displaystyle a=A }

{\displaystyle b=-A(α+β) }

{\displaystyle c=Aαβ }となるのでここから

{\displaystyle α+β=-\frac{b}{a} }

{\displaystyle αβ=\frac{c}{a} }が求められます。

 

2つ導出方法を紹介しましたがどちらを覚えるべきでしょうか?どちらも覚えてほしいですが重要なのは2つ目です。理由は解の公式は4次式までしかありませんし、とてもじゃありませんが覚えるなんて不可能に近いです。とりあえず2つ目の方法を使って3次方程式の解と係数の関係を求めてみます。

{\displaystyle ax^3+bx^2+cx+d=0 }が3つの解{\displaystyle α,β,γ }を持つとき、因数定理より

{\displaystyle A(x-α)(x-β)(x-γ)=0 }となります。展開すると

{\displaystyle Ax^3-A(α+β+γ)x^2+A(αβ+βγ+γα)x-Aαβγ=0 }となるので係数比較すると

{\displaystyle α+β+γ=-\frac{b}{a} }

{\displaystyle αβ+βγ+γα=-\frac{c}{a} }

{\displaystyle αβγ=-\frac{d}{a} }となります。

まだ2次と3次しか見ていませんが何か規則性が"観えて"きますね。ムムッ

1次の時は{\displaystyle α=-\frac{b}{a} }ですし多分解を足したら同じ結果になるんでしょうね。あとは解を掛けたら定数項/aとか。

さいごに

 今回は手計算でごり押し風に3次までやりましたが5次あたりからきつくなると思います。なのでn次として一般化しなければならないのですが、そこは僕も受験生時代お世話になった以下のサイトさんがやっててくれました。

mathtrain.jp

上のサイトにあるならやらなくていいんじゃないかという声が聞こえてくる気がしますが、高校数学あたりの公式の証明って良い頭の体操になるんですよ。それに"調べれば"出てくるという仮定つきなので調べなくても誰かの目に留まればいいなって感じです。自己満です。頭の体操としてやったのでサイトを観ていません。なのでもし間違っているところ等あればこっそり教えてください。

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

予測損失と経験損失について簡単にまとめる

 機械学習の大きな目的は訓練データから未知のデータ、すなわちテストデータに対する損失を小さくすることです。予測損失(テストデータ)と経験損失(訓練データ)についてまとめてみます。

予測損失

 予測損失というよりも汎化誤差という言葉の方が親しみがあるのではないでしょうか。また、他にも期待損失などとも言うようです。仮説{\displaystyle h }の予測損失{\displaystyle R(x) }が、損失関数として{\displaystyle l }、テストデータ{\displaystyle (X,Y) }の分布{\displaystyle D }を用いて以下のように定義されます。

{\displaystyle R(h) = E_{(X,Y)~D}[l(h(X),Y)]}

つまり、テストデータの分布に対してのテストデータの損失の期待値ということです。しかし、テストデータの分布は未知であるためこの予測損失{\displaystyle R(x) }を計算することはできないです。目標は観測データのみからできるだけ{\displaystyle R(x) }を小さくする仮説{\displaystyle h }を求めることです。

経験損失

 標本誤差、経験誤差とも言われています。データ{\displaystyle (X_1,Y_1),(X_2,Y_2),.....(X_n,Y_n) }が観測され、仮説と損失関数を先ほどと同じ文字に設定すると観測データに対する仮説{\displaystyle h }の経験損失{\displaystyle R ̃(h) }は以下のようになります。

 {\displaystyle R ̃(h) =∑_{(i=1)}^nl(h(X_i),Y_i) }

先ほどの予測損失と異なり、観測データは明らかになっているので{\displaystyle R ̃(h) }は求めることが可能です。

 特にこの時、確率{\displaystyle 1/n }{\displaystyle (X_i,Y_i) }を取る時、確率分布を{\displaystyle D_1 }とすると上式は

{\displaystyle R ̃(h) = E_{(X,Y)~D_1}[l(h(X),Y)] }

と表すことができる。この式は予測損失の式ととても似ていますね。違いは従っている確率分布です。つまり、データが同一の確率分布に従うとき、

{\displaystyle R ̃(h) ≒ R(h) }

とすることができます。

結局???

 予測損失を最小にしたいのはわかっていただけたと思います。簡単に説明すると"予測損失を最小にすることが(実質的に)機械学習の主たる目的だから"です。ではなぜ経験損失を求める必要があるのでしょうか?それは上でも述べた通り、経験損失と予測損失が近似できるからです。流れは以下のような感じです。

 

予測損失が最小となるよう仮説を設定したい

テストデータの分布は未知であるため値が求められない

予測損失と近似できる経験損失がある

経験損失は実測値から求められる

 

という感じです。今回は理論的な部分から予測損失(汎化誤差)にアプローチしてみましたが、応用的な部分から観てみるとなぜ予測損失を最小にしたいかが感覚的にわかってくると思います。以下のサイトをご覧になってみてください。

訓練誤差と汎化誤差の理論計算 - Qiita

参考文献

以下の書籍を参考に書きました。

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

 

モデルを蒸留するのではなくデータセットを蒸留する(論文紹介②Dataset Distillation)

蒸留とは

 中学生の時に化学で学んだ蒸留について、

蒸留(じょうりゅう、Distillation)とは、混合物を一度蒸発させ、後で再び凝縮させることで、沸点の異なる成分を分離・濃縮する操作をいう。

引用元:Wikipedia

 深く、大きいモデルが優秀であることは想像に難くありません。しかし、実際にはそのような大きいモデルが使用できないが機械学習モデルを使用したい場面があります(ラズパイとかでやる時など)。そのような時に、深く大きいニューラルネットワークの知識を蒸留し、より浅く小さいニューラルネットワークへ学習させるために使われるものです。特に大きいモデルを教師モデル、小さいモデルを生徒モデルと言います。つまり性能をできるだけそのままに教師モデルから生徒モデルへ知識の継承を行うことを目的としています。これについての元論文は以下です。

Distilling the Knowledge in a Neural Network,Geoffrey Hinton, Oriol Vinyals, Jeff Dean,2015,https://arxiv.org/abs/1503.02531

日本語でまとめられた文献もあります。

Deep Learningにおける知識の蒸留 | Code Craft House

論文紹介

今後、本記事での画像等の引用は全てこの論文からです。

引用数は9でタイトルはそのまま「データセットの蒸留」です。

概要

 先ではモデルの蒸留を行っていましたが本論文ではデータセットの蒸留をします。具体的には膨大なデータセットをサンプリングすることなく、各クラスごとに新たな画像を生成することでデータセットを圧縮している。

f:id:Parco1021:20191127182634p:plain

引用元:Dataset Distillation

 

イメージとしては上のような感じ。このように新たに画像を生成することで数万枚のデータセットが10~300枚へと蒸留することができている。

アルゴリズム

f:id:Parco1021:20191127184527p:plain

引用元:Dataset Distillation

<!--以下自己解釈

蒸留後データセット{\displaystyle x ̃ }を初期化する。

元データ{\displaystyle x }を取得する。

ある重み{\displaystyle }θ_0^{(j )}において勾配を求め、より良い重み{\displaystyle }θ_1^{(j )}を決定

元データと{\displaystyle }θ_1^{(j )}を使ってロス関数を計算する。

ロス関数の勾配から蒸留後データセット{\displaystyle x ̃ }を更新する。

-->

実験結果

まず、上記のアルゴリズムを繰り返し行う2パターンの実験を行う。

上のアルゴリズムを拡張して2つの方法を用意する。

(a)重み{\displaystyle θ }の更新を複数回行う

(b){\displaystyle x ̃ }の更新を複数回行う

f:id:Parco1021:20191127190345p:plain

引用元:Dataset Distillation

 

実験対象としてMNISTとCIFAR10が用いられたが、(a),(b)どちらの場合にも複数回行った方が正確となっている。

 

次に、ベースライン条件として以下の4つの条件を用意し、それとデータセットを蒸留した時の結果を比較する。

ベースライン条件

  1. ランダム
  2. 学習効果の高かった上位20%
  3. k-means法
  4. 各画像の平均

結果が以下です。ベースライン条件よりも良い結果になっていることがわかります。

f:id:Parco1021:20191127193422p:plain

引用元:Dataset Distillation 

さいごに

 今回は蒸留という手法の新しいアプローチを行った論文でした。どのようなクラスからどのような画像が生成されたかは参考文献の公式リンクから観てみてください。carクラスだったりが1つの画像になっているのは結構面白いです。

英語キチィ~

参考文献

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Python】Twitter apiを使って複数画像を投稿する

はじめに

 Twitter botを作成する際にapiを使って複数枚画像を投稿する方法があまりネットでは見つからなかったり、のっている情報が誤っていたりしたのでメモします。今回はいらすとやさんの画像を使いました。

プログラム

import requests

import twitter

import urllib.request

import requests

from requests_oauthlib import OAuth1Session

import json





CK=''

CS=''

AT=''

AS=''

twitter = OAuth1Session(CK,CS,AT,AS)



url_media = "https://upload.twitter.com/1.1/media/upload.json"

url_text = "https://api.twitter.com/1.1/statuses/update.json"



img_url = ['https://1.bp.blogspot.com/-SWOiphrHWnI/XWS5x7MYwHI/AAAAAAABUXA/i_PRL_Atr08ayl9sZy9-x0uoY4zV2d5xwCLcBGAs/s1600/pose_dance_ukareru_man.png',

            'https://1.bp.blogspot.com/-CSIokkL0VJc/XVKgHNKp2QI/AAAAAAABUHU/znkuxlOlQ5giZ3gDbks7KAK3TJnT2q1XwCLcBGAs/s1600/kotowaza_hato_mamedeppou.png',

            'https://1.bp.blogspot.com/-8sMAiPmvFuo/XVjgKN2BXoI/AAAAAAABUM0/IfTQp8hHWRsVk_u7s84OE6yvFJ5ekpnLwCLcBGAs/s1600/kid_seikaku_uchiki_girl.png',

            'https://1.bp.blogspot.com/-ahlT7Kd7-T0/XVjgJ3hrbFI/AAAAAAABUMw/MV4su85SnoAMYnSitR9DXVgNFuorpprwQCLcBGAs/s1600/kid_seikaku_uchiki_boy.png']  #①



def call():    

    media_id = []

    for i in range(4):

        headers = {"User-Agent": "Mozilla/5.0"}  #②

        request = urllib.request.Request(url=img_url[i],headers=headers)

        response = urllib.request.urlopen(request)

        data = response.read()

        files = {"media" : data}

        req_media = twitter.post(url_media,files = files)  #③

        media_id.append(json.loads(req_media.text)['media_id_string'])

    media_id= ','.join(media_id)  #④

    status = "投稿テスト"

    params = {"status": status, "media_ids": media_id}

    twitter.post(url_text,params=params)

    

        

if __name__ =='__main__':

    call()

解説と結果

  • ①ここで投稿したい画像のURLをリストにいれておいて準備します。僕はURLから画像を取得したかったのでやっていませんが、ローカルのファイルのパスを指定して投稿したい場合は他の方が多くやっていらっしゃるのでそちらを参照してください。
  • ②ユーザーエージェント(どのようなブラウザがサーバへアクセスしているかの情報)をこのようにFirefoxなどに指定しないと権限エラーが出てアクセスできないので注意してください。これについても多くの情報があるので調べてみてください。
  • ③②~③までの間でリスト内の画像URLをサーバから受け取りました。Twitterには直接画像のURLを画像として呟く事ができないので③ではこれをTwitter(url_media)へpostすることでURLを画像コード(数字の羅列)に変換しています。
  • ④今回の主たるところです。media_idが最終的にTwitterへ送る際にはじめはリストを渡せばいいと思っていましたが一枚しか投稿されませんでした。おそらく、['111','112',・・・]となっていることで途中のシングルクォーテーションが区切りと判断されたことが原因だと思います。なので④のようにリストの要素をカンマでjoin結合し、[111,112,・・・]とすることで複数枚投稿が可能となります。

 呟いた結果がこちら↓

f:id:Parco1021:20191123200647j:image

 

さいごに

 今回はTwitter apiの複数枚投稿についてまとめました。4で割り切れない場合などに臨機応変に対応させて複数枚投稿させたい場合はmodなどを使うといいです。僕が作ったbotはそのような設計になっているのでもしよければ観てみてください。

parco1021.hatenablog.com

(あげたあとにあげる必要ないって気づいたけど一応gitにもあげたので…https://github.com/tnb1021/tweetimgs)

参考文献

こちらのプログラムを拡張し、複数枚投稿できるようにしました。

qiita.com

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

最近月曜日と金曜日の雨多くない??

はじめに

 僕は今、月曜日と金曜日に実験の講義があります。そしてその時、軒並み雨のような気がしています。果たしてそれは僕が他の曜日に外出しないが故の勘違いなのかあるいは正しいのか検証してみます。

 '最近'と曖昧にしましたが、実験が始まったのが10月からなので10月1日~昨日(11月21日)までの情報を気象庁さんが提供してくださっているものをcsv保存しました。

f:id:Parco1021:20191122170019p:plain

データは概ねこのような感じです(一応データは隠しました)。csv保存せず、スクレイピングしてもよかったのですが曜日計算がめんどくさかったのと必要な情報が少なかったのでやりませんでした。

※筆者は統計学の学がないです。また、決して曜日と天気に因果関係があることを示唆しているわけではありません。

プログラム

 「このぐらいなら手で数えろよ…」の声が聞こえてきますが嫌です。書きました。

import pandas as pd

f = pd.read_csv('data.csv',encoding='cp932')
f.columns = ['day','dow','precipitation']

count_rain = 0
count_rainexp = 0
count_exp = 0
count_day = 0

for row_index,row in f.iterrows():
    if row[2] != '--':
        if float(row[2]) > 1:
            count_rain += 1
            if row[1] == '月' or row[1] == '金':
                count_rainexp += 1
    if row[1] == '月' or row[1] == '金':
        count_exp += 1
    count_day += 1

'''
for row_index,row in f.iterrows():
    if row[2] != '--':
        if float(row[2]) > 1:
            count_rain += 1
            if row[1] == '金':
                count_rainexp += 1
    if row[1] == '金':
        count_exp += 1
    count_day += 1
'''    

print('雨日:',count_rain)
print('実験で雨日:',count_rainexp)
print('実験日:',count_exp)
print('総合日数:',count_day)

 おなじみのpandasライブラリでf.iterrows()で一行ずつ参照しています。降水量が無の時を表す"--"でないとき他は全て数値なのでfloat型で変換しています。あとはそれぞれ求めたい数値をインクリメントしています。一応月金verと金のみverを書きましたが結果はほぼ同じでした。

実行結果

 今回、総合降水量で判断しているので多少誤差がありますが1mmを超えた時に雨日としました。

雨日: 17
実験で雨日: 7
実験日: 14
総合日数: 52

 つまり実験がある日が14/52、雨の日が17/52、実験の日かつ雨の日が7/52日ということになります。実験がある日という条件の下で雨が降った条件付き確率は7/14=1/2ということになります。さらに、11/4(月)と11/8(金)は変則日課で実験がありませんし雨も降っていません。これを加味すると条件付き確率は7/12≒0.58となります。さらにさらに今日11/22は実験でありさらに雨が降っています。よって8/13≒0.62となります。

さいごに

 補足すると雨かつ火or水は5日、雨かつ土or日は2日でした(ってことは木は3日)。つまり偏りがありますが今回そんなことはどうでもいいんです。重要なのは

ただでさえ憂鬱な実験の日に雨が6割も降って空気ジメジメするしより憂鬱になるんだよ!!!!

ってことです。

 後期も折り返しです。頑張りましょう。

 

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

Windowsで毎日定時にプログラムを実行する方法

はじめに

 Twitterbotを作るために毎日定時にプログラムを実行したいのでタスクスケジューラを使います。

parco1021.hatenablog.com

手順

  1. プログラム実行用のバッチファイルを用意する
  2. 1のバッチファイルをタスクスケジューラで実行する

まず、バッチファイルを用意します。これについては下の記事を参照してください。

parco1021.hatenablog.com

要するに実行したいコマンドが打ち込まれているファイルが拡張子.batで作られていればいいです。

 次にタスクスケジューラの設定をします。窓からタスクスケジューラを開きます。適当なライブラリで右クリック→タスクの作成を選択してください。名前を設定してから「ユーザがログオンしているかに関わらず実行する」にチェックします。これをしないと貴方がPCを開いていないとプログラムが実行されません。そして「最上位の特権で実行する」にもチェックをします。そしてトリガーを実行したいように設定します。

f:id:Parco1021:20191120152028p:plain

僕は9時ちょい過ぎに毎日実行したいのでこのように設定します。

操作はまず「プログラムの開始」を選択します。そしてプログラム/スクリプトは参照から作成したバッチファイルを選択し、開始(オプション)にはバッチファイルのディレクトリを設定します。これをしないと実行されないので注意してください。僕はこれをしていなくて躓きました。

f:id:Parco1021:20191120153041p:plain

そして次に条件において「タスクを実行するためにスリープを解除する」のチェックをします。

f:id:Parco1021:20191120153345p:plain

しかし、ここで設定しただけではスリープを解除することがPC本体において有効ではないのでそこの設定もいじらなければなりません。そこは以下を参照してください。

qiita.com

あとはデフォルトで大丈夫っぽいです。

さいごに

 Windows内のプログラムを定期実行したい場合はまず一回だけタスクスケジューラから実行できているか確認することをお勧めします。ローカルのプログラムではなく、Herokuにデプロイした場合はHeroku側で定期的に実行してくれるものがあるようなのでそちらもご検討してみてはいかがでしょうか。何かあればコメントでお願いします。

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Python】Fortniteのショップ情報を呟くTwitterのbotを作った

はじめに

 今回の記事は技術的なことになります。どのようなbotかなどは別途以下の記事をみてください。

parco1021.hatenablog.com

 また、今回は全体的なことのみ書いて具体的なことを書いたものは別途書いてこのブログへリンクを追加していこうと思っています。

使用環境

conda 4.7.10

Python 3.7.3

Twitter api

Fortnite Tracker api

処理の流れ

今回作成したbotの処理のフローが以下です。

 

f:id:Parco1021:20191119125250p:plain


この図の①~⑧までの処理を後で別々に書いていこうと思います。

プログラム

import requests
import twitter
import urllib.request
import requests
from requests_oauthlib import OAuth1Session
import json
import time
from datetime import date

key=''
URL='https://api.fortnitetracker.com/v1/store'
CK=''
CS=''
AT=''
AS=''
twitter = OAuth1Session(CK,CS,AT,AS)

url_media = "https://upload.twitter.com/1.1/media/upload.json"
url_text = "https://api.twitter.com/1.1/statuses/update.json"
   


def tweet(media_id,j,result): #⑦、⑧
    now_date = date.today()
    y = now_date.year
    m = now_date.month
    d = now_date.day
    len_pic = len(media_id)
    if len_pic == 4:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n{} {}vBucks\n{} {}vBucks\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'],result[j*4+1]['name'],result[j*4+1]['vBucks'],
        result[j*4+2]['name'],result[j*4+2]['vBucks'],result[j*4+3]['name'],result[j*4+3]['vBucks'])
    elif len_pic == 3:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n{} {}vBucks\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'],result[j*4+1]['name'],result[j*4+1]['vBucks'],
        result[j*4+2]['name'],result[j*4+2]['vBucks'])
    elif len_pic == 2:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'],result[j*4+1]['name'],result[j*4+1]['vBucks'])
    else:
        tweet="{}年{}月{}日のショップその{}\n{} {}vBucks\n#Fortnite #フォートナイトショップ"
        status = tweet.format(y,m,d,j+1,result[j*4]['name'],result[j*4]['vBucks'])
    media_id= ','.join(media_id)
    params = {"status": status, "media_ids": media_id}
    print(params)
    twitter.post(url_text,params=params)
    time.sleep(5)

def pic(media_id,i,j,result): #⑤、⑥
    img_url = result[i+4*j]['imageUrl']
    print(img_url)
    headers = {"User-Agent": "Mozilla/5.0"}
    request = urllib.request.Request(url=img_url,headers=headers)
    response = urllib.request.urlopen(request)
    print(response)
    data = response.read()
    files = {"media" : data}
    req_media = twitter.post(url_media,files = files)
    media_id.append(json.loads(req_media.text)['media_id_string'])
    print(media_id)
    return media_id

def call():
    #②、③、④ここから
    headers = {'TRN-Api-Key' : key}
    r = requests.get(URL, headers = headers)
    result = eval(r.text)
    print(len(result))
    print(result)
    num = len(result) // 4
    mod = len(result) % 4
#ここまで for j in range(0,num): media_id = [] name = [] vbucks = [] for i in range(4): pic(media_id,i,j,result) #⑤、⑥ tweet(media_id,j,result) #⑦、⑧ media_id = [] name = [] vbucks = [] for k in range(0,mod): pic(media_id,k,j+1,result) #⑤、⑥ tweet(media_id,j+1,result) #⑦、⑧ if __name__ =='__main__': call()

 データ数は毎日異なるのでそれに対応させるように書きます。4つずつデータを呟きたいのでまずは4枚ずつできるだけ呟きます。例えば17個のデータだったらnum=17//4=4となります。なのでまずはfor文のところのjを4回まわすことで16個呟きます。そして残りの1を呟く方法としてmod=17%4=1となるのでfor文のところのkをmodの数だけまわします。

 それぞれ値を関数に渡して処理をします。本当は呟く文章の箇所でif-elifを多用したくなかったのですがよくわからなかったのでゴリ押しました。

 

各処理の説明

①毎日定時に実行

parco1021.hatenablog.com

 

②、③呟くデータをAPIを叩いて取得する

parco1021.hatenablog.com

 

④~⑧データを呟く

parco1021.hatenablog.com

 

全体のコードはgithub見てください。コードが汚いのは許してね。

https://github.com/tnb1021/fortnitebot

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

Fortniteショップbotのトリセツ

 今回、Fortniteのショップ情報を呟くbotを作成しました。その説明を書きます。あくまでトリセツなので技術的なことについて深く書きません。技術的な話は別で書きます。情報は元はFortnite Trackerさんです。

  • 呟く内容は「商品名 値段vBucks」となっています。詳細は書きませんが、海外から情報を受け取っているので英語表記となっています。手作業で翻訳することも可能ですが、現在実施する方針はありません。
  • 商品の画像を4枚(Twitterで投稿できる最大枚数)区切りで呟いているので一日の投稿数が(商品数)÷4+1となります。画像付きなので多少ライムラインを圧迫します。
  • 情報の特性上、ある商品の別バージョンがショップに並んでいる場合、値段が0表記になる可能性があります。0vBuckとなっていた場合はそのような解釈をしていただけると幸いです。
  • Fortniteのショップは日本時間の午前9時に更新されますが、本botは9時5分の更新となります。
  • ご意見・ご要望ありましたら本記事へのコメントまたはbotへリプライしてください。しかし全て対応できるわけではないことをご容赦ください。
  • botは予告なく終了する可能性があります。

↓↓もしよろしければフォロー・いいね・RTお願いします!!

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

(個人的)ワンピースEDランキング

はじめに

 あまり目立っていない(と思う)のですがワンピースのEDもOPに引けを取らないぐらいいい歌が多くあります。今回もワンピースEDランキング(TOP5)を作ってみました。例のごとく個人的ランキングです。

OPランキング↓↓

parco1021.hatenablog.com

 

歌リスト

今回もanimateさんからの引用です。また、使用期間はWikiを参照しています。

大槻真希「memories」
大槻真希「RUN! RUN! RUN!
トマトキューブ「私がいるよ」
推定少女「しょうちのすけ」
AI-SACHI「BEFORE DAWN」
The Kaleidoscope「fish」
上原多香子「GLORY-君がいるから-」
Janne Da Arc「Shining ray」
Ruppina「Free Will」
Ruppina「FAITH」
ZZ「A to Z~ONE PIECE Edition~」
shela月と太陽
イクタ☆アイコ「DREAMSHIP」
タッキー&翼未来航海
エイジアエンジニア「エターナルポーズ」
TRIPLANE「Dear friends」
東方神起「明日は来るから」
デリカテッセン「ADVENTURE WORLD」 

第5位

 AI-SACHI「BEFORE DAWN」

BEFORE DAWN

BEFORE DAWN

  • provided courtesy of iTunes

 使用期間は第82話から第94話までです。ドラム王国の最後の方からボンちゃん初登場あたりまでですね。思い出はないです!

第4位

デリカテッセン「ADVENTURE WORLD」 

ADVENTURE WORLD

ADVENTURE WORLD

  • provided courtesy of iTunes

 使用期間は第264話から第278話までです。俗にいうエニエスロビー編の始めから生ぎたいっ!!までですね。ワンピースは途中でEDがなくなるのですが、この歌が最後のEDとなります。視聴者が描いた絵が流れてた記憶があります。

第3位

Janne Da Arc「Shining ray」

Shining ray

Shining ray

  • provided courtesy of iTunes

 使用期間は第119話から第132話までです。アラバスタ編の終盤なので聞いたことがある人も多いのではないでしょうか。普通に好きです。

第2位

大槻真希「memories」

memories

memories

  • 大槻 真希
  • J-Pop
  • ¥255
  • provided courtesy of iTunes

  使用期間は第1話から第30話までです。サンジが仲間になるところまでですね。ワンピースのEDで最も有名で人気な歌だと思います。

第1位

大槻真希「RUN! RUN! RUN!

RUN! RUN! RUN!

RUN! RUN! RUN!

  • 大槻 真希
  • J-Pop
  • ¥255
  • provided courtesy of iTunes

  使用期間は第31話から第63話までです。アーロン編からレッドライン超えるまでです。何も言いません。神歌です。以上!

さいごに

 いかがでしたでしょうか。OPの陰に隠れてはいますがとてもいい歌が多いので他の歌も是非聴いてみてください。OPランキングもよろしければ観てみてください。

parco1021.hatenablog.com

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Python】batファイルにおいてAnaconda環境を呼び出す方法

はじめに

 ファイルを開くだけでコマンドを実行してくれるbatファイルですが、Windowsコマンドプロンプトで行うためライブラリなどの環境が揃っていません。僕のようにPythonは元からライブラリが揃っているAnaconda環境で実行している人は多いのではないでしょうか。逐一必要なライブラリやPython環境を別途用意しても良いのですがせっかくなのでbatファイルでAnacondaの環境を呼び出す方法を調べたので紹介します。

呼び出す方法

 では早速方法です。例えば同一ディレクトリ内のtest.pyを実行したい時、

call C:\Users\{ユーザ名}\Anaconda3\Scripts\activate.bat
python test.py

 call (activate.batまでの絶対パス)とします。つまりAnacondaのactivate.batというバッチファイルを呼び出してます。callってなんやって思って調べてみたところバッチファイル内でバッチファイルを呼び出す時のコマンドです。

 そしてAnacondaの環境が整ったのでそのまま実行します。同一ディレクトリ内なのでpython test.pyを実行してもらうだけです。

参考文献

stackoverflow.com

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

【Django】Djangoでbootstrapのテンプレートを使う方法

はじめに

 好きなテンプレートをダウンロードしてコピペはいおっけー!とはいかないのです。

今回使ったテンプレートはhttps://templatemag.com/minimal-bootstrap-template/です。

やり方

 まず、お好きなテンプレートをダウンロードして解凍します。静的ファイルなのでまずプロジェクト内にstaticというフォルダを作り、そこに中身のフォルダ(css,js,lib)などをコピペしてください。

 また、この時点でsetting.pyに

STATIC_URL = '/static/'

とない場合は足してください。

templateフォルダにテンプレートをダウンロードした時のindex.htmlなどを入れ、URLおよびビューを設定してからアクセスしてもまだcssが反映されておらず、以下のようになると思います。

f:id:Parco1021:20191111171207p:plain

 はじめに1行目に

{% load static %}

を記述し、staticフォルダを読み込むように宣言?します。そして

<link href="css/style.css" rel="stylesheet">

<link href="{% static 'css/style.css' %}" rel="stylesheet">

とすることでstaticフォルダからの相対パスを指定し、cssなどを読み込みます。すると

f:id:Parco1021:20191111171036p:plain

さいごに

 今までbootstrapのテンプレートを使ったことがなく、使い方もlaravelやrailsでの使い方ばかり見受けられたので(使い方はほぼ一緒)、メモで残します。テンプレート初めて使ったんですけどいいですね、バエます。

 

おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

自動運転に潜む怖さ(論文紹介①Adversarial examples in the physical world)

はじめに

 先日、UberのAI車が死亡事故を起こすという痛ましいニュースが流れました。

news.yahoo.co.jp

 この事故は「歩行者は歩道にいる」というシステム設計から起こった事故ですが、例えばAI車が読み込む標識などに誰かが細工をして「とまれ」を別の標識に認識させるようにしてしまったらどうなるでしょうか?結果は目に見えていると思います。今回はそこに関連する論文を紹介します。 

今回読んだ論文について簡単に

  • タイトル:Adversarial examples in the physical world
  • 発行年:2017(ICLR)
  • 著者:Alexey Kurakin,Ian Goodfellow,Samy Bengio
  • URL:https://arxiv.org/abs/1607.02533

Adversarial Examplesについての先行研究

 まず、Adversarial Examplesについて一言で説明すると、「画像にノイズを加えてモデルに誤った出力をさせてしまう」ことです。

f:id:Parco1021:20191109212451p:plain引用元:Goodfellow et al. (2014)

  元々のモデルの出力は57.7%でパンダとなっています。そこに真ん中の図のようなノイズを加えることでモデルの出力が99.3%でgibbon(テナガザル)となります。このように人間にとって見た目に差がなくても機械学習システムの出力を誤らせてしまうようなモデルに対する脆弱性攻撃のことをAdversarial Examplesといいます。

 機械学習、特にニューラルネットワークにおけるモデルは、モデルへの入力時の微弱な変化に対してとても弱いことがわかっています。また、モデルを複数用意しAdversarial Examplesの実験を行った場合、あるモデルが誤った出力をする時はそのほかのモデルも誤った出力をする可能性が高いことが示されています。

新規性

 上で挙げた先行研究は攻撃が全てコンピュータ内で為されていることを前提にしています。しかし実際に私達が機械学習システムを用いる時は声をSiriなどに入力したり、顔認証でスマートフォンをアンロックしたりなど実世界であることが多いです。今回の論文は特にカメラを通じた画像の認証におけるAdversarial Examplesの生成および実験を行っています。

実験で用いられたAdversarial Examplesの生成方法

 まずは変数の定義を説明します。

  • {\displaystyle X }…入力画像。3次元ベクトルであり、ピクセルの値は[0,255]の整数値
  • {\displaystyle y_{true} }…入力{\displaystyle X }の正しいクラス
  • {\displaystyle J(X,y) }…損失関数
  • {\displaystyle Clip_{\{X,ε\}}X'(x,y,z)=min⁡\{255,X(x,y,z)+ε,max⁡\{0,X(x,y,z)-ε,X'(x,y,z)\}\}} ピクセルが[0,255]の範囲外にならないようにクリッピングする処理

変数の定義がされたので今回の論文で用いられた手法を3つ説明します。

Fast Method

 上でも示したGoodfellow et al. (2014)による手法です。

{\displaystyle X^{adv}=X+εsign(∇_X J(X,y_{true} )) }

ざっくり式の説明をすると{\displaystyle ∇_X J(X,y_{true} ) }によって勾配ベクトルを求め、符号を求めるsign関数に引数として渡します。それが正ならば正の方向、負ならば負の方向(=正解クラスの遠ざける方向)へノイズを加え、より正解から遠ざける方法です。εは変数です。

Basic Iterative Method

 Fast Method を繰り返し行う方法です。

{\displaystyle X^{adv}_{N+1}=Clip_{X,ε}\{X^{adv}_N+αsign(∇_X J(X^{adv}_N,y_{true} ))\}}

 繰り返し行うのでピクセルの値が範囲外とならないようにクリッピングを行っています。

Iterative Least-Likely Class Method

{\displaystyle y_{LL}=argmin\{p(y|X)\} }

{\displaystyle X^{adv}_{N+1}=Clip_{X,ε}\{X^{adv}_N-αsign(∇_X J(X^{adv}_N,y_{LL} ))\}}

 Basic Iterative Methodと符号と損失関数の引数が違いますね。yLLはモデルが出力するクラスのうち、最も確率の低いものを示します。なのでこの方法は最も"あり得ない"クラスに寄せています。

εの決定

 先ほどの数式におけるεを決定するための実験です。

f:id:Parco1021:20191109235316p:plain引用元:Alexey Kurakin et al.

εが8を超えたあたりから滑らかになりますね。また、誤認率はl.l方法が最も高いです。

f:id:Parco1021:20191110000319p:plain引用元:Alexey Kurakin et al.

 上の画像を観てもわかる通り、εが8でも人間の目からはノイズが加わっていることはわからないと思います。 

実験の方法

 実験の方法はまず、画像を印刷します(a)。そして印刷した画像を携帯電話のカメラで写真を撮り(b)、自動でトリミングしたもの(c)をモデルへ入力します。

f:id:Parco1021:20191110001702p:plain引用元:Alexey Kurakin et al.

 以上のように入力は完了しました。また、本実験では

①Average case

②Prefiltered case…あらかじめ画像をフィルタリングし、元のモデルの出力を0か1かになるようにする

の2ケースが用意されていますが、②は考えずに①のみ結果を示します。

f:id:Parco1021:20191110003217p:plain引用元:Alexey Kurakin et al.

 Photosがカメラで撮った画像であり、Source imagesが元の画像です。Adv. imagesがノイズ込みの画像。

 表を見ると、例えばfast method のε=16の時、カメラを介すると誤認率がtop-1だとおよそ2/3、top-5だと1/3となっておりかなり低くなっています。元の画像においてはl.l.方法がAdversarial Examplesの誤認率が高く、fast methodが最も低いです。しかし、カメラを通じると、fast methodが最も誤認率が高くなっています。つまりカメラを介する場合とそうでない場合とでAdversarial Examplesの作成方法の優劣が変わっています。

さいごに

 今回は、僕達の身近なケースであるカメラを通じたAdversarial Examplesの論文を読みました。機械学習もセキュリティも初心者なのですが先輩や先生に教えていただきながらなんとか読み切ることができました。内容としてはとても興味深いものであり読んでいて楽しかったです。

 カメラを介するケースとそうでないケースで攻撃側の優劣が異なるということは防御側もテストをコンピュータ上で行うのではなく、カメラを介さなければいけないということであり、これもいたちごっこになっているそうです。

参考文献

 

 おわり。

もしよければ↓ぽちっと↓お願いします。

ブログランキング・にほんブログ村へにほんブログ村

 

PVアクセスランキング にほんブログ村

スポンサーリンク