ひらめの日常

日常のメモをつらつらと

Python3.6で文字列を扱うならf-strings

f-stringsとは

Python3.6から追加された文字列の操作のための新しい記法の一つです。例をあげてみるとこのような感じになります。

name = 'Bob'
age = 20
f"my name is {name}. I am {age} year's old."
# => my name is Bob. I am 20 years's old.

f'文字列'というように、文字列の前にfをつけて宣言します。そして{}の中で動的に変数を展開し、その値を出力しています。

ドキュメントはこちらです。
www.python.org

This PEP is driven by the desire to have a simpler way to format strings in Python.

とあるように、文字列をフォーマットするためのより簡潔な記法を実現しています。 今までだと上記の例でしたら、次のように書く必要があり、format()の分行が長くなります。
さらに、文章が長くなり代入する文字列も増えてくると、{}を発見した後にfomatの中身をみてもう一度{}を確認しに行く...といったコードリーディングの際にも冗長性が発生します。

"my name is {n}. I am {a} year's old.".format(n=name, a=age)

使い方例

こちらの記事を参考にしました。

qiita.com

関数を評価

{}内は動的に評価されるために、関数を書いてその返り値を出力することができます。

def calc_tax(price):
    return price * 1.08

f'This pencil is {calc_tax(100)} yen.'
# => This pencil is 108 yen.

配列アクセス

fruits = ['apples', 'oranges', 'bananas']
f'I like {fruits[0]}'
# => I like apples.

{}のネスト

{}はネスとしてもよく、その都度変数が展開されます。

float_val = 0.123456
size = 4
f'result: {float_val:.{size}}'  
#=> 'result: 0.1235'

注意点

f-strings記法では、バックスラッシュ(\)を入れてはいけません。一番最初にあげた例だと、次のように書くことができそうですが、SyntaxErrorが帰ってきます。

f'my name is {name}. I am {age} year\'s old'
# => SyntaxError: f-string expression part cannot include a backslash

再帰的にmkdirする(Linux, Python)

Linuxコマンドでは

mkdir -pコマンドで、再帰的に深い階層のディレクトリまで作成してくれます。
また、ディレクトリの中を再帰的に表示する場合は、ls -Rで表示することができます。

[/Users/hiramekun/sample]
>> mkdir -p a/b/c
[/Users/hiramekun/sample]
>> ls -R
.  .. a

./a:
.  .. b

./a/b:
.  .. c

./a/b/c:
.  ..

Pythonでは

os.makedirs()によって再帰的に作成することができます。

import os
os.makedirs(os.path.join('a', 'b', 'c'))

HHKB Pro JPでKarabiner Elementsを設定する

事の発端

キーボードのリマッピングをしてくれるツールです。
自分のブログでもこの回で紹介しています。
hiramekun.hatenablog.com
ところが、先日HHKB Pro JPキーボードを買って設定したところ、以下のキーが押しても反応しなくなりました。

  • 英数キー
  • かなキー
  • 右command

結論と解決

専用ドライバのアンインストール、Karabiner Elementsのアンインストールなど試しましたが一向に状況は改善されず、泣く泣くKarabinerを使うことを諦めようと思った時でした。

同じ悩みを持った人のissueをKarabiner Elementsで発見!
For HHKB Professional JP keyboard, "right-cmd" and "lang" keys are not detected
f:id:thescript1210:20180318152734p:plain

この画像のようにSimple Modificationを設定したところ、めでたく上の3つのキーを認識してくれるようになりました。
f:id:thescript1210:20180318152907p:plain

Sierraで機械学習時に用いる物体検出用アノテーション作成

物体検出用データセット

概要

SSD, YOLO, Faster R-CNN等、物体検出のディープラーニングアルゴリズムは多々ありますが、それらの多くが学習時に「imagenetの重みで初期化→PASCAL VOCのデータセットで学習」という流れを踏んでいます。

PASCAL VOCは、The PASCAL Visual Object Classes Challenge 2007 (VOC2007) Development Kitに各アノテーションの説明が書いてあります。

データセットの例

アノテーションxmlファイル形式で、以下にその一部を挙げます。これは鳥が表示されている画像ですね。 大事なのは、どこに何が位置しているのかをきちんと説明できるフォーマットになっているところです。
f:id:thescript1210:20180318122852j:plain

  • 物体のクラス名(name)
  • 物体の座標(bndbox)
  • 写真そのもので判断できるか(difficult)
<annotation>
    <folder>VOC2007</folder>
    <filename>000040.jpg</filename>
    <source>
        <database>The VOC2007 Database</database>
        <annotation>PASCAL VOC2007</annotation>
        <image>flickr</image>
        <flickrid>97167996</flickrid>
    </source>
    <owner>
        <flickrid>ResQgeek</flickrid>
        <name>?</name>
    </owner>
    <size>
        <width>500</width>
        <height>332</height>
        <depth>3</depth>
    </size>
    <segmented>0</segmented>
    <object>
        <name>bird</name>
        <pose>Right</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>1</xmin>
            <ymin>52</ymin>
            <xmax>384</xmax>
            <ymax>290</ymax>
        </bndbox>
    </object>
</annotation>

自作のデータセットを作る

なぜ作る必要があるのか

