Pythonコードの"if __name__=='__main__':"の意味に関する個人メモ

備忘録です。

nameの条件分岐の意味をちゃんと理解していなかったので。他人に何かを教えるときにはちゃんと理解した上で説明すべきだし、公開しとくと尚良いです。

Pythonのコードを読んでいると、以下の条件分岐がコードの最終行近くに書いてあるのを見かけるかと思います。

def ConfNameSample():
    print('これは__name__確認用のサンプルコードです')
if __name__ == '__main__':
    ConfNameSample()

↑のif以降の部分

これはスクリプトとして実行された場合のみ、関数の中身を実行するという条件を表しています。言い換えると、トップレベルファイルとして実行した場合のみConfNameSampleが実行されます。

トップレベルファイルとして実行された場合、nameにはmainが代入されます。一方で、モジュールとしてインポートされた場合には、nameにはファイル名が代入されます。

分かりにくいので補足

例えば、以下の様なPythonスクリプトを作成します。名前は適当で良いですが、今回はsample.pyとしました。defで定義した関数の二行目でnameに何が入っているか確認できるようになっています。

def WhatIsName():
    print('__name__の中身を確認するよ!')
    print(__name__)
if __name__ =='__main__':
    WhatIsName()

これをどっかのフォルダに入れておいて、コマンドプロンプトやコンソールから実行してみます。すると以下の様な出力が得られるはずです。

f:id:kazutaka83:20160828124747p:plain

スクリプト(トップレベルファイル)として実行するとnameの中身はmainになっています。じゃあモジュールとして読み込んだらどうなってるのかも確認してみましょう。

さっきのやつをちょっと修正して

def WhatIsName():
    print('モジュールとしてインポートしたときの__name__の中身は')
    print(__name__)

コマンドプロンプトからPythonの対話シェルに入ってインポートします。モジュールと関数を呼び出すとこんな感じ。

f:id:kazutaka83:20160828130240p:plain

実行スクリプトが事故を起こさないようにするために、ちゃんと記しておいたほうがいいですね。

シン・ゴジラを楽しむための地図を作りました

シン・ゴジラを見ていても、土地勘のない人はなかなか場所のイメージが付きにくいです。というわけでゴジラを楽しむための地図を作りました(主に自分がロケ地巡りするときのため)

第一次上陸ルートを作成する際にはからぱたさんのサイトを参考にさせていただいています。

wivern.exblog.jp

第二次上陸ルートは土地勘が無さすぎるため、あいまいな部分が多々あります。ゴジラがそばを通り過ぎた煙突とかどこにあるのだろう。 あとは

  • ゴジラが倒した居住用ビル
  • ゴジラが第二形態→第三形態に変態する場所
  • 放射火炎の被害地区

なんかを地図上に落としたいところです。詳しい方情報をお待ちしております。

Pythonで学ぶ初歩からの統計学(ヒストグラムを作るまで)

Pythonを使って統計学のおさらいをします。手始めに度数分布表とヒストグラムを作ります。 度数分布表の作り方は以下の通り。

  1. データの範囲(最大値と最小値の差)を求める
  2. 階級(Class)の数を定める
  3. 階級の幅(Class Interval)を決める
  4. 度数(Frequency)を集計する
続きを読む

『実践 機械学習システム』の第6章をやってみる

この記事は5月30日のAITCオープンラボにてお話しした感情分類器の作り方の補足記事を兼ねています。積み残しがあるのでまだ未完です。

最近オライリーから発売された『実践機械学習システム』はとても良い本で、機械学習の概要と何をしてどのような結果が得られるのかを一通り学ぶことができます。数学的な補足説明もあり良書の類である一方、教師データが手に入らない、ソースコードが間違っている等初心者を殺す罠が満載です。このエントリは罠を回避しつつ、第6章の感情分析を一通りやってみます。

続きを読む

Pythonを使ってTwitterのタイムラインを収集する

「実践 機械学習システム」の第六章ではTwitterのタイムラインを使った感情分析を行っています。ただし英語のTweetを対象としているので、(たぶん)*1サンプルコードを実行してもあまり面白くはないのです。できることなら日本語でやりたい、というわけで自分のタイムラインからTweetを収集してみましょう。実行環境はPython3系を想定してますが、2系でも動くはずです。

基本的には↓のやり方を踏襲します。

qiita.com

必要なものは以下

  • Twitter APIの認証キー
  • PythonのOauthライブラリ(requests_oauthlib)
  • Pythonのデータ解析ライブラリ(Pandas)

Twitter APIの認証キーを取得する

Twitterのアプリケーションマネジメントサイトに行ってアプリケーションの登録を行います。

apps.twitter.com

"Create New App"から必要事項を入力していくと特に問題なく登録できるはず。最近は電話番号の登録を迫られるみたいです。営業電話でもかかってくるんだろうか。。

