エンターテイメント!!

遊戯王好きのJavaエンジニアのブログ。バーニングソウルを会得する特訓中。

tsifyでout of memoryが発生した時に対応したこと

きっかけ

金曜日の夜に、現場のGitリポジトリに修正内容をプッシュしたら、ビルドエラー通知が飛んできて、ビルド時にメモリ不足が指摘された。
一応対処はしたけど、原因究明はまだできてないが、忘れそうなので、記録に残しておく

余談

問題発生タイミングが最悪。
なんで、よりによって金曜の定時後に発生するん?
起こしたのは俺だけどさぁ。。。

メンバーが残り少ない状態で発生して、かなり焦ったわ。

詳細

対応

gulpのタスクに、--max-old-space-size=4096 を追加した。
なぜ発生したのかは分からない。
月曜、調査しないといけない。。。

たぶん、クラス情報をコンパイル時にメモリ保持していると思うのだが、たぶん、大量にクラスを作ってたから起きたんだろうと勝手に予測。
月曜に本格的に調べる。

悩んだこと・詰まったこと

node のコマンドに --max-old-space-size=4096 って付けたんだけど、効果がなくてかなり迷った。
gulpは別プロセスで起動するのだろうか?とりあえず解決したからあまり調べなかったけど、後々になって気になった。

ついでに覚えたこと

--max-old-space-size で指定するサイズは、MB。

反省

手元ではメモリ不足になることは分かってなかったですわ。。。
そもそもマージしただけで、マージ元でエラーなかったし、先でもエラーなかったから大丈夫だろうって思ってたら、コレですわ。。。
ちゃんとプッシュ前にビルド通るかきちんと確認しておけば良かった。。。

参考サイト

Node.js の out of memory エラー回避方法 : まだプログラマーですが何か?

Gulp で process out of memory が出た時の解決方法 | フロントエンドの道標

最近気づいた恥ずかしい話 Javaのインスタンスメソッド参照

きっかけ

Javaは得意分野だけど、知らないことが合ったので、無知を減らすために晒す。
戒めの意味も込める。

導入

はい、タイトル通りでぇーす。
最近知りました。

static(クラス)メソッド参照、コンストラクタ参照は知ってましたが、普通のメソッドも参照できるとは思わなかった。。。。

サンプルコード

とりあえず、実験のため、コード書いてみる。

import java.util.stream.Stream;

public class Test {

    public static void main(String[] args) {
        Stream.of(1,2,3).map(MethodRed::new).forEach(MethodRed::exec);
    }

}

class MethodRed {

    private int target;
    public MethodRed(int target) {
        this.target = target;
    }

    public void exec() {
        System.out.println("test:" + target);
    }
}

やっていることは、Streamに 1~3 の数値を流して、それをもとにMethodRed を生成して、exec メソッド呼び出しているだけ。

こんな使い方できるんだなぁ~って最近知った。

念のため、実行した結果も確認

test:1
test:2
test:3

想定通り。

考察

本当は、stream内であんまり呼び出さないほうがいいのだろうと感じる。
状態が変わるようなら、別インスタンスでやったほうがいいですからね。。。
やる場合は、メソッドが状態を切り替えたりしないような実装とメソッド名にしておかないと、ソフトウェアとして成長する過程で、変な依存を生んでバクを作り出すような気がしました。

あと、これ知ったときは脳天を叩かれたくらいの衝撃が走りましたわ。。。
己の無知を恥じるばかりである。

ちなみに、知ったキッカケは、IntelliJ IDEAのヒント。
マジ、IntelliJ賢いな。
俺より賢い。

指示語が指すものを判別する その2

前回記事

suzaku-tec.hatenadiary.jp

今回、書くに至ったきっかけ

よくよく考えたら、同じ文でも指示語の対象があるな~と思い、ちょっと考えなした。

詳細

例えば、以下のケース

机の上に本があり、それは、母が読んでいたものだ。

前回の実装だと、前の文から探しにいくので、何も設定されない。
だが、この場合の それ は明らかに文章内にある を指している。

解決方法

まず、同一文内で、指示語より前にある主語があれば、それを適用するようにした。
倒置法だったらどうするのって思ったけど、その場合は、指示語を使えないハズなので、考慮の対象外にした。

問題点

上記の解決方法で全部なんとかなるだろうと思ったけど、上手くいかなかった。。。
なぜかと言うと、分単位で位置を特定しているため。。。。

