pandasのseriesをintへ変換


import pandas as pd
df = pd.DataFrame({'age': [24, 42], 'state': ['NY', 'CA'], 'point': [64, 92]},index=['Alice', 'Bob'])
df
       age state  point
Alice   24    NY     64
Bob     42    CA     92

これからpointの値をとる


val=df["point"]
type(val)

Seriesとなり,Intでは所得できない

valuesをつければNumpyのarrayとして取得できる。


val.values
array([64, 92])

type(val.values)


val.values[0]
64

AWSlambdaでkerasを動かす

AWSのlambdaはサーバレスアーキテクチャで非常に扱いがいいのですが、一つ難点があって、アップロードできるファイルサイズが限られていることです。
最大50MのZIPファイルまでなのですが、裏技を使って展開時に500M以上のファイルを使うことができます。

そのカラクリは、Lambdaの/tmp以下は500Mまで使うことができます。この領域に、Lambdaが起動するときにファイルをS3から読み込めば、非常に大きなライブラリが必要なプログラムも動かすことができます。
以下は、pythonにてkeras+tensorflow+opencvを動かすサンプルです。

ライブラリ準備

python3を使用します。
ライブラリは、あらかじめ、EC2でAmazonLinuxを使って作成しておきます。

requirements.txt

keras
opencv-python
tensorflow
numpy
mkdir lib
pip3 install -U -r requirements.txt -t lib

このlib以下にライブラリがインストールされます。

find lib -name "*.pyc" -exec rm -rf {} ¥;

pycは削除しておきます。しなくてもいいですが。。。

これを全てLambdaの起動時に追加してもいいのですが、ロードが面倒になるので2つに分けます。

mv lib lib_other
mkdir lib
cd lib_other
mv cv2* ../lib
mv h5py* ../lib
mv keras* ../lib
mv tensor* ../lib
cd ..

libを固めてS3にアップ

zip -r lib.zip lib
aws s3 cp s3://bucketname/

lambdaディレクトリ

lambda用のディレクトリに、先ほど分けたlib_otherのライブラリを入れておきます。
これ全部を入れてようやく50Mぐらいまでに収まります。

mkdir lambda_dir
cd lambda_dir
mkdir vendor
cd vendor
cp -pr ../../lib_other/* .

lambdaプログラム

lambdaのプログラムには少し工夫が必要です。
起動時に、S3から先ほどアップしたlib.zipをダウンロードし展開、ロードします。

lambda_functioy.py


import sys
import os
sys.path.append(os.path.join(os.path.abspath(os.path.dirname(__file__)), './vendor'))

import boto3
import zipfile
import importlib

def lambda_handler(event, context):
    s3 = boto3.resource("s3")

    def load_zip(file):
        print("load_zip:"+file)
        s3.Bucket(bucket_name).download_file(libfiledir+"/"+file,"/tmp/"+file)
        with zipfile.ZipFile("/tmp/"+file) as zip:
            zip.extractall("/tmp")
        os.remove("/tmp/"+file)

    if os.path.exists("/tmp/lib") is False:  # 2回目以降はスキップ
        load_zip("lib.zip")

    sys.path.append('/tmp/lib')
    importlib.import_module("numpy")
    importlib.import_module("scipy")
    importlib.import_module("six")
    importlib.import_module("yaml")
    importlib.import_module("enum")
    importlib.import_module("h5py")
    importlib.import_module("absl")
    importlib.import_module("astor")
    importlib.import_module("bleach")
    importlib.import_module("external")
    importlib.import_module("gast")
    importlib.import_module("google.protobuf")
    importlib.import_module("grpc")
    importlib.import_module("html5lib")
    importlib.import_module("markdown")
    importlib.import_module("werkzeug")
    importlib.import_module("wheel")
    importlib.import_module("cv2")
    importlib.import_module("tensorflow")
    importlib.import_module("keras")

    import cv2
    import keras
    import numpy as np

こんな感じでコードを書きます。
Lambdaは一度起動すると、しばらくはインスタンスが残っているので、2回目以降に再度S3からダウンロードするのを防ぎます。

こんな感じで、500M以上のモジュールをつかったLambdaファンクションが作ることができます。

multivariate regressionをkerasで

複数出力の回帰をKerasで行います。

通常、回帰分析は複数の説明変数に一つの目的変数なのですが、これは、複数の目的変数を取ることができます。
multivariateとmultivariableの違いはこのあたりを参照のこと。

コードはこちらを参考にこんな感じ。


import numpy as np
from keras.layers import Dense,Activation
from keras.models import Sequential
model = Sequential()
model.add(Dense(16, input_shape=(1,)))
model.add(Activation('relu'))
model.add(Dense(16, input_shape=(1,)))
model.add(Activation('relu'))
model.add(Dense(2))
model.compile(loss='mean_squared_error', optimizer='Adam')


inputs = np.zeros((10, 1), dtype=np.float32)
targets = np.zeros((10, 2), dtype=np.float32)

for i in range(10):
    inputs[i] = i / 10.0
    targets[i, 0] = 1.0-0.1 * i / 2.0
    targets[i, 1] = 0.01 * i

model.fit(inputs,targets,epochs=200,batch_size=5)

print(targets)
print(model.predict(inputs))


結果

[[1.   0.  ]
 [0.95 0.01]
 [0.9  0.02]
 [0.85 0.03]
 [0.8  0.04]
 [0.75 0.05]
 [0.7  0.06]
 [0.65 0.07]
 [0.6  0.08]
 [0.55 0.09]]
[[0.88971126 0.00797045]
 [0.9289691  0.02162787]
 [0.8843044  0.02890772]
 [0.8396398  0.03618753]
 [0.7949753  0.04346737]
 [0.7503106  0.0507472 ]
 [0.70564604 0.058027  ]
 [0.6609814  0.06530684]
 [0.61631685 0.07258669]
 [0.57165223 0.0798665 ]]

ちゃんと学習できているようです

R.3.4.3にmxnetをインストール

mxnetのインストールがエラーになるのでその対処方法

環境

mxnetを使用する際に,インストール方法が公式サイトにも書いているのですが,
その方法ではインストール時にエラーが出ます。使っている環境がMacだからなのかもしれませんが。。

  • OS:MacOS 10.13.3
  • R 3.4.3 brewでインストールしたもの

この環境で下記コマンドでインストール

> install.packages("mxnet", type = "el-capitan.binary")
Installing package into ‘/usr/local/lib/R/3.4/site-library’
(as ‘lib’ is unspecified)
Warning in install.packages :
  package ‘mxnet’ is not available (for R version 3.4.3)

どうやらVersionがあっていないようでインストールできないようです。
ググっていろいろなやり方を試したのですがダメ。

> cran <- getOption("repos")
> cran["dmlc"] <- "https://s3-us-west-2.amazonaws.com/apache-mxnet/R/CRAN/"
> options(repos = cran)
> install.packages("mxnet")
Installing package into ‘/usr/local/lib/R/3.4/site-library’
(as ‘lib’ is unspecified)
 URL 'https://s3-us-west-2.amazonaws.com/apache-mxnet/R/CRAN/src/contrib/mxnet_0.10.1.tar.gz' を試しています 
Warning in install.packages :
  cannot open URL 'https://s3-us-west-2.amazonaws.com/apache-mxnet/R/CRAN/src/contrib/mxnet_0.10.1.tar.gz': HTTP status was '404 Not Found'
Error in download.file(url, destfile, method, mode = "wb", ...) : 
   URL 'https://s3-us-west-2.amazonaws.com/apache-mxnet/R/CRAN/src/contrib/mxnet_0.10.1.tar.gz' を開けません 
Warning in install.packages :
  download of package ‘mxnet’ failed

> install.packages("mxnet", type = "mac.binary")
Installing package into ‘/usr/local/lib/R/3.4/site-library’
(as ‘lib’ is unspecified)
Warning in install.packages :
  unable to access index for repository https://cran.rstudio.com/bin/macosx/contrib/3.4:
   URL 'https://cran.rstudio.com/bin/macosx/contrib/3.4/PACKAGES' を開けません 
Warning in install.packages :
  unable to access index for repository https://s3-us-west-2.amazonaws.com/apache-mxnet/R/CRAN/bin/macosx/contrib/3.4:
   URL 'https://s3-us-west-2.amazonaws.com/apache-mxnet/R/CRAN/bin/macosx/contrib/3.4/PACKAGES' を開けません 

   package ‘mxnet’ is available as a source package but not as a binary

Warning in install.packages :
  package ‘mxnet’ is not available (as a binary package for R version 3.4.3)

> install.packages("mxnet", type = "el-capitan.binary")
Installing package into ‘/usr/local/lib/R/3.4/site-library’
(as ‘lib’ is unspecified)
Warning in install.packages :
  package ‘mxnet’ is not available (for R version 3.4.3)

対処方法

ここここの方法でようやくインストールできました。

opencv

まずOpenCVをインストール

brew install opencv

openblas

OpenBlasも入れます

brew install openblas

mxnet

最後にソースコードからダウンロードしてインストールします

git clone --recursive https://github.com/dmlc/mxnet
cd mxnet
cp make/osx.mk config.mk
make -j4
make rpkg

確認

これでインストールが終わっています

$ R

R version 3.4.3 (2017-11-30) -- "Kite-Eating Tree"
Copyright (C) 2017 The R Foundation for Statistical Computing
Platform: x86_64-apple-darwin17.4.0 (64-bit)

R は、自由なソフトウェアであり、「完全に無保証」です。 
一定の条件に従えば、自由にこれを再配布することができます。 
配布条件の詳細に関しては、'license()' あるいは 'licence()' と入力してください。 

R は多くの貢献者による共同プロジェクトです。 
詳しくは 'contributors()' と入力してください。 
また、R や R のパッケージを出版物で引用する際の形式については 
'citation()' と入力してください。 

'demo()' と入力すればデモをみることができます。 
'help()' とすればオンラインヘルプが出ます。 
'help.start()' で HTML ブラウザによるヘルプがみられます。 
'q()' と入力すれば R を終了します。 

> library(mxnet)
>

これで使えそうです。多分。

リモートでJupyter Notebookをつかう

大学のサーバでどうしてもJupyter Notebookが動かしたいのでメモ。

経緯

データをSQLiteで管理しており,これのサイズが10Gを超え始めた。計算などは大学のサーバで行なっているのであるが,RやJupyterなどビジュアルなツールを使いたい時にはいちいちローカルのPCへSQLiteをコピーするのが大変。

以前Xサーバを使ったリモートでの起動を試したが,どうも使いづらい。
Macからだと,XQuartzをあらかじめMacにインストールしておき,
以下のSSHコマンドで接続し,

[mac] $ ssh -Y remotehost

Jupyterを起動するだけ。

[server] $ jupyter notebook

これで,リモートサーバでFirefoxが立ち上がり,MacのXQuartzで表示される。
しかしこれがいかんせん使いづらい。遅いし,サーバ側のFirefoxなので見た目も悪く,日本語入力も一苦労。

設定

Jupyter

まずはここを参考に設定する。

$ jupyter notebook --generate-config

~/.jupyter/jupyter_notebook_config.pyを編集。ポートが8080が空いている場合には以下のように指定する。

c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 8080

R

Rも使いたいので,ここを参考にRを起動してインストール。

install.packages(c('repr', 'IRdisplay', 'crayon', 'pbdZMQ', 'devtools'))

devtools::install_github('IRkernel/IRkernel')
IRkernel::installspec()  

起動

$ jupyter notebook

[I 17:43:07.065 NotebookApp] Serving notebooks from local directory: /tmp
[I 17:43:07.066 NotebookApp] 0 active kernels
[I 17:43:07.066 NotebookApp] The Jupyter Notebook is running at:
[I 17:43:07.066 NotebookApp] http://0.0.0.0:8080/?token=37e418b82da8472bf89798f70a92dda90003f61509xxxxx

起動時に現れるこれから,

http://0.0.0.0:8080/?token=37e418b82da8472bf89798f70a92dda90003f61509xxxxx

以下のようにPCのブラウザのアドレスバーに打ち込めばOK

http://server:8080/?token=37e418b82da8472bf89798f70a92dda90003f61509xxxxx

githubの仕様変更に対応する

昨日までちゃんとアクセスてきていたのですが,今日,git pushしようとするとエラーが発生。

fatal: unable to access 'http://github.com/xxxxx/yyyy.git/': error:1407742E:SSL routines:SSL23_GET_SERVER_HELLO:tlsv1 alert protocol version

ここに書いていました。SSLプロトコルはどうやら仕様から外れた模様。TLSにあげてくださいとのことです。

使っている大学のサーバのアプリケーションは古いモジュールが多く,OPENSSLもいまだに0.9.8のもの。相当古いです。。。

そこでインストールし直しますが,大学のサーバなので,ユーザ領域にインストールする必要があります。

環境

サーバcray スパコン
ユーザ領域/work/$USER

OpenSSL

wget https://www.openssl.org/source/openssl-1.0.2n.tar.gz
tar zxvfp openssl-1.0.2n.tar.gz
cd openssl-1.0.2n
./config -fPIC --prefix=/work/$USER/local shared
make
make install

ここを参考に,32bitモードでコンパイルします,これはいらないかも?

setarch i386 ./config -m32 -fPIC --prefix=/work/$USER/local shared
make clean
make
make install

curl

wget https://curl.haxx.se/download/curl-7.47.1.tar.gz
tar zxvfp curl-7.47.1.tar.gz
cd curl-7.47.1
PKG_CONFIG_PATH=/work/$USER/local/lib/pkgconfig ./configure --prefix=/work/$USER/local --enable-libcurl-option --with-ssl=/work/$USER/local  --with-includes=/work/$USER/local/include/openssl
make
make install

git

wget https://github.com/git/git/archive/v2.16.2.tar.gz
tar zxvfp v2.16.2.tar.gz
cd git-2.16.2
./configure CFLAGS='-I/work/$USER/local/include' LDFLAGS='-L/work/$USER/local/lib64' --prefix=/work/$USER/local --with-openssl=/work/$USER/local --without-tcltk
make 
make install

vimでXML整形

xmllintをインストール

sudo apt-get install libxml2-utils

.vimrcの設定

~/.vimrc

au FileType xml exe ":silent 1,$!xmllint --format --recover - 2>/dev/null"

OpenWnnの内部辞書解析

OpenWnnの内部辞書を解析したのでそのメモ

経緯

OpenWnnはオープンソースの日本語変換辞書でこの派生製品がそこそこ使われているようです。NicoWnnGというソースコードをダウンロードしていじりだしたのがきっかけ。

どうしても辞書に手を入れる必要があったので調べました。NicoWnnGだけで使うのであればJava側で辞書を持っても良かったのですが,速度や他への転用を考えて,内部辞書を解析することにしました。

オープンソースとは言いつつこの辞書に関しては,バイナリを16進数配列にしたものをソースコードにベタがきしたものしか公開されておらず,このバイナリ部分を自分で作るためのソースコードは見当たりませんでした。

10年くらい前のモバイルデバイスに使われていたらしく,その時に解析された結果がいくつかあり,このサイトを参考に,ソースとにらめっこしながらようやく解析が終了しました。

使っていないであろうコードも結構見受けられたのですがなんとか。多分100%わかっているわけではないのですが,とりあえずNicoWnnGに組み込んで動くところまでは終了しました。

仕様

ヘッダ
00000000-00000003:[NJDC]識別子
00000004-00000007:バージョン
00000008-0000000b:タイプ
0000000c-0000000f:データサイズ
00000010-00000013:extサイズ
00000014-00000017:max check用(使ってない?)
00000018-0000001b:maxlen check用(使ってない?)
0000001c-0000001f: 1c-1d:前品詞数,1e-1f:後品詞数
00000020-00000023:単語ブロックのアドレス
00000024-00000027:登録されている単語の数
00000028-0000002b:登録されている単語の数?
0000002c-0000002f:que size,データ領域の一つのブロックのバイト数
00000030-00000033:最後に編集した単語ブロックの位置, 未使用
00000034-00000037:Write Flag
00000038-0000003b:未使用
0000003C-0000003F:インデックス1のアドレス
00000040-00000043:インデックス2のアドレス

インデックス
インデックス1は読み、インデックス2は表記の昇順で、
単語ブロックの位置が2バイトずつ並んでいる
最後に2バイト00がついている

単語ブロック
00000000-00000000: 2bit fflag, 4bit mflag, 6-7bit type
00000001-00000002: 1-9bit 前品詞,10-16bit 読みバイト数
00000003-00000004: 1-9bit 後品詞,10-16bit 表記バイト数
00000005- :読み、表記が詰めて設定されている
文字コードはUNICODE

フッタ
[NJDC]識別子

変換方法

ソースコードはここに入れておきました。

writedic.cppが変換用プログラムです。
入力ファイルはタブ区切りで
よみ 表記
の順に並んでいることが必要です。

一ファイルは最大65535行まで。

作成したファイルをWnnJpnDic.hのdic_07_dataなどを作成し貼り付ける。
dic_dataにもdic_07_dataを追加。プログラムから出力されるサイズをdic_sizeの該当の場所にコピー。

コンパイル

コンパイルはAndroidStudioから行う場合には文字量によるがメモリが必要なので注意。AnroidStudioのメモリ量を増やしておく必要あり

 

こんな感じで内部辞書を新しくすることができました。

Pythonで誕生日計算


def calc_age(birthdate):
    now=datetime.datetime.now()
    bdate=datetime.datetime.strptime(birthdate,"%Y-%m-%d")
    age=now.year-bdate.year
    if now.timetuple().tm_yday < bdate.timetuple().tm_yday:
        age-=1
    return age

>>> calc_age("2001-11-18")
15
>>> calc_age("2001-10-18")
16

AmazonLinux(CentOS)にMPIを入れる

yumでインストール

sudo yum install openmpi openmpi-devel
sudo yum install mpich2 mpich2-devel # これは不要かも?

パス追加

~/.bashrcに追加

export PATH=$PATH:/usr/lib64/openmpi/bin
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/usr/lib64/openmpi/lib
export C_INCLUDE_PATH=$C_INCLUDE_PATH:/usr/include/openmpi-x86_64
export CPLUS_INCLUDE_PATH=$C_INCLUDE_PATH

python

ライブラリを追加

sudo yum install gcc gcc-c++ make git openssl-devel bzip2-devel zlib-devel readline-devel sqlite-devel bzip2 sqlite
sudo yum -y install  zlib-devel bzip2 bzip2-devel readline-devel sqlite sqlite-devel openssl-devel

pyenv

git clone https://github.com/yyuu/pyenv.git ~/.pyenv

.bashrcに追加 

export PYENV_ROOT=$HOME/.pyenv
export PATH=$PYENV_ROOT/bin:$PATH
eval "$(pyenv init -)"

python install

. ~/.bashrc
pyenv install 3.6.2
pyenv global 3.6.2

mpi4pyを導入

pip install mpi4py

chainermn

wget https://github.com/NVIDIA/nccl/archive/v1.2.3-1+cuda7.5.tar.gz
tar zxvfp v1.2.3-1+cuda7.5.tar.gz 
cd nccl-1.2.3-1-cuda7.5/
make 
sudo make install
pip install chainer python chainermn