Stimulator

機械学習とか好きな技術話とかエンジニア的な話とかを書く

xonshrcを書く

- はじめに -

この記事は、Xonsh Advent Calendar 2017 - Qiitaの9日目の記事です。

1日目にXonshを勧める記事を書いて「アドベントカレンダーでxonshrcのオススメ設定が出揃う」と言ったものの、なかなかそれらしい記事が出てこないので書いておきます。


Python Prompt Toolkitが使えるなら、アドベントカレンダー内の以下の記事もオススメです。
qiita.com


追記2018/06/22:
さらにちゃんとまとめました
vaaaaaanquish.hatenablog.com
vaaaaaanquish.hatenablog.com


追記2019/08/28
さらに最新のxonsh 0.9.10のEnvを全て実装付きでまとめました
こちらのほうが参考になると思います。
vaaaaaanquish.hatenablog.com

 

- 私のxonshrc -

先に結論として設定している最もシンプルな部分のrcを出しておきます。
xonshrcを制御するxonsh/configファイルについては基本的にはdefaultのものを利用しています。

# vi風の操作
$VI_MODE = True
# Ctrl + D で終了しない
$IGNOREEOF = True
# tabではなく空白4つ
$INDENT = "    "
# 補完時に大小区別しない
$CASE_SENSITIVE_COMPLETIONS = False
# 補完選択Enterで即実行しない
$COMPLETIONS_CONFIRM = True
# 連続重複コマンドを保存しない
$HISTCONTROL = (ignoredups)
# 括弧を補完
$XONSH_AUTOPAIR = True
# ディレクトリ名を入力すればcdできる
$AUTO_CD = True
# エラー全て吐くように
$XONSH_SHOW_TRACEBACK = True
# プロンプトの設定タイムアウトのメッセージ抑制
$SUPPRESS_BRANCH_TIMEOUT_MESSAGE = True

# 見た目ウザかったら切か変更する
# 参考:http://xon.sh/tutorial.html#customizing-the-prompt
# プロンプト上には場所だけ出す
$PROMPT = "{INTENSE_YELLOW}[ {cwd} ] {GREEN}$ "
# 下部にuser, host情報を追加
$BOTTOM_TOOLBAR = "{BACKGROUND_WHITE}{BLACK}{user}@{hostname}"
# 右にbranch情報
$RIGHT_PROMPT = "{curr_branch}"
# lsコマンドの結果の見た目
$LS_COLORS="di=34:ln=35:so=32:pi=33:ex=31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30"

#えいりあす
aliases["lt"] = "ls -ltr"
aliases["l"] = "ls -ltr"
aliases["la"] = "ls -la"
aliases["ll"] = "ls -l"
aliases["so"] = "source"
aliases["v"] = "vim"
aliases["vi"] = "vim"
aliases["vx"] = "vim ~/.xonshrc"
aliases["vv"] = "vim ~/.vimrc"
aliases["vs"] = "vim /etx/ssh/ssh_config"
aliases["cp"] = "cp -i"
aliases["rm"] = "rm -i"
aliases["ju"] = "jupyter notebook"

見た目はこんな感じ

f:id:vaaaaaanquish:20171209154013p:plain

これだけで大体良い感じですが、Pythonで関数を作ってそこにaliasを貼ることももちろんできるので、加えて幾つか記述していますがそれらについてはまた別途。


 

- xonshrcで使える環境変数まとめ -

以下ではxonshrcで使える環境変数をまとめておきます。
基本的には、以下Referenceに書いてある内容です。
Environment Variables — xonsh 0.9.11 documentation

  

見た目、表示系

    # カラーテーマ
    # 自分はdefaultでiTerm2側の設定を利用
    # xonfig styles コマンドで全てのスタイル表示
    # 良さげなのだと'native'
    $XONSH_COLOR_STYLE = ‘default’

    # 下部に表示するツールバー
    # prompt-toolkitが導入されているShellのみ
    $BOTTOM_TOOLBAR

    # Shell上のシンタックスハイライト強調表示
    $COLOR_INPUT = True

    # コマンド実行の戻り値にもシンタックスハイライト
    $COLOR_RESULTS = True

    # インデント文字列
    # 空白4つとかTabとか任意に
    $INDENT = "    "

    # 改行した時にでてくる左端の文字
    # 指定された長さ以下だった場合は繰り返し表示される
    $MULTILINE_PROMPT = "."

    # 右揃えで表示する文字列
    $RIGHT_PROMPT = ""

    # プロンプトのサブプロセス、書式設定などのタイムアウト
    $VC_BRANCH_TIMEOUT = 0.1

    # プロンプトの設定タイムアウトのメッセージ抑制
    $SUPPRESS_BRANCH_TIMEOUT_MESSAGE = False

    # MercurialのbranchをTerminalに表示するか
    $VC_HG_SHOW_BRANCH = True

    # datetime.strptime()で出せる時間の表示の仕方
    $XONSH_DATETIME_FORMAT = ‘%Y-%m-%d %H:%M’

    # xonshの見た目の色々、文字のシンボル
    # http://xon.sh/envvars.html#xonsh-gitstatus
    $XONSH_GITSTATUS_*

    # エラーが出たときトレースバックを表示するかどうか
    $XONSH_SHOW_TRACEBACK = False

    # defaultプロンプトの見た目設定
    # http://xon.sh/tutorial.html#customizing-the-prompt
    $PROMPT = xonsh.environ.DEFAULT_PROMPT

    # titleとpromptのカスタマイズ
    # http://xon.sh/tutorial.html#customizing-the-prompt
    $PROMPT_FIELDS = xonsh.prompt.PROMPT_FIELDS

    # PROMPTのエラー表示版
    $XONSH_STDERR_POSTFIX
    $XONSH_STDERR_PREFIX

 

操作

    # マウス操作で履歴戻ったりするかどうか
    # prompt_toolkitが導入されているShellのみ
    $MOUSE_SUPPORT = False

    # Ctrl + D で終了しない
    $IGNOREEOF = False

    # vi風の操作
    $VI_MODE

 

補完

    # キー入力ごとに評価する
    $UPDATE_COMPLETIONS_ON_KEYPRESS = False

    # プロンプト間でコマンドをcacheしない設定にするか
    # Trueにすると毎回キー入力待ち再評価が発生する
    $UPDATE_PROMPT_ON_KEYPRESS = False
    
    # 補完時に大文字小文字区別するか
    # LinuxだとdefaultでTrue
    # 個人的にはFalse派
    $CASE_SENSITIVE_COMPLETIONS

    # コマンド履歴の保存の仕方
    # ignoredupsは重複コマンドを保存しない
    # ignoreerrは失敗したコマンドを保存しない
    $HISTCONTROL = (ignoredups, ignoreerr)

    # 補完時に[]と()を考慮する
    $COMPLETIONS_BRACKETS = True

    # ユーザ確認する前に補完を表示する上限数
    $COMPLETION_QUERY_LIMIT = 100

    # Tab補完メニューで表示する行数
    # prompt-toolkitが導入されているShellのみ
    $COMPLETIONS_MENU_ROWS = 5

    # Tab補完メニューが表示されている時にEnterで即実行するか
    # Trueなら実行しない
    # prompt-toolkitが導入されているShellのみ
    $COMPLETIONS_CONFIRM = False

    # Tab補完のPathのsubsequence matching
    # ~/u/ro で ~/lou/carcolh をよしなに補完してくれるみたいなやつ
    $SUBSEQUENCE_PATH_COMPLETION = True

    # Pythonスクリプトの補完
    # 基本的にdefaultがサイコー
    # prompt-toolkitが導入されているShellのみ
    $COMPLETIONS_DISPLAY = multi

    # あいまい補完をするか
    $FUZZY_PATH_COMPLETION = True

    # 補完サジェストを出す
    # defaultでTrue
    $AUTO_SUGGEST_IN_COMPLETIONS = True

    # 補完サジェストを 右矢印キーで入力
    # $SHELL_TYPE=prompt_toolkitが指定されている必要あり
    # defaultがTrueなのでptkが入っていればデフォで動いてるはず
    $AUTO_SUGGEST = True

    # BASHの補完機能をそのまま利用するための
    # defaultでは以下、tupleを指定する
    $BASH_COMPLETIONS = ('/usr/share/bash-completion/bash_completion', )

    # パターンマッチなどglobした時に結果をソートするか
    $GLOB_SORTED = True

    # 実行可能なファイルの拡張子
    # 大文字で書く必要がある
    $PATHEXT = [".EXE"]

    # 変なコマンドを入力したら もしかして を出す
    $SUGGEST_COMMANDS = True

    # もしかして最大数
    $SUGGEST_MAX_NUM = 5

    # もしかしてサジェストの誤字数
    $SUGGEST_THRESHOLD = 3

    # 出力後に新しい空行を追加するか
    $XONSH_APPEND_NEWLINE = False

    # [], ()などの括弧を補完するか
    $XONSH_AUTOPAIR = False

    # 全てのコマンド実行をcacheするか
    $XONSH_CACHE_EVERYTHING = False

    # コードをcacheしておくか(T)、毎回コンパイルして実行するか(F)
    $XONSH_CACHE_SCRIPTS = True

 

ディレクトリ移動

    # ディレクトリ名を入力すればcdできる
    $AUTO_CD = False

    # ディレクトリ移動したらスタックにpush
    # dirstack実装 : https://pypkg.com/pypi/xonsh/f/xonsh/dirstack.py
    $AUTO_PUSHD = False

    # pushdした時にdirで現在のスタック内容を表示しない
    $PUSHD_SILENT = False

    # dirstack最大数
    $DIRSTACK_SIZE = 20

    # CD時にshとのroot関係が壊れないようにPATH指定するやつ
    # zshでいうこれ : https://robots.thoughtbot.com/cding-to-frequently-used-directories-in-zsh
    $CDPATH = ("/", )

    # cwdコマンドで指定したディレクトリに向けたショートカット
    $DYNAMIC_CWD_ELISION_CHAR = "/"

    # cwdプロンプト変数の文字数の指定
    $DYNAMIC_CWD_WIDTH = (inf, ‘c’)

 

変数、設定

    # PYTHON_PATH
    $PATH = (...)

    # 前回の作業ディレクトリ
    $OLDPWD

    # サブプロセスモードで文字列内の環境変数を展開するか
    $EXPAND_ENV_VARS = True

    # xonshの場所
    $XONSH_CONFIG_DIR = $XDG_CONFIG_HOME/xonsh

    # 外部のaliasを優先するかどうか
    # $XONSH_CONFIG_DIR/config.jsonに書くのでxonshrcに書いても意味はない
    $FOREIGN_ALIASES_OVERRIDE = False

    # $XONSH_CONFIG_DIR/config.jsonが読まれたかどうかがboolで入ってるので判定用
    $LOADED_CONFIG

    # 読見込まれたRCが動いているかのbool値のlist
    $LOADED_RC_FILES = (~/.xonshrc)

    # 連続でコマンド実行した時にスリープする秒数
    $XONSH_PROC_FREQUENCY = 0.0001

    # pretty printingの戻り値があるかどうか
    # import pprintしたりするなら
    $PRETTY_PRINT_RESULTS

    # configファイルへのPATH
    $XONSHCONFIG = $XONSH_CONFIG_DIR/config.json

    # rcファイルへのPATH
    $XONSHRC = ['/etc/xonshrc', '~/.xonshrc']

    # デスクトップ標準のディレクトリ
    $XDG_CONFIG_HOME = ~/.config

    # デスクトップ標準のデータディレクトリ
    $XDG_DATA_HOME = ~/.local/share

    # 実際のxonshデータが入っている場所
    $XONSH_DATA_DIR = $XDG_DATA_HOME/xonsh

    # ディレクトリプッシュがされているかどうかのフラグ
    $PUSHD_MINUS

    # xonsh環境が変化したかのフラグ
    $UPDATE_OS_ENVIRON

    # python実行環境へのPATH
    $VIRTUAL_ENV

    # インタラクティブ実行で動いてるかどうかのフラグ
    $XONSH_INTERACTIVE

    # xonshがログインシェルになっているかどうかのフラグ
    $XONSH_LOGIN

    # xonshスクリプトを実行している場合、そのスクリプトへの絶対Path
    $XONSH_SOURCE

 

