kaggle初挑戦 手書き文字認識

概要

kaggleコンテスト(チュートリアル)に初参加した。 手書きの文字認識を4層のNeural Networkでやってみると、ベンチマーク(ランダムフォレスト)は超えられた。 これからちょくちょくやっていきたい。

はじめに

研修で別の業務をやっているので、退屈している、プログラムが書きたい、機械学習したい。 ということで、データサイエンス的なコンテストであるkaggleに参加することにした。 kaggleは初挑戦かつ色々にわかなので、適当ですが、許してほしい。

kaggleとは

公式サイトはこちら

Wikipediaによると

Kaggleは企業や研究者がデータを投稿し、世界中の統計家やデータ分析家がその最適モデルを競い合う、予測モデリング及び分析手法関連プラットフォーム及びその運営会社である。

要するに、企業とかがデータを提供して、世界中の人でそれを解くコンテストである。 今やってるコンテストを見ると、例えば、降水量の予測とか売上の予想とか色々あって面白そう。 本番のコンテストは賞金がついてるものもあって、出題者が本当に課題を解決したいんだなぁという感じがある。

いきなり本番のコンテストに参加するのは色々ハードルが高いので、とりあえず、チュートリアル的なコンテストをやることにする。 チュートリアル的なコンテストは4つ。

とりあえず、一番簡単そうな手書き数字認識をやることにした。

手書き数字認識(mnist)

今回認識するデータはmnistという大規模手書き数字データ。 画像の大きさは28x28ピクセルで白黒画像である。 今回のコンテストでは42000枚のラベル付きの画像で学習を行い、28000枚のラベルなしの画像を認識させる。 このコンテストはチュートリアルなので、ベンチマークアルゴリズム(ランダムフォレスト)、コード、結果(正答率93.514%)が公開されていた。 とりあえずこれを超える結果を出すこと今回の目標とした。

データ

とりあえず、生データをみる。 たまに人間でもなかなか厳しそうなやつがある。もうちょっと丁寧に書いてほしい。 f:id:ksknw:20151108163057p:plain

まずは何も考えずに、画素データを単にベクトルと思って、PCAしてプロットしてみる。

from sklearn.decomposition import PCA
pca = PCA(n_components=2)
pcaed_data = pca.fit_transform(data[:,1:]/255.0)
pcaed_data = zip(*pcaed_data)

plt.scatter(pcaed_data[0], pcaed_data[1], marker=".", c=data[:,0], linewidths=0, alpha=0.7)
f=plt.gcf()
f.set_size_inches(20.0,20.0)
plt.savefig("pca.png")

f:id:ksknw:20151108163045p:plain この時点ですでに、いくつか分かれているものもあるけど、まあ正直よくわからない。 真面目にやるならもうちょっとデータを眺めているのもいいと思うけど、そこまでやる気はないので適当にささっと判別する。

アルゴリズム選択

教師あり学習、画像判別ということで、パッと思いつくアルゴリズムは以下。

  • ランダムフォレスト
  • SIFTやHOG、HLACなどを計算した後、SVMとか
  • Convolutional Neural Network
  • 多層パーセプトロン

最近CNNを使った際、かなり性能が良かったこともあり、これらの中で、直感的に性能が出そうなものはCNNと思う。 ただ、数字だけの認識なのでCNNまでいかなくても、多層パーセプトロンで何とかなるだろうと思った。 そこで、今回はまず多層パーセプトロンで実装してみて、だめなら、もうちょっと強そうなアルゴリズムを使うことにした。

mnistは有名なデータセットなので、少し調べるだけで、多層パーセプトロンで分類をやっている人はたくさんいた。 これらの記事をありがたく参考にさせてもらいつつ、実装を行う。

こちらのブログ で4層のパーセプトロンで認識を行っていたので、とりあえず、4層のネットワークを組むことにした。

実装

今後の勉強も兼ねて、chainerで実装を行う。 もし4層でイマイチな性能だったときに簡単に層数を増やせそうというのもある。

中間層の数は1000ずつ、活性化関数はReLUにして、Dropoutもすることにした。 chainer使うとこのへんの処理がとても簡単に書けるので良い。

学習方法について、最近こういうの を見て、確率的勾配法いまいちなのではと思っている。 今回は、詳細を知らないけど強そうなAdamを使うことにした。

エポック数は20に設定した。 本当は汎化誤差とか見ながら打ち切りするといいと思う。 4層程度ならgpuはいらないかなと思ってcpuで動くコードにした(あとで後悔した)。

import chainer
import chainer.functions as F
from chainer import optimizers
import numpy as np


class Perceptron(object):

    def __init__(self):
        self.batchsize = 100
        self.num_epoch = 20
        self.num_hiddens = 1000
        self.model = chainer.FunctionSet(
            l1=F.Linear(784, self.num_hiddens),
            l2=F.Linear(self.num_hiddens, self.num_hiddens),
            l3=F.Linear(self.num_hiddens, 10)
        )
        self.optimizer = optimizers.Adam()
        self.optimizer.setup(self.model)

    def forward(self, x_data, y_data=None, train=True):
        x = chainer.Variable(x_data)
        if train == True:
            t = chainer.Variable(y_data)
        h1 = F.dropout(F.relu(self.model.l1(x)), train=train)
        h2 = F.dropout(F.relu(self.model.l2(h1)), train=train)
        y = self.model.l3(h2)
        if train:
            loss = F.softmax_cross_entropy(y, t)
            return loss
        else:
            return y.data

    def train(self, inputs, labels, tests):
        N = len(inputs)
        inputs = np.array(inputs).astype(np.float32)
        labels = np.array(labels).astype(np.int32)
        tests = np.array(tests).astype(np.float32)

        for epoch in range(self.num_epoch):
            print "epoch: %d" % epoch

            perm = np.random.permutation(N)
            sum_loss = 0
            for i in range(0, N, self.batchsize):
                x_batch = np.asarray(inputs[perm[i:i + self.batchsize]])
                y_batch = np.asarray(labels[perm[i:i + self.batchsize]])

                self.optimizer.zero_grads()
                loss = self.forward(x_batch, y_batch)
                loss.backward()
                self.optimizer.update()
                sum_loss += float(loss.data) * len(y_batch)
            print "train mean loss: %f" % (sum_loss / N)
        np.asarray(tests)
        y = self.forward(tests, train=False)
        return y

これをipython notebookから読んで使う。

import pandas as pd
import numpy as np

data = pd.read_csv("train.csv")
data = data.as_matrix()
test_data = pd.read_csv("test.csv")

import nn
perceptron = nn.Perceptron()
test_results = perceptron.train(data[:,1:]/255.0, data[:,0], test_data[:]/255.0)
epoch: 0
train mean loss: 0.314591
epoch: 1
train mean loss: 0.149317
epoch: 2
train mean loss: 0.115880
epoch: 3
train mean loss: 0.101776
epoch: 4
train mean loss: 0.082577
epoch: 5
train mean loss: 0.082045
epoch: 6
train mean loss: 0.074332
epoch: 7
train mean loss: 0.064091
epoch: 8
train mean loss: 0.059199
epoch: 9
train mean loss: 0.061192
epoch: 10
train mean loss: 0.053155
epoch: 11
train mean loss: 0.054124
epoch: 12
train mean loss: 0.050729
epoch: 13
train mean loss: 0.050139
epoch: 14
train mean loss: 0.048307
epoch: 15
train mean loss: 0.045948
epoch: 16
train mean loss: 0.044958
epoch: 17
train mean loss: 0.046211
epoch: 18
train mean loss: 0.040627
epoch: 19
train mean loss: 0.041885

ちゃんと損失が下がっている。 あとは提出用のフォーマットを作成する。

results =  np.argmax(test_results, axis = 1)
import csv
f = open("results.csv", "w")
f.write(('"ImageId","Label"\n'))
for i, result in enumerate(results):
    f.write(('%d,"%d"\n'%(i+1,result)))
f.close()

結果

結果をkaggleのサイトに送信すると、正答率とランキングを教えてくれる。 今回の正答率は98%で、順位は205/830位でした。 f:id:ksknw:20151108162603p:plain

間違ったデータを確認してアルゴリズムを改良したいところだけど、テストデータはラベルがないのでどれ間違ったのかわからない。 ちゃんとやるなら、学習データ分割してvalidationしないとだめそう。

今後

パラメータもデータの正規化も、アルゴリズムもかなり適当だったので、色々もうちょっとちゃんとすれば性能上がると思う。 とはいえ、mnist自体はやり尽くされている感じで、あまりおもしろい感じではないので、次はタイタニックのやつをやってみようと思う。

参考

Kaggle: The Home of Data Science

MNIST handwritten digit database, Yann LeCun, Corinna Cortes and Chris Burges

Deniz Yuret's Homepage: Alec Radford's animations for optimization algorithms

Chainerによる多層パーセプトロンの実装 - 人工知能に関する断創録

iPython notebookを使おうかと思ったけどやめた話(最近むちゃくちゃ使ってるのでこれは嘘)

概要

iPython notebookというPythonコードと数式、グラフなどを統合的に扱えるものを知ったので、 使ってみたけど、Emacsからは微妙だったので使うのやめようかなと思ってる。 あくまでも小一時時間さわってみた感想なので、もう少し使っていれば別の感想になると思う。 タスクごとにエディタを変えることに抵抗が少ない人にはおすすめ。

iPython

iPythonはPythonの対話型インタプリタの拡張。 普通のPythonの対話型インタプリタbashとするなら、iPythonはzshみたいな感じ。 変数名、オブジェクトのメソッド名など、タブで色々補完してくれるので、便利。 他にもシェルのコマンドが使えたり、実行時間が簡単に測れたり色々ある。 こちら が詳しい。

(え、対話型インタプリタって使うの?って正直思ってるんですが、みんな使ってるんですか?)

iPython notebook

iPython notebookではPythonMarkdown、普通のテキストを書くことができる。 これらはそれぞれ、セルごとにどれを使って記述するか指定することができる。 詳しくはこちら を参考。

実際に使ってみたときの画像を以下に示す。 f:id:ksknw:20151010195152p:plain

Markdownで数式を書いて、その下にPythonのコード、さらに結果のグラフを一つのファイルの中で完結させることができている。

また、画面上にツールバーがあり、記述したPythonのコードをその場で実行し、結果をすぐ下に表示させることができる。

今まで、パラメータを変更した際の結果を管理する方法として、ファイル名やフォルダ名にパラメータを記述するという手段をとっていた。 iPython notebookを使うことで、Markdownでパラメータ(値だけでなく式でもいい)を記述し、グラフを管理することができるかもしれない。

Emacsから使う

確かに一つのファイルの中で、Python、その出力結果、Markdownを管理できるのは魅力的な機能である。 一方で、その機能を使うために、別のエディタ(しかもブラウザ上で動作する)を使うというのは、 Emacs教徒である僕には我慢ならない。 ということで、EmacsからiPython notebookを使う。

EmacsにおけるiPython notebookはein(Emacs iPython notebook)から利用できる。 こちら を参考にした。

実際に使ってみた画像は以下。 f:id:ksknw:20151010194432p:plain

Markdownの数式が表示させることができなかった。

結局使うのをやめた理由

以下の理由から、真面目に使うのはもうちょっと後かなぁと思っている。 とはいえ、数式とプログラムと実行結果を一つにまとめられるというのはとても魅力的なので、 そのうち、もう一度トライしてみようと思う。

また、自分の結果をまとめるというよりは、教育や知識の共有に向いているような印象を持った。 理論的な部分の説明から実際のコードの実装、結果を見ることができて、なおかつ、自分でコードを色々いじって結果をすぐに見れるというのは、理解を助けてくれると思う。

Emacsから扱うためのモード"ein"が使いにくい

einはまだ開発途中なのか、動作が不安定な場面が多い気がした。 また、普段Emacspythonを使うときはautopep8やwhite spaceでコードの体裁を整えている。 これらの機能が正常に動いてくれなかったので、コードがぐちゃぐちゃになってしまった。 演算子の両側のスペースとか手動で打つ気にはまったくならない。 設定をいじればどうにかなるのかもしれない。

そもそもMarkdown書けなかった

実はMarkdown書けなかった。 できればorg-modeの中にコードと実行結果を埋めこみたい。

追記(2016/4/23)

Markdown書けるようになったので最近むっちゃ使ってる。 einは今のところ使っていない。

参考

IPythonの使い方

はじめるiPython notebook

EmacsでiPython notebookを使う(EIN / Emacs iPython notebook)

Ubuntu14.04 のクリーンインストールからchainer-goghを実行して、芸術的な猫を描くまで

概要

Ubuntu14.04をクリーンインストールするところから、CUDAやChainerをインストールした。 chainer-goghが正しく動作することを確認し、芸術的な猫を描いた。

以下のものをインストールする。

  • Ubuntu 14.04
  • cuda-7.5
  • chainer(-cuda-deps)

(2015/12/26 追記)

あまりに適当だったので環境の構築を書き直した。 Ubuntu14.04での自分的環境構築をちゃんと書く - やったことの説明


CUDAのインストール

インストールに関して、主にこちらの記事を参考にした。 クリーンインストールした Ubuntu14.04 に環境構築 (2)

とりあえず、今後のことを考えてディレクトリを英語にする。

LANG=C xdg-user-dirs-gtk-update

色々インストールする。

$ sudo apt-get  update
$ sudo apt-get install freeglut3-dev build-essential libx11-dev libxmu-dev  libxi-dev libgl1-mesa-glx libglu1-mesa libglu1-mesa-dev linux-headers-`uname -r`
$ sudo lshw -short -class display
$ sudo apt-get remove --purge nvidia*
$ mkdir cuda
$ cd cuda/

NVIDIAのサイトからCUDAの最新版とグラボのドライバをダウンロードして色々やる。

$ chmod +x cuda_7.0.28_linux.run
$ chmod +x NVIDIA-Linux-x86_64-352.41.run
$ sudo nano /etc/modprobe.d/blacklist-nouveau.conf
$ echo options nouveau modeset=0 | sudo tee -a /etc/modprobe.d/nouveau-kms.conf
$ sudo update-initramfs -u

再起動して、Ctrl+Alt+F1を押してCUIに入る。 そのままではグラボのドライバをインストールできないので、以下をする。

$ sudo service lightdm stop

グラボのドライバをインストールする。

$ chmod +x NVIDIA-Linux-x86_64-352.41.run

そのままCUDAをインストールする。

$ chmod +x cuda_7.0.28_linux.run

.bashrcなり.zshrcなりに環境変数を書いて、CUDAのインストールは終わり。

chainerのインストール

ささっとchainerをインストールする。Caffeと違って非常に簡単にインストールできた。

$ sudo apt-get install python-pip
$ sudo apt-get install python-dev
$ sudo pip install chainer
$ sudo visudo -> secure pathをコメントアウト
$ sudo pip install chainer-cuda-deps

ここまでで、すでにchainerでプログラムが動く。すごい。 chainerのテストのために、こちら をダウンロードする。解説はこちら。 中身は一般物体認識で学習させたCNNを使って、絵の画風を変換するというもの。 詳細は解説記事の方を見てほしい。すごい。

$ sudo apt-get install git
$ git clone https://github.com/mattya/chainer-gogh.git
$ cd chainer-gogh

vgg model fileもダウンロードしておく。

実行

手元のマシン(GTX-750Ti)では、メモリが足らず、256x256の画像を生成することができなかったので、画像サイズは128x128にした。 入力画像として可愛い猫の画像を使う。 f:id:ksknw:20150920205050p:plain かわいい。

スタイル画像はもともとのものを使わせてもらう。

実行結果

f:id:ksknw:20150920205043p:plain f:id:ksknw:20150920205103p:plain f:id:ksknw:20150920205113p:plain f:id:ksknw:20150920205116p:plain

左がスタイル画像、右が生成画像。 簡単に芸術的な猫を描くことが出来ました。 かわいいね!

参考

git + latexdiff でTeXの原稿を添削してもらいやすくする。

(latexdiffのバージョンが古かったりで微妙だったので書き直した 2018年3月)

はじめに

論文や報告書で,TeXの文章を人に添削してもらう機会は多い. それなりに長い文章を添削してもらうとき,前回の添削からどこをどう訂正したのかわからないと, 何度も読まないといけないだろうし,申し訳ない.

自分が訂正した部分をわかりやすくするために,

などがあると思うが,どれも手動でやらなければならないので,めんどくさい. 画期的なソリューションが必要である.

探してみるとlatexdiffというのがあり,gitから呼ぶと便利らしいので,使ってみる.

latexdiff

latexdiffは2つのTeXファイルの差分をTeXファイルで出力してくれるアプリケーション.

サイトはこちら . 普通にapt-getからインストールできた.

$ sudo apt-get install latexdiff
$ latexdiff --version
Latexmk, John Collins, 1 January 2015. Version 4.41

とりあえず,以下のTeXファイルを適当に作る.

before.tex

\documentclass{jarticle}
\begin{document}
消したところは赤で表示される.

\end{document}

after.tex

\documentclass{jarticle}
\begin{document}
追加したところは青で表示される.

\end{document}

あとは以下のコマンドを叩く.

$ latexdiff -e utf8 -t CFONT before.tex after.tex > diff.tex

文字コードnkf –guess とかで調べる. ちなみに指定しないと,日本語が文字化けしてコンパイルできなかった.

コンパイルするとこんな感じのPDFファイルができる.便利.

f:id:ksknw:20180314221745p:plain

latexdiff-git

このままでも使えなくはないけど,変更前のファイルを残しておかないといけない. めんどくさいし,なによりださい. もともとgit使って管理しているなら,前のコミットをlatexdiffの入力として使える.

$ latexdiff-git -r -t CFONT -e utf8 test.tex

とすれば,差分ファイルが出力される.

直前以外のコミットと現在のファイルの差分を出力したいときは

$ latexdiff-git -r HEAD~1 -e utf8 -t CFONT main.tex

などでリビジョンを指定することもできる.

複数ファイルにまたがるとき

ここまでのやり方だと,inputのようなコマンドを使用しているときに,うまく差分ファイルを生成することができない. こちらによると,flattenというオプションを指定すればいいらしい.

以下のようなファイルで実際にやってみると,ちゃんとdiffファイルが生成された.

$ latexdiff -e utf8 --flatten main.tex main2.tex > diff.tex
\documentclass{jarticle}
\begin{document}
\input{before.tex}

\end{document}

参考にしたサイト

Emacsの上にも3年

はじめに

研究室に配属されて以来Emacsを使い続けて,そろそろ3年になる.研究室のPCもそろそろ返却しないといけないので,自宅のPCにEmacsをインストールしつつ,今やってる設定をまとめてみようと思う.3年使っているけれど,lispはさっぱりなので,色々な方のブログ等を頼りに.だいたいはコピペしているだけなので,参考元のページを参照してほしい.使っている言語はpythonC++TeXが主なので,そのあたりの設定だけしかしていない.

環境

Emacs24.4は普通にやると入らなかった覚えがある.特にMacは,こちらをみてパッチを当てるなどした.

[追記]

1年たって、helmを導入したり色々変わった。 特にpythonの設定について、こっちに書きなおした。 ksknw.hatenablog.com

init-loader

最近まで,init.elに全部書いて,適当に管理していたので,設定がぐっちゃぐちゃになっていた.init-loaderは特定のディレクトリ以下のすべてのファイルを自動的に読み込んでくれる.設定ファイルを簡単に分割できるので便利.

こちらのサイトから設定,その他をありがたくコピペさせていただいた.

;;init-loaderで残りの設定を読み込む
(require 'init-loader)

;;initファイルを読み込むときのエラーを表示
(defun init-loader-re-load (re dir &optional sort)
  (let ((load-path (cons dir load-path)))
    (dolist (el (init-loader--re-load-files re dir sort))
      (condition-case e
      (let ((time (car (benchmark-run (load (file-name-sans-extension el))))))
        (init-loader-log (format "loaded %s. %s" (locate-library el) time)))
    (error
     (init-loader-error-log (format "%s. %s" (locate-library el) (error-message-string e))) ;追加
     )))))

;;~/.emacs.d/inits/ 以下を読み込み
(init-loader-load "~/.emacs.d/inits")

分割は今のところこんな感じ.

anything

研究室にあったinit.elを捨てて,自分で最初に入れた拡張がこれだった.すべてのファイル,コマンド,クリップボードなんかを統合的に扱ってくれるインターフェイスといえばいいのか.とにかく便利だった.今では依存しきっていて,anythingがないと,ちょっと前に作ったファイルは開けないだろうし,コマンドもほぼ打てないだろうと思う.

こちらはるびきちさんのサイトを参考に.

(require 'anything-startup)

(setq anything-c-filelist-file-name "~/.emacs.d/all.filelist")
(setq anything-grep-candidates-fast-directory-regexp "^~/.emacs.d/")

;;anythingでファイルリストを検索
(define-key global-map (kbd "C-:") 'anything-filelist+)
;;クリップボードの履歴をanythingで検索
(global-set-key "\M-y" 'anything-show-kill-ring)
(global-set-key (kbd "C-.") 'anything-do-grep)

ファイルとコマンドだけでなく,クリップボードに溜め込んだものを扱える,anything-kill-ringも便利.anything-grepは未だに使い方がよくわかってなくて,たまにうまく検索できない.

undo histを使ってるので,filelistを作るスクリプトにそのディレクトリを見ないように設定した以外は,ほぼデフォルト.最近はhelmのほうがいい(?)らしいけど,初めに入れたのがanythingだったので,なんとなく使っている.

migemo

migemoは日本語をローマ字のまま検索してくれる機能.コード書いてて,コメントを検索したいときに,いちいち変換する必要がなくなる.

このあたりを参考にさせていただいて,インストールして

sudo apt-get install cmigemo

適当に設定を書く.

(setq migemo-dictionary "~/cmigemo/dict/utf-8.d/migemo-dict")
(setq migemo-command "cmigemo")
(setq migemo-options '("-q" "--emacs"))
(setq migemo-user-dictionary nil)
(setq migemo-coding-system 'utf-8)
(setq migemo-regex-dictionary nil)
(load-library "migemo")
(migemo-init)

そんなに賢くはないので,大量の日本語から英単語を見つけるときにはむしろ邪魔かもしれない.特にTeX書いてるときとか.

white space

white spaceはスペースやタブなどを可視化してくれる機能.ついでに行末のスペースとか文末の改行とか消すこともできる.

僕は諸悪の根源たる全角スペースを可視化している.ついでに,行末のスペースとかも不要なので消すようにした.

こちらこちらを参考にした.

;;保存時に行末のスペースを削除.文末の改行は削除しない
(require 'whitespace)
(set-face-foreground 'whitespace-space "DarkGoldenrod1")
(set-face-background 'whitespace-space nil)
(set-face-bold-p 'whitespace-space t)
(setq whitespace-style '(tabs           ; タブ
             trailing       ; 行末
             spaces         ; スペース
             space-mark     ; 表示のマッピング
;;                         tab-mark
             ))
(setq whitespace-action '(auto-cleanup))
(global-whitespace-mode 1)

;;全角のスペースを目立たせる   <-こんな感じ
(setq whitespace-space-regexp "\\(\x3000+\\)")
(setq whitespace-display-mappings
      '((space-mark ?\x3000 [?\□])
    (tab-mark   ?\t   [?\xBB ?\t])
    ))

undo tree and hist

undo histはファイルを閉じてもundoの履歴を保存してくれる機能.undo tree は今までのundoの履歴を樹形図みたいに表示してくれる機能.

こちらこちらを参考にした.

;; undoの履歴をウィンドウを閉じても保持する
(when (require 'undohist nil t)
  (undohist-initialize))

;; undoの樹形図を表示する C-x u
(when (require 'undo-tree nil t)
  (global-undo-tree-mode))

関係ないけど,EmacsのundoはWindowsとかの場合と挙動が違っていて,最初に躓いた記憶がある.

その他の細かい設定

基本は研究室にもとからあったものを参考.

自分で入れたのはpopwinとieditとflycheck.それぞれ,コンパイルとかanythingとかでウィンドウ構成を変えないようにする機能.複数箇所の同時編集.文法チェック.

を参考にした.

;;改行時に自動でインデントする
;;C-mとEnterは同等なので,これでOK
(global-set-key "\C-m" 'newline-and-indent)

;;ファイルを開くときに大文字小文字の違いを無視
(setq read-buffer-completion-ignore-case t)    ;; バッファ名
(setq read-file-name-completion-ignore-case t) ;; ファイル名

;; 問い合わせを簡略化 yes/no を y/n
(fset 'yes-or-no-p 'y-or-n-p)

;; C-k で行末の改行も消去
(setq kill-whole-line t)

;;バッファ自動読み込み
(global-auto-revert-mode 1)

;;同名のファイルのバッファ名を変更
(require 'uniquify)
(setq uniquify-buffer-name-style 'post-forward-angle-brackets)

;;compileとかでウィンドウ構成がこわれないようにする
(require 'popwin)
(setq display-buffer-function 'popwin:display-buffer)

;;コンパイル画面でスクロールする
(setq compilation-scroll-output t)

;; 行番号を表示する
(require 'linum)
(global-linum-mode t)      ; デフォルトで linum-mode を有効にする
(setq linum-format "%5d ") ; 5 桁分の領域を確保して行番号のあとにスペースを入れる

;; スタートアップページを表示しない
(setq inhibit-startup-message t)
(server-start)

;タイトルバーにファイル名を表示
(setq frame-title-format (format "%%f - Emacs@%s" (system-name)))

;; ツールバーを消す
(tool-bar-mode 0)

;; バックアップファイルを作らない
(setq backup-inhibited t)
(setq make-backup-files nil)
;; 終了時にオートセーブファイルを消す
(setq delete-auto-save-files t)

;;音を鳴らさない
(setq visible-bell t)
(setq ring-bell-function 'ignore)

;;対応する括弧を挿入
(defun electric-pair ()
  "Insert character pair without sournding spaces"
  (interactive)
  (let (parens-require-spaces)
    (insert-pair)))

;;複数箇所の同時編集 sublime text的なやつ
(require 'iedit)

;; syntaxチェック
(require 'flycheck)

python-mode

追記:結局jediが最強だったので、以下のpython設定はもう使っていない。

最近は以下。 PythonをEmacsで書く+α - やったことの説明

elpy

僕のPythonの設定はほぼこれで終わりといってもいいかもしれない.どこまでがelpyなのかよくわからないが,package-list-packagesで入れると,色々くっついてインストールされた.変数名の補完から,文法チェックまでいろいろしてくれる."."を打つだけで,メソッド名を補完してくれるのが嬉しい.

英語で説明してくれるビデオを参考にして入れた.この動画のシリーズが結構いいかもしれない.

設定は1行.

(elpy-enable)

elpyをインストールする前に入れていた,yasnippetとかauto-completeとかflycheckとかと干渉してよくわからないことになったことがあった.結局Python時にACを切って,snippetのフォルダからpython-modeを削除して,flycheckも言語ごとに設定するようにして,なんとかなった.

その他

色々書いているけど,なくてもelpyで動くとこもありそう.

(add-hook 'python-mode-hook
           '(lambda ()
              (setq indent-tabs-mode nil);;tabの幅を変える
              (setq indent-level 4)
              (setq python-indent 4)
              (setq tab-width 4)
              (define-key python-mode-map "\"" 'electric-pair) ;;括弧の補完
              (define-key python-mode-map "\'" 'electric-pair)
              (define-key python-mode-map "(" 'electric-pair)
              (define-key python-mode-map "[" 'electric-pair)
              (define-key python-mode-map "{" 'electric-pair)
              (define-key company-active-map (kbd "\C-n") 'company-select-next)
              (define-key company-active-map (kbd "\C-p") 'company-select-previous)
              (define-key company-active-map (kbd "\C-d") 'company-show-doc-buffer)
              (define-key company-active-map (kbd "<tab>") 'company-complete)
              (auto-complete-mode -1)
              ))

;;elpy 色の設定 デフォルトは黄色でださい
(custom-set-variables
 ;; custom-set-variables was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(company-minimum-prefix-length 1)
 '(company-selection-wrap-around t))
(custom-set-faces
 ;; custom-set-faces was added by Custom.
 ;; If you edit it by hand, you could mess it up, so be careful.
 ;; Your init file should contain only one such instance.
 ;; If there is more than one, they won't work right.
 '(default ((t (:background "#131313" :foreground "white"))))
 '(company-scrollbar-bg ((t (:inherit company-tooltip :background "dim gray"))))
 '(company-scrollbar-fg ((t (:background "blue"))))
 '(company-tooltip ((t (:background "dim gray" :foreground "white"))))
 '(company-tooltip-annotation ((t (:inherit company-tooltip :foreground "white"))))
 '(company-tooltip-common ((t (:inherit company-tooltip :foreground "white"))))
 '(company-tooltip-common-selection ((t (:inherit company-tooltip-selection :foreground "white"))))
 '(company-tooltip-selection ((t (:inherit company-tooltip :background "blue"))))
 '(mode-line ((t (:foreground "#F8F8F2" :background "#303030" :box (:line-width 1 :color "#000000" :style released-button)))))
 '(mode-line-buffer-id ((t (:foreground nil :background nil))))
 '(mode-line-inactive ((t (:foreground "#BCBCBC" :background "#101010" :box (:line-width 1 :color "#333333"))))))

ネットで見ていると,どうもEmacspython書くには微妙という記述をちょくちょく見かける.どうなんでしょうか.

YaTex-mode

修士論文書くのにも大活躍中のYaTeX.数式のショートカット覚えてから,数式を打つのがそんなに苦ではなくなった.

auto-complete入ってるけど,使うコマンドはだいたいショートカットかsnippetがあるので,あまり必要ないかもしれない.RefTeXの使い方を全く知らないので,設定も研究室にあったものをそのまま.

;; YaTeX
(autoload 'yatex-mode "yatex" "Yet Another LaTeX mode" t)
(setq auto-mode-alist (append
  '(("\\.tex$" . yatex-mode)
    ("\\.ltx$" . yatex-mode)
    ("\\.cls$" . yatex-mode)
    ("\\.sty$" . yatex-mode)
    ("\\.clo$" . yatex-mode)
    ("\\.bbl$" . yatex-mode)) auto-mode-alist))

;;自動改行を抑制 これがないと長い文章のよくわからないところで改行される
(add-hook ' yatex-mode-hook
'(lambda () (auto-fill-mode -1)))

;; RefTexという参考文献とかを補完するモードをONにする 使い方がよくわかってないので調べる
(add-hook 'yatex-mode-hook
      #'(lambda ()
          (reftex-mode 1)
          (define-key reftex-mode-map
        (concat YaTeX-prefix ">") 'YaTeX-comment-region)
          (define-key reftex-mode-map
        (concat YaTeX-prefix "<") 'YaTeX-uncomment-region)
          ))

;;YaTeXのいろいろをAutoCompleteの補完リストに追加する
;;snippetsは"\"いらないけど,ACは"\" も打たないと補完されない 変えたほうがいい?
;; for YaTeX
(require 'auto-complete-latex)
(setq ac-l-dict-directory "~/.emacs.d/ac-l-dict/")
(add-to-list 'ac-modes 'yatex-mode)
(add-hook 'yatex-mode-hook 'ac-l-setup)
(add-to-list 'ac-modes 'foo-mode)
(add-hook 'foo-mode-hook 'ac-l-setup)

(add-hook 'yatex-mode-hook
      #'(lambda ()
          (define-key YaTeX-mode-map (kbd "C-c c") 'compile) ;;C-c c でmake できるようにする
          (auto-complete-mode t)
          ))

c++-mode

auto-complete,yasnippet,gtags,flycheckぐらいしか使っていない.昔はauto-complete-clangとか使っていたような気もする.

それぞれ以下のサイトを参考にした.

cc-mode いらないのではないかという気はしている.

(setq auto-mode-alist (append
  '(("\\.cpp$" . c++-mode)
    ("\\.hpp$" . c++-mode)
    ("\\.h$"   . c++-mode) )auto-mode-alist))


(setq gtags-prefix-key "\C-c")
(require 'gtags)
(require 'anything-gtags)
;; キーバインド
(setq gtags-mode-hook
      '(lambda ()
     (define-key gtags-mode-map "\C-cs" 'gtags-find-symbol)
     (define-key gtags-mode-map "\C-cr" 'gtags-find-rtag)
     (define-key gtags-mode-map "\C-ct" 'gtags-find-tag)
     (define-key gtags-mode-map "\C-cf" 'gtags-parse-file)))


(defvar c++-ac-sources
          '(ac-source-yasnippet
        ac-source-abbrev
        ac-source-dictionary
        ac-source-words-in-same-mode-buffers
        ;;ac-source-clang-async
        ))


;; cc-modeの自前スタイル設定
(add-hook 'c-mode-common-hook
      (lambda()
         (setq completion-mode t)
         (setq compilation-window-height 10)
         (setq c-basic-offset 2)
         ;; cc-mode内で定義されるキーバインド
         (define-key c-mode-base-map "\C-cc"      'compile)
         (define-key c-mode-base-map "\C-cg"      'gdb)
         (define-key c-mode-base-map "\C-ck" 'kill-compilation);やめる
         (define-key c-mode-base-map "\C-ce" 'next-error)   ;エラー検索
         (define-key c-mode-base-map "\"" 'electric-pair)
         (define-key c-mode-base-map "\'" 'electric-pair)
         (define-key c-mode-base-map "(" 'electric-pair)
         (define-key c-mode-base-map "[" 'electric-pair)
         (define-key c-mode-base-map "{" 'electric-pair)
         ;; 括弧や;を入力すると自動で改行
         ;(setq c-auto-newline t)
         ;; TAB はスペース 2 個ぶんで
         (setq-default tab-width 2)
         (setq indent-tabs-mode nil)
         ;; # をインデントしない
         ;;(setq c-electric-pound-behavior '(alignleft))
         (c-set-offset 'cpp-macro 0)
         (c-set-offset 'cpp-macro-cont '+)
         (setq-default ac-sources c++-ac-sources)
         (flycheck-mode t)
         (gtags-mode 1)
         ))


(add-hook 'c++-mode-common-hook
      (lambda()
        (setq completion-mode t)
        (setq compilation-window-height 10)
        (setq c-basic-offset 2)
        ;; cc-mode内で定義されるキーバインド
        (define-key c++-mode-base-map "\C-cc"      'compile)
        (define-key c++-mode-base-map "\C-cg"      'gdb)
        (define-key c++-mode-base-map "\C-ck" 'kill-compilation);やめる
        (define-key c++-mode-base-map "\C-ce" 'next-error)  ;エラー検索
        (define-key c++-mode-base-map "\"" 'electric-pair)
        (define-key c++-mode-base-map "\'" 'electric-pair)
        (define-key c++-mode-base-map "(" 'electric-pair)
        (define-key c++-mode-base-map "[" 'electric-pair)
        (define-key c++-mode-base-map "{" 'electric-pair)
        ;; TAB はスペース 2 個ぶんで
        (setq-default tab-width 2)
        (setq indent-tabs-mode nil)
        ;; # をインデントしない
        (setq c-electric-pound-behavior '(alignleft))
        (c-set-offset 'cpp-macro 0)
        (c-set-offset 'cpp-macro-cont '+)
        (setq-default ac-sources c++-ac-sources)
        (flycheck-mode t)
        (gtags-mode 1)
        ))

;; update GTAGS
(defun update-gtags (&optional prefix)
  (interactive "P")
  (let ((rootdir (gtags-get-rootpath))
    (args (if prefix "-v" "-iv")))
    (when rootdir
      (let* ((default-directory rootdir)
         (buffer (get-buffer-create "*update GTAGS*")))
    (save-excursion
      (set-buffer buffer)
      (erase-buffer)
      (let ((result (process-file "gtags" nil buffer nil args)))
        (if (= 0 result)
        (message "GTAGS successfully updated.")
          (message "update GTAGS error with exit status %d" result))))))))
(add-hook 'after-save-hook 'update-gtags)

org-mode

TODOリストとかメモとかを管理できるモード.最近入れたので,まだ使い方はよくわかっていない.この記事もこのモードで書いて,Markdownで出力している.このモードがなければ,この記事の長さは10分の1以下になっていたであろうと思う.

こちらを参考にした.

画面の切り替えをC-Tabに設定しているので,そこだけ動くようにした.

(require 'ox-qmd)

;; capture templates
(setq org-capture-templates
      '(("p" "Project Task" entry (file+headline (expand-file-name "~/project/project.org") "Inbox")
         "** TODO %?\n    %i\n    %a\n    %T")
    ("m" "memo" entry (file (expand-file-name "~/memo.org"))
         "* %?\n    %i\n    %a\n    %T")))

;; agenda
(setq org-agenda-files (list (expand-file-name "~/project")))

;; C-tab はウインドウの移動に使いたいのではずす
(add-hook 'org-mode-hook
      '(lambda ()
         (define-key org-mode-map [(control tab)] nil)))

見た目

基本的に研究室にあったinit.elからそのまま.mode-lineの色とかはいじった気がする.

;;文字サイズ
(set-face-attribute 'default nil
       :height 110)    ;; font siez
;; 日本語
(set-fontset-font
 nil 'japanese-jisx0208
;; (font-spec :family "Hiragino Mincho Pro")) ;; font
  (font-spec :family "Hiragino Kaku Gothic ProN")) ;; font

;; 半角と全角の比を1:2に
(setq face-font-rescale-alist
      '((".*Hiragino_Mincho_pro.*" . 1.2)))

;;折り返し記号の色
(set-face-foreground 'fringe "#7f7f7f")
;;折り返し記号のとこの背景色
(set-face-background 'fringe "gray12")

;; region の色
(custom-set-faces
 '(default ((t
         (:background "#131313" :foreground "white")
         )))
 '(mode-line ((t (:foreground "#F8F8F2" :background "#303030" :box (:line-width 1 :color "#000000" :style released-button)))))
 '(mode-line-inactive ((t (:foreground "#BCBCBC" :background "#101010" :box (:line-width 1 :color "#333333")))))
 '(mode-line-buffer-id ((t (:foreground nil :background nil))))
 )


;;カーソル行のハイライト
(defface hlline-face
  '((((class color)
      (background dark))
     (:background "gray13" :underline nil))
    (((class color)
      (background light))
     (:background "#00AA00":underline nil))
    (t ()))
  "*Face used by hl-line.")

(setq hl-line-face 'hlline-face)
(global-hl-line-mode)
;;; カーソルの点滅を止める
(blink-cursor-mode 0)


;;透過の設定
(when window-system
  (progn
    (setq default-frame-alist
      (append
       (list
        '(vertical-scroll-bars . nil) ;;スクロールバーはいらない
        '(alpha  . 93))
       default-frame-alist))))

;;起動時にウィンドウを最大化する
(set-frame-parameter nil 'fullscreen 'maximized)

;; リージョン指定,括弧対応に色をつける
(setq transient-mark-mode t)
(show-paren-mode)
(setq show-paren-style 'parenthesis)
(setq show-paren-delay 0.05) ;; default: 0.125

;;行,桁番号,バッファサイズの表示
(line-number-mode t)
(column-number-mode t)

;; 行末のスペースを表示
(setq-default show-trailing-whitespace t)

そのうち入れようと思っているもの

helm

anythingとなにが違うのか,ちゃんと調べてないので保留.

jedi

pythonのオムニ補完.最初入れてたけど,elpyを設定しなおしたときに消してしまった.elpyの設定,しばらくは触りたくない.

stan-mode

pythonとかRからも触れて,簡単にMCMCできるstanという言語のモード.stanについてほぼ知らないので保留.

git関連

バージョン管理の大事さは最近とても感じる.git-gutterとかその辺りをいれるつもり.

おわりに

入れたほうがいいものがあったら教えてください.

参考にさせていただいたサイト

Yosemite で Emacs-24.4 をビルドして動かす

年末emacs設定大掃除をして、これは捨てられないと思った設定書いてく - $shibayu36->blog;

anything導入のeverything ~3分で使えるanything.el~

migemoを使ってEmacsライフを快適に

whitespace-modeを使って、ファイルの保存時に行末のスペースや末尾の改行を削除する

emacsで全角スペースを見やすくする。 - プログラミングのメモ

Emacs24.3の導入とundo-tree.elの紹介

ヘルプバッファや補完バッファをポップアップで表示してくれるpopwin.elをリリースしました - Functional Emacser

Emacs as a C/C++ Editor/IDE (Part I): auto-complete, yasnippet, and auto-complete-c-headers

flymakeの設定する前に flycheckを確認しよう - Life is very short

Emacs as a Python editor and IDE (Part 1): Installing elpy mode

「Emacsのトラノマキ」連載第09回「auto-completeを使おう」(松山智大) | ありえるえりあ

Emacs - コードリーディングにとっても便利な GNU GLOBAL と gtags.el (と anything-gtags.el) をつかおう

Emacs - org-modeの使い方例

ドコモメールをGmailのスパムフィルタでフィルタリングする

ドコモメールにおけるスパムメールフィルタは「迷惑メールおまかせブロック」というサービスによって提供されているが,月額200円というのが癪なので,Gmailスパムメールフィルタを使ってドコモメールをフィルタリングすることにした.

調べてみるとSPモードメールをGmailで受信している方がいた.

徒然覚書: ドコモのSPモードメール(@ docomo.ne.jp)がGmailやパソコンでも受信できるようになったゾ!!

この記事によると,SPモードメールはGmail側でPOPの設定をすれば,なんとかなるらしい.
ただ

"*Gmailでの受信はPOP3通信のみ対応。
SPモードメールはPOP3対応、ドコモメールはPOP3非対応なので
ドコモメール(IMAP)をGmailで受信することはできません。 "

ということ.
残念ながらドコモメールを利用しているのでこの方法は使えない.

いまいちいい方法が思いつかないので,
imapでドコモメールをダウンロードして,imapGmailに転送することにした.

PythonでIMAPを使ってみる | 流連荒亡

こちらを参考にさせてもらって,pythonで適当にスクリプトを書いた.
以下のスクリプトをcronとかで走らせれば,何分かおきにドコモの未読メールをGmailに送ってくれて,その都度Gmailのフィルタリングが機能するはず.

import imaplib
import time

maildatalist= []
imap_server = "imap.spmode.ne.jp"
imap_port = 993
imap_user = "自分のアドレス@docomo.ne.jp"
imap_pw = "自分のパスワード"
mailbox = "INBOX"

m = imaplib.IMAP4_SSL(imap_server, imap_port)
m.login(imap_user, imap_pw)
m.select(mailbox)

typ, data = m.search(None, 'UNSEEN')
if data[0] != "" :
    msg_ids = data[0].split()
    for msg_id in msg_ids:
        typ, data = m.fetch(msg_id, '(RFC822)')
        maildata = data[0][1]
        maildatalist.append(maildata)
        m.store(msg_id, '+FLAGS', '\\SEEN')
m.close()
m.logout()


imap_server = "imap.gmail.com"
imap_port = 993
imap_user = "自分のアドレス@gmail.com"
imap_pw = "自分のパスワード"
folder = 'inbox'
#folder = 'docomo'

m = imaplib.IMAP4_SSL(imap_server, imap_port)
m.login(imap_user, imap_pw)
m.select(mailbox)

for maildata in maildatalist:
    m.append(folder, '', imaplib.Time2Internaldate(time.time()),  maildata)


実行結果

f:id:ksknw:20141226180006p:plain

だめやん…

メールの転送はできてるけど,肝心のスパムフィルタが動作せず,迷惑メールが全部表示されている.

 

調べてみるとこんな記事があった. 

node.js - IMAP APPEND with gmail, treat as new incoming email - Stack Overflow

 どうやらimaplibのappend関数はフィルタリングとかの工程をすっ飛ばして,フォルダに追加するだけらしい.

 

さらに色々調べているとPOPでGmailに同期されたものはフィルタリングされるらしいということがわかった.

2つのGmailアカウント間はPOPで同期が可能なので,ドコモメールをimapでGmail1に転送→Gmail1をPOPでGmail2と同期で,なんとかなるはず.

 

GmailにおけるPOPの設定は割と簡単(不正アクセス扱いされて上手くいかないことが何度かあった).

Gmailの設定→アカウントとインポート→POP3を使用して他のアカウントのメッセージを確認 からドコモメールを転送したGmailアカウントを指定する.

f:id:ksknw:20141226222006p:plain

結果

f:id:ksknw:20141226222113p:plain

 無事,迷惑メール以外のメールを抽出することが出来た.

 

まとめ

ドコモメールを解約しよう.

 

逆プリクラ プリクラで大きくなった目をもとに戻すアプリ

プリクラで大きくなった目を元の大きさに戻すアプリです.

プリクラ画像から目を自動的に検出し,元の大きさに修正することができます.

f:id:ksknw:20131023130531p:plainf:id:ksknw:20131023130549p:plain

 

ダウンロード:

f:id:ksknw:20131023145137p:plain

Android版 : https://play.google.com/store/apps/details?id=org.opencv.samples.tutorial2

iOS版 : そのうち公開予定

 

 

Facebooktwitterなどを見ているとプリクラ画像がアップロードされていることがあります.最近のプリクラでは,美白修正,デカ目修正,足長修正などが自動で行われており,「こいつ誰だよ...」と思うことも少なくはありません.撮る方からすれば便利な機能なのかもしれませんが,見る方からすればいろいろ問題があります.

詐欺プリクラにだまされてしまったり,目が大きくなりすぎて気持ち悪くなったり,現実をがわからなくなったりします.そんなときこのアプリを使えば,大きくなった目を元の大きさに修正することで,簡単にこれらの問題を解決することができます.

 

Naverまとめ とかはちま起稿とかに載っていました.

http://matome.naver.jp/odai/2138150909534360701

http://blog.esuteru.com/archives/7358511.html

 

ダウンロード:

Android版 : https://play.google.com/store/apps/details?id=org.opencv.samples.tutorial2

iOS版 : そのうち公開予定

 

2017年追記

新しいスマホを買ったら,新しいバージョンのandroidでは動作しないことに気がついた.

更新するのも面倒なので,公開を停止しました.