もう少し詳しく説明する前に、ちょっと導入説明。
形態素解析には、kuromojiを使っているのだが、その解析単位は、分単位でしている。
下記を例にする。

企業は自動車やテレビや冷蔵庫など新らしい製品が次々と発売する。それらを買うためには古い製品を捨てなければならず捨てたものの大半がゴミになる。

この場合、文は、企業は自動車やテレビや冷蔵庫など新らしい製品が次々と発売する。それらを買うためには古い製品を捨てなければならず捨てたものの大半がゴミになる。 になる。
その文単位で形態素解析をしているため、形態素解析した結果のトークン情報の位置情報が、文ごとにリセットされている。
最初から、全部一緒に形態素解析すればいいじゃんって思ったけど、そうすると、段落毎の関係性の解析、文書間の関連性の解析が難しくなるのと、長文の場合、位置情報がオーバーフローすると感じたため。
kuromojiの位置情報は、int型なので。。。
今作っている文章解析のライブラリは、長文が前提にあるので、避けたかった。

長くなったが、そういう理由があって、分単位で解析していた。

結構、これに気づくのに時間がかかったわ。

解決方法

もう、どうしようもないので、全部位置情報でなんとかするのは諦めた。

問題は分割して解決するようにした。

どうしたかというと、まず、同一文章内で指示語がないかを、位置情報で解決するようにした。
それで見つからない場合、全文の主語をあてがうようにした。

今後の問題点

ある程度、思い描いたことができるようになってきた。

ただ、まだ動作がおかしい感じがするわ。。。
喋り言葉は、ほぼNGなんだよね。。。。
きちんとした文章なら、きちんと解析できるんだけど。。。
文章の正確さによって、解析結果があてにならなくなったりするのが辛い。。。
今後は、そこら編の精度を高める必要があると感じている。
もしかしたら、アプローチ変える必要があるかも知れない。

プログラミングの初心者を抜け出すための習慣の感想と要約

きっかけ

ソニックガーデンの倉貫のブログはよく見る。
かなり感心したので、自分の考えと経験を踏まえてまとめてみる。

感想

エラーが出ても慌てず、メッセージを読もう

エラーをググって、解決法を片っ端から試すってことを、初心者のうちはよくしてたなぁ~って思い出す。
本当にやるべきは、吐き出したエラーの意味を理解して、正しく対処すること。

書いている意味がわからない状態だと、ググって調べた解決法を試して、さらなる深みにハマることが多々ある。

ググるってのが、さらなるエラーを呼び出す可能性を忘れてはイケない。

ネットの情報を鵜呑みにしない

エラーが出ても慌てず、メッセージを読もう と同じ。
ネットの情報を鵜呑みにした結果、さらなるエラーを呼び出す可能性が高い。

状況を理路整然と書いてあるかどうかも分からない。
特に多いのが、環境情報をまったく書いてないこと。
だから、読み間違うことが多い。
ブログ書く場合は、環境情報をきちんと書く必要がある。

公式ドキュメントから読もう

難しいね、これは。
ボリュームもそうだが、言い回しが面倒なときもあるんだよね。。。

あと、意外と知りたいことが書かれてないこともある。
たまに、分かっている前提の記載がある気がするわ。

ギャグセンスも必要だと思うんですよ。ドキュメントってのは。
面白くかけるかも、ドキュメントには必要だと思うのです。

当てずっぽうで試していかない

エラーが出ても慌てず、メッセージを読もう と同じですね。
あとは、ログをちゃんと読んで、時系列と動作状況を認識しないと、いろんなひとを誤解させてしまう。

未知のものは、まっさらな環境で試そう

不穏分子があると、未知はより大きな未知になる。

なるべくクリーンな環境を作る必要がある。
あと、そのクリーンな環境を簡単につくる方法を用意しておくと良いだろう。

ライブラリを見つける力と目利きを鍛えよう

プログラミングは、何かしらのライブラリを使うことが多い。
俗に言う、「車輪の再発明」をしないため。

だから、ベストな開発をするためにも、便利な環境が必要だと思う。

大雑把に理解できる力を身に付けよう

なんでも全部調べていたら、キリがないのです。
必要な知識レベルを見計らって、適度な内容で撤退するのも、時間をうまく使うという意味ではあり。

深入りする前に、本当にそこまで必要なのか、考えても良いでしょう。