Windows向け

    # Windowsのanxicon用
    $ANSICON = False

    # 補完した時に"/"を強制的に使用
    $FORCE_POSIX_PATHS = False

    # cmd.exe上で色を変える
    $INTENSIFY_COLORS_ON_WIN = True

    # Winでユニコード使う
    $WIN_UNICODE_CONSOLE

 

その他

    # readline, prompt_toolkit, random, best
    # 基本的にはptlが使われてそれ以外の状況ではよしなに選択してくれるbestでOK
    $SHELL_TYPE = best

    # プロンプトのタイトル
    # http://xon.sh/tutorial.html#customizing-the-prompt
    $TITLE = xonsh.environ.DEFAULT_TITLE

    # 文字コード
    $LANG = ‘C.UTF-8# サブプロセスが利用するエンコーディング
    $XONSH_ENCODING

    # エンコーディングエラーを処理するフラグ
    # https://docs.python.org/3/library/codecs.html#error-handlers
    $XONSH_ENCODING_ERRORS = surrogateescape

    # サブプロセスでエラーが出た時終了させるかどうか
    # xonshプロンプト上ではあまり良くないが、 xonshスクリプトを実行する時効果あり
    # subprocess.CalledProcessErrorがraiseされる
    $RAISE_SUBPROC_ERROR

    # historyでjson以外にsqliteが選べる
    $XONSH_HISTORY_BACKEND = ‘json’

    # historyファイルの保存先
    $XONSH_HISTORY_FILE = ~/.xonsh_history

    # コマンドやファイルのhistory保存数
    # http://xon.sh/envvars.html#xonsh-history-size
    $XONSH_HISTORY_SIZE = (8128, 'commands')

    # Standard I/OをHistoryに保存するか
    $XONSH_STORE_STDIN
    $XONSH_STORE_STDOUT

    # 端末エミュレータによるTerminalの設定色々。基本触る機会はない
    $TERM

    # エラーのトレースバックログを保存するPathの指定
    $XONSH_TRACEBACK_LOGFILE = "/"

    # デバッグ機能、数値に応じて以下が出てくる
    # 1, 重複importの抑制情報
    # 2, 入力変換、コマンド置換の情報
    # 3, PLYデバッガによる解析結果
    $XONSH_DEBUG = 0


 

- おわりに -

ひとまずまとめて終わりです。

またアドベントカレンダー内に空きがあれば自作のrcに書いている関数群を出していこうと思います。

誰か今からpip installして埋めてくれてもいいのよ!

qiita.com


 

xonshの過去のコマンド履歴を可視化する

- はじめに -

この記事は、Xonsh Advent Calendar 2017 - Qiitaの6日目の記事です。

せっかくxonshではMatplotlibが使えたりするので、Command履歴の分析等の補助をする関数を書いてメモしておきたいと思います。


 

- xonshのhistory -

xonshの過去の入力履歴は以下で呼び出す事ができます。

__xonsh_history__

実際には、xonshのコマンド履歴は以下のようにSession毎にjsonファイルで管理されています。

history file
# ~/.local/share/xonsh/xonsh-7305fb13-34ea-44fd-9845-197fe015359d.json

さっそくの余談ですが、このバックエンドにsqliteを指定する事も可能です(Tutorial: History — xonsh 0.6.0.dev151 documentation)。


__xonsh_history__で得られるxonsh.history.json.JsonHistoryオブジェクトは、Commandの履歴を取得するためのメソッドを2種類持っています。

__xonsh_history__.items()    # 今のSessionでのHistory
__xonsh_history__.all_items()    # 過去全てのSessionでのHistory

どちらもIteratorが返ってくるので、例えば現在過去全てのコマンド履歴を取得するには以下のように

for x in __xonsh_history__.all_items():
    print(x["inp"])

Reference : History Backend JSON – xonsh.history.json — xonsh 0.6.0.dev151 documentation


また、jsonを直接読みにいく事ももちろんでき、xonshのhistory.jsonを直接読みに行くスクリプトは、アドベントカレンダー内の以下の記事でも既に書かれています。

qiita.com


 

- 過去のコマンドを可視化 -

以下の記事でも利用したitermplotパッケージを利用して、iTerm2上にインラインに表示してみます。
導入や綺麗な表示の仕方は以下記事で。
(以下記事内にiTerm2以外の方法も一応記述しています)
vaaaaaanquish.hatenablog.com


空白で区切られた最初のコマンド部分が10文字以下のものをCounterに投げてMatplotlibに可視化します。

import itermplot
import matplotlib.pyplot as plt
import numpy
from collections import Counter

data = Counter([x["inp"].split(" ")[0] for x in __xonsh_history__.all_items() if len(x["inp"].split(" ")[0])<10])
labels, values = zip(*data.items())
indexes = np.arange(len(labels))

plt.figure(figsize=(20,10))
plt.bar(indexes, values, width)
plt.xticks(indexes, labels, rotation='vertical')
plt.show()

結果がxonshコンソール上で見えます
f:id:vaaaaaanquish:20171206225049p:plain


ちょっと業務で使ったものを削った結果を出していますが、これは恥ずかしいですね。

xonshなのでimportやforが多いのは当たり前ですが、ls しすぎだし、X, Yといった変数を使っていたり、果にはexitもかなり使っています。xonshが嫌いなのでしょうか。
これがまだ手元のMacなので良いですが、普段はリモートサーバで作業しているので、そちらではより酷いものが見れると思います(公開はしないですが)。


しかし、これでlsというコマンドにめちゃくちゃ時間を取られている事が分かりました。lsは基本的には自動的に発動するようにしていくのが吉という事ですね。

 
 
ついでなので最も多いimportから、何を多く使っているか見てみます。

data取得箇所を変えてやれば実現できそうです。

data = Counter([x["inp"].split(" ")[1] for x in __xonsh_history__.all_items() if x["inp"].split(" ")[0]=="import"])

 
import time, plt, mathが多そう。xonshrcに書いておいて事前importするようにすれば私の仕事も減りそうです。
f:id:vaaaaaanquish:20171206230255p:plain


 

- おわりに -

ギリギリ滑り込みセーフで記事を書きましたが何とかなりました。

もうちょっと分析らしいところまで行きたかったのですが、(見せてもOKそうな)Historyが以外に少なく、時間も微妙だったので断念しました。
まあでもギリギリでも可視化まで出来たのは、Pythonという言語がシェルで扱える事の利点でもあるなと思いました。

今まで使っていたzshのログのconvertとか前後のコマンドを確認とかまでやれれば良かった…が、アドベントカレンダーに空きを見つけて書きたいと思います。


それでも全然空きがありそうなので、xonsh試したい方でも是非ご参加下さい!!

qiita.com


 

Xonshでmatplotlibグラフをコンソールにインライン描画してメモリ状況を観察する

- はじめに -

この記事はXonsh Advent Calendar 2017 4日目の記事です。

Xonshの中にはxontribというメソッド群が存在します。
その中のmplhooksは、画像の描画をサポートしてくれます。

本記事では以下について記述します

  • xontrib.mplhooksを利用したxonshコマンドプロンプト上へのMatplotlibグラフのインライン描画
  • vm_statコマンドを利用したMac OS Xのメモリ状況の取得とPythonによるparse
  • Xonshでメモリ状況のリアルタイム可視化

以下アジェンダです


 

- Xonshのグラフインライン描画 -

Xonshでグラフは端末状にインライン描画する方法は、以下の2種類が容易されています。

  • xontrib.mplhooks.display_figure_with_iterm2(fig)
  • xontrib.mplhooks.show()

以下がソースコードです。
xontrib.mplhooks — xonsh 0.5.12.dev97 documentation
xonsh/mplhooks.py at master · xonsh/xonsh · GitHub
Pythonなのですぐ読めます。

display_figure_with_iterm2は、 iterm2_toolsを使ってiTerm2上にグラフを描画するようになっています。
showは、iterm2_toolsがimportできればdisplay_figure_with_iterm2で描画、iterm2_toolsが存在しない場合はplt.gcf()で現状プロット図を取得してきてRGB値をcolor stringにして描画する形になっています。

iTerm2でインライン描画

私はiTerm2利用者ですので以下でiterm2_toolsを導入しています。

pip install iterm2_tools

GitHub - asmeurer/iterm2-tools: iTerm2 tools for Python

以下エラーが出るのでXonshコンソールを再起動しておきます。

NameError: name 'display_image_bytes' is not defined

再起動後、Xonshコンソール上で以下を淡々と入力していきます。
もしくは適当にxshスクリプトにしてもOKです。

import matplotlib.pyplot as plt
import xontrib.mplhooks
import numpy as np
x = np.linspace(-3, 3, 20)
y = x ** 2
fig = plt.figure(figsize=(6, 4))
ax1 = fig.add_subplot(1, 1, 1)
ax1.plot(x, y)
xontrib.mplhooks.display_figure_with_iterm2(fig)

f:id:vaaaaaanquish:20171121140615p:plain:w350
xonsh上でもインライン描画できました

 

Terminal.app上のxonshでインライン描画

試しにMacにデフォルトで付随するTerminal.appでもXonsh上でインライン描画をしてみます。

上記iTerm2の時と同じGraphを作って以下。

xontrib.mplhooks.show()

f:id:vaaaaaanquish:20171121141037p:plain:w350
ちょっとアレですがまあまあ…

iTerm2の描画は良いですね

 

itermplotでインライン描画

上記2つに加えてiTerm2にはインライン描画パッケージとして、itermplotというのがあります。
GitHub - daleroberts/itermplot: An awesome iTerm2 backend for Matplotlib, so you can plot directly in your terminal.

Animation supportもされており、インラインでリアルタイム表示ができそうです。
(といっても事前にGIF画像にしてiTermの表示機能に送る形ですが…)

導入はpipで、xonshを起動する前にMPLBACKENDにitermplotを指定しておくとplt.show()がインライン描画になります。

pip install itermplot
export MPLBACKEND="module://itermplot"

また、後述しますがリアルタイム表示するにはImageMagickが必要なのでインストールしておきます。

brew install imagemagick

sampleスクリプトを動かしてみます。

import matplotlib.pyplot as plt
plt.plot([1,2,3])
plt.show()

f:id:vaaaaaanquish:20171202214602p:plain:w350
いちばんつよそう

背景が黒い場合は以下で良さげな表示に

export ITERMPLOT=rv


  

- vm_statコマンドでメモリ可視化 -

Macでメモリ状況を出力するコマンドではfreeやtop、vm_statといった選択肢があります。

今回は適当にvm_statを選択します。
Xonshであれば以下コマンドどちらも結果を得ることができます

vm_stat
$(vm_stat)    # python string

vm_statコマンドの結果をparseしてdictにする関数を作って実行してみます。

def vms():
    vm_dic = {}
    for i,x in enumerate($(vm_stat).split("\n")):
        row = x.split(":")
        if i>1 and len(row)==2:
            vm_dic[row[0]] = int(row[1].strip().replace(".",""))*4096/(1024.0 ** 3)
    return vm_dic

以下のようにGB単位でメモリ状況が出力されます。

