Bashのブレース展開について

普段、ターミナルでコマンドを打ちはしますが、Bashスクリプトを書くことも読むこともあまりありません。ただ、必要とあれば読み書きできるつもりでいたのに他の人のコードを見ていて知らない記法に出会ったので、それについて調べたメモです。

見かけたのはこんな記述でした。

$ cp file.txt{,.backup}

みなさんはこれが何をしているかわかりますか?
実は上記のコマンドは以下のコマンドと同じ動きになります。

$ cp file.txt file.txt.backup

{}の中身が,で区切られて、0文字の文字列と「.backup」という文字列に分けられ、多項式の展開(因数分解の逆)のように、それぞれに file.txt がくっついて解釈されるのです。

このような記法をブレース展開(Brace Expansion)というそうです。ドキュメントはbashのマニュアル中にあります。 $man bash でマニュアルを開いて、 /Brace Expansion でマニュアル中を検索しましょう。

,(カンマ)区切りの単語群をそれぞれの単語に展開するというのが一番シンプルな動きです。また、数値や文字(1文字)であれば、{開始..終了}のようにして連番も生成できます。
また、面白いことに複数のブレース展開をくっつけると、数式の展開みたいなこともできます。

$ echo a{d,c,b}e
ade ace abe
$ echo {1..5}
1 2 3 4 5
$ echo {e..h}
e f g h
$ echo {1..3}{x..z}
1x 1y 1z 2x 2y 2z 3x 3y 3z

マニュアルを見ると、これを使って複数のディレクトリを作るサンプルなどが載っていますね。

$ mkdir /usr/local/src/bash/{old,new,dist,bugs}

これを実行すると、/usr/local/src/bash/ 配下に、old、new、dist、bugs、の4ディレクトリが作れるようです。
自分なら以下のように書きますが。

$ cd /usr/local/src/bash/
$ mkdir old new dist bugs

mv や cp のように 引数を2つ取るコマンドに対して、このブレース展開をさっと書けると確かにかっこいいかもしれないですね。特にmv やcpは既存のファイルに対する操作なので補完が効きます。
cp file.txt まで補完でさっと入力して {,.backup} をつけて実行と。
ただ、ファイルパスが短い場合、特にカレントディレクトリでの作業の場合は cp file.txt file.txt と補完で入力して .backup をつけるのと比べてどれほど手間の削減になっているのかと考えると微妙な気もします。

cdで該当ディレクトリにどうせずに深い階層にあるファイルをバックアップするときは確かに便利です。以下の例のような長いパスを2回書かずに済みます。

$ cp /Users/username/Documents/folder1/folder2/folder3/sample_file.txt{,.bk}

このブレース展開はbashのfor文の範囲指定でも使うことができます。というより、こちらの方が一般的な使い方だと思います。

$ for i in {1..5}
> do
> echo $i
> done
1
2
3
4
5

正確では無いかもしれませんが、このfor文の記法の{1..5}の部分にブレース展開という名前がついていて実は他のコマンドの引数を生成するのにも使えますよ、と理解するのが良いように思っています。

MeCabのIPA辞書の中身を確認する

前々から形態素解析の仕組みやMeCabの細かい挙動に興味があり、最近色々調べたりいじったりしています。その中で、普段使っているIPA辞書にどんな単語がどんな設定で登録されているのか見てみたくなったのでその時のメモです。主に文字コードの影響でダウンロードして開いたらみれました、とはいかなかったので記事にしました。そのため、この記事の内容は実質にテキストファイルの文字コードを変換する話です。

そもそも、IPA辞書僕はIPA辞書はコンパイル済みのものをHomebrewで入れてたので、元ファイルを見たことがなったのです。
参考: MacにMeCabをインストールする

まず、IPA辞書の入手ですが、MeCabのドキュメントのこちらのページにダウンロード先のリンクが貼ってあります。
参考: MeCab: Yet Another Part-of-Speech and Morphological Analyzer (ダウンロードの所)
直接ダウンロードする場合はこちら: ダウンロード

ダウンロードすると mecab-ipadic-2.7.0-20070801.tar.gz というファイルが入手できます。
Windowsのかたは、Lhaplus などの解凍ソフトで展開しましょう。Macの場合はダブルクリックで解凍できます。

解凍したフォルダに多くのファイルが含まれていますが、この中の{品詞名の英語表記}.csv ファイルたちが目当ての語彙ファイルです。

これをvimなどのエディタで開くと何やら文字化けして読めめません。Macでは開けないのかと思ってWindowsのメモ帳やエクセル等でも試したのですが同様に文字化けしてしまって読めないファイルでした。

file コマンドに –mime オプションをつけると、ファイルの文字コードを調べられるのでやってみた所、文字コードは iso-8859-1 だと出てきました。

$ file --mime Adj.csv
Adj.csv: application/csv; charset=iso-8859-1

これが罠でした。iso-8859-1 を開けばいいのだと思って、vimを起動し、ファイル読み込み時の文字コードを iso-8859-1 に設定し、同じファイルを開いてみた所、結局文字化けしたままでした。どうやら、本当の文字コードは EUC-JP だそうです。(fileコマンドで、iso-8859-1 が返ってきた理由は今でも不明です。)

そこで、vimの読み込み時の文字コードに、EUC-JPを追加します。

# 例として形容詞の辞書をvimで開く(この段階では文字化け。)
$ vim Adj.csv
# vimのコマンドで現在の設定を確認
:set
# 僕の環境では、以下が設定されていました。
  fileencoding=utf-8
  fileencodings=ucs-bom,utf-8,default,latin1
# 読み込み時の判定は、fileencodings を順に試すので、EUC-JPを追加
: set fileencodings=EUC-JP,ucs-bom,utf-8,default,latin1
# ファイルを再読み込み
: e

これでcsvファイルの中身を読むことができました。
EUC-JPを追記する位置ですが、fileencodings の末尾に追記すると先にutf-8で開いてしまって結局読めないので、utf-8より前に書く必要があります。.vimrc に書く方法もあるのですが、正直、utf-8よりEUC-JPを優先する設定を恒久的に入れるのは弊害が大きそうなのでお勧めしません。setコマンドで都度入れるか、.vimrcに入れるとしても不要になったら消した方が良いでしょう。

ほぼ裏技的な方法なのですが、Chromeなどのウェブブラウザを使って読むこともできました。.csvのままだと、ブラウザにドラッグ&ドロップした時にそのファイルをダウンロードしてしまうのですが、拡張子を.txt に変えてChromeにドラッグ&ドロップすると、正常に読める形で開いてくれます。

さて、これでエディタやブラウザで開くことができたのですが、肝心のファイルがそのままだと、 grep などで検索することができず結構不便です。

そこで、 iconv というコマンドで変換しましょう。(他にも nkf というツールもあるそうです。MacにはHomebrewで導入が必要。)
一番基本的な使い方以下の通りです。

$ iconv -f ENCODING -t ENCODING INPUTFILE
# -f: 元の文字コード (今回は EUC-JP)
# -t: 出力する文字コード (今回は UTF-8)

ただ、このまま使うと変換結果を標準出力にダーっと出して終わってしまうので、別ファイルにリダイレクトします。(他サイトで -o オプションで出力先を指定できる、と書いてあったのですが、僕のMacのiconvのドキュメントには-o オプションの記載がなく試しても動作しませんでした。)

$ iconv -f EUC-JP -t UTF-8 Adj.csv > utf8_Adj.csv

元ファイルとリダイレクト先ファイルを同じにして実行すると中身が消えてしまったので、上記の通り一旦別ファイルに書き出す必要があります。

find . -f あたりでファイル名の一覧を取得して、 vimか何かでそれを加工して上記のコマンドを一通り作って走らせましょう。
元のファイル名を使いたい場合は、 utf8_hoge.csv たちを hoge.csv へ上書きmvさせればOKです。

と、ここまで書きましたが結構やってみると結構面倒でした。(全ては僕のMacのiconvコマンドが-oオプションを持ってないせいですが。)

やはりnkf コマンドを使う方法も紹介しておきます。
nkf は Macには標準で入ってないので Homebrewでインストールします。

# インストール
$ brew install nkf
# インストールできたのでバージョンの確認
$ nkf --version
Network Kanji Filter Version 2.1.5 (2018-12-15)
Copyright (C) 1987, FUJITSU LTD. (I.Ichikawa).
Copyright (C) 1996-2018, The nkf Project.

まず、 -g オプションでファイルの文字コードを調べられます。

$ nkf -g Adj.csv
EUC-JP

正しくEUC-JPが出力されました。これは頼りになります。

文字コードを変換する場合は、 -w で UTF-8 に変換してくれ、 –overwrite オプションがあると元のファイルをそのまま書き換えます。

$ nkf -w --overwrite Adj.csv

これで、Adj.csv がさっとvimで開けるようになりまししたし、grepで中を検索できるようになりました。

あとはこれを全ファイルに適応すれば良いのですが、以前紹介したfindを使ったテクニックがあるのでそれを使いましょう。
参考: ディレクトリやファイルの権限を一括で修正する

$ find . -type f -exec nkf -w --overwrite {} +

さて、これで IPA辞書の関連ファイル全部が UTF-8に変換され、中身が確認しやすくなりました。

最後に注意ですが、ここで文字コードを変換したファイル群はあくまでもそのまま中身を検索したり確認する目的で使いましょう。
というのもこれをコンパイルとして辞書として使う場合、コンパイル時に文字コードを指定するオプションがあり、それを意識せずに、EUC-JPのファイルが使われている前提で動かしてしまうと危険だからです。(Makefile.amや、Makefile.in といったファイル内に、 EUC-JPとハードコーディングされている部分があります。)
その辺まで理解して必要な変更を加えてコンパイルするするのであれば大丈夫だと思いますが、不要な手間とリスクだと思うので、コンパイルして使う場合は文字コードを変更する前の状態を使いましょう。

sedコマンドの使い方メモ

テキストの編集は大抵vimでやっちゃうので滅多に使わないのですが、稀にコマンドラインでファイルの置換を完結させたり、一つのテンプレートファイルから中身を一部置換したファイルを複数生成する必要が発生し、それをコマンドラインで済ませたいことがあります。
そんなときに、sed (Stream Editor) コマンドを使うのですが、その度に使い方を調べているのでここメモしておきます。

基本的な使い方は、
sed -e {編集コマンド} {入力ファイル}
です。パイプラインで利用する場合は{入力ファイル}を省略できます。
ファイル中の aaa を xxx に置換する場合は次のように書きます。

$ cat input.txt
aaa,bbb,ccc
ddd,eee,fff

$ sed -e s/aaa/xxx/g input.txt
xxx,bbb,ccc
ddd,eee,fff

-e は省略可能で、省略した場合は最初の引数が編集コマンドとみなされます。
なので、大抵の場合は -e を省略して大丈夫です。

$ cat input.txt | sed s/aaa/xxx/g
xxx,bbb,ccc
ddd,eee,fff

-e オプションは複数指定することもできて、同時に複数の置換をかけることもできます。

$ sed -e s/aaa/xxx/g -e s/bbb/yyy/g input.txt
xxx,yyy,ccc
ddd,eee,fff

編集コマンドは、シングルクオーテーション、もしくはダブルクオーテーションで囲むこともできます。(置換前後の文字列のどちらかにスペースを含む場合は、確実に囲むようしましょう。そうしないとエラーになります。)

$ sed "s/aaa/X Y G/g" input.txt
X Y G,bbb,ccc
ddd,eee,fff

置換結果を別のファイルに出力する時は、他のシェルコマンド同様にリダイレクションしてあげれば大丈夫です。僕はもっぱらその形で使います。
例えば、 input.txt の aaa を xxx に置換した output.txt を生成するには次のようにします。

$ sed "s/aaa/xxx/g" input.txt > output.txt

元のファイルをそのまま書き換えることもでき、その場合は
-i {拡張子} オプションをつけます。
すると、{元のファイル名}{拡張子} というファイル名でバックアップを取った上で、入力ファイルを書き換えてくれます。
バックアップはいらないよという場合は、拡張子として長さ0の文字列を渡します。

$ sed -i '' -e 's/aaa/xxx/g' input.txt

この時、” をつけ忘れると、 input.txt-e という変な名前のファイルが残ってしまうので注意してください。

多くの編集コマンドを同時に実行したい場合などは、編集コマンドをまとめたファイルを用意しておき、それを -f オプションで渡すこともできます。

$ cat edit.sed
s/aaa/xxx/g
s/bbb/y y y/g
s/ccc/zzz/g

$ sed -f edit.sed input.txt
xxx,y y y,zzz
ddd,eee,fff

あとは、入力ファイルはスペース区切りで複数同時に渡すことも可能です。
-i オプションをつけている場合は、渡した入力ファイルたちがそれぞれ編集されます。
-i オプションがない場合は、それぞれのファイルを編集した結果が連結されて標準出力に返されます。

sed コマンドで文字列を置換することに関して主に知っておくべきことはこれくらいかなと思います。

tensorflow-textのインストールに苦戦した話

conda / pip の混在にこだわらなければ、もしくは初めから pipのみで環境を作っていれば何も問題がなかったのですが、
予想外に大苦戦してしまったので tensorflow-text のインストールについてメモしておきます。
(この記事は 2020年5月5日 時点の話です。近い将来のうちに、conda install でさっと入るようになるのを期待します。)

さて、そもそも変な苦労をする羽目になった背景から説明します。
condaの基本的な使い方 という記事で書いたとおり、今使っている環境はできるだけcondaのみで構築しています。
そして、 Tensorflow-Hub にある、 universal-sentence-encoder-multilingual というモデルを試したくなりました。

これを使うのに、 tensorflow_hub と tensorflow_text というライブラリをインポートする必要があります。
tensorflow_hub は 簡単です。
$ conda install tensorflow-hub
で入ります。 (インポート時とインストール時でアンダーバーとハイフンが変わる罠はありますがそれだけです。)

一方、 tensorflow_text ですが、 これが conda の公式リポジトリにも、 conda-forgeにも存在しません。
それだけならいいのですが、 conda skeleton でもエラーが出ます。
(conda skeleton についてはこちら。)


$ conda skeleton pypi tensorflow-text
# ~~ (中略) ~~
Error: No source urls found for tensorflow-text

いろいろ調査しましたが、原因は分からずとりあえず今回は condaでのインストールを諦めることにしました。

これだけ pip で入れることにしたのですが、ドキュメントにあるとおり、
>$ pip install tensorflow-text
すると、1点困ったことになります。
condaで入れていた、tensorflowなどの複数の依存ライブラリをアンインストールしてpipで入れ直してしまうのです。
(僕が確認した範囲だと7つほど影響を受けました。)
これだと、pipとcondaが大きく混在した環境になります。

ということで、pipで入ってしまったライブラリは一旦pipで消して、condaで入れ直します。

そして、次に試みたのが、 依存ライブラリを入れない no-deps オプションです。
$ pip install --no-deps tensorflow-text

これで綺麗にさっと入ったのですが、これでもまだ問題があり、jupyterで動かすとすぐにkernelが死んでしまうようになりました。
エラーを調査すると、ライブラリの依存関係に問題があったようです。(依存関係無視してインストールしたので当然ですね。)
pip check で確認すると、次のように出ました。


$ pip check
tensorflow-text 2.1.1 has requirement tensorflow<2.2,>=2.1.0, but you have tensorflow 2.0.0.

tensorflow のバージョンを上げればいいかと思ったのですが、
$ conda search tensorflow
で調べてみるとまだ condaには2.0.0しかありません。

ということで、次に tensorflow-text の方を古いものに入れ替えることにしました。pip uninstallして消した後、
$ pip install tensorflow-text==1.15.1 --no-deps

今度は tensorflowが新しすぎるからダメだとのことでした。


$ pip check
tensorflow-text 1.15.1 has requirement tensorflow<1.16,>=1.15.0, but you have tensorflow 2.0.0.

最終的に、バージョン2.0.1なら問題ないようでした。


$ pip install tensorflow-text==2.0.1 --no-deps
# ~~ (中略) ~~
Installing collected packages: tensorflow-text
Successfully installed tensorflow-text-2.0.1

$ pip check
No broken requirements found.

本来ならライブラリは新しいバージョンを使っていくべきですし、
condaについてしっかり理解していれば、condaでインストール方法もありそうです。

なので、この記事の内容は全く推奨できず、真似される場合は自己責任でお願いしますとしか言いようがないのですが、
とりあえず自分の環境にはこうやって入れた、というメモとして記録させていただきました。

やってることは最終的に次の1行だけなのに、とても疲れました。
$ pip install tensorflow-text==2.0.1 --no-deps

PyPIのパッケージをcondaでインストールする方法

前回の記事で、condaの公式リポジトリとconda-forgeを探して、それでも見つからなかったパッケージは環境を分けてpipで入れるという話を書きましたが、
一応、PyPIのパッケージをcondaで入れる方法は存在します。

それが、自分でcondaバッケージをビルドする方法で、(スムーズに進めば)具体的には次の手順でできます。
(前回の記事の反省を踏まえてさっさとコマンドを載せておきます。)


conda skeleton pypi [パッケージ名]
conda build [パッケージ名]
conda install --use-local [パッケージ名]

ドキュメントはこちら:Conda-build documentation

試しにこのブログを書くのに欠かせない pycodestyle_magic を入れてみます。これはcondaの公式リポジトリにもconda-forgeにも今日時点では存在しません。
準備として、必要なパッケージである、次の3つをcondaで入れておきます。
これがconda install の場合との大きな違いで、依存するライブラリは事前自分で入れておかないとエラーになります。
flit はこれが何かよく理解していないのですが、入れておかないとビルドする時に、 No module named ‘flit’ というエラーが出ました。


conda install pycodestyle
conda install flake8
conda install flit

さて、準備できたら次のコマンドを順番に実行します。


conda skeleton pypi pycodestyle_magic
conda build pycodestyle_magic
conda install --use-local pycodestyle_magic

conda skelton を実行した段階で、カレントディレクトリ直下に、meta.yamlファイルを含むディレクトリが出来上がります。


$ ls
pycodestyle_magic
$ ls pycodestyle_magic/
meta.yaml

次のconda build も成功するはずだったのですが、結局エラーが出たので対応します。
(3行目の conda installはまだ実行できず。)

出たエラーはこれ。


ModuleNotFoundError: No module named 'flit'

事前にインストールしているのに見つけられていないようです。
meta.yamlファイルを開いて、追記してみます。
(numpyで似たようなことをして解決している人がいたので真似しました。結果的に成功したようです。)


vim pycodestyle_magic/meta.yaml

#requirements の host: と run: に - flit を追記して保存。

requirements:
  host:
    - pip
    - python
    - flit
  run:
    - python
    - flit

さて、もう一回、conda build pycodestyle_magicすると成功しました。


####################################################################################
Resource usage summary:

Total time: 0:00:23.6
CPU usage: sys=0:00:00.3, user=0:00:00.6
Maximum memory usage observed: 75.1M
Total disk usage observed (not including envs): 264B


####################################################################################
Source and build intermediates have been left in /Users/[ユーザー名]/.pyenv/versions/[インストールしたAnacondaのディレクトリ]/conda-bld.
There are currently 1 accumulated.
To remove them, you can run the ```conda build purge``` command

メッセージにある通り、Anacondaのインストールフォルダ配下にビルドのアウトプットは移動しており、
さっきのmeta.yamlファイルがあった所の中身はそのままです。

conda-bld/ の下には、 pycodestyle_magic_1582538942427 というディレクトリができていて、よくわからないファイルがあります。

さて、buildが成功したので最後にインストールです。
(紛らわしい書き方して済みませんが、Anacondaのディレクトリではなく、skeletonやbuildしたのと同じディレクトリでそのまま)


# 今度は成功する。
conda install --use-local pycodestyle_magic

# インストール結果の確認
$ conda list | grep pycodestyle
pycodestyle               2.5.0                    py37_0
pycodestyle_magic         0.5                      py37_0    local

結果確認は、わかりやすいように普通にcondaで入れたpycodestyleも表示しましたが、
このskeletonを使う方法で入れたパッケージは local マークがつきます。

最後に後片付けです。
カレントディfレクトリに、skeletonでできた meta.yamlファイルが入ったディレクトリがあると思いますが、
インストールが終わったら不要なので消してよいと思います。
また、
conda build purge コマンドで、
[Anacondaのインストールディレクトリ]/conda-bld
にできていた一次ファイルたちを消せます。


rm -r [パッケージ名]
conda build purge

あとは入れたパッケージを使うだけです。
今回はjupyterのmagicコマンドだったので、
%load_ext pycodestyle_magic

%%pycodestyle
をそれぞれ試しました。

これで、conda-forgeにもないパッケージもPyPIからインストールできました。

condaの基本的な使い方

PyCon JP 2019 に参加して、
Anaconda環境運用TIPS 〜Anacondaの環境構築について知る・質問に答えられるようになる〜
という講演を聞いてから、自分の環境がcondaとpipの混在状態で結構リスキーだったことが懸念でした。
参考: 資料のページ

(実際何度も環境壊れていますし。)
会社で使っている端末では環境を極力condaのみで作り直していたのですが、実は自宅の端末では相変わらず混在していました。
そんな時に先日、SSDが壊れてMBPを修理に出す機会があり、完全に初期化されたので今回はできる限りpipを使わないように作り直しました。

まず、Anaconda入れるところまでは昔の記事の通りです。
参考: Macにpyenvとanacondaをインストールする

これまではこの後pip install [ライブラリ名]で、どんどんライブラリを入れていましたが、これはとても危険な行為です。
condaとpipの仕組みには互換性がないからです。

condaのドキュメントにも Using pip in an environment というセクションで注意事項が書かれています。
要約すると、pipを使うなら環境を分けることと、condaでできるだけ多くのライブラリをインストールした後に残りをpipで入れるべきということです。

免責事項
さて、ここからcondaの説明など書いていきますが、僕自身がパッケージの開発者でもなく、環境構築等を専門にするエンジニアでもないただのユーザーなので、
とりあえず自分はこういう理解で使っています、というレベルの内容になります。
厳密には各自公式のドキュメントを確認の上、自己責任でご利用お願いします。
(どちらかというと、他の記事の pip install 〜と書いてるところにこそ、この免責事項が必要ですね。)

さて、 pip と conda ですが、どちらもパッケージマネージャー(パッケージを管理するツール)です。
そして管理の方法が違い、互換性がないので混ぜると二重管理になって競合し、環境の破壊等が発生しえます。

インターネット上のリポジトリで管理されているパッケージを手元の端末に追加したりアップデートしたりできるのですが、
その大元になるリポジトリが違います。
pip は PyPI 、で、 condaはrepo.anaconda.comです。

condaの最大のデメリットが、PyPIに比べてrepo.anaconda.comで配布されているパッケージの少なさだと思います。
この点を補うために、condaでは別の場所(チャンネル)からもパッケージを追加できます。
特に conda-forge は比較的充実しているのでオススメです。
ドキュメントの中でも紹介されているので安心して使えるかと思います。
参考: Conda channels

余談ですが、Python初心者の頃、-c conda-forgeの意味がわからなかったのもcondaを敬遠した理由でした。
要はconda公式リポジトリにそのパッケージはないけど、ユーザーグループが管理している conda-forge にはある時にこれを使います。

さて、チートシートに主なコマンドはまとまっているので、詳しいことはそちらを見てもらうとして、自分がいつもやっている手順を紹介します。

最初にインストールしたいパッケージの名前を確認しておきます。


# インストール済みのパッケージの中に、該当のパッケージがないことを確認する。(必要に応じてgrep)
conda list
# 公式リポジトリ内に存在するかどうか確認
conda search [パッケージ名]
# 公式リポジトリにあったらそこからインストール
conda install [パッケージ名]
# 公式リポジトリになかったら conda-forge 内を検索
conda search -c conda-forge [パッケージ名]
# conda-forgeに存在したらそこからインストール
conda install -c conda-forge [パッケージ名]
# バージョンを指定したいときは==の後ろにバージョン番号を指定
conda install [パッケージ名]==[バージョン番号]

また、インストール済みのパッケージのアップデートとアンインストールは次です。


# アップデート
conda update [パッケージ名]
# アンインストール
conda uninstall [パッケージ名]

前置きが長くなって、記事が冗長になってしまったので一旦ここまで。
次はconda-forgeでも見つからないライブラリをPyPIからcondaで入れることのできる、
conda buildや conda skeletonについて紹介したいです。

Mac に LightGBMをインストールする

手順のメモです。

公式ドキュメントにイストールガイドがありますが、実は使うのはこちらではありません。
Installation Guide

僕はpythonから使う予定なので、Githubのリポジトリの方を読んで作業します。
LightGBM Python-package

次のコマンドを順番に実行します。


brew install libomp
pip install wheel
pip install lightgbm

自分の環境では wheel はすでにインストールされているという趣旨のメッセージが出ました。


$ pip install wheel
Requirement already satisfied: wheel in ./.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages (0.31.1)

これでインストールできたはずなのですが、インポートしてみると次の警告がでます。


$ python
>>> import lightgbm
/Users/xxxxxx/.pyenv/versions/anaconda3-5.2.0/lib/python3.6/site-packages/lightgbm/__init__.py:46: UserWarning: Starting from version 2.2.1, the library file in distribution wheels for macOS is built by the Apple Clang (Xcode_8.3.3) compiler.
This means that in case of installing LightGBM from PyPI via the ``pip install lightgbm`` command, you don't need to install the gcc compiler anymore.
Instead of that, you need to install the OpenMP library, which is required for running LightGBM on the system with the Apple Clang compiler.
You can install the OpenMP library by the following command: ``brew install libomp``.
  "You can install the OpenMP library by the following command: ``brew install libomp``.", UserWarning)

Warningは出るものの、動作に問題はなさそうなので一旦はこのまま使うおうと思っています。
とはいえ気持ち悪いのでいつか直したいです。
brew install libomp は実行してるし、 brew list すると、libompは出てくるのですけどね。

Xcodeがどうのこうのと書かれているので、以下の記事で行なったcommand Line Toolsのインストールが影響してるような気もします。

Mac(Mojave) に pip で mecab-python3をインストールする時にはまった

pyenvで作成した環境を消す

うまくインストールできないライブラリがあり、
pipで入れたり消したり、condaで入れたり消したりとやっていたら何やら全体的に環境がおかしくなってしまいました。
(またかよという感じですが。)

しかたがないので、その環境は消して作り直すことにしました。
pyenv uninstall で環境は消せます。
参考 : pyenv uninstall


# 確認
$ pyenv versions
  system
* anaconda3-5.2.0 (set by /Users/******/.pyenv/version)

# 利用するpythonの環境をsystemのものに戻す。
$ pyenv global system
$ python --version
Python 2.7.10

# 不要になった環境を消す
$ pyenv uninstall anaconda3-5.2.0
# もう一度入れ直し
$ pyenv install anaconda3-5.2.0
$ pyenv global anaconda3-5.2.0
$ python --version
Python 3.6.5 :: Anaconda, Inc.

あとはこのブログで pip で検索して、うまくインストールできていたものを順に入れていけば元に戻るはず。
そもそも、anacondaで作った環境でcondaではなくpipを使ってるのがトラブルの原因でもあるのですが、
condaとpipの違いとか使い分けとか十分理解できてないので、どうしてもpipの方使っちゃいます。
この辺りはいつかしっかり勉強したい。

mecabの新語辞書をインストールする

非常に便利な形態素解析ソフトMeCabですが、デフォルトの辞書は最近登場した単語に弱いと言う欠点があります。
自分で辞書を改善していけたらいいのですがそれも工数が大きくめんどくさい。

以上の状況において、定期的にメンテナンスされている非常にありがたい辞書があります。
mecab-ipadic-neologd

インストール手順はリポジトリの README.ja.mdにある通りです。


$ cd ~/Downloads
$ git clone --depth 1 https://github.com/neologd/mecab-ipadic-neologd.git
$ cd mecab-ipadic-neologd
# -a をつけると全部入り
$ ./bin/install-mecab-ipadic-neologd -n -a

途中で
Do you want to install mecab-ipadic-NEologd? Type yes or no.
と聞かれるのでこれは yes.

ドキュメントにある通り、インストール先は次のコマンドで確認できます。
(出力は僕の環境の例)


$ echo `mecab-config --dicdir`"/mecab-ipadic-neologd"
/usr/local/lib/mecab/dic/mecab-ipadic-neologd

動作確認してみましょう。
まずデフォルト辞書の場合。


~$ mecab
志村五郎先生は偉大な数学者でした。
志村	名詞,固有名詞,人名,姓,*,*,志村,シムラ,シムラ
五郎	名詞,固有名詞,人名,名,*,*,五郎,ゴロウ,ゴロー
先生	名詞,一般,*,*,*,*,先生,センセイ,センセイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
偉大	名詞,形容動詞語幹,*,*,*,*,偉大,イダイ,イダイ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
数学	名詞,一般,*,*,*,*,数学,スウガク,スーガク
者	名詞,接尾,一般,*,*,*,者,シャ,シャ
でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS

neologdの場合


~$ mecab -d /usr/local/lib/mecab/dic/mecab-ipadic-neologd
志村五郎先生は偉大な数学者でした。
志村五郎	名詞,固有名詞,人名,一般,*,*,志村五郎,シムラゴロウ,シムラゴロー
先生	名詞,一般,*,*,*,*,先生,センセイ,センセイ
は	助詞,係助詞,*,*,*,*,は,ハ,ワ
偉大	名詞,形容動詞語幹,*,*,*,*,偉大,イダイ,イダイ
な	助動詞,*,*,*,特殊・ダ,体言接続,だ,ナ,ナ
数学者	名詞,固有名詞,一般,*,*,*,数学者,スウガクシャ,スーガクシャ
でし	助動詞,*,*,*,特殊・デス,連用形,です,デシ,デシ
た	助動詞,*,*,*,特殊・タ,基本形,た,タ,タ
。	記号,句点,*,*,*,*,。,。,。
EOS

志村五郎先生の名前が固有名詞として認識されていますね。
数学者も。

cloneしてきた辞書ファイルの中を見るとこのように登録されていることがわかります。


mecab-ipadic-neologd$ grep 志村五郎 * -r
build/mecab-ipadic-2.7.0-20070801-neologd-20190610/mecab-user-dict-seed.20190610.csv:志村五郎,1289,1289,4757,名詞,固有名詞,人名,一般,*,*,志村五郎,シムラゴロウ,シムラゴロー

ディレクトリやファイルの権限を一括で修正する

職場で使っている端末の調子が悪く、新端末に交換することになったので大量のファイルを移行しました。
その際、一度NASにファイルを移して持って行ったのですが、
なぜかファイルやディレクトリの権限が全部 777 になってしまうと言う面倒な事態になりました。

chmod で一つ一つ直すのが面倒だったので一括で修正するコマンドがわかったので紹介します。

前提として、カレントディレクトリ”.”配下のすべてのファイルとディレクトリを対象に、
ファイルは644、ディレクトリは755に設定するには次のコマンドを実行します。
カレント以外を対象にする場合は、”.” の代わりにそのPathを入力したらできます。


find . -type d -exec chmod 755 {} +
find . -type f -exec chmod 644 {} +

一応解説。
find . -type d
と、
find . -type f
はそれぞれ、カレントディレクトリ配下の ディレクトリとファイルの一覧を取得します。
そして、 -exec はその後ろに書かれたコマンドを{}を find で見つけたpathに置換して実行します。
+ をつけておくと、各ファイル/ディレクトリに対してコマンドを個別に実行するのではなく、
まとめて実行してくれます。

詳細は man find で、マニュアルを読むのが確実です。