VOCのデータセットにクラスがあればいいのですが、必ずしもあるとは限りません。
例えば、トラの物体検出を行いたいと考えた時に、トラのデータセットは存在していません。

その時は、自分で画像に対してbounding boxを作って1画像に対して1つのxmlファイルを作成しなければなりません。そのツールとして「物体検出用の画像アノテーション正解データ作成に便利なツール」で取り上げられていたものが見つかりました。
tzutalin/labelImg
f:id:thescript1210:20180318123606p:plain 手動で囲った結果を自動的にPASCAL VOCと同じ形式のxmlファイルとして出力、保存してくれます。

インストール

インストールですが、前述のサイトの通りに行ってもうまくいきませんでした。

$ brew install qt
$ brew install pyqt
$ make qt4py2
make: *** No rule to make target `qt4py2'. Stop.

こちらのissue(Installation in macOS SIerra: No rule to make target qt4py2. Stop.)と同様のエラーが出てmakeできません。pythonのversionやqtのversionを変更していじってみましたが、同様のエラーが出ます。

時間を取られすぎていたので、下のこちらの方が提示してくれているパッケージをインストールし、アプリとして使いました。
jiyeqian/labelImg labelImg_qt5py3_mac_latest
f:id:thescript1210:20180318125127p:plain

エラーが出ている理由をきちんと突き止めてはいない(3/18現在、githubのissueもopenのままです)ので、わかりしたいアップデートしたいと思います。

データ前処理で使うLinuxコマンドをまとめる

コマンドで分析する理由

データを処理するときに、やろうと思えばfinderから確認したり、エクセルで開いたりすることはできます。ですが、非常にファイルが大きくなり数GB程度にもなると、GUIで確認するのは非常に困難です。
実際に自分も1GB程度のデータが書き込まれたcsvファイルをエクセルで開こうとしましたが、エクセルがカクカクしてろくに作業することもできませんでした。

そう言った意味でも、CUIからデータを閲覧、操作できるようにしておきましょう。

ファイル閲覧

  • cat:ファイルを閲覧する。ファイルの中身全てがコマンドに表示されるので、大きなデータだと非常に読みにくくなります。
  • head:ファイル先頭10行表示する。
  • tail:データをファイル末尾10行表示する。
  • less:ファイルの中身を1画面後のに表示するコマンド。

文字コードの確認, 変更

①現在の文字コードを調べる
env | grep LANG で、現在の環境を読み込み、その中からgrepコマンドで文字コード設定のもののみを抽出します。

nkfコマンドを使う

  • ファイルの文字コードを確認する
    nkf -g hoge.csv
  • ファイルの文字コードUTF-8に変更して別ファイルに書き出す
    nkf -w hoge.csv > hoge_utf-8.csv

ここで、別ファイルに書き出す理由は、データ加工を間違えたときに元データからやり直せるようにするためです。

データの加工

①データを取得する
curl -s http://hoge > hoge.jsonと打って、APIからデータをダウンロードしてきます。

②ファイルを確認する
jsonファイルを取得したとします。jqコマンド(別途ダウンロードが必要です)を使うと、jsonファイルが見やすくなります。

# 例)hoge.jsonファイルを、色付きで行番号もつけて閲覧
$ json . hoge.json -C | less -NR

③データの加工

  • sed:文字列の置換や行の削除を簡単に行えるもの。
# 例)1行目から26行目まで削除する。
$ sed -e '1, 26d' hoge.csv > hoge_deleted.csv
  • awkcsvやtsvに対して、必要なデータだけを抽出するのに便利なもの。
# 特定の条件を満たした対象に対して処理ができる。
$ awk -F 区切り文字 '条件 {実行文}' ファイル名' 

参考

こちらの本を参考にしました。

データサイエンティスト養成読本 登竜門編 (Software Design plus)

データサイエンティスト養成読本 登竜門編 (Software Design plus)

10分でtmuxコマンドをまとめる

tmuxとは

端末多重化ソフトウェアと呼ばれます。pc内に仮想端末を立ち上げることができます。

機械学習をサーバーで走らせる時などは必須で、「sshログイン→tmux立ち上げる→学習走らせる→sshログアウト」としても、サーバー上で立ち上げた仮想端末が動き続けているので学習が止まることはありません。のちにログインしてもう一度その仮想端末にアタッチすることで、以前アタッチした時の状態の端末に入ることができます。

こちらの記事のtmuxとはという項目がとても参考になりました。
tmuxを使い始めたので基本的な機能の使い方とかを整理してみた

tmuxコマンド

# tmux新規セッション開始
$ tmux

# セッション名の名前のついたtmuxの仮想端末を新しく立ち上げます。
$ tmux new -s [セッション名]  

# セッション一覧表示
$ tmux ls

# セッションを再開する
$ tmux a

# セッションを名前をつけて再開する
$ tmux a -t [セッション名]

プレフィックスキーを用いた操作

デフォルトはctrl + bで、これを押した後に入力することで以下の操作が可能になります。

# セッションからデタッチ
d

# 横にペイン分割
%

# 縦にペイン分割
"

# ペイン間の移動
o

# ペインの破棄
x

# ペインの入れ替え
ctrl + o

# コピーモードに入る(履歴を遡ることができるようになります。)
[