$ vms()
{'"Translation faults"': 2588.0195083618164,
 'Anonymous pages': 7.266414642333984,
 'Compressions': 54.13356018066406,
 'Decompressions': 33.81982421875,
 'File-backed pages': 2.6624984741210938,
 'Pageins': 32.48748779296875,
 'Pageouts': 0.26355743408203125,
 'Pages active': 4.984306335449219,
 'Pages copy-on-write': 82.98124694824219,
 'Pages inactive': 4.944099426269531,
 'Pages occupied by compressor': 3.5574417114257812,
 'Pages purgeable': 0.14667129516601562,
 'Pages purged': 1.3369598388671875,
 'Pages reactivated': 22.909423828125,
 'Pages speculative': 0.000507354736328125,
 'Pages stored in compressor': 8.809425354003906,
 'Pages throttled': 0.0,
 'Pages wired down': 2.446277618408203,
 'Pages zero filled': 1392.7644996643066,
 'Swapins': 16.50379180908203,
 'Swapouts': 17.286388397216797}

 
せっかくですのでwatchコマンドのように、メモリ状況をリアルタイムで表示し続けてみます。

import json
while True:
    vm_dic = vms()
    $[clear]
    print(json.dumps(vm_dic, indent=4))

f:id:vaaaaaanquish:20171121144149g:plain:w400

watch vm_statでよくない!?みたいな何かが出来上がりました。

vms functionをprintするスクリプトにして、watchもできます。
watchコマンドはデフォルトでsh -cにコマンドを飛ばすだけなので、--exec, -xで指定できるよう環境設定するか、以下のようにxonshを定期的に作るという酷いやつで対応できます。

# mac -> $ brew install watch
watch "xonsh sample.xsh"

watch vm_statでよくない!?みたいな何かです。

  

- vm_statをMatplotlibでリアルタイム描画 -

上記2項目で作った関数を利用して、Matplotlibでvm_statの結果をリアルタイム描画してみます。

wired, active, inactive, speculative辺りがusedメモリに関連する項目ですのでそちらを可視化してみます。
(occupied by compressorも必要かな?)

スクリプトが適当です。

import time
import xontrib.mplhooks
import numpy as np
import matplotlib.pyplot as plt
plt.style.use('ggplot') 

def init_data(fig, id, title):
    x = np.zeros(100)
    y = np.zeros(100)
    subplot = fig.add_subplot(2,2,id)
    subplot.set_title(title)
    subplot.set_ylabel('GB')
    subplot.set_xlabel('time')
    li, = subplot.plot(x, y)
    return x, y, subplot, li

def set_data(x,y,vm_dic,key):
    x = np.append(x, time.time())
    x = np.delete(x, 0)
    y = np.append(y, vm_dic[key])
    y = np.delete(y, 0)
    return x,y

def update_fig(x, y, subplot, li):
    li.set_xdata(x)
    li.set_ydata(y)
    subplot.set_ylim(min(y), max(y))
    subplot.set_xlim(min(x), max(x))

def watch_vms_windows():
    fig = plt.figure()
    x,y,subplot,li = init_data(fig, 1, "Pages active")
    x2,y2,subplot2,li2 = init_data(fig, 2, "Pages inactive")
    x3,y3,subplot3,li3 = init_data(fig, 3, "Pages speculative")
    x4,y4,subplot4,li4 = init_data(fig, 4, "Pages wired down")
    count = 0
    while True:
        vm_dic = vms()
        x,y = set_data(x, y, vm_dic, "Pages active")
        x2,y2 = set_data(x2, y2, vm_dic, "Pages inactive")
        x3,y3 = set_data(x3, y3, vm_dic, "Pages speculative")
        x4,y4 = set_data(x4, y4, vm_dic, "Pages wired down")
        if count > 100:
            update_fig(x, y, subplot, li)
            update_fig(x2, y2, subplot2, li2)
            update_fig(x3, y3, subplot3, li3)
            update_fig(x4, y4, subplot4, li4)
            plt.pause(.01)
        else:
            count += 1
            print(count, end="\r")

以下参考にしています。
Arduino で測定したデータを Matplotlib でリアルタイムプロット | org-技術

100ループ回してGraph描画に十分なデータを集めたらGraph描画を開始するスクリプトです。

f:id:vaaaaaanquish:20171121144909g:plain

QuickTime Playerを利用して画面の動画を撮っているのでactiveがガンガン上昇しinactiveが下降、メモリ利用と廃棄が頻繁に行われている事がわかります。


$[clear] して display_figure_with_iterm2(fig) でインライン描画するスクリプトにする事も可能で、試しましたがdisplay_figure_with_iterm2では実行時描画になるため、思ったより綺麗に表示されませんでした。


 

- MatplotlibのAnimationモジュールを使ってリアルタイム描画を実現する -

Matplotlibにはpltで作られた配列をアニメーションにして表示するモジュールが存在する。
全てのGraphを事前に配列に取っておいて描画するArtistAnimation、動的に生成していくFuncAnimationの2つである。
animation module — Matplotlib 2.1.0 documentation

Animationはgifやmp4を生成するだけなので、これらを前述したitermplotに流してiTerm2にインライン描画する。

itermplotのカッケー背景はAnimationには対応してないので以下だけ設定しておく。

export MPLBACKEND="module://itermplot"
export ITERMPLOT_FRAMES=100

適当に書いたコード

import time
import xontrib.mplhooks
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.animation as animation
plt.style.use('ggplot') 

class VMS:
    def __init__(self, fig):
        self.fig = fig
        self.x, self.y, self.subplot, self.li = self.init_data(1, "Pages active")
        self.x2, self.y2, self.subplot2, self.li2 = self.init_data(2, "Pages inactive")
        self.x3, self.y3, self.subplot3, self.li3 = self.init_data(3, "Pages speculative")
        self.x4, self.y4, self.subplot4, self.li4 = self.init_data(4, "Pages wired down")
        self.c = 0
        for i in range(100):
            self.plotsub(i)
        
    def init_data(self, id, title):
        x = np.zeros(100)
        y = np.zeros(100)
        subplot = self.fig.add_subplot(2,2,id)
        subplot.set_title(title)
        subplot.set_ylabel('GB')
        li, = subplot.plot(x, y)
        return x, y, subplot, li

    def vms(self):
        vm_dic = {}
        for i,x in enumerate($(vm_stat).split("\n")):
            row = x.split(":")
            if i>1 and len(row)==2:
                vm_dic[row[0]] = int(row[1].strip().replace(".",""))*4096/(1024.0 ** 3)
        return vm_dic

    def count(self):
        self.c += 1

    def plotsub(self, frame):
        vm_dic = self.vms()
        self.count()
        # subplot1
        self.x = np.append(self.x, self.c)
        self.x = np.delete(self.x, 0)
        self.y = np.append(self.y, vm_dic["Pages active"])
        self.y = np.delete(self.y, 0)
        self.li.set_xdata(self.x)
        self.li.set_ydata(self.y)
        self.subplot.set_ylim(min(self.y), max(self.y))
        self.subplot.set_xlim(min(self.x), max(self.x))
        self.subplot.set_xticks(np.arange(min(self.x), max(self.x), 20))
        # subplot2
        self.x2 = np.append(self.x2, self.c)
        self.x2 = np.delete(self.x2, 0)
        self.y2 = np.append(self.y2, vm_dic["Pages inactive"])
        self.y2 = np.delete(self.y2, 0)
        self.li2.set_xdata(self.x2)
        self.li2.set_ydata(self.y2)
        self.subplot2.set_ylim(min(self.y2), max(self.y2))
        self.subplot2.set_xlim(min(self.x2), max(self.x2))
        self.subplot2.set_xticks( np.arange(min(self.x2), max(self.x2), 20) )
        # subplot3
        self.x3 = np.append(self.x3, self.c)
        self.x3 = np.delete(self.x3, 0)
        self.y3 = np.append(self.y3, vm_dic["Pages speculative"])
        self.y3 = np.delete(self.y3, 0)
        self.li3.set_xdata(self.x3)
        self.li3.set_ydata(self.y3)
        self.subplot3.set_ylim(min(self.y3), max(self.y3))
        self.subplot3.set_xlim(min(self.x3), max(self.x3))
        self.subplot3.set_xticks( np.arange(min(self.x3), max(self.x3), 20) )
        # subplot4
        self.x4 = np.append(self.x4, self.c)
        self.x4 = np.delete(self.x4, 0)
        self.y4 = np.append(self.y4, vm_dic["Pages wired down"])
        self.y4 = np.delete(self.y4, 0)
        self.li4.set_xdata(self.x4)
        self.li4.set_ydata(self.y4)
        self.subplot4.set_ylim(min(self.y4), max(self.y4))
        self.subplot4.set_xlim(min(self.x4), max(self.x4))
        self.subplot4.set_xticks( np.arange(min(self.x4), max(self.x4), 20) )


fig = plt.figure(figsize=(8,8))
vms = VMS(fig)
animation.FuncAnimation(vms.fig, vms.plotsub, blit=True)
plt.show()

plt.show()がitermplotによって継承されてればインラインで見れる
f:id:vaaaaaanquish:20171203221702g:plain

これは動的に見れている訳ではなく、事前に100フレーム分をgif画像にしてbyteIOでiTerm2に送り込んでいるだけなのでリアルタイムの本質を見失っている状態である。

iTerm2に表示できるGIFのフレーム数を上手くコントロールできないとか課題は多いがまあできたという事で…

 

- おわりに -

「これ watch vm_stat で良くね!?」
「リアルタイムインライン描画とは」
Pythonスクリプトなら os.system や commands.getoutput でコマンド実行できるよね!?」
「これXonshじゃなくても良くない!?」
等の耳が痛い声が聞こえて来ます。

どんどんおかしい方向に進んだ気がしますが、xonshの繁栄のための知見として納めておきます。

おわり。

 

Webスクレイピングする際のルールとPythonによる規約の読み込み

- はじめに -

この記事は Webスクレイピング Advent Calendar 2017 - Adventar の1日目の記事です。

近年では、Pythonが様々な場面で使われるようになりました。
Webからデータを取ってくる際のスクリプトとして利用し、そのままデータを機械学習における学習データとするといった案件も多く見るようになっています。

ありがたい事に本年度書きました以下の記事は、はてなブログに投稿されたPython関連の記事の中で歴代はてブ数1位だそうです。

Webスクレイピングも日に日に情報が増え、様々なパッケージやフレームワークによって手軽になっています。

本記事は、スクレイピングやクローラを記述する際に抜けがちな、「規約」について記載するものです。

スクレイピングの間隔はどうすればいい?規約は?違法でないの?という人のために法律等もまとめています。

追記2019/01/07:
著作権法が改正され、機械学習モデリングなどに使えるスクレイピング関連のデータの取扱も変わりました。
以下の記事が詳しいので一読しておくと良いでしょう。
www.itmedia.co.jp


アジェンダ


 

- Webスクレイピングにおけるルール -

Webスクレイピングまとめ記事の後半で記載しているが、ネット上のデータを収集して取り扱う上での著作権法対象のWebサーバに適切にアクセスし身元の開示や負荷を考える上での動産不法侵入の2つを特に気にすべきである。

よりシンプルに以下にまとめてあるため、参考に。
https://vaaaaaanquish.hatenablog.com/entry/2017/06/25/202924#法律の話


 

著作権法

前者の著作権法は、スクレイピングしたデータでデータセットを作って公開したりしたらダメ、データ分析に使用する場合は他法律に触れなければOK等といった内容で、SNS等でもよく議論に上がる知的財産権に属する内容である。

日本におけるスクレイピングでの著作権の取扱は「つまるところ、データ分析や教育、引用等の認められた利用の範囲内であれば、スクレイピング行為自体は著作権法上認められた行為」となっている。これについては、以下記事が最も参考になる。
「日本は機械学習パラダイス」 その理由は著作権法にあり - ITmedia NEWS

公開されている情報の利用、機械学習におけるデータの取得等は、著作権法においては問題ない。
しかし得たデータの分析においては問題ないが、それらを公開したり、そのデータを直接的に利用して金銭を得る事は問題となる。
また当然、各サービスの規約や後述する動産不法侵入、robot.txtによって制限されている場合がある。

また、取得するスクリプトの公開等についても現状グレーとなっている。

ちなみに取得著作物が自由に使えるパターンについては文化庁のWebサイトにある以下を見ておくと良い。

 

動産不法侵入

後者の動産不法侵入は、スクレイピングするコードを書いたのだから意図性がある、相手のサーバへの負荷を考慮する、Webページが提示する条項を守るといった内容である。
著作権等で認められた場合でも高負荷なbotを作成した場合、例えツールを利用しただけの場合でも意図性が優先され裁判となる可能性がある。

相手のサーバの負荷、ネットワークの負荷、アクセス先の制約について「知らなかった」で済まされないようになっており、また実際の判例も存在する。

 
本記事で取り扱う規約保持のスクリプトは、主に後者の動産不法侵入の内容に含まれるWebページが提示する条項を守る「同意の欠如」から身を守るためのものである。

主に以下の内容をPythonスクリプトで実行していくための記事である。

  • aタグにrel="nofollow"が設定されていたら辿らない
  • robots metaタグの属性記載に従う
  • HTTP ヘッダーのX-Robots-Tagに従う
  • robots.txtに従う
  • User-agentなどを正しく設定する


   

- robot.txt -

metatagやHTTPヘッダーの確認も重要であり、後述するが、まず前提としてrobot.txt周りの話を記述する。

robot.txtとは

robot.txtとはクローラーに対する指示書である。

1994年に採用されたMK1994、および拡張のMK1996Google, Yahoo and Microsoftが2008年に出してきたGYM2008、2007年のACAP等が存在し、各検索サービス等が対応したりしていなかったりというのが現状である。

そもそもは検索エンジンのクローラに対する指示書。
これ以上の歴史的経緯は割愛するが、気になる場合は以下追っていくと良。
Nikita The Spider * Articles and News
Robots Exclusion Standard - WikipediaAutomated Content Access Protocol - Wikipedia

 
Webスクレイピング、クローリングをする上では、HTACCESS等より拘束力はないが、まずはじめにrobot.txtの準拠をしておくと良い。

robot.txtの拘束力については、「法として定義されたルールではない」「検索エンジンに向けたものでありスクレイピングにおいて準拠すべきか」などの議論が幾度となく繰り返されているが、そちらについてはここでは強く言及しないものとする。

拘束力についての議論もありながら、現実robot.txtの準拠については事件の判例にも関わっている。
検索エンジンと著作権 - 三浦基/小林憲一
フィールド対Google事件 - Wikipedia
Google、新聞記事掲載が著作権侵害とするベルギーの判決にコメント

また、以下日本における「1回URL叩いたら1秒Sleepしましょう」という言説の元となっている、国立国会図書館法に関連する資料にもrobot.txtに関する記載がある。
国立国会図書館法によるインターネット資料の収集について

この国立国会図書館の資料については、言及しておく。
岡崎市立中央図書館事件について調べ、容疑者のブログ等をよく読むと理解できるはずだが、「1アクセスごとに1秒の間隔」という基準に意味は何の意味もなく、これらの言説は無視すべきである(筆者はそういった基準を国立国会図書館が公開している事自体どうかと思う)。この岡崎市中央図書館の件は、スクレイピング時に間隔を開けていたにも関わらず、サーバ側の不具合によって高負荷と判断され、逮捕、起訴猶予となった。高木浩光氏のブログにもあるように、明らかな誤認逮捕であり、警察、検察ならびに岡崎市の技術理解が乏しい事が分かったというだけの事件ではあったものの、この事件のように「相手のサーバにとっての高負荷」が発生してしまうだけで裁判となる可能性があり、その事について我々は肝に命じておくべきである。

 
要は「節度」となるのだが、実際の判例を見るに準拠しておいて損はないだろう。


これらが気になる場合は、以下の書籍に歴史的経緯や判例の項目があるため、一読すべきである。

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

 

robot.txtフォーマット

  
robot.txtはドメイン直下に配置されるテキストファイルであり、Webスクレイピングやクローリングを行う際、以下のように読みに行く事になる。

https://hogehoge.com/robot.txt

以下にrobot.txtのsampleを示す。

User-agent: *
Disallow: *

User-agent: Googlebot
Allow: *
Disallow: /private

上記は「Googleクローラーは/private以外どこでもアクセスしていいけど、それ以外のbotは全て禁止する」という指示を記したものである。

基本的にMK1994のSyntaxに従っていれば、python内のurlib.robotparserでparseする事が出来る。
後述するように、自作パーサーを作る他、Robotexclusionrulesparser、reppyといったパーサーパッケージも存在する。

また、一部Webスクレイピングまとめ記事でも紹介したようなmechanizeパッケージ等、自動でrobot.txtを読み込んでキャッシュしておき、規約に応じたスクレイピングが可能なものもある。

# mechanize
# set_handle_robots(False)しなければ以下エラーになる
httperror_seek_wrapper: HTTP Error 403: request disallowed by robots.txt

http://wwwsearch.sourceforge.net/mechanize/

後述するようにスクレイピングのためのフレームワークとしても有名なScrapyにもそれらを適応するパラメータが存在する。


 

- Pythonスクリプトでの規約の読み込み -

上記の内容を踏まえ、Pythonで各規約情報を読み込むスクリプトを示す。
ここでは「aタグのrelチェック」「robot metaの検出」「HTTPヘッダーのチェック」に加えて、既存のPython謹製パーサーによるrobot.txtのパースについて記述する。

aタグのrelチェック

aタグにはrel属性でnofollowが指定されている場合がある。
rel="nofollow"はスパムコメントに対する防御策として提案され、コメント欄等にスパムURLが投稿される可能性のある箇所に自動的にnofollowを付ける事で、GoogleやYahooの検索エンジンにおけるリンク先考慮のPageRankを下げないように設置するものである。
nofollow - Wikipedia
RFC 3667 - IETF Rights in Contributions
RFC 3668 - Intellectual Property Rights in IETF Technology

近年ではSEO対策に加え、スクレイピング負荷対策等に使われる場合がある。

robot.txtに比べスクレイピング、クローリングに対する拘束範囲は小さいが、rel="nofollow"されたリンクはWebサイト作者の意図しないリンクである可能性が高いため、処理しておくと良い。


BeautifulSoupならfindAllの引数としてlambdaや正規表現が渡せるので、それらを利用する。

from bs4 import BeautifulSoup
import re

html = """
<html><body>
<a href="sample.com" />
<a rel="nofollow" href="badsample.com" />
<a rel="nofollow" href="badsample.com" />
<a href="sample.jp" />
<a href="sample.ne.jp" />
</body></html>
"""

soup = BeautifulSoup(html, "html5lib")
# hrefが設定されておりrelにnofollowが設定されてないaタグを探す
links = soup.findAll('a', href=True, rel=lambda x: "nofollow" not in str(x).lower())
for link in links:
    print(link['href'])


lxmlを使って解析している場合はrel属性のついたlinkを探せるfind_rel_linksがある。

import lxml.html

h = lxml.html.fromstring(html)
for x in h.find_rel_links("nofollow"):
    print(lxml.html.tostring(x))


 

robot metaの検出

クローリングされないため、Webサイトにmetatagとしてnofollow、noarchive、noindexを設置する方法がある(他にもnocacheや特定サービス拒否のcontent属性がある)。noarchiveであればそのページを保存しないし、nofollowがついていれば以降リンクを走査しないようにしておくと安全。
http://www.robotstxt.org/meta.html
HTML 4.01仕様における記載

BeautifulSupの解析器にLambdaを投げるのが吉。

from bs4 import BeautifulSoup
html = """
<html><body>
<meta content="nofollow" name="robots"/>
<meta content="noarchive" name="robots"/>
<meta content="noindex" name="robots"/>
<a href="sample.com" />
</body></html>
"""

soup = BeautifulSoup(html, "html5lib")
meta = soup.find_all('meta',
                     attrs={"name":"robots"},
                     content=lambda x: "nofollow" in str(x).lower() or "noarchive" in str(x).lower())
print(meta)
print(len(meta) > 0)


 

HTTPヘッダーにおけるX-Robots-Tagのチェック

Googleによると、HTTPヘッダーでも上記metatag設定と同義の事ができるらしい。
Robots meta tag and X-Robots-Tag HTTP header specifications  |  Search  |  Google Developers

一応チェックできる。例えばrequestsなら下記。

import requests
r = requests.get('https://hogehoge.com')
print( "nofollow" not in str(r.headers.get("X-Robots-Tag")) )
print( "noarchive" not in str(r.headers.get("X-Robots-Tag")) )

設定してるWebページがそこまで多い訳じゃないが、見ておくと良さげ。

 

urllib.robotparserを使ったrobot.txtのparse

21.10. urllib.robotparser — robots.txt のためのパーザ — Python 3.6.5 ドキュメント

Pythonデフォルトで使えるパーサ。

Googleのrobot.txtをparseしてみる。

[https://www.google.com/robots.txt]

以下のように読み込んでcan_fetchしていく

import urllib.robotparser
rp = urllib.robotparser.RobotFileParser()
rp.set_url("https://www.google.com/robots.txt")
rp.read()

# エージェントがURLを見れるか
if rp.can_fetch("*", "https://www.google.com/search"):
    print("OK")
else:
    print("NG")

# クローラの遅延時間指定パラメータの取得
# なければNone
print(rp.crawl_delay("*"))
print(rp.request_rate("*"))

参考:Parsing Robots.txt in python - Stack Overflow

 

Robotexclusionrulesparserを使ったrobot.txtのparse

Robotexclusionrulesparserはurllib.robotparserのBSD License代替スクリプト
Nikita The Spider * A Robot Exclusion Rules Parser for Python

前述したGYM2008とMK1994/96との構文の差で発生する問題(ワイルドカード*をどう読むか)等について触れられており、両者をparseできるようになっている。non-ASCIIやBOM等にも対応。
RobotExclusionRulesParser and RobotFileParserLookalikeの2つのクラスを提供していて前者がwrapperになっている。
BSDライセンスなのでGithubで検索すると導入しているところがちらほら。

以下URLのスクリプトを利用するか、pipで導入する。
http://nikitathespider.com/python/rerp/robotexclusionrulesparser-1.7.1.py

pip install robotexclusionrulesparser

使い方はほぼurllibと同じ。

import robotexclusionrulesparser

rerp = robotexclusionrulesparser.RobotExclusionRulesParser()
rerp.fetch('https://www.google.com/robots.txt')
if rerp.is_allowed('*', '/search'):
    print("OK")
else:
    print("NG")

get_crawl_delayやparseもあるので結構使える。
複数のWebサイトを取って回る、urllibじゃparseできない時に有用。

 

reppyを使ったrobot.txtのparse

robot.txtのparseパッケージ
クロール遅延やサイトマップの読み込み、robots.txtをキャッシュしておく機能が備わっている。
GitHub - seomoz/reppy: Modern robots.txt Parser for Python

導入はpipで

pip install reppy

使い方もほぼ上記と同じ。
sitemapが見れるだけでなくHeaderWithDefaultPolicyでこちらのPolicyに合わせてbool値が出せたりする。

from reppy.robots import Robots

# This utility uses `requests` to fetch the content
robots = Robots.fetch('https://www.google.com/robots.txt')
if robots.allowed('https://www.google.com/search', 'robot'):
    print("OK")
else:
    print("NG")
    
print(robots.agent('*').delay)
print(list(robots.sitemaps))

reppyの強みはcacheにある。

from reppy.cache import RobotsCache
robots = RobotsCache(capacity=100)
robots.allowed('https://www.google.com/search', 'robot')
print(robots.cache)

これによりrobotsを使いまわしながら、複数のサイトのrobot.txtを採用しながらスクレイピングを行うことができる。

 

scrapyではどうすればいいの?

scrapyでは、以上のrobot.txtパーサを利用しなくてもurllibを利用してくれるパラメータが存在する。

ご存知の通り、scrapyのデフォルト設定はスクレイピング先のサーバに負荷をかけまくる極悪設定になっているので、必ず以下くらいを設定しておくと良い。

DOWNLOAD_DELAY = 5
ROBOTSTXT_OBEY = True 

負荷を気にするなら、そもそもScrapyを使わないという選択肢も大いにあるが…


 

- おわりに -

robots.txt、Metatags辺りに対応する方法についてまとめておきました。

最近、辻さんがTwitterで仰っていましたが、robot.txtとnoindexを情報隠ぺいのように使う企業も存在します(下記はrobot.txtとタグの優先順序により失敗していましたが…)。


直近だと、Ads.txtなるものも出てきました。
Industry Aligns to Adopt ads.txt Specification – IAB Tech Lab

今後クローラ界隈がどうなっていくかは未知ですが、する側もされる側も良識を持って対応しなければいけないというのが現状で、こうしていれば間違いない、批判されないという方法はありません。

日本では解析のためのWebスクレイピングが認められている訳ですが、その中でも全員が節度を持って行動する事が全員のためになると私は思います。
「日本は機械学習パラダイス」 その理由は著作権法にあり - ITmedia NEWS


最後になりましたが、上記に加えてWebスクレイピングを行う際はUser-Agentを適切に設定しましょう。

明日はanoChickさん!期待です!
adventar.org


Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

Real World HTTP ―歴史とコードに学ぶインターネットとウェブ技術

 

Pythonistaに贈るXonshのススメ

- はじめに -

この記事は Xonsh Advent Calendar 2017 1日目 の記事です。

タイトルが煽りです。

なんとなく贈るという単語が12月っぽいです。

内容は、Pythonで動くShellである「xonsh」の勧めを書く記事です。


追記2018/06/25:

xonshの設定に関する記事を書きました。
本記事よりも利用した上でのxonshの概要やメリット、デメリット、設定方法まで詳しく以下記事に書いてます。
vaaaaaanquish.hatenablog.com

xonsh 0.7.0が出ていますが、現在prompt-toolkit2.0の各機能対応中という感じです。
これは、ptk1.x -> 2.xにおいて結構な破壊的変更があるためです。現状はpip install xonshする時に
pip install xonsh==0.6.10
pip install prompt_toolkit==1.0.15
としておくと良いと思います。

 

- xonshとは -

xonshは、Pythonで作られたクロスプラットフォームUnixライクなシェル言語とコマンドプロンプトです。

sh + Pythonインタプリタのような取扱が可能です。
つまり以下のような事ができます。

f:id:vaaaaaanquish:20171118064346p:plain:w400:h350

もはやシェルスクリプトを触っているのかPythonを書いているのか分からなくなってきます。

後述しますが、もちろんShell scriptとPython scriptをサブプロセスで動作させ、それぞれの結果を参照する事も可能です。


XonshはPyCon2016でも発表されており、YouTubeに動画が上がっています。
youtu.be
その時のスライドが以下
http://lucasicf.github.io/talks/shell_python/#/


良い機能をいくつか挙げると、xonshrcがPythonで書ける、ptkとprompt-toolkitに対応しており拡張も書ける、pygmentsによるシンタクッスハイライト、proctitle対応などがあります。

bashzshユーザ各位に殴られそうな、公式の比較の表があるので貼っておきます。

f:id:vaaaaaanquish:20171118065738p:plain
http://xon.sh/index.html#comparison


基本的に疑問があったら、Githubのissueで作者がカジュアルに色々答えてくれてたりします。
StackOverflowよりissueみたいな状態です。
もちろん私のTwitterでも答えれる限りで答えます。


 
ちなみに下記ツイートみたく「まだ日本語の情報が全然ないのでアドベントカレンダーを書いてほしい」とTwitterで散々言っていましたが、アレはほぼウソで、英語の情報も全然ないのでみんなGithub issueに集まるというのが今です。使ってみた記事を書くなら今です!


ドキュメント : http://xon.sh/index.html
Github : https://github.com/xonsh/xonsh
作者がxonshについて語るpodcast : https://www.podcastinit.com/episode-29-anthony-scopatz-on-xonsh/


 

- 導入 -

http://xon.sh/#contents 内のInstallationに書いてある。
Mac, Windows, Linuxそれぞれの代表的なパッケージ管理やpip、condaを使ってのインストールが可能。

pyenv上のpipでインストールすると `/Users/hoge/.pyenv/shims/xonsh` にXonshが入る。
今時居ないかもしれないが、仕事の都合で2系と3系を行き来するという場合は不便な場合がある。

そもそもvenvやvirtualenv、pewなどがbashzsh向けに作られているために上手く動作しないので、Xonshでは Vox なる独自のenvツールが用意されている。
http://xon.sh/python_virtual_environments.html
virtualenvっぽい形式で操作が可能なので、純粋に標準Pythonで入れてVoxで十分な環境構築が可能である。

 
試しにPython3.xに付随するpipで導入してみる。
readline shellとして使いたい時はgnureadlineも必要。引数周りが激的によくなる。

pip install xonsh
pip install gnureadline

Macの場合のみ以下bashの補完パッケージを入れておく。

brew install bash-completion2

xonshコマンドで実行するか、`which xonsh` した先のxonshを標準コマンドプロンプトとして登録すれば終わり。

$ xonsh


 

- 使ってみよう -

導入は済んだね!

イエーイ!!
よくできました!!

それじゃあさっそくテンション上げて使ってみましょう!!
 

Pythonとshell scriptどちらも走る

変数を使ったりコマンドを使う事もできるよ!簡単だね!

 $ ls -l
total 0
 $ ls = 100
 $ l = 20
 $ ls -l
80
 $ del ls
 $ ls -l
total 0

面白いね!

 

サブプロセスとして走らせる

shell scriptとpython stringの相互変換もできるよ!
その結果をpipeしたりredirect、I/O redirect、background jobにすることも容易だよ!

もちろん下に書くサブプロセス演算子は複合して色々書けるけど悪用しないでね!公式もそう言ってるよ!絶対ダメだよ!
http://xon.sh/tutorial.html#nesting-subprocesses
 

shell script -> python string

$()でPython Stringが返ってくるよ!

x = $(ls -l)
print(x)    # lsの結果
shell script -> python class

!()でClassが返ってくるよ!

x = !(ls .)
print(type(x))    # <class 'xonsh.proc.CommandPipeline'>
python -> shell script

@でPythonスクリプトの結果が文字列が返ってくるよ!

import sys
echo @(sys.version_info.major)   # 3
python -> stdio

実行結果を直接出力してNone返す事もできるよ!

x = ![ls -l]    # この行が走った時点で標準出力される
x is None    # True

 

スクリプトとして走らせる

xonshコマンドで-cオプションをつければスクリプトが走るよ!

xonsh -c "echo @(7+3)"

test.xshでスクリプトファイルを書くこともできるよ!

#!/usr/bin/env xonsh
# test.xsh
echo @(7+3)

上のファイルを走らせるよ!

xonsh test.xsh

別fileからのスクリプトのインポートもPythonらしさあるよ!

from test import *

以下が参考になるよ!
http://xon.sh/tutorial.html#executing-commands-and-scripts
http://xon.sh/tutorial.html#importing-xonsh-xsh

 

xonshrc

Pythonでxonshrcが書けるよ!

Pythonで関数を定義してその関数にaliasを貼ったりできるからPythonさえ書ければshell script忘れてもまあ書けるし、「よく分からんけどネットで見つけたshコピペしてbashrcに貼ってる」みたいなPythonエンジニアにはオススメだよ!もちろんそんなエンジニアは居ないと思うけどね!!

/etc/xonshrcを書こうね!

# xonshrc
def _hello(args, stdin=None):
    return ('Hello, World!', None)
aliases['hello'] = _hello

実行してみよう!

 $ source /etc/xonshrc
 $ hello    # Hello, World!

http://xon.sh/tutorial.html#customizing-the-prompt

xonshrcのイケてるセッティングはきっとXonsh Advent Calendar 2017で出揃うから要チェックだよ!


 

- bashからの移行 -

Bash to Xonsh Translation Guide — xonsh 0.7.0 documentation

ガイドがあるよ!簡単だね!

 
 

- おわりに -

テンションに疲れましたがこんな感じです。

Xonshはまだまだ情報がネットになく、日本語の記事は多分この記事が最初という感じですが、Pythonを日常的に使っていればかなり便利に取り扱う事ができるシェルだと思います。

Futureでは、urwid base化やPython2系対応、各Mac OS検証が提言されており、コミッターも募集しています。Pythonユーザの増加から考えても、今後も拡張が続きそうです。


python toolkitを使ってみた記事やxonshrcのイケてる書き方から、RNNでコマンド予測してみたみたいなハードな記事まで、アドベントカレンダーは未だ人を募集しています

さあ今すぐpip install

qiita.com

 
追記1:

アドベントカレンダー1日早く投稿してしまいました…
 
追記2:

xonshの読み方について

聞き間違いっぽい↓

今一番有力
コンシュが正解として俺もコンシュと読んでる


一応公式ページでランダムに表示される文言の中に [コンシュ] が入っている。
f:id:vaaaaaanquish:20180520181037p:plain

その他、カンク/コンクという強めの説もある。
GitHub - xonsh/xonsh: Python-powered, cross-platform, Unix-gazing shell
`pronounced conch`



正直わからんのでコンシュで…

 
 

CIKM2017聴講メモ(後編)

- はじめに -

シンガポールで行われているInternational Conference on Information and Knowledge Management (CIKM) 2017に参加した。

workshop day + main conference day (3day) の合計4日間。
メモはその場で書いたものを少し編集しただけで、論文を詳しく読めているものと読めていないものがある。論文読みは別途。
メモだけは長くなりそうなので前半後半に分ける。

以下が前半

各文献は以下から追える
dblp: 25. CIKM 2017


 

- Conference(3日目) -

大雨で笑った。シンガポール蒸し暑いし、スコールが厳しい。
また最後のセッションが3つしかないのはDEMOみたいなのがあったからで、今回はそちらを見ていた。

Metaricaみたいなデータ分析、ビジュアライズツールの作者がDEMOをしていた。
Metarica:https://hpi.de/naumann/projects/data-profiling-and-analytics/metacrate.html
他で気になったのは特段無かったかなあ…

 

Online learning, Stream mining

BoostVHT: Boosting Distributed Streaming Decision Trees

オンラインなBoostingは並列化難しいと言われているが、提案するBoostVHTなら分散エンジンにも乗るし分類も適切にできるよという話。

Vertical Hoeffding Tree(VHT)は、1つのModel Aggregatorが複数の統計計算をコントロールしてその結果を使って学習していくモデル。計算した複数の結果から上位を選んで(木であれば)葉の分割するしないを決定してModel Aggregatorが更新されていく。

VHTのつらいところはOzaBoostとかAdaBoost、OSBoostといった最近のBoostingモデルに適応する時に、各インスタンスの重みを変更する部分で相互接続が必要になること。なので、Model Aggregatorの部分を以下のように逐次的な感じにしてやれば良いのではという話。

f:id:vaaaaaanquish:20171118225545p:plain:w350f:id:vaaaaaanquish:20171118225553p:plain:w350<

既存のMOA(OzaBoostの並列拡張)と同等くらいに早くて精度が高い。
Boosting好きそうな登壇者とBoosting好きそうな質問者による質疑があり、Git公開も考えてるとのことだった。

VHT: Kourtellis, Nicolas, et al. "VHT: Vertical hoeffding tree." Big Data (Big Data), 2016 IEEE International Conference on. IEEE, 2016.
MOA: Bifet, Albert, et al. "Moa: Massive online analysis." Journal of Machine Learning Research 11.May (2010): 1601-1604.
SAMOA: Morales, Gianmarco De Francisci, and Albert Bifet. "SAMOA: scalable advanced massive online analysis." Journal of Machine Learning Research 16.1 (2015): 149-153.

 

Stream Aggregation Through Order Sampling

論文: Stream Aggregation Through Order Sampling

ユニークキーの無いデータで効率的にオーダーサンプリングするアルゴリズム、Priority-Based Aggregation(PBA)の提案。

スライドにも数式多く、時間ないと分からない部分が多すぎるので論文を読む。

 

FUSION: An Online Method for Multistream Classification

論文: FUSION

ストリーム状のデータ分類では、データにあるドメイン情報があるはずで、それらを利用してsourceを学習した結果を活かしながらtarget学習できるアーキテクチャを提案。

f:id:vaaaaaanquish:20171118233930p:plain:w350

図内のDensity Ratio Estimation Module(DRM)が入力データストリームと今までの分布の差を計算、Drift Detection Module(DDM)に回りしきい値を超えた場合に「入力データ分布が変わった(driftした)」として学習が進むアーキテクチャ

結果いい感じだけどどういった状態で使うかなぁというイメージ。

 

Deep Learning 1

部屋を間違えて1つ目の発表を聞き逃す等した

Length Adaptive Recurrent Model for Text Classification

論文: Length Adaptive Recurrent Model for Text Classification

テキスト分類のLSTMに対して以下のようにFCN付けて拡張したLength Adaptive Recurrent Model(LARN)を提案。

f:id:vaaaaaanquish:20171118235602p:plain:w350

まあテキスト全体と一部の効果どっちも欲しいよねという前提で分からんでもないモデル。
結果はバニラLSTMと比較しているのだが、質疑で「バニラLSTMとの比較はフェアではないのではないか」とかなり激しめの口調で指摘する人が居るなどしていた。心が痛い。

 

Multi-Task Neural Network for Non-discrete Attribute Prediction in Knowledge Graphs

論文: Multi-Task Neural Network for Non-discrete Attribute Prediction in Knowledge Graphs

Graph Embeddingの新しいネットワークの提案。
ネットワークのRelationalとAtributeそれぞれ入出力にした1つのネットワークMULTI-TASK KNOWLEDGE GRAPH NEURAL NETWORK (MT-KGNN)。

f:id:vaaaaaanquish:20171119002056p:plain:w350

気持ちは分からなくもないが、何で左右に挟まれてたりするかは聞いてたが謎だった…

 

Movie Fill in the Blank with Adaptive Temporal Attention and Description Update.

論文: http://delivery.acm.org/10.1145/3140000/3132922/p1039-chen.pdf?ip=175.177.5.173&id=3132922&acc=OPEN&key=4D4702B0C3E38B35.4D4702B0C3E38B35.4D4702B0C3E38B35.6D218144511F3437&CFID=822711636&CFTOKEN=60985772&__acm__=1511019051_cba0bc5f027c502b908eb39acc33e0d2

動画から文章が出てほしいタスクを解くため、大きめのネットワークモデルを提案。
なんかまずは穴埋めからやっていた。

f:id:vaaaaaanquish:20171119002845p:plain:w350

モデルの図はデカいけど、やってる事はシンプルで多層LSTM挟んでConcatしてMLP。結果はめちゃくちゃ良いわけではないような感じだったがこれいかに。


 

- Conference(4日目) -

Efficient Learning

Sequence Modeling with Hierarchical Deep Generative Models with Dual Memory

論文: Sequence Modeling with Hierarchical Deep Generative Models with Dual Memory

discrete sequencesで似たテキストが欲しい時、RNN、CNNだとOverfitting、Lack diversityしやすい。Deep Generative Modelsだとpoor result。
長期、短期の記憶を考慮したVAE拡張のsequenceアーキテクチャを提案。

Dual Memoriesと呼んでいて、Encoding側にBroad Memory(B-HDGM)、Generative側にDeep Memory(D-HDGM)を組み合わせ接続したBi-BD-HDGM。
f:id:vaaaaaanquish:20171119181716p:plain:w350

デカいすぎてもうこれ分からんなという感じで、学習時間もVAE等に比べて遅くなるが、結果は良い感じの文章。
質疑では、良くない文章が生成される場合もありそうだとの指摘があったが全般的に良くなる(?)といった回答だった。

 

Active Learning for Large-Scale Entity Resolution

論文: Active Learning for Large-Scale Entity Resolution

IBM Researchの人。発表が丁寧だった。
「アイツだれだっけ…」を解決したい(Entity Resolution, ER)。TwitterIBMのEnterpriseデータをマッチングしたいけどデカいし全然マッチングしないので、両者から適切に検索しマッチングさせたい。
そこでactive learningベースで高いprecisionとrecallを出せるERLernを提案。

プロファイルデータのマッチングのルールを学習(名前ANDステータスOR…みたいな)。
そのルールを元にqueryを生成してマッチングユーザを探す。

f:id:vaaaaaanquish:20171119185337p:plain:w350

Twitterとのマッチングとか、入力になる特徴量を増やすのが難しいのでこういったアーキテクチャは使われそう。

 

Indexable Bayesian Personalized Ranking for Efficient Top-k Recommendation

論文: Indexable Bayesian Personalized Ranking for Efficient Top-k Recommendation

Top-K推薦検索のタスクでは速度と精度どちらも大事。
MFはitem行列デカい。exhaustive-searchはpracitialじゃない(力任せ探索は実践向きじゃない)。

item Vectorをhash tableかけてTop-K itemをだすLocality Sensitive Hashing(LSH)、Maximum Inner Product Search(MIPS)、Nearest Neighbar Search(NNS)、Maximum Cosine Similarity Search(MCSS)あたりあるけど内積検索と同等レベルではない。

Bayesian Probabilistic Matrix Factorizationを参考に、相対的なTop-Kを出せるIndexable Bayesian Personalized Ranking(Indexable BPR)を提案。
speedも精度もかなり上がってハッピーそう。

Bayesian Probabilistic Matrix Factorization: Salakhutdinov, Ruslan, and Andriy Mnih. "Bayesian probabilistic matrix factorization using Markov chain Monte Carlo." Proceedings of the 25th international conference on Machine learning. ACM, 2008.

 

Latency Reduction via Decision Tree Based Query Construction

論文: Latency Reduction via Decision Tree Based Query Construction

Facebook社の人の発表。
Linked Inのジョブレコメンド、ジョブサーチについて。

query生成にはTerm MatchとDecision TreeとLinear Modelが入ってるらしい。
検索では当たり前になりつつあるWANDオペレータとFLEXオペレータで繋げたqueryを生成。

f:id:vaaaaaanquish:20171119192306p:plain:w600

アーキテクチャAWS配置がプレゼン内に出てきたが、さほど複雑な使い方はしておらず、拡張子しやすさやDecision Treeによる確認、改修のしやすさを大事にしている段階とのこと。
というかFacebook社もAWSだったの何気に初めて知ったかも。

 

Adversarial IR

Sybil Defense in Crowdsourcing Platforms

論文: Sybil Defense in Crowdsourcing Platforms

クラウドソーシングって色んな所で活用できるけど、悪意のあるユーザがアカウントを大量に使って攻撃してきた場合に品質保証できないから、対策したい。
従業員の類似性を定量化するフレームワークで、いくつかの質問で悪意あるユーザをグルーピングしていくだけでなく、オンラインに検出する方法を提案。

普通にいくつかの質問の答えに重みを付けていたのでう〜んという感じ

 

HoloScope: Topology-and-Spike Aware Fraud Detection

論文: HoloScope
Github: GitHub - shenghua-liu/HoloScope: HoloScope: Topology-and-Spike Aware Fraud Detection

ネットの詐欺師の検出。大体悪意あるユーザは大量の偽アカウントやIP大量購入したりしてくるので、一般的な手法だと攻撃として目立ちにくい。

なんなら中国では、国民の53.1%がネットに触れていて、平均3時間/日≒8年分が1日に消費されていて世界2位で、年間で7,500億ドルが動いている。Methbotのfakeレビューやfake投稿は日に3000億件あるし、それらが5百万ドル稼いでると予測されているという話からスタート。規模〜。

手法的には簡易で、Graphトポロジーと時間軸におけるスパイクを利用してユーザを検出。そのユーザ分けに使う動的な重み付け、ユーザ評価を含んだ検出フレームワークを提案。

 

Building a Dossier on the Cheap: Integrating Distributed Personal Data Resources Under Cost Constraints

論文: Building a Dossier on the Cheap

TwitterとかNetflixとか色んなデータを合わせれば、特定個人の個人情報や機密情報って結構作れるから危ない。公開するデータの危なさを評価するフレームワークと、予測モデルみたいなのを作ったという話。

特段難しい事はしていないが、今後こういったタスクをやる時にまた読むかもくらい。

 

DeMalC: A Feature-rich Machine Learning Framework for Malicious Call Detection

論文: DeMalC

アリババ社の人の発表。
中国では2015年に590,000件電話詐欺が発生しているし、悪意ある電話本当損失になる。
かと言って、データは無いしあっても不均衡だし詐欺師は検出されないよう進化するし、ブラックリストでもなかなか対策できない。

なのでIPアドレスから端末UIDからありとあらゆるデータをマイニングして判別するようなDeMalCフレームワーク作りましたという内容。
精度が91%になっているけど、実際それで検出するのはなかなか…という感想。

 

Representation learning

An Attention-based Collaboration Framework for Multi-View Network Representation Learning

論文: An Attention-based Collaboration Framework for Multi-View Network Representation Learning

いろいろなネットワークの形から目的とする人について学習タスクでも、DeepWak, LINE, w2vみたく、ノード空間の埋め込みがやりたい。

複数のネットワークをそれぞれ学習させるのではなく、まとめて1つの入力にする。
f:id:vaaaaaanquish:20171119204118p:plain:w350

こういった複数ネットワークを入力にするモデルはA co-regularized multi-view spectral clustering model (CMSC)、 A multi-view non-negative matrix factorization model(MultiNMF)等があるがそれらともまたちょっと違っていて、ちょっとSOMっぽい(?)。

辞書共有などは特段しているわけではないがFuture work。

CMSC: Kumar, Abhishek, Piyush Rai, and Hal Daume. "Co-regularized multi-view spectral clustering." Advances in neural information processing systems. 2011.
MultiNMF: Liu, Jialu, et al. "Multi-view clustering via joint nonnegative matrix factorization." Proceedings of the 2013 SIAM International Conference on Data Mining. Society for Industrial and Applied Mathematics, 2013.

 

Representation Learning of Large-Scale Knowledge Graphs via Entity Feature Combinations

論文: Representation Learning of Large-Scale Knowledge Graphs via Entity Feature Combinations

Knowledge Graphに対する手法でTranslation-baseなモデルではTransE, TramsH, TransR, TransDがある。

TransE: h+r=t
TransH: h-w_{r}^{T}hw_{r}+r=t-w_{r}^{T}tw_{r}
TransR: hM_{r}+r=tM_{r}
TransD: h+h_{p}^{T}hr_{p}+r=t+t_{p}^{T}tr_{p}
となってる訳だけど、このバイアスになってる  r でentityとrelation featuresを同時に表現したい。
そこにプラスとマイナスのcombinationを入れてやってScoreでマージするCombinEを提案。SOTA。

TransE: Bordes, Antoine, et al. "Translating embeddings for modeling multi-relational data." Advances in neural information processing systems. 2013.
TransH: Wang, Zhen, et al. "Knowledge Graph Embedding by Translating on Hyperplanes." AAAI. 2014.
TransR: Y. Lin, Z. Liu, M. Sun, Y. Liu, and X. Zhu. Learning entity and relation embeddings for knowledge graph completion. In Proceedings of the Twenty-Ninth AAAI Conference on Artificial Intelligence, January 25-30, 2015, Austin, Texas, USA., pages 2181–2187, 2015.
TransD: Ji, Guoliang, et al. "Knowledge Graph Embedding via Dynamic Mapping Matrix." ACL (1). 2015.

  

Learning Edge Representations via Low-Rank Asymmetric Projections

論文: Learning Edge Representations via Low-Rank Asymmetric Projections

Googleの人。
Node Embeddingを2つつくって組み合わせDeep Walkの深いverを提案。

f:id:vaaaaaanquish:20171119212309p:plain:w350

コードが公開してあるから使ってくれよなって
GitHub - google/asymproj_edge_dnn


 

- おわりに -

総評は1日目のメモに結構書いたけどDeepやオレオレフレームワークな話とGraph Embeddingが多め。

最後もうしんどくなって来てメモも適当になっていた。
4日間人の話を聞くだけというのはしんどい。

シンガポールは雨と蒸し暑さがすごい!」と聞いていたのだけど、行き帰りに雨降ったのはは1日だけだったし、しんどくなる程の暑さでもなかった。


バスやタクシー、地下鉄だけでなく、貸し自転車や貸し電動キックボードが街中にあり、サラリーマンが朝電動キックボードで通勤していたりする姿があって先進的だった。

食べ物も悪くないし、100m歩けばマクドナルドがあるし、サブウェイ、スタバ、ユニクロ、無印などがあるので不自由しなさそう。物価は1.5倍くらいだけど、中華とか安いお店が沢山ある。

まあでも2度はいいかなシンガポール

 

CIKM2017聴講メモ(前半)

- はじめに -

シンガポールで行われているInternational Conference on Information and Knowledge Management (CIKM) 2017に参加した。

workshop day + main conference day (3day) の合計4日間。
メモはその場で書いたものを少し編集しただけで、論文を詳しく読めているものと読めていないものがある。論文読みは別途。
メモだけは長くなりそうなので前半後半に分ける。

全体の所感としては、SIGIRの時と同じく「Deep Learning」「Embedding」「Social Network Analytics」「Knowledge Graph」といった単語がメインでそれらをどうやってレコメンドエンジンやランキングのようなIRに繋げようかという話が多かった。
(まあ、SIGIR協賛に居るから…)

シンガポール外はめっちゃ暑いのに、会場クーラー効きすぎて寒い。
アジアだし中国人が大体4~6割くらい。みんな寒くてコーヒーを飲みに外に出ている様子だった。
セッションが並列だったのでどれ聞いたかはタイトルと勘。

後半も書いたので追記


文献は以下から追える
dblp: 25. CIKM 2017

 

- Workshop -

2017/11/06はワークショップだった。
「登壇者来てないのでこのセッションは2人で終わりです」みたいなのが2回あって、マジかってなった。
聞き取りに必死で、割りと殴り書きメモ。
 

バイオメディカル分析

専門ではないが、DTMBioちょっと気になってたのでバイオメディカル系の話を聞いた。
DTMBio – Data and Text Mining in Biomedical Informatics

CNNでレントゲンから人の身体の異常を見つけるとか、人体の代謝(Human Metabolism)の仕組みを分析して製薬する話を聞いた。
あと、人間の構造をネットワークと捉えれば何種類かに分類できるとか。

大体内容はありがちなDeepNetやk-means等の機械学習器を使っている感じだった。
質疑では、実務系の質問以外にも「よく知られたDeepモデルとハイパパラメータとReLUを使っているが他は試したか」という内容があり、特段試してはないとの事だった。

専門用語が多くて英語だと事前知識がないと厳しかった…

 

ソーシャルメディア分析とスマートシティの実現

SMASC2017

シンガポールはスマートシティを目指してるらしく「シンガポールが国としてオープンデータを提供しているからソレとソーシャルメディアを合わせて解析したぜ!」という話がいくつかあった。

確かPyCon2017の時に聞いたのだけど、シンガポールではタクシーのGPS情報がAPI経由で取得できたりする。
たしかこれ
Taxi Availability-Data.gov.sg

あと都市のあらゆるデータが見れたり
Projects | Cities of Data

加えて、Telcoからユーザ行動ログを貰ったり、バスや監視カメラの画像まで貰って研究が進んでいるとのことだった。

質疑でも「どうやってそのデータを手に入れていくの?個人情報は?」という質問があって、「Academic Power」と応えてたのでスゲーってなった(もちろん解決しなければいけない課題があるとも言ってた)。


上記に加えてソーシャルメディアを分析に使うのはかなり有効で、結果も出るんだけど、データの全体感を掴んでhadoopとか色々適切なツールや分析手法を選ぶのが大事。
適切に時系列を選択したり、ノイズをクリーニングしたり。

街中で行われるイベントを例に出して、Twitterはイベント発生前に何度かバーストして、イベント発生直前に一気に伸びて、発生後は1~2日経ったら余計な情報しか残らないよねってグラフを出してた。


面白かった所だと、タクシー文化だけど実はUberみたいなサービスの方が使われてる(でもタクシー数はほとんど減ってない)とか。

 

Customer churn prediction(顧客解約予測)

顧客の解約予測は、時間にとてもsensitiveであるはず(退会原因のトリガーは必ず直近にある)。
だが、原因になる要素は複数あるし、その時間軸もユーザによって違うので「データの不例が定義しにくい」課題がある。

そこでSupervised learningではよくないのでPU learning使いますという話。
長期間のデータの分析結果と短期間のデータに対してPU learningモデリングした結果を見比べるアーキテクチャを提案。

PU Learningは、不例データが定義しにくい場合に使う手法で以下辺り見ると良い。
Elkan and Noto (2008): Learning Classifiers from Only Positive and Unlabeled Data | LingPipe Blog
PU Learning: Learning from Positive and Unlabeled Examples
正例とラベル無しデータからの学習 (PU classification) – nktmemo

すごくシンプルに解決できていた(ように見えた)し、一般的に解約予測で言われるような経験則よりAUC良かったので、まあそういう方向性もあるかという感じ。
質疑で「データの公開はあるか」と聞かれて「自社データなのでないです」と答えていたので本当に使えるかは謎。
ちょうどIBISでもPULearningが話題に上がったらしいが…

 

ソーシャルにおけるSinglishの分析

bigtransport17

ソーシャル分析って良いけど、多言語とかローカル性があってノイジーだから気を付けないとという話。

特にシンガポールには、英語ベースだけど中国や東南アジアの訛が混ざった「Singlish」というやつがあって、本当最悪みたいな話からスタート。
前処理における名前やURL、ストップワードの調整などを紹介。

word2vecしてLSTM、CNNに突っ込んだという話だった。


日本語Twitterも難しいから「そうだよね…つらいよね…」ってなった。

それでもw2v + LSTMである程度まで解析できるのですごい。

 

ユーザのなりすまし判定

ユーザの行動ログをDeepに突っ込んで、なりすましで金持ってく悪いユーザを検出した試みの話。
KDDやICMLでも見たGradient Boosting Decision Tree (GBDT)でfeature transformationしてConvolutional Neural Network(CNN)に入れるやつを使っていた。
GBDTを使ったfeature transformationの適用例

行動ログと端的に言っても、アクセスログや閲覧時間、視線追跡データ等があり、それら形式の違うものを組み合わせられるのがGBDTでfeature transformationする利点。

実際にあるアプリに組み込まれたみたいな話があり、悪徳ユーザを判定してloginされたら真ユーザにNotificationするだけで不正利用件数自体が減るらしい。

素晴らしいなと思ったが、この悪徳ユーザ判定でどれほど金が掛かってるんだろうと思った。
GPUパワーで殴り倒す感。

 

- Conference(2日目) -

Keynote: Machine Learning (Amazon)

Machine Learning @ Amazon

Amazon内ではレコメンド以外にも倉庫内で動くドローン、ロボットのチューニングも機械学習でやっていて、ノウハウをいくつか紹介(大体他企業と変わらないが)。シンプルなベイズモデルから製作し、チューニング。後に複雑なモデル、アーキテクチャに拡大していくとのこと。
「Washing Machine Learning」という単語を出し、機械学習器を定期的に洗浄し精度とデータの時系列性に対応しましょうねとも。

画像から商品を探すビジュアルサーチ、声で探すボイスサーチ、Botも作っている。
商品サマリの生成、商品サイズのレコメンド、離脱ユーザや新規ユーザもそれぞれモデル作ってる。
そういった研究がユーザに還元されていく予定。

Amazonユーザが返品する大半の理由が「商品のサイズ」と言っていたけど、実際は「商品に不満があったのをとりあえずサイズって答えてんじゃねーの…」とちょっと思った。

AmazonもDeep!Embedding!でどうチューニングしていくかを模索しているようだった。

ポケットに手を入れイカしたシャツの人だった

 

Multimedia

Jointly Modeling Static Visual Appearance and Temporal Pattern for Unsupervised Video Hashing

論文: Jointly Modeling Static Visual Appearance and Temporal Pattern for Unsupervised Video Hashing

動画データというのは概ねshort-termなActionの集合であるはずで、textやspeechに対してLSTMでやっているようなhash code化する工程が適応できるはずという課題感。

動画データは視覚的外観と時間的外観がありそれぞれ強みがある。
それぞれ対応するために、Temporal EncoderとAppearance Encoder&Decoderを組み合わせたアーキテクチャを提案。
f:id:vaaaaaanquish:20171112155905p:plain
半教師あり学習も適応できるため、学習データが少ない場合でも適応できそう。

ActivityNetとFCVIDの大規模動画データセットでテスト。
ビデオフレームの平均とPCAを利用する教師なしハッシュ化手法のIterative Quantization(ITQ)、ハッシュコードの平均値を使うMFH、LSTM形式でBinaryコードを吐くように教師なし学習させるBLSTMと比較。
全ての手法に対して優位な結果が得られていた。
ITQ: Gong, Yunchao, et al. "Iterative quantization: A procrustean approach to learning binary codes for large-scale image retrieval." IEEE Transactions on Pattern Analysis and Machine Intelligence 35.12 (2013): 2916-2929.
MFH: Song, Jingkuan, et al. "Multiple feature hashing for real-time large scale near-duplicate video retrieval." Proceedings of the 19th ACM international conference on Multimedia. ACM, 2011.
BLSTM: Zhang, Hanwang, et al. "Play and rewind: Optimizing binary representations of videos by self-supervised temporal hashing." Proceedings of the 2016 ACM on Multimedia Conference. ACM, 2016.

 

Construction of a National Scale ENF Map using Online Multimedia Data

論文: Construction of a National Scale ENF Map using Online Multimedia Data

電源周波数(Electrical Network Frequency: ENF)を解析する方法やハードはいくつかあるけど、YouTubeUstreamみたいなストリーミングで得られるデータから正確に解析する手法ほしい。出来たら違法なUst生放送とかやってる個人の住居特定等に繋げられるはず。といったモチベーション

信号処理をいくつかカマした後に、データを分割してオーバラップして地図上にビジュアライズしたよ(ENF Map)という発表だった。
短時間フーリエ変換(STFT)を拡張したGIFFTを使いましたというのが新規性(だと思う)
信号処理ワードが何個か分からずだった

高専の時の卒論とかで似たようなアイデアを見た気がする。
demo動画とデモサイトあるよって言ってたと思うんだけど、デモサイトはURLでググっても出てこなかった…
www.youtube.com


質疑では「IPアドレスや身体的特徴(Move band等から得られるやつ)ではダメなのか?」みたいなのがあったが、特徴量が1つ増えるし地方レベルで割りと正確に場所を特定できるから良いみたいな感じだった。

あとは、アメリカのデータで実験していて中国でもやりたいとか、BroadCastに拡張したいという話をしていた。

 

Dual Learning for Cross-domain Image Captioning

論文: Dual Learning for Cross-domain Image Captioning

画像からのCaption生成タスクでは、データ作りに時間と費用がかかるので、Cross-domainに学習できるアーキテクチャを提案してsource domain -> target domainの順に学習できるようにしたという内容。
転移学習(transfer learning)的な事をして環境に頑強なモデルを作りたいといったモチベーション。

アーキテクチャ図を以下に引用
f:id:vaaaaaanquish:20171112183911p:plain
メインとするImage Captionの生成はDeepなLSTM、それと並列に画像合成(Image synthesis)タスクを行うGANを走らせている。
pre-trainingさせておくことで、画像データの分布を学習した状態のGANの結果を使いながら文章生成に移れる。また、どちらも半強師あり、教師なしを交互に組み合わせて使う事ができるので、targetにする学習データは少なくて良いよという内容。

キャプション生成はCNNとLSTMを別に学習して織り交ぜるDeep Compositional Captioner (DCC)、CNN-LSTMモデルの拡張であるShow, attend and tell model (SAtT)、Show, Adapt and Tell (SAdT)と比較。pre-trainingはMS COCOでAdam等である程度最適化していた。FlickrとOxfordのデータセットをtargetにして学習。

DCC: Anne Hendricks, Lisa, et al. "Deep compositional captioning: Describing novel object categories without paired training data." Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition. 2016.
SAtT: Xu, Kelvin, et al. "Show, attend and tell: Neural image caption generation with visual attention." International Conference on Machine Learning. 2015.
SAdT: Chen, Tseng-Hung, et al. "Show, Adapt and Tell: Adversarial Training of Cross-domain Image Captioner." arXiv preprint arXiv:1705.00930 (2017).

結果も良く、出てくる文章がかなり良さそう。
f:id:vaaaaaanquish:20171112184910p:plain

ただそれにしては複雑すぎるアーキテクチャのような気がしないでもないが…
「GANが不安定」というイメージが強いのでその辺どうなんだろうと思った。

A New Approach to Compute CNNs for Extremely Large Images

論文: A New Approach to Compute CNNs for Extremely Large Images

Art Transferの新しいモデルの提案。
画風変換だが、デカい画像を学習させようとすると複数GPUを使うことになるが、モデル複数並列にしてもモデル並列にしても結論ちょっとつらい。なので、bulk synchronization parallel(BSP)なる機構で高速な学習を実現するアーキテクチャを提案。

f:id:vaaaaaanquish:20171112194713p:plain:w300f:id:vaaaaaanquish:20171112194717p:plain:w300

単純にやるとCoordinatorなるメインのworkerに対して各GPUに遅延が発生するのだが、同じCNNカーネルを利用しても良いんじゃないかという提案だと思われる。

発表の多くが結果の説明でアーキテクチャの部分がイマイチ把握しきれていないが、生成する画像も良く画像サイズを大きくしていった時にも早い速度で学習することが可能になっている。

f:id:vaaaaaanquish:20171112195452p:plain
f:id:vaaaaaanquish:20171112195107p:plain

あまり詳しくないが、ちゃんとやらないとマズいなあと思っているジャンルのひとつ。

 

Network Embedding

このセッションに関して調べてるついでに以下見つけたのでハッピー

論文: From Properties to Links

ネットワークはubiquitonsだし応用先も多い。クラスタリングとかリコメンドとか。
UserProfileみたいなmetadataの変化とネットワークの変化をMultiViewに埋め込みたい。
加えて静的なGraph Embeddingする手法だとDeepWalk、LINE、GraRep、Node2Vec、SDNE、TADW辺りがあるが、やっぱりグラフというのはDynamicなもので、新しいNodeがきたり情報が変化した時に動的に学習できれば最高だよね。というのがモチベーション。

Graphの変化があった場合に再学習できるようCorrelation-learningを取り入れたGraph Embedding手法であるMultiView Correlation-learning based Deep Network Embedding method(MVC-DNE)を提案。

ベースはAuto Encoder状のネットワークで、添字となっているPTはマルチビューとしている2つの空間である(例えばTがネットワーク構造の情報で、PがNodeに含まれるmetadataとか)。

f:id:vaaaaaanquish:20171112211216p:plain:w300f:id:vaaaaaanquish:20171112211220p:plain:w300

Naive combinationとの組み合わせが効いてた。
新しいNodeが挿入された場合の追加での学習においてもCiteseerGoogle+、DBLPデータセット全てにおいて、AUC、classification等良くなっていた。

DeepWark: Perozzi, Bryan, Rami Al-Rfou, and Steven Skiena. "Deepwalk: Online learning of social representations." Proceedings of the 20th ACM SIGKDD international conference on Knowledge discovery and data mining. ACM, 2014.
LINE: Tang, Jian, et al. "Line: Large-scale information network embedding." Proceedings of the 24th International Conference on World Wide Web. International World Wide Web Conferences Steering Committee, 2015.
GraRep: Cao, Shaosheng, Wei Lu, and Qiongkai Xu. "Grarep: Learning graph representations with global structural information." Proceedings of the 24th ACM International on Conference on Information and Knowledge Management. ACM, 2015.
Node2Vec: Grover, Aditya, and Jure Leskovec. "node2vec: Scalable feature learning for networks." Proceedings of the 22nd ACM SIGKDD international conference on Knowledge discovery and data mining. ACM, 2016.
SDNE: Wang, Daixin, Peng Cui, and Wenwu Zhu. "Structural deep network embedding." Proceedings of the 22nd ACM SIGKDD international conference on Knowledge discovery and data mining. ACM, 2016.
TADW: Cheng Yang, Zhiyuan Liu, Deli Zhao, Maosong Sun, and Edward Y Chang. 2015.
Network Representation Learning with Rich Text Information.. In Proceedings of
the 24th International Joint Conference on Artificial Intelligence. 2111–2117.

 

Learning Community Embedding with Community Detection and Node Embedding on Graphs

論文: Learning Community Embedding with Community Detection and Node Embedding on Graphs

コミュニティの検出したいという内容。
既存では、DeepWalk、LINE、GraRep、Node2Vecなど埋め込みでやる代表的な手法各位以外に、コミュニティ検出向けモデルのSpectral、DNR、M-NMF、などがある。

良いところどりしたComEを提案。
Community DetectionとCommunity EmbeddingとNode Embeddingの手法をそれぞれ使いながら、その情報によってコミュニティを出していく。グラフが G=(V,E) で表されるとき、 O(|V| + |E|)でコミュニティをスケーラブルに推論できるアルゴリズムを提案。
加えてロス関数やパラメータを色々試して競ってみてる。

Githubでコードも公開しているので良さ。


Spectral: Tang, Lei, and Huan Liu. "Leveraging social media networks for classification." Data Mining and Knowledge Discovery 23.3 (2011): 447-478.
DNR: Yang, Liang, et al. "Modularity Based Community Detection with Deep Learning." IJCAI. 2016.
M-HMF: Wang, Xiao, et al. "Community Preserving Network Embedding." AAAI. 2017.

 

Attributed Network Embedding for Learning in a Dynamic Environment

論文: Attributed Network Embedding for Learning in a Dynamic Environment

やりたいタスクは2つ上のと同じで、ネットワーク+ユーザデータとなっているデータを分析するためにEmbeddingしたいという話で、ネットワークは新しいNodeやEdge、ユーザデータはPostやEventで更新されるから動的にやりたいよねというモチベーション。

Dynamic atributed network embedding(DANE)を提案し、静的な状態で行列によりそれぞれのデータを埋め込む方法と、埋め込み時の行列の変化を勾配にして学習していくオンライン埋め込み法を提案している。

いまいちアルゴリズム追い切れてないので、ちゃんと論文を読まないと把握無理そう。

 

Learning Node Embeddings in Interaction Graphs

論文: Learning Node Embeddings in Interaction Graphs

根本解きたいタスクは上記と同じ。ただネットワークにおけるNodeには、ユーザのデータとトランザクションデータのように、エンティティと時間的なEdgeが複合している場合がある(時系列データと時系列情報が同じネットワーク内にあるような場合がある)ので、そういったタスクでも解けるようにInteraction Graph Embedding(IGE)を提案。

f:id:vaaaaaanquish:20171112220123p:plain:w300f:id:vaaaaaanquish:20171112220420p:plain:w300

IGEは複雑なモデルではなく、複数の種類のデータを合わせて入力できるような構造にしたよという話なので、比較先もPV-DM、node2vec、APEとなっていて、 DBLP、PPD、Stock、Yelp各データセットでclusteringして良さそうな結果。
かなり特定の状態の時に使えるモデルかなというのが所感。

Doc2Vecとかはじめて見たの2年前なのに、Embedding相当進歩してんなあと思った。

PV-DM: Le, Quoc, and Tomas Mikolov. "Distributed representations of sentences and documents." Proceedings of the 31st International Conference on Machine Learning (ICML-14). 2014.
APE: Chen, Ting, et al. "Entity embedding-based anomaly detection for heterogeneous categorical events." arXiv preprint arXiv:1608.07502 (2016).

 

Temporal data

Covering the Optimal Time Window Over Temporal Data

論文: Covering the Optimal Time Window Over Temporal Data

いまいち掴みきれてないが、「時間軸で数を最大化するある区切られた時間窓を決定する問題」をthe optimal time window covering algorithm(OTWC)と呼び、OTWCへの2つの対応策を提案。

これは例えば、A、B、Cさんが一番長くミーティングに参加できる時間は何時から何時まで?みたいなタスク。

sliding time window algorithm(STW)とalgorithm based on Timeline Index(TLI)の2つで時系列での複雑な方が後者。
タスクを命名していたが普通に探索問題な気がした。

 

Scaling Probabilistic Temporal Query Evaluation

論文: Scaling Probabilistic Temporal Query Evaluation

時系列knowledge graphsに対するquery評価という課題に対してPRBAbilistic Temporal Query Evaluation(PRATiQUE)フレームワークを提案。

KnowledgeGraphに疎く、Google’s Knowledge Vault、NELL、YAGO、DeepDive、ReVerbといったKGsと呼ばれるKnowledge Graphの形式がある事すら知らなかったのでなかなか苦しかった。

Knowledge Graphもう少し勉強しないと...

 

Efficient Discovery of Abnormal Event Sequences in Enterprise Security Systems

論文: Efficient Discovery of Abnormal Event Sequences in Enterprise Security Systems

NEC labで研究されている侵入検知システムの話。Intrusion detection system (IDS)。

「異常検知」で言うところの「異常」はLowレベルな異常行動の塊である。たとえば、変なディレクトリ参照して -> 権限見て -> 書き換えて…のような一連の行動。

コマンドログをグラフベースにし、異常な行動をしている人が居たら検知するというフレームワークの提案。
f:id:vaaaaaanquish:20171118182902p:plain

中身は単純なTop Kのように見えたけど、毎分約200万レコード処理できて正確に侵入検知ができるようになっているとのことだった。

  

Temporal Analog Retrieval using Transformation over Dual Hierarchical Structures

論文: Temporal Analog Retrieval using Transformation over Dual Hierarchical Structures

古いオープンデータとかアクセスできても、古い用語や言葉遣いに困るので、時系列で類義語見つけて新しい言葉でも表現できると良いよねという話。

時系列順に階層状にクラスタを構造して、そこから追っていくアーキテクチャを提案。
すごい精度が上がっていたがデータセットがいまいちわからなかった。

確かにウォークマンとかiPod的なやつって言わないと分からんよなあ…ってなった。

 

おわりに

Temporal dataの話聞いたのだけど、正直ぐぬぬって感じだった(理解と英語で処理能力足りなかった)。
また勉強しなきゃという感じ。

スタートではDeep Learningの勢いがすごいですねえ!みたいな話とワードクラウドを見た。


2日目はReceptionとしてご飯食べながらポスター発表もあった。
そこもやはりDeep Learningで色んなデータをConcatして優勝、動的なKnowledge Graph、RankNetみたいな話が多かった。流行り。
本当に刺激的な1日だった。


1日目終わってから行ったマーライオンさん
https://pbs.twimg.com/media/DN8LOiNUEAApgIg.jpg
俺の会社での態度くらいデカい