Search on the blog

2017年10月21日土曜日

Signal Handler in Python

PythonでSignal Handlerを書いて遊んでみた。

プログラム
Python 3で動作確認してます。
遊び方
まず上記のPythonプログラムを起動します。
$ python sample.py

プログラムを起動したら以下の表を参考にシグナルを送ってみてください。
シグナル キーボードから コマンドラインから
SIGINT ctrl + c kill -INT プロセス番号
SIGTSTP ctrl + z kill -TSTP プロセス番号
SIGTERM - kill プロセス番号
SIGKILL - kill -KILL プロセス番号

プログラムを停止したい場合は、SIGKILLを送ってください。
プログラムのプロセス番号は以下のコマンドで調べることができます。
$ pgrep -f "python sample.py"

単一障害点とは

まえがき
システム全体のアーキテクチャを考えるときに、「単一障害点」という概念が大事らしい。
意味は一目瞭然だけど、大切な概念っぽいので調べてみることにした。

語句の意味
その単一箇所が働かないと、システム全体が障害となるような箇所のこと。
ちなみに英語だとSingle Point of Failure(SPOF)というらしい。

単一障害点の例
コンポーネント 説明
アプリケーションサーバ アプリケーションサーバが一つしかないと、クリティカルなエラーが発生したときにユーザがシステムを利用できなくなってしまう。よってサーバをレプリケーションしておくことでSPOFにならないようにする必要がある。
ディスクストレージ ディスクストレージが故障するとデータの読み書きができなくなり、システム全体が利用不可になってしまう可能性がある。よってRAIDなどの冗長構成を取る必要がある。
ネットワークスイッチ ネットワークスイッチが故障と、ネットワーク内のサーバ間の疎通ができなくなってしまう。よって冗長なスイッチとネットワーク構成によって、SPOFを解決する必要がある。

トレードオフ
SPOFを解決するためには、レプリケーションや冗長構成などが必要となるので、コストがかかる。
どこまでSPOFの排除に取り組むかはコストとのトレードオフも考えて決定しなければならない。

2017年10月1日日曜日

Perplexityとは

 自然言語処理で良く使われるメトリクスのひとつであるperplexityについて説明します。

定義

分布pに従って生成されるデータxがある。xの分布をqでモデリングする。
このとき確率モデルqのperplexityは、

と表される。
ただし、xiはpから生成したデータで、Nはxiの個数である。

直感的な説明

  • 指数部はクロスエントロピーになっている
  • モデルにデータを見せたときに、どれくらい"驚く"かを表す
  • いいモデルほどperplexityは小さい

サンプル

サイコロの目の分布をモデリングしてみて、そのモデルのperplexityを計算してみます。
まずサイコロを用意します。サイコロは六面で各面が出る確率は一様とします。

真の分布はわからないので、30回サイコロを振ってみて観測化された結果から分布を推定してみます。このモデルのperplexityをテストデータ1,000個を使って計算してみると、6.358となります。


import numpy as np
from collections import Counter

np.random.seed(1234)


N = 1000     # test data size
M = 30       # train data size

test_data = np.random.randint(6, size=N)
train_data = np.random.randint(6, size=M)

p = Counter(test_data)    # test distribution
q = Counter(train_data)   # proposed distribution

exponent = 0
for i in range(6):
  exponent -= p[i] / N * np.log2(q[i] / M)

print (2 ** exponent)

次に訓練データを増やしてモデリングしてみます。サイコロを1,000回振ってみます(上記のコードのMを1000に変更してプログラムを実行)。
perplexityは5.998となり、モデルの良さが改善されたことがわかります。

2017年9月17日日曜日

ElastiCacheを使ってみた

 Redisのマネージドサービスを試しに使ってみた。AWSではElastiCacheというサービス名で提供されている(ElastiCacheでは、Redisの他にMemcachedも使うことができる)。

Redisクラスタの作成

  • AWSコンソール> ElastiCacheダッシュボード> サブネットグループからサブネットグループを作成
    • サブネットグループはRedisクラスタを作るときに指定しないといけないので、あらかじめ作っておく
  • AWSコンソール> ElastiCacheダッシュボード> RedisからRedisクラスタを作成
    • 練習用なのでレプリカは作らない
    • Redisと同じAZにEC2を立てたいので、優先AZを指定しておく
    • EC2からアクセスできるようにSGを設定しておく(今回のサンプルではdefault SGをつける)

EC2の作成

  • Redisクラスタと同じVPC、subnet内にEC2を立てる
  • AmazonElastiCacheFullAccessポリシーをアタッチしたロールを付与しておく
  • RedisクラスタにアクセスできるようにSGを設定しておく(今回のサンプルではdefault SGをつける)

クライアントアプリ

  • Pythonから使う
  • pipでredisライブラリを入れる
    • pip install redis
  • get, set, hset, hget, hmset, hmgetとかを試してみる
  • 速度がどれくらいでるか気になったので以下のプログラムで測定してみた

import time
import redis

host = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.amazonaws.com'
port = 6379
r = redis.StrictRedis(host=host, port=port)

T = 10000