登録が完了したら"Consumer Key (API Key)"の欄にある"manage keys and access tokens"のリンクから先に進み、以下の4種類のキーを取得します。

これはコピペでどっかわかるところに保管しておきます。

Pythonライブラリの取得

pip使って導入。

pip3 install requests_oauthlib
pip3 install pandas

タイムラインの収集

Twitter APIでタイムラインを取得しますが、一度に取得できるTweet数の上限とAPI制限があるのでその辺と上手く付き合います。取得Tweetの上限が100件、API制限が15分に15回までとのこと。

分類器作る場合には10,000件ほどのTweetが欲しいので、パラメータで100件とってくるよう指定して、数分ごとに再取得を繰り返すようにしておきます。

CK、CS、AT、ASには先ほどコピペしたConsumer Key (API Key)、Consumer Secret (API Secret)、Access Token、Access Token Secretをそれぞれ入れておきます。

from requests_oauthlib import  OAuth1Session
import json
import time

CK = 'XXXXXXXXXXXXXXXXXXXXXX'
CS = 'XXXXXXXXXXXXXXXXXXXXXX'
AT = 'XXXXXXXXXXXXXXXXXXXXXX'
AS = 'XXXXXXXXXXXXXXXXXXXXXX'

url = "https://api.twitter.com/1.1/statuses/home_timeline.json"

params = {'count': 100}

TweetList = []

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

for i in range(100):
    req = twitter.get(url, params = params)
    if req.status_code == 200:
        timeline = json.loads(req.text)
        for tweet in timeline:
            TweetList.append(tweet["text"])
    else:
        print ("Error: %d" % req.status_code)
    time.sleep(240)

4分もあればタイムラインが一巡しそうだったので、timeモジュールを使って240秒ごとに回るように指定をかけています。これを7時間ほど置いとくとTweetListにタイムラインが格納されていきます。

CSVで吐き出す

とってきたタイムラインをテキストデータとして加工したいので、Pandasを使ってデータフレームに落とし込み、それをCSVとして吐き出します。他にもやり方はありますが、型やエンコードで嵌らないのでPandasがおすすめです。

import pandas as pd

df = pd.DataFrame(TweetList)
df.to_csv('hogehoge.csv')

これで教師用データの収集はできたはず。後は発言にネガティブ/ポジティブ/そのほかのラベル貼りをやらないと。その辺は別枠で。

追記

Tweetは200件まで取れました。教えていただいてありがとうございます!

*1:実際に動かしてないのでホントのところは不明

Python3でJSONデータを解析する

ググって出てくるJSON解析の方法はPython2系ばっかりなので、Python3系でのやり方をまとめます。 JSONデータは「 pythonのurllib2でjsonを取得して解析する - 文系プログラマによるTIPSブログ 」でも使われているお天気Webサービスを使います。

APIから読み込む

JSON形式のデータはWEBAPIから呼ぶことが多いかと思います。Pythonの標準ライブラリurllibとjsonを使ってAPI経由でデータを取りに行きます。

import urllib
import json

url = 'http://weather.livedoor.com/forecast/webservice/json/v1?city=400040'
html = urllib.request.urlopen(url)
jsonfile = json.loads(html.read().decode('utf-8'))

これで変数jsonfile内にデータが格納されました。jsonfileを呼び出してやるとそれっぽいデータが返ってきます。 以下はiPython環境での出力サンプルです。

In [1]jsonfile
Out[1]: 
{'copyright': {'image': {'height': 26,
   'link': 'http://weather.livedoor.com/',
   'title': 'livedoor 天気情報',
   'url': 'http://weather.livedoor.com/img/cmn/livedoor.gif',
   'width': 118},
  'link': 'http://weather.livedoor.com/',
  'provider': [{'link': 'http://tenki.jp/', 'name': '日本気象協会'}],
  'title': '(C) LINE Corporation'},
 'description': {'publicTime': '2016-04-30T16:32:00+0900',
  'text': ' 九州北部地方は、高気圧に覆われ、晴れています。\n\n 30日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 5月1日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 波の高さは、対馬海峡では30日と5月1日は2メートルでしょう。九州\n西海上では30日と5月1日は1.5メートルでしょう。豊後水道では30\n日と5月1日は1メートルでしょう。\n 福岡県の内海では、30日と5月1日は0.5メートルでしょう。\n\n<天気変化等の留意点>\n 特にありません。'},
 'forecasts': [{'date': '2016-04-30',
   'dateLabel': '今日',
   'image': {'height': 31,
    'title': '晴れ',
    'url': 'http://weather.livedoor.com/img/icon/1.gif',
    'width': 50},
   'telop': '晴れ',
   'temperature': {'max': None, 'min': None}},
  {'date': '2016-05-01',
   'dateLabel': '明日',
   'image': {'height': 31,
    'title': '晴れ',
    'url': 'http://weather.livedoor.com/img/icon/1.gif',
    'width': 50},
   'telop': '晴れ',
   'temperature': {'max': {'celsius': '26', 'fahrenheit': '78.8'},
    'min': {'celsius': '12', 'fahrenheit': '53.6'}}},
  {'date': '2016-05-02',
   'dateLabel': '明後日',
   'image': {'height': 31,
    'title': '晴のち曇',
    'url': 'http://weather.livedoor.com/img/icon/5.gif',
    'width': 50},
   'telop': '晴のち曇',
   'temperature': {'max': None, 'min': None}}],
 'link': 'http://weather.livedoor.com/area/forecast/400040',
 'location': {'area': '九州', 'city': '久留米', 'prefecture': '福岡県'},
 'pinpointLocations': [{'link': 'http://weather.livedoor.com/area/forecast/4020200',
   'name': '大牟田市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4020300',
   'name': '久留米市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4020700', 'name': '柳川市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4021000', 'name': '八女市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4021100', 'name': '筑後市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4021200', 'name': '大川市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4021600', 'name': '小郡市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4022500',
   'name': 'うきは市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4022800', 'name': '朝倉市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4022900',
   'name': 'みやま市'},
  {'link': 'http://weather.livedoor.com/area/forecast/4044700', 'name': '筑前町'},
  {'link': 'http://weather.livedoor.com/area/forecast/4044800', 'name': '東峰村'},
  {'link': 'http://weather.livedoor.com/area/forecast/4050300',
   'name': '大刀洗町'},
  {'link': 'http://weather.livedoor.com/area/forecast/4052200', 'name': '大木町'},
  {'link': 'http://weather.livedoor.com/area/forecast/4054400',
   'name': '広川町'}],
 'publicTime': '2016-04-30T17:00:00+0900',
 'title': '福岡県 久留米 の天気'}

要素ごとにアクセスしようとおもったら、パースした後の変数に引数を渡します。

In [1]:jsonfile['description']
Out[1]: 
{'publicTime': '2016-04-30T16:32:00+0900',
 'text': ' 九州北部地方は、高気圧に覆われ、晴れています。\n\n 30日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 5月1日の九州北部地方は、高気圧に覆われ、晴れでしょう。\n\n 波の高さは、対馬海峡では30日と5月1日は2メートルでしょう。九州\n西海上では30日と5月1日は1.5メートルでしょう。豊後水道では30\n日と5月1日は1メートルでしょう。\n 福岡県の内海では、30日と5月1日は0.5メートルでしょう。\n\n<天気変化等の留意点>\n 特にありません。'}

はまりどころ

Python2系のurllib2ではエンコーディング処理までやってくれていたような気がします。 Python3のurllibではデコードしないとエラーが出ます。JSONのパース時にdecode('utf-8')でデコードします。

やりたいこと

これ使って総務省API(Ver2)を上手くたたく方法模索中。

追記

Pythonの2系ではurllib2を使ってURLを読み込むのが通例でした。

import urllib
import urllib2

url = urllib2.urlopen('http://www.hogehoge.com')

python3系ではurllib2の持っていた機能がurllibに統合され、urllib.requestから呼び出せるようになっているようです。

最近読んだ本・読んでいる本

余裕がなくなってても定期的に本を読む習慣は続けたい今日この頃。最近読んだ本と読んでいる本の棚卸をしておきます。

アニメやドラマ、その他のコンテンツがなぜ人を惹きつけるのかということを探求した本。川上量生さんはぼんやりした概念をまとめることが素晴らしく上手いです。 天才クリエータとは、人を魅了するコンテンツとは何かということをまとめつつ、良質のコンテンツは普遍化し、良いクリエータは普遍化するコンテンツの中に引っかかりや別の軸を作っているという。この本はもう一回通読して自分の中で咀嚼しておきたい感じ。

コンサルタントの秘密―技術アドバイスの人間学

コンサルタントの秘密―技術アドバイスの人間学

秘密続き。この本がすこぶる読みにくくて読み進まない。書いてあること、伝えたいメッセージはわかるものの読むのがつらい。物理本(書籍)という制限もあって空き時間に読めないのもつらい。読書継続中。

コンサルタントの道具箱

コンサルタントの道具箱

とはいえ尊敬するベンチャー社長の人がお勧めしてて、ちょっと読んだだけでも知見を得られることはわかったので何とか慣れたい。こういう時には同じ著者の簡単な本から読むのが良いと思ってるので、ワインバーグ氏の電子書籍も並行して読んでおります。こっちは個人的に結構読みやすい。コンサルタントの道具箱はおそらく「コンサルタントの秘密」の要約版なので、こちらの本からぼちぼち攻めて行こうと思います。電子書籍なのでいつでも気軽に読めますし。

3月に入れば若干仕事の余裕・心の余裕が出てくるといいなあ。


スポンサード リンク