一度に大きく作ろうとせず、小さく進めよう

これな、一気にやろうとして、どこまでできていたのか分からんパターン。

だいたい、自分に自信があるやつが陥るパターンやで。
昔の俺がそうだった。

自尊心が高いやつほど、気をつけないといけない。

「正しく動く状態」をキープするってのが大切。

コミットする前には、動作確認しよう

コミット前にはテスト。

正しい状態を保つための基本

最初にTODOリストを作ってから、始めよう

だいたい、一つのことに熱中すると、やることは大抵忘れる。
だから、TODOリストは必要なのだ。

頭で理解しきれないなら、絵にしてみよう

字にしても、関係性は見えてこないことがある。
イメージに落とし込むことで、理解が簡単になることもある。

字ってのは、頭のメモリをいっぱい使うので、注意が必要なのだ。

メンテナンスの前に、コードを読み込もう

内容理解してからやらないと、オヤシロ様の祟りが起きます。本当です。

WordNetの試し実装

きっかけ

文章を解析するようになったけど、意味合い的に同じなのかチェックしたくなるだろうって思って、実装について調べた。

実装

build.gradle

group 'kuropaper'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.8

repositories {
    mavenCentral()
}

dependencies {
    testCompile group: 'junit', name: 'junit', version: '4.12'
    // https://mvnrepository.com/artifact/de.sciss/ws4j
    compile group: 'de.sciss', name: 'ws4j', version: '0.1.0'
}

resources

src/main/resoces 配下に、下記リンクのjawjaw.conf, similarity.confを置く。
たぶん、クラスパスが通っている箇所なら、どこでも大丈夫だと思う。

ws4j/config at master · Sciss/ws4j · GitHub

そんでもって、同じディレクトリにwnjpn-0.9.dbっていう辞書のDBファイルを置く。
中身は、Sqliteらしい。

http://compling.hss.ntu.edu.sg/wnja/data/1.1/wnjpn.db.gz

かなり大きなファイルなので、githubとかにあげるときは、要注意。

mainファイル

mainとなる実装。
とりあえず、下記をコピペ。

import edu.cmu.lti.jawjaw.JAWJAW;
import edu.cmu.lti.jawjaw.pobj.*;
import java.util.Set;

public class Sample {
    public static void main(String[] args) {
        // "買収"(動詞)という単語から得られる関係の一部をデモします
        new Sample().run( "買収", POS.v );
    }

    private void run( String word, POS pos ) {
        // ファサードから日本語 WordNet にアクセス
        Set<String> hypernyms = JAWJAW.findHypernyms(word, pos);
        Set<String> hyponyms = JAWJAW.findHyponyms(word, pos);
        Set<String> consequents = JAWJAW.findEntailments(word, pos);
        Set<String> translations = JAWJAW.findTranslations(word, pos);
        Set<String> definitions = JAWJAW.findDefinitions(word, pos);
        // 結果表示
        System.out.println( "hypernyms of "+word+" : \t"+ hypernyms );
        System.out.println( "hyponyms of "+word+" : \t"+ hyponyms );
        System.out.println( word+" entails : \t\t"+ consequents );
        System.out.println( "translations of "+word+" : \t"+ translations );
        System.out.println( "definitions of "+word+" : \t"+ definitions );
    }
}

思ったこと

似たような文言を取ってこれる。
うまく使えば、文章の近似性を求められそうな気がする。

不満点は、初期化処理に10秒くらい時間がかかること。。。
どうにかならんもんかね?
SqliteのDBファイルをメモリ展開しているみたいだが、毎回DBアクセスだと遅いのだろうか?

実装にかなり疑問がある。

あまり、偉そうなことは言えないが。。。

実運用にするようになったら、考えよう。。。

参考サイト

日本語WordnetのJavaフロントエンドを利用して,類義語の検索を行った. - へっぽこ修士の忘れ物

WordNetをJavaから使う | Apitore blog

日本語 Wordnet

jshellを使いたくなった瞬間と正規表現

きっかけ

こういうときに使いたいって思ったので、記録として残しておこうかと。

詳細

文字列分割を試みたのだが、予期した状況と違っていた。

いちいち確認用のクラスを作るのは面倒くさかったので、この際、jshell使ってみるとかと思い使った。

やりたかったことは、"遅く起きた。だから、授業に遅刻した。" っていう文を、 文字含んだ状態での分割がしたかった。

まずは、初期の実装。

"遅く起きた。だから、授業に 遅刻した。".split("。")

これだと、結果は、["遅く起きた", "だから、授業に 遅刻した"] になって、予期した結果と違った。 いろいろ調べた結果、後読みってのが使えればいいという結論に至った。

"遅く起きた。だから、授業に 遅刻した。".split("(?<=。)")

これで、["遅く起きた。", "だから、授業に 遅刻した。"] にできた。

結論

  • 正規表現は面倒くさい
  • 使って知識を得るものに対してjshellは有効

言葉の説明が難しいものが世の中にはあって、それを試すのにjshllは有効そう。
それが顕著にでるのが、正規表現な気がしますわ。

正規表現がやりたいことを満たしているのか、実行してみないと分からないからな。。。
サンプル見るけど、本当に理解したのとあっているか、実行してみないと分からない。

正規表現って、もっと簡単に覚えられないものなのか?
使っていると、知識が足りないとかなり苦労する。

参考サイト

正規表現の先読み・後読みを極める! - あらびき日記

[JAVA] 文字列を区切って区切り文字も含める | ぷすぅ~ぷすぅ~

[コラム] 正規表現の先読み/後読みは、どう考えても名前が悪いので、呼称禁止令を出してルックと気軽に呼んでみませんか。 - Qiita

修飾語と被修飾語で、1日ずっと神経をすり減らした。。。

前回記事

suzaku-tec.hatenadiary.jp

連体修飾語と連用修飾語

連体修飾語と連用修飾語の振り分けにかなり苦戦した。。。

主語、述語は分けられたけど、連体修飾語と連用修飾語が難しい。。。

主語や述語の前にあるのが修飾語でしょって安易に考えてたけど、かなり痛い目にあった。

格助詞

キーは、格助詞。

格助詞で「を・に・へ・で」が来れば、格助詞決定。
あとは、主語、述語以外で、活用のあり/なしで連体修飾語と連用修飾語を決めた。

見分け方でかなり悩んだ。。。
土曜の朝から日が変わる直前まで悩んでた。
TDDで開発してるんやけど、全部テストクリアすると、マジで気持ちいい。

強制修飾

これも結構悩んだ。

連体修飾語は、体言にしかかからないと思ったけど、例外もあるのが、かなり悩んだ。
逆も然り。連用修飾語も用言以外にかかることがある。

自分の実装は、読点がある文節があれば、今まで修飾させることができなかった修飾語は、強制的に修飾させている。
なぜそうしたかというと、さすがに読点をまたいで修飾関係になるような文は、文として成り立っていないと思ったから。
いろいろ考えたけど、読点またいだ修飾関係の文を考えることはできなかったわ。。。

実はありますってのがあれば、教えて欲しいものだね。

参考サイト

修飾語について学ぼう - 国語の文法(口語文法)

品詞の分類をマスターしよう - 国語の文法(口語文法)

格助詞の覚え方 | 国語の先生が教える国語文法

日本語勉強してみての感想

日本語って、助詞・助動詞の力がかなり強い。
もちろん、動詞・形容動詞・副詞なども重要だけど、英語を勉強したときには助詞ってあんまり意識したことはなかった。
日本語をより探求するには、助詞を理解することが大切な気がする。

あと、品詞を見分ける力が超重要。
品詞の情報を見て、どれがどういう関係になるのか、かなり悩んだわ。。。

次回タスク

  • 指示語の情報付与
  • 命令系・過去形・断定などの文章の特徴情報の付与
  • 文同士の関係情報の付与
  • デバック用の情報出力機能の実装

愚痴

かなりストレス溜まったわ。。。
考えても考えても、理詰めできない感じがして、ものすごいツライ。。。
日本語の文節の説明って、システムチックな説明じゃないのが、腹立たしい。
よくあるのが、意味が通る/通らないで判別ってのが、マジで意味不明だった。
システム的に、こうだから、これは適用されず、この条件の文節に適用されるって感じで説明してくれないと、システム化できへんねん。。。

そう考えると、人間の考える能力って素晴らしいと感じますわ。

おかげで、情報処理の資格試験の勉強、まったく未着手状態。。。

ストレス解消

もう、ものすごいストレスを溜めた気がする。
ストレス解消のために、ToLOVEるのデジタルカラー版を買ったので、これから読みますわ。

github

GitHub - suzaku-tec/kuropaper