set_elapsed_times = []
for i in range(T):
    key = 'k%d' % i
    val = 'v%d' % i
    start_time = time.time()
    r.set(key, val)
    t = time.time() - start_time
    set_elapsed_times.append(t * 1e6)  # micro sec
    
get_elapsed_times = []
for i in range(T):
    key = 'k%d' % i
    val = 'v%d' % i
    start_time = time.time()
    v = r.get(key)
    t = time.time() - start_time
    get_elapsed_times.append(t * 1e6)  # micro sec


測定結果

  • get/secともに、平均で250 micro secくらい
  • setのmaxが13milli secくらいかかってるのが気になる
処理 GET [microsec] SET [microsec]
mean 259.323335 241.534066
std 138.918826232.519214
min 212.669373 206.708908
25% 234.842300 224.113464
50% 246.286392 231.504440
75% 260.114670 241.279602
max 3891.468048 13475.656509

ついでにボックスプロット(1% - 99%範囲外のデータは例外とみなして除去)も書いてみた。

expressionとstatementの違い

まえがき

Scala Schoolを読んでいて、以下のような表現に遭遇した。

Scala is highly expression-oriented: most things are expressions rather than statements.

日本語ではexpressionは「式」、statementは「文」と訳される。

両者の違い

プログラムの例を見ると言わんとすることは分かるけど、両者の定義が明確に分からなかったので調べてみた。
  • 式は値を生み出す、文は何か処理をする
  • 式は文の部分集合
  • 式は”それは何か”を表しており、文は"何をするか"を表している
  • 関数型言語は式を、命令型言語は文を使うことが多い気がする

Pythonでの例

if/else
以下のようにif/elseはstatementっぽくも書けるし、expressionっぽくも書ける。

# statement
x = 1
if x % 2 == 0:
 y = "even"
else:
 y = "odd"

# expression
"even" if x % 2 == 0 else "odd"

print
printはPython 2までは文だったが、Python3から式になった。

Python 2では文なので値は返されない。

>>> type (print ("hello"))
  File "<stdin>", line 1
    type (print ("hello"))
              ^
SyntaxError: invalid syntax

Python 3では式なので値が返される。

>>> type (print ("hello"))
hello
<class 'NoneType'>

2017年9月16日土曜日

IAMユーザにIPアドレス制限をかける

AWSのIAMユーザにIPアドレスをかける手順&確認。

IAMユーザの作成

AWSコンソールからIAMユーザを作成する。
今回の例では、AmazonS3ReadOnlyAccessポリシーをアタッチしておく。

接続確認

コマンドラインからprofileを設定
$ aws configure --profile test-user

S3にアクセスしてみる。
$ aws --profile test-user s3 ls
2016-02-20 15:50:19 xxxxxxxxxxxxx
2016-02-20 16:10:29 yyyyyyyyyyyyy

IPアドレス制限をかける

AmazonS3ReadOnlyAccessをコピーして以下のようなポリシーを作る。(xx.xx.xx.xxのところは自分のIPアドレスを入れる)

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "s3:Get*",
                "s3:List*"
            ],
            "Resource": "*",
            "Condition": {
                "IpAddress": {
                    "aws:SourceIp": [
                        "xx.xx.xx.xx/32"
                    ]
                }
            }
        }
    ]
}

AmazonS3ReadOnlyAccessをデタッチして、上記で作成したポリシーを代わりにアタッチする。

指定したアドレスから接続確認

S3にアクセスできることを確認。
$ aws --profile test-user s3 ls
2016-02-20 15:50:19 xxxxxxxxxxxxx
2016-02-20 16:10:29 yyyyyyyyyyyyy

指定したアドレス以外から接続

S3にアクセスできないことを確認。
$ aws --profile test-user s3 ls
A client error (AccessDenied) occurred when calling the ListBuckets operation: Access Denied

2017年9月10日日曜日

オントロジーとタクソノミーの違い

オントロジー(Ontology)とは
  • type, properties, relationshipの集合から構成される世界を記述するモデルのこと。
  • Grakn Knowledge Modelというモデルではオントロジーを以下の4つのコンポーネントで記述する。
    • entity: もの。例: 人、男、女
    • relation: entity同士の関連。例: 親子関係
    • role: relationにおける役割。例: "結婚"というrelationには、"夫"、"妻"というroleがある
    • resource: entity/relationに紐づく属性。 例:名前、日付


タクソノミー(Taxonomy)とは
  • entityを親子関係を使って階層的に並べて表現するモデル。
  • 例: 植物 - 被子植物 - 単子葉類 - ユリ目 - ユリ科 - チューリップ属


両者の違い
  • Ontologyの方がTaxonomyより複雑な表現をすることができる。
  • Taxonomyは木構造、Ontologyはグラフ構造になっているとイメージしておくとよさそう。
  • Taxonomyはentityの分類や類似度を測るときに使われるのに対して、Ontologyは知識表現に使われる。Ontologyを使って知識を表現しておくと、マシンを使って新しい知識を推論することができる。

参考
https://www.quora.com/Whats-the-difference-between-an-ontology-and-a-taxonomy
https://blog.grakn.ai/what-is-an-ontology-c5baac4a2f6c