Nlp 100 Section 1 Part 3

前回、言語処理100本ノック の04までやったので05からやります。

05. ngram

こいつはbi-gramを単語、文字二つを実装するひつようがあります

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
fn bigram(words: Vec<String>) -> Vec<String> {
    let mut bi: Vec<String> = Vec::new();
    let mut i = 0;

    loop {
        let w = i + 2;
        if w > words.len() { break; }
        bi.push(words[i..w].join(""));
        i += 1;
    }
    bi
}

fn main() {
    let words = "I am an NLPer".split(' ').map(|m| m.to_string()).collect::<Vec<String>>();
    println!("\n===word bi-gram");
    for word in bigram(words) {
        println!("{}", word);
    }

    let words = "I am an NLPer".chars().map(|m| m.to_string()).collect::<Vec<String>>();
    for word in bigram(words) {
        println!("\"{}\"", word);
    }

}

06. 集合

これは単純に HashSet を利用して、解決します。HashSet の差集合は difference を利用し、和集合は union を、積集合は intersection をそれぞれ利用します。また、特定の要素が含有していることを判定するには contains を利用して判定します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
use std::collections::HashSet;

fn bigram(words: Vec<String>) -> HashSet<String> {
    let mut bi: HashSet<String> = HashSet::new();
    let mut i = 0;

    loop {
        let w = i + 2;
        if w > words.len() { break; }
        bi.insert(words[i..w].join(""));
        i += 1;
    }
    bi
}

fn chars(s: String) -> Vec<String> {
    s.chars().map(|m| m.to_string()).collect::<Vec<String>>()
}

fn main() {
    let s1 = bigram(chars("paraparaparadise".to_string()));
    let s2 = bigram(chars("paragraph".to_string()));

    println!("===UNION===");
    for x in s1.union(&s2) {
        println!("{}", x);
    }

    println!("\n===DIFF===");
    println!("===s1 - s2===");
    for x in s1.difference(&s2) {
        println!("{}", x);
    }
    println!("===s2 - s1===");
    for x in s2.difference(&s1) {
        println!("{}", x);
    }

    println!("\n===intersection===");
    for x in s1.intersection(&s2) {
        println!("{}", x);
    }

    println!("\n===INCLUDE===");
    let se = "se";
    println!("s1: {}", s1.contains(se));
    println!("s2: {}", s2.contains(se));
}

07. テンプレートによる文生成

これは format! を使えば終りです。(問題意図ほんとこれなんか?)

1
2
3
4
5
6
7
8
fn string_template(x: i8, y: &str, z: f32) -> String {
    format!("{}時の{}は{}", x, y, z)
}

fn main() {
    let string = string_template(12, "気温", 22.5);
    println!("{}", string);
}

08. 暗号文

ASCII以外の判定と、小文字のASCIIが判れば簡単です。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
use std::ascii::AsciiExt;

fn cipher(src: &str) -> String {
    let chars = src.chars().collect::<Vec<char>>();
    let mut result: String = String::new();
    for c in chars {
        let s = if c.is_ascii() {
            let var: u8 = c as u8;
            match var {
                97 ... 122 => (219 - (var)) as char,
                _ => c,
            }
        } else {
            c
        };
        result.push(s);
    }
    result
}

fn main() {
    println!("{}", cipher("Today is fine."));
    println!("{}", cipher(&cipher("Today is fine.")));
}

09. Typoglycemia

こちらは、 Vecshuffle 的なものがないので、rand を呼び出して shuffle を使います。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
extern crate rand;
use rand::Rng;

fn words(src: &str) -> Vec<String> {
    let mut result: Vec<String> = Vec::new();

    for s in src.split(' ').collect::<Vec<&str>>() {
        let mut chars = s.chars().collect::<Vec<char>>();
        if chars.len() < 5 {
            result.push(s.to_string());
        } else {
            let last_index = chars.len() - 1;
            let first_char = chars[0];
            let last_char = chars[last_index];

            let rand_chars = &mut chars[1..last_index];
            shuffle(rand_chars);
            let mut rand_string = String::new();
            for c in rand_chars { rand_string.push(*c) }
            result.push(format!("{}{}{}", first_char, rand_string, last_char));
        }
    }
    result
}

fn shuffle(chars: &mut [char]) {
    rand::thread_rng().shuffle(chars);
}

fn main() {
    let paragraph = "I couldn't believe that I could actually understand what I was reading : the phenomenal power of the human mind .";

    for w in words(paragraph) {
        println!("{}", w);
    }
}

おわり

ということで Rust で言語処理100本ノック1章をやってみました。 最近 Ruby しか書いていなかったので、新鮮で楽しいですね Rust

NLP100本ノック Section 1 Part 2

前回、言語処理100本ノック の01までやったので02からやっていきます。

extern crate nlp100;

ってやれるように Cargo を作成

1
cargo new nlp100

02. 「パトカー」+「タクシー」=「パタトクカシーー」

これはムズカシイので素直に zip を利用する

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
fn concat(t: (Vec<char>, Vec<char>)) {
    let (f, s) = t;
    let mut r = String::new();

    for (x, y) in f.iter().zip(s.iter()) {
        r.push_str(&format!("{}{}", x, y));
    }
    println!("{}", r);
}

fn main() {
    let p: Vec<char> = String::from("パトカー").chars().collect();
    let t: Vec<char> = String::from("タクシー").chars().collect();
    let f = (p, t);
    concat(f);
}

03. 円周率

この問題は思い切り勘違いしてたので、「これのどこが円周率なの?」って思ってました。こいつは Regex を用いて単語毎に分解、単語毎に文字数数えて解決してます。

1
2
3
4
5
6
7
8
fn char_count_list(w: &str) -> Vec<usize> {
    Regex::new(r"\W+").unwrap().split(w).map(|m| m.len()).collect()
}

fn main() {
    let pi = char_count_list("Now I need a drink, alcoholic of course, after the heavy lectures involving quantum mechanics.");
    println!("{:?}", pi);
}

04. 元素記号

これは、英語版「水兵リーベー僕の船」ですので条件に合うときだけ1文字に変更します。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
use std::collections::HashMap;

fn main() {
    let atomic_words: Vec<&str> = "Hi He Lied Because Boron Could Not Oxidize Fluorine. New Nations Might Also Sign Peace Security Clause. Arthur King Can.".split(' ').collect();
    let mut atomic_table = HashMap::new();
    for (i, a) in atomic_words.iter().enumerate() {
        let chars = a.chars().map(|v| v.to_string()).collect::<Vec<String>>();
        let r = match i {
            0 | 4...8 | 14...15 | 18 => chars[0].to_string(),
            _ => chars[0..2].join(""),
        };
        atomic_table.insert(r, i + 1);
    }

    for (k, v) in &atomic_table {
        println!("{}: {}", k, v);
    }
}

おわり

やっぱり難しいのを実感

Happy New Year and New Language

いまさらですが、あけましておめでとうございます。

happy new language

年開けから新しくプログラミング言語(Rust)始めました。(ってわけでもない)

雑に rust book 2nd edition を一通り読み終えたので、 言語処理100本ノック をやりはじめました。 とりあえず第1章が終ったので、メモとしてのこします。 基本的に Rust (に限らず)でやりたいことがとくにないので ちょうどよさそうな勉強 として自然言語処理を選択しています。

躓いたところ

躓いていないところがないです。 まあやっていくうちに以下二つは常に書いておくと楽になるかなと。

1
2
3
4
5
6
7
8
9
// 1文字毎
fn chars(string: &str) -> Vec<char> {
    string.chars().collect::<Vec<char>>()
}

// 1単語毎
fn words(sentence: &str) -> Vec<&str> {
    sentence.split(' ').collect::<Vec<&str>>()
}

00. 文字列の逆順

これは簡単で(でもなかった)、1文字ずつ分解して反対化したあと String にします。

1
2
3
fn reverse_string(string: &str) {
    println!("{}", string.chars().rev().collect::<String>());
}

01. 「パタトクカシーー」

これも簡単で、1文字ずつ分解して抜き出します。(絶対違う)

1
2
3
4
fn main() {
    let c = "パタトクカシーー".chars().collect::<Vec<char>>();
    println!("{}{}{}{}", c[0], c[2], c[4], c[6]);
}

おわり

とりあえず2問解いてみたけど、自然言語処理 && Rust 難しい。

今年いったビール屋さん 2017

今年行ってよかったビアバー、ビアパブをまとめてみようとおもいます。

何軒いった?

まず、今年何軒いったのか確認します。

  1. 浅草ビアホール D’s diner
  2. Titans
  3. ブラッセルズ
  4. アンテナアメリカ
  5. WIZ CRAFT BEER and FOOD
  6. Bon Fire
  7. 谷中ビアホール
  8. アボットチョイス 渋谷店
  9. グッド スリープ ベーカー
  10. Mikkeller Tokyo
  11. デビルクラフト 五反田店
  12. BrewDog Roppongi
  13. Craft Beer Bar iBREW
  14. カンピオンエール
  15. シェイク シャック 東京国際フォーラム店
  16. Watering Hole
  17. ザロイヤルスコッツマン
  18. Belg Aube
  19. びあマ & Beer-Ma BAR
  20. Tail’s Ale House 本郷店
  21. クラフト ワークス
  22. 地ビールハウス 蔵くら
  23. BEER DINING The Griffon
  24. SWANLAKE Pub Edo 田町店

24軒、大分いってますね・・・

どこがよかった?

だいたいよいですね。Mikkeller, BrewDog, Swanlakeなどの直営店、Watering Hole, 蔵くら, Devil Craftの有名店は説明不要だとおもうんでパスします

特に気に入ったお店

北千住のびあマと大塚のTitansがとくによく、 両店ともボトルビールが充実しています。

びあマのほうはボトルビール選べるお店とタップや角打ちができる複合タイプのお店です。 近くに大きな公園があり、ここでビールを買ってわいわいしながら公園で飲むのがよいかんじです。店のなかで飲むのもよいです。

Titans は持ち込みありのお店で、近くに商店街があり、そこに有名なたこ焼き屋のはち八があるのでここで買ってきて飲むのもいいですし、 鍋持ち込んで鍋するのもよいですね。

あと、いいかんじの雰囲気で住宅街にある店でGood Sleep Bakerが好きです。 ここは Tap 数が少ないですが、パンがとてもおいしいです。 おすすめのメニューとしてはバインミーがとくにおすすめです。

今年行ってない店

意外でポパイ、萬感今年行ってないようでびっくりしてます。

おわり

こうやってみると24軒(重複してるのは数えていない)とほぼ毎週行ってるようで、それはお金がなくなるよね 今年、広島、兵庫行きましたが、どちらも日本酒しか飲まなかったので来年は、東京(関東)以外でも行こうとおもってます。

IRubyはじめました

表題のとおり、 IRuby をはじめてみました

インストール

インストールは簡単で gem install iruby でいけますが、私の利用している環境では依存している czmq が古かったので手動でインストールして回避しています。

1
2
3
4
5
6
7
8
git clone https://github.com/zeromq/czmq.git
cd czmq
./autogen
./configure --prefix=${HOME}/.local
make -j4
make install
gem install iruby cztop
LD_LIBRARY_PATH=${HOME}/.local/lib iruby

でインストールと動作はできます。画像貼るのがメンドイので ipython 貼っておきます。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "\n",
       "  <script>\n",
       "  requirejs.config({paths: { 'plotly': ['https://cdn.plot.ly/plotly-latest.min'] }})\n",
       "  </script>\n",
       "\n",
       "\n",
       "<div id=\"c34db0db-dc37-4ae3-a2b3-33ab99830b89\" style=\"height: 100%; width: 100%;\"></div>\n",
       "\n",
       "<script>\n",
       " require(['plotly'], function(Plotly) { \n",
       "Plotly.newPlot(\n",
       "  'c34db0db-dc37-4ae3-a2b3-33ab99830b89',\n",
       "  [{\"x\":[0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20],\"y\":[100,81,64,49,36,25,16,9,4,1,0,1,4,9,16,25,36,49,64,81,100],\"type\":null,\"mode\":\"\"}],\n",
       "  {\"width\":1000,\"height\":500},\n",
       "  {\"linkText\":\"Export to plot.ly\",\"showLink\":true}\n",
       ")\n",
       "\n",
       "window.addEventListener('resize', function() {\n",
       "  Plotly.Plots.resize(document.getElementById('c34db0db-dc37-4ae3-a2b3-33ab99830b89'))\n",
       "})\n",
       " }) \n",
       "</script>"
      ],
      "text/plain": [
       "#<Plotly::Offline::HTML:0x000056356f14be00 @id=\"c34db0db-dc37-4ae3-a2b3-33ab99830b89\", @data=[{:x=>[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20], :y=>[100, 81, 64, 49, 36, 25, 16, 9, 4, 1, 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100], :type=>nil, :mode=>\"\"}], @layout={:width=>1000, :height=>500}, @config={:linkText=>\"Export to plot.ly\", :showLink=>true}, @embedded=true>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "data": {
      "text/plain": [
       "#<CZTop::Socket::PUB:0x56356e7f3620 last_endpoint=\"tcp://127.0.0.1:45835\">"
      ]
     },
     "execution_count": 4,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "require 'daru'\n",
    "require 'daru/plotly'\n",
    "include Daru::Plotly::Methods\n",
    "\n",
    "dv = Daru::Vector.new((-10..10).map{|n| n ** 2 })\n",
    "plot(dv, x: \"x\", y: \"y\").show"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Ruby 2.4.2",
   "language": "ruby",
   "name": "ruby"
  },
  "language_info": {
   "file_extension": ".rb",
   "mimetype": "application/x-ruby",
   "name": "ruby",
   "version": "2.4.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}

ウイスキーアドベントカレンダー2日目

ウイスキー Advent Calendar 2017 の2日目の記事です。

ウィスキーはピートの香りが強いほうがすきです。

とりあえず蒸留所に行ってきた話を 以前、白州蒸留所山崎蒸留所 に行ったことがあるのでその話を。

白州蒸留所

白州へは5年くらい前に5人でわいわいしながら行ってきました。 ここでは、工場見学のツアーに参加しました。 また、テイスティングルームですこしウイスキーを試せて良いです。

山崎蒸留所

山崎は去年、京都へ行く機会があり、ウイスキーを買うために行きました。 ここでも工場見学可能だったのですが、事前に予約が必要であるため 今回はパスして、工場に併設されているウイスキーのテイスティングルーム で幾つかのウイスキーをたのしみ、ショップでウイスキーと梅酒を買って 鴨川へ

おわり

日本のウイスキーはあまり得意じゃないのですが、蒸留所に行くのは楽しいし 楽しみ方を教えてもらえるので近くに蒸留所がある方は一度行ってみるとよいとおもいます

Mikutter合宿いってきた

mikutter Advent Calendar 1日目のエントリです 先月の11/23-26に @toshi_a の垢凍結記念の mikutter合宿 に行ってきた

なにしにいってきたの?

リフレッシュ、気分転換、野々村せんせーの気分を味わいに、toshi_aさんをAORIに。 蟹、但馬牛、温泉を楽しみに。 くわしくは @akkiesoftブログエントリ を読んで。 城崎は温泉もよく、宿も落ち着いており、周りの店が早く閉まる以外の不満はなかったですね。

でなにやってたの?

温泉、酒、飯以外なにもやってない。

mikutterのgtk3対応手をつけようかとおもったけど、無理だった。

ついでに天橋立もいってきた

室長()が天橋立いくぞっていってたので連れてってもらった。

酒蔵

ついでに天橋立近くの酒蔵 向井酒造 にいってきた。ここは室長が9時までやってるから! って5時半くらいに行ったらすでに閉まってて、丁度女将さんが出てきたところだったので開けてもらい酒を買いました。

おわり

おわり

Emacsの構成管理をitamaeで管理

仕事とプライベート環境でemacsのフォント等設定するのがいいかげんダるくなってきたので、Itamaeを流すだけでイイカンジにするようにした

もともとどうかんりしてたのか

もともとgithubで管理していたが、さすがにFontの環境異差をちょこちょこ変えるのが面倒になった

Itamae de kanri

gitで管理しているので環境異差ある部分をitamaeで管理するように方針を転換。

1
2
3
4
5
6
7
8
emacs:
  font:
    family: Ricty
    height: 120
  packages:
    - auto-complete
  settings:
    - git

とか書いてあとはItamaeを実行することで必要なパッケージのインストール、 必要な設定へのリンク追加などをするようにしました。

おわり

これでなにも考えなくてすむようになるのかな?

Rustful Web

rust で Web Application をつくろうと思って rustful を使ってやってみてたりした。

ドキュメントと利用しているバージョンのコードが異なり、必要なモジュールが読み込めなかったり、関数の引数が異なったりしてうごかねぇってなったのでHEADを使うことで解決。

🍻

とりあえずいつものメンバーで🍻にいってきた。浅草のカンピオンエールという店でのんでそのあと隣の店でお好み焼きをたべてた。お好み焼き屋のあとは河原まであるて吾妻橋からみえる やつをながめながらビールのんでた

Use red-arrow.gem

こないだインストール した Apache Arrow がとりあえず Ruby でうごくようになったのでメモ

メモ

gemのインストールは前回のインストールを行なえば問題ないです。ですが、arrowを利用しようとすると失敗します。

1
2
require "arrow"
/home/katsu/.rbenv/versions/2.4.1/lib/ruby/gems/2.4.0/gems/gobject-introspection-3.1.4/lib/gobject-introspection/loader.rb:37:in `require':GObjectIntrospection::RepositoryError::TypelibNotFound: Typelib file for namespace 'Arrow' (any version) not found

これは GObjectIntrospectionロードに失敗しているようです。 なのでここここを参考に環境変数 GI_TYPELIB_PATH を設定すると読み込まれるようになり実行できます。

1
2
$ export GI_TYPELIB_PATH=/path/to/girepository-1.0
$ irb -rarrow

とやるとエラーがなくなります。

最後にサンプルを実行して確認しました!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
% ruby write-file.rb
% ruby read-file.rb
========================================
record-batch[0]:
  uint8: [1, 2, 4, 8]
  uint16: [1, 2, 4, 8]
  uint32: [1, 2, 4, 8]
  uint64: [1, 2, 4, 8]
  int8: [1, -2, 4, -8]
  int16: [1, -2, 4, -8]
  int32: [1, -2, 4, -8]
  int64: [1, -2, 4, -8]
  float: [1.100000023841858, -2.200000047683716, 4.400000095367432, -8.800000190734863]
  double: [1.1, -2.2, 4.4, -8.8]
========================================
record-batch[1]:
  uint8: [2, 4, 8]
  uint16: [2, 4, 8]
  uint32: [2, 4, 8]
  uint64: [2, 4, 8]
  int8: [-2, 4, -8]
  int16: [-2, 4, -8]
  int32: [-2, 4, -8]
  int64: [-2, 4, -8]
  float: [-2.200000047683716, 4.400000095367432, -8.800000190734863]
  double: [-2.2, 4.4, -8.8]

おわり

最初ろーどえらーでこまってた