Rでword2vec

こちらを参考にRでWord2Vecを実行してみたが、ちょっとハマったのでメモ

パッケージインストール

必要なパッケージをインストールします

install.packages("devtools")
library(devtools)
install.packages("tsne")
install.packages("magrittr")
install.packages("stringi")
library(tsne)
library(magrittr)
library(stringi)
devtools::install_github("bmschmidt/wordVectors")

データ作成

青空文庫から夏目漱石の三四郎をテストデータとします

$ wget http://www.aozora.gr.jp/cards/000148/files/794_ruby_4237.zip
$ unzip 794_ruby_4237.zip
$ nkf -w  --overwrite sanshiro.txt
$ mecab -Owakati sanshiro.txt -o data.txt

UTF8へ文字コードを変換しておきます。ちなみにmecabはUTF8のものをインストールしておいてください

R実行

Rから実行します

library(devtools)
library(wordVectors)
library(magrittr)
library(tsne)
library(magrittr)
wordVectors::train_word2vec(
  train_file = "data.txt", output_file = "model.txt",
  vectors = 200, window = 10,
  threads = 3
)

threadsはCPU数−1あたりで設定します
これを実行すると

 type.convert(data[[i]], as.is = as.is[i], dec = dec, numerals = numerals,  でエラー: 
   '(;;{ֺ3:q9<9a><99>
8(c<91>:' に不正なマルチバイト文字があります 追加情報: 警告メッセージ: 1: utils::read.table(filename, header = F, skip = 1, colClasses = c("character", で: line 1 appears to contain embedded nulls 2: utils::read.table(filename, header = F, skip = 1, colClasses = c("character", で: line 2 appears to contain embedded nulls 3: utils::read.table(filename, header = F, skip = 1, colClasses = c("character", で: line 3 appears to contain embedded nulls 4: utils::read.table(filename, header = F, skip = 1, colClasses = c("character", で: line 4 appears to contain embedded nulls 5: utils::read.table(filename, header = F, skip = 1, colClasses = c("character", で: line 5 appears to contain embedded nulls 6: utils::read.table(filename, header = F, skip = 1, nrows = 1, で: line 1 appears to contain embedded nulls

このようなエラーが出ます
この場合には気にせずRで

word2vec_model <- read.vectors("model.txt",binary=TRUE)

これで読み込み直してやります。

確認

> nearest_to(word2vec_model,word2vec_model[["三四郎"]])
      三四郎       与次郎       じっと           秋     ますます         勇気     見合わせ     おかしく           次 
3.330669e-16 4.131871e-01 4.873280e-01 4.886600e-01 4.895344e-01 4.948309e-01 5.033392e-01 5.220245e-01 5.278047e-01 
      腹の中 
5.329964e-01 
> nearest_to(word2vec_model,word2vec_model[["東京"]])
        東京       生まれ     これから       ずっと         変る         おれ       いなか         うえ       いっそ 
5.551115e-16 3.663971e-01 3.754231e-01 3.864140e-01 4.024397e-01 4.056571e-01 4.078920e-01 4.080678e-01 4.103215e-01 
    文芸時評 
4.340431e-01 

ま、こんなもんです

ubuntu14.04へRの最新版をapt-getでインストール

ubuntu14.04にapt−getでインストールできるRのバージョンは3.0.2とちょっと古いです。
最新版をインストールするには以下のようにします

$ sudo echo "deb http://cran.rstudio.com/bin/linux/ubuntu trusty/" >> /etc/apt/sources.list
$ sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys E084DAB9
$ sudo add-apt-repository ppa:marutter/rdev
$ sudo apt-get update
$ sudo apt-get upgrade
$ sudo apt-get install r-base

PROXY環境下の場合には

export http_proxy="http://server:port/"

の環境変数を入れる必要があります

ここを参考にしました

RSRubyの使い方

よく忘れるのでメモ

#!/bin/env ruby
# coding:utf-8

require  "rsruby"
require "rsruby/dataframe"

r=RSRuby.instance
r.class_table["data.frame"]=lambda{|x| DataFrame.new(x)}
RSRuby.set_default_mode(RSRuby::CLASS_CONVERSION)

x=[1,2,3]
y=[2,4,6]
df=r.as_data_frame(:x=>{'x'=>x,'y'=>y})
r.assign('df',df)
res=r.eval_R(<

CentOS5.11へgcc-4.8.5をインストール

たまたま余っていたCentOS5.11のサーバにpython2.7.12をインストールし、pylabをインストールしようとするとエラー。

 error: ‘SOCK_CLOEXEC’ was not declared in this scope
    error: command 'gcc' failed with exit status 1

どうもOSが古いと色々問題があります。

そこでこちらを参考にGCCをインストールします

ダウンロード

以下のサイトからダウンロードします。とりあえず最新版をダウンロードしました。

コンパイル

# mkdir /usr/local/gcc-4.8.5
# export LD_LIBRARY_PATH=/usr/local/gcc-4.8.5/lib:$LD_LIBRARY_PATH
# bunzip2 gmp-6.1.1.tar.bz2 
# tar xvfp gmp-6.1.1.tar
# cd gmp-6.1.1
# ./configure --prefix=/usr/local/gcc-4.8.5
# make && make install
# xz mpfr-3.1.4.tar.xz 
# cd mpfr-3.1.4
# ./configure --prefix=/usr/local/gcc-4.8.5 --with-gpm=/usr/local/gcc-4.8.5
# make && make install
# tar zxvfp mpc-1.0.3.tar.gz 
# cd mpc-1.0.3
# ./configure --prefix=/usr/local/gcc-4.8.5 --with-gmp=/usr/local/gcc-4.8.5 --with-mpfr=/usr/local/gcc-4.8.5
# make && make install
# tar zxvfp gcc-4.8.5.tar.gz 
# cd gcc-4.8.5
# ./configure --prefix=/usr/local/gcc-4.8.5 --enable-checking=release --with-gpm=/usr/local/gcc-4.8.5 --with-mpfr=/usr/local/gcc-4.8.5 --with-mpc=/usr/local/gcc-4.8.5 --enable-languages=c,c++
# make && make install

環境設定

使う際には、環境変数に入れて使い分けます

$ export LD_LIBRARY_PATH=/usr/local/gcc/lib:/usr/local/gcc/lib64:$LD_LIBRARY_PATH
$ export PATH=/usr/local/gcc/bin:$PATH
$ alias gcc="gcc-4.8.5"
$ alias g++="g++-4.8.5"

RでLDA

自分用メモ

こちらのRでLDAのサンプルがありますが、うまく動かなかったので修正メモ

環境

  • MacOS10.11
  • RStudio 0.99.484
  • R version 3.3.0

エラー

こちらのスクリプトを順番に実行していくと

# ggplotで可視化
ggplot(topic.proportions.df, aes(x=topic, y=value, fill=document)) + geom_bar() + facet_wrap(~ document, ncol=N) + coord_flip()

この部分で以下のエラーが出ます

 eval(expr, envir, enclos) でエラー:  オブジェクト 'topic' がありません 

以下のように修正します

# ggplotで可視化
ggplot(topic.proportions.df, aes(x=variable, y=value, fill=document)) + geom_bar() + facet_wrap(~ document, ncol=N) + coord_flip()

次はこのエラーです

 エラー: stat_count() must not be used with a y aesthetic.

ここを参考に修正します

修正スクリプト

# coraデータの読み込み(2410の科学記事のデータセット。LISTで2410成分ある)
data(cora.documents)
head(cora.documents, n = 2)

# 科学記事で使われているユニーク単語(2910個)のベクトル
data(cora.vocab)
head(cora.vocab)

# 科学記事で使われているタイトル(2410個)のベクトル
data(cora.titles)
head(cora.titles)

# 分析データの作成(トリッキーな参照をしているので注意)
# 1列目がcora.documentsの第一成分で使われる単語のリスト、2列目がその出現回数
data_cora <- as.data.frame(cbind(cora.vocab[cora.documents[[1]][1, ] + 1], cora.documents[[1]][2,]))
# coreの1番目の記事はこれらの単語とその出現回数で構成されていることが分かる。
head(data_cora)

### LDA
# 推定するトピック数の設定
k <- 10

# ldaパッケージはギブスサンプラーでやるようです。
# ギブスサンプラーの中でも3つくらいmethodがあるようです。
result <- lda.collapsed.gibbs.sampler(cora.documents, 
                                      k,
                                      cora.vocab,
                                      25,  # 繰り返し数
                                      0.1, # ディリクレ過程のハイパーパラメータα
                                      0.1, # ディリクレ過程のハイパーパラメータη
                                      compute.log.likelihood=TRUE)

# サマリを見ると、10成分のリストで構成されている。
# assignments:文書Dと同じ長さのリスト。値は単語が割り当てられたトピックNoを示す。
# topic:k × vの行列。値はそのトピックに出現する単語数を表す。
# topic_sums:それぞれのトピックに割り当てられた単語の合計数
# document_sums:k × Dの行列。割り振られたトピックにおける一文章内の単語数を示す。
summary(result)

# 各クラスターでの上位キーワードを抽出する
# 例は各トピックにおける上位3位の単語の行列。
top.words <- top.topic.words(result$topics, 3, by.score=TRUE)
top.words

# 最初の3記事だけトピック割合を抽出してみる
N <- 3
topic.proportions <- t(result$document_sums) / colSums(result$document_sums)
topic.proportions <- topic.proportions[1:N, ]
topic.proportions[is.na(topic.proportions)] <-  1 / k

# 上位3番までのトップワードを用いて列名をつけて、意味付けを行う。
colnames(topic.proportions) <- apply(top.words, 2, paste, collapse=" ")
par(mar=c(5, 14, 2, 2))
barplot(topic.proportions, beside=TRUE, horiz=TRUE, las=1, xlab="proportion")


###
# ggplotで可視化するために、meltを駆使してデータを作成(トリッキーなので注意)
topic.proportions.df <- melt(cbind(data.frame(topic.proportions), document=factor(1:N)), variable.name="topic", id.vars = "document")

# ggplotで可視化  この部分がうまく動かないので修正
#http://tutorials.iq.harvard.edu/R/Rgraphics/Rgraphics.html
ggplot(topic.proportions.df, aes(x=variable, y=value, fill=document)) + geom_bar(stat="identity") + facet_wrap(~ document, ncol=N) + coord_flip()

# 予測はこんな感じ
predictions <- predictive.distribution(result$document_sums[,1:2], result$topics, 0.1, 0.1)
top.topic.words(t(predictions), 5)


まとめ

Rのパッケージは時々仕様が変わってしまいますので自分でコードを修正する必要があります。

load data local infile で文字化け対応

MySQLのload data local infileの際に文字化けする対策
ポイントはcharacter_set_databaseパラメタを確認することでした

環境

  • MySQL 5.5.43
  • 文字コード utf8

テーブル作成

まずはUTF8でテーブルを作成します。なおデータベースエンジンにはInnodbを使用します

create table TEST(
  id integer not null,
  name varchar(32) null,
  kana varchar(32) null
)engine=innodb default charset=utf8
;

ファイルの確認

インポートするファイルの文字コードをUTF8にします

$ head TEST.txt |nkf --guess
UTF-8 (LF)

UTF8でない場合には以下のコマンドで変換します

$ cat TEST.txt |nkf -w > TEST.txt.utf8
$ mv TEST.txt.utf8 TEST.txt

データベースの設定

データベースの設定を確認します。なおmysqlコマンド起動時に –local-infile をつけないとload data local infileコマンドがエラーになります。5.5あたりからの仕様変更でしたっけ?

$ mysql -uroot -hlocalhost -ppassword --local-infile=1
mysql> show global variables like "character%";
+--------------------------+----------------------------+
| Variable_name            | Value                      |
+--------------------------+----------------------------+
| character_set_client     | latin1                     |
| character_set_connection | latin1                     |
| character_set_database   | utf8                       |
| character_set_filesystem | binary                     |
| character_set_results    | latin1                     |
| character_set_server     | latin1                     |
| character_set_system     | utf8                       |
| character_sets_dir       | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
8 rows in set (0.01 sec)


mysql> set global  character_set_database=utf8;

一時的に変更したい場合にはこちらのコマンドです。このセッションのみで有効です

mysql> set character_set_database=utf8;

インポート

それではインポートします

mysq>load data local infile "/path/to/file/TEST.txt" into table TEST;

これで文字化けせずインポートできます

ubuntu14.04のDockerのipアドレスを変更

dockerはdocker0インターフェースに自動で172.17.42.1のIPアドレスを割り当てます。
これで困るのが、実際のネットワーク上にこのセグメントがある場合。
dockerを起動したこのサーバに、リモートからアクセスできなくなります。

デフォルトの設定
# ifconfig
docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
          inet addr:172.17.42.1  Bcast:0.0.0.0  Mask:255.255.0.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

そこで、docker0のIPアドレスを変更します

修正

/etc/default/dockerファイルに追加

DOCKER_OPTS="--bip=172.66.33.0/24"

リブートします

$ sudo reboot
確認

再度ログインし確認します

$ ifconfig
docker0   Link encap:Ethernet  HWaddr 56:84:7a:fe:97:99  
          inet addr:172.66.33.0  Bcast:0.0.0.0  Mask:255.255.255.0
          UP BROADCAST MULTICAST  MTU:1500  Metric:1
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0 
          RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)

ubuntu14.04のDockerをubuntuユーザで起動

ubuntu14.04にDockerをインストールし、一般ユーザで動かします。

インストール
$ sudo apt-get install docker.io

面倒になると困るのでiptablesを削除します

$ sudo iptables -F -t nat
$ sudo iptables -F 
起動

こちらを参考に

$ sudo groupadd docker   # これは不要かもしれない
$ sudo gpasswd -a ${USER} docker
$ sudo /etc/init.d/docker restart

一度ログアウトしもう一度ログインします

$ docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS               NAMES

Atomのlatexで日本語表示

ちょっとはまっていたのでメモ。

環境:MacOS 10.11

こちらを参考に。

$ cat $HOME/.atom/packages/latex/lib/builders/latexmk.js


'use babel'

import childProcess from 'child_process'
import path from 'path'
import Builder from '../builder'

export default class LatexmkBuilder extends Builder {
  constructor () {
    super()
    this.executable = 'latexmk'
  }

  static canProcess (filePath) {
    return path.extname(filePath) === '.tex'
  }

  run (filePath) {
    const args = this.constructArgs(filePath)
    const command = `${this.executable} ${args.join(' ')}`
    const options = this.constructChildProcessOptions()

    options.cwd = path.dirname(filePath) // Run process with sensible CWD.
    options.maxBuffer = 52428800 // Set process' max buffer size to 50 MB.
    options.env.max_print_line = 1000 // Max log file line length.

    return new Promise((resolve) => {
      // TODO: Add support for killing the process.
      childProcess.exec(command, options, (error) => {
        resolve((error) ? error.code : 0)
      })
    })
  }

//  constructArgs (filePath) {
//    const outputFormat = atom.config.get('latex.outputFormat') || 'pdf'
////    const args = [
//      '-interaction=nonstopmode',
//      '-f',
//      '-cd',
//      `-${outputFormat}`,
//      '-file-line-error'
//    ]
//
//    const enableShellEscape = atom.config.get('latex.enableShellEscape')
//    const enableSynctex = atom.config.get('latex.enableSynctex') !== false
//    const engineFromMagic = this.getLatexEngineFromMagic(filePath)
//    const customEngine = atom.config.get('latex.customEngine')
//    const engine = atom.config.get('latex.engine')
//
//    if (enableShellEscape) {
//      args.push('-shell-escape')
//    }
//    if (enableSynctex) {
//      args.push('-synctex=1')
//    }
//
//    if (engineFromMagic) {
//      args.push(`-pdflatex="${engineFromMagic}"`)
//    } else if (customEngine) {//      args.push(`-pdflatex="${customEngine}"`)
//    } else if (engine && engine !== 'pdflatex') {
//      args.push(`-${engine}`)
//    }
//
//    let outdir = this.getOutputDirectory(filePath)
//    if (outdir) {
//      args.push(`-outdir="${outdir}"`)
//    }
//
//    args.push(`"${filePath}"`)
//    return args
//  }

  constructArgs (filePath) {
    const args = [
      '-interaction=nonstopmode',
      '-f',
      '-cd',
      '-synctex=1',
      '-file-line-error',
      '-pdfdvi',
      '-latex=platex',
      '-e \'$dvipdf="dvipdfmx %O -o %D %S";$bibtex="pbibtex %O %B";$makeindex="mendex %O -o %D %S";\''
    ]

    const enableShellEscape = atom.config.get('latex.enableShellEscape')
    if (enableShellEscape) {
      args.push('-shell-escape')
    }

    let outdir = this.getOutputDirectory(filePath)
    if (outdir) {
      args.push(`-outdir="${outdir}"`)
    }

    args.push(`"${filePath}"`)
    return args
  }
}


こんな感じで修正。

AtomのメニューPackages->Latex->build
で日本語コンパイルできました

Atomで”markdown-pdf referenceerror callback is not defined”

Atomとは、Github謹製のリッチなエディターです。SublimeTextの対抗といったところでしょうか?
プラグインも豊富でかなり使い勝手がいいです。特にMarkdownで文章を書いたりするのが非常に便利

markdown-previewプラグインを入れればctrl+shift+mでMarkdownで書いたドキュメントの成形したプレビューを見ることができます。また、MarkdownからPDFを作成することもできるので非常に便利です

ただし、この設定を上手くしておかないとエラーが出ます。

markdown-pdf referenceerror callback is not defined

このエラーが出た場合には、markdown-pdfとmarkdown-preview-plusというプラグインがEnableになっていると思いますので、markdown-preview-plusをdisableにして、markdown-prevewをenableにすれば治ります

参考URL