wassup?

新ブログ→memo.wass80.xyz

京都小旅行 大徳寺→たこ焼き→船岡温泉→ステーキ

突発的な観光のお時間です。

今回は船岡温泉周辺のスポットに行きました。

まず大徳寺龍源院を眺めました。 このサイズ感、ボドゲ枯山水にそっくりですね。(拝観料350円)

f:id:wass80:20181223211356p:plain 大徳寺はめちゃくちゃ敷地が広く、拝観できる場所も4つあるらしいです。それぞれ拝観料が取られるので諦めて龍源院だけ見ました。龍源院には、日本に伝来した最古の火縄銃や、蒔絵の碁盤などが飾られていました。歴史的ですね。

西に出て堀川通にあるたこ焼き屋「すずや」(8個500円) 関西にはあまりない大ぶりのタコが入っていて満足度が高い。ソースが旨味が強くて美味しい。 f:id:wass80:20181223211259p:plain

雨が降ってきたので更に北上するのをやめて船岡温泉に向かいます。 船岡温泉の最高さは他の記事を見てください。京都で最も格式の高い銭湯です。彫り物とタイルがものすごく立派です。写真を取りたくなるんですが、脱衣所内は撮影禁止。 (湯料430円)

www.kyo1010.com

1時間ゆっくり風呂に入った後は、お待ちかねのステーキです。

tabelog.com

この12月にできた新店舗らしいですね。 +250円でカレーが食べ放題になってすごい。

食べ放題のカレーはこんな感じです。4杯食べてしまったのでとても反省しています。 f:id:wass80:20181223212753p:plain

(アンガスステーキ150g 980円+ご飯カレースープ食べ放題250円) f:id:wass80:20181223212858p:plain

肉とカレーを手に入れたら当然こうなります。 f:id:wass80:20181223213035p:plain 美味しかったです。

スパワールドからの串カツが最高

スパワールドをご存じでしょうか。 知りたい人は次の記事を見ると速いです。

srdk.rakuten.jp

朝、出町柳駅に集合し、京阪でまっすぐ大阪へ。

昼ごはんは「ほまれ」に行った。

最近だとVTuberの日雇礼子さんが紹介してはったような。少なくとも中の人はやる夫スレで紹介していたはず。500円の天丼がすごい。物価の崩壊を感じる。 www.youtube.com

その後は、新世界で昔夢見たスマートボールをプレイ。未成年は遊べないんですよねこれ。 結果は惨敗。300円吸い込まれた。 友人は勝ちまくってとんがりコーンを手に入れていた。すごい。

お待ちかねのスパワールドは最高だった。平日の昼に行くとものすごく快適。10年ぶりだったが昔のまま変わらずという感じだった。塩サウナから滝湯までたっぷり2時間も堪能した。

そういえば昔行ったときもヨーロッパゾーンで、もう一方のゾーンには未だ行ったことがない。

スパワールドで何が便利かというと、入場料1000円以外 はクレカで払えるんですよね。しかも出場時払い。手首に巻いたやつで自販機から牛乳を買うことができる。

ただコインロッカーが100円硬貨式なんですよね。そこだけが悔やまれる。

そのあとは新世界で串カツですよ、串カツ。 とりあえずどこかに吸い込まれておけば串カツを食うことには困らないはず。

風呂上がりのゆったりした気分で京阪で京都に帰る。最高ですね。

ふらっと京都旅「一乗寺(詩仙堂・狸谷不動院)」

京都にずいぶん長くいるんですが、実はほとんど観光したことがありません。 そのため、最近また京都観光の気分が高まっています。

今回は紅葉の始まった時期に行った詩仙堂と狸谷不動院の写真たちです。

詩仙堂

京都に数多ある紅葉の名所の一つ。 名前の由来は三十六詩人を飾った詩仙の間によるらしい。*1

山荘に入るとすぐに目の前の庭を見ることが出来ます。この景色がメインです。 f:id:wass80:20181222204945p:plain

その後、庭に降りることが出来ます。この時は斑紅葉でしたが、これはこれで趣がある。 f:id:wass80:20181222205605p:plain

鹿威しを威すことができます。紅葉が乗っていて風流ですね。 f:id:wass80:20181222205523p:plain

八大神社

すぐ西、山の上側には八大神社があります。宮本武蔵がいました。 f:id:wass80:20181222205814p:plain

狸谷不動院

今回特に行きたかった所です。 詩仙堂の前の坂をさらにさらに登ると辿り着きます。 自転車を押して登りました。

f:id:wass80:20181222210016p:plain

入り口には狸の名前の通りたくさんのたぬきの信楽焼があります。

ここに来たかった理由は、『有頂天家族』の聖地巡礼というやつです。矢三郎のお母さんのパネルが建物の中にありました。

不動明王を祀る本殿がこちらです。中は撮影禁止でした。 f:id:wass80:20181222210212p:plain

この建物の不動明王を祀ってあるところは洞窟になっています。どういうことかというと、この建物を逆側から見たのが下の写真です。 f:id:wass80:20181222210251p:plain

このように崖に接しています。この崖にあった洞窟の目の前に本堂を建て、洞窟の中に不動明王を祀ったらしいです。

この日は特別にその洞窟の中まで入れました。人も居なかったのでその洞窟の静けさを味わうことができました。

百舌谷さんのMVが最高な件

2018-12-19に公開されたこのMVを見てほしい…

www.nicovideo.jp

かっこよすぎる。

百舌谷(もずや)さんを知ったのはこの曲のMV。 www.nicovideo.jp

tilt-sixさんのchiptuneの名曲である。 このPVも百舌谷さんのものであった。 2013年の映像なんですが、今でもめっちゃ新しく感じてしまう。

2016年にもコラボをしていて、またこのMVがめちゃくちゃ力が入っている。

www.nicovideo.jp

3Dの技術面白いですね。

エレクトロサチュレイタ (feat. 初音ミク)

エレクトロサチュレイタ (feat. 初音ミク)

アルコールって美味しいんですか?

お酒に弱いわけではない。お酒の影響はあまり受けない。ただちょっと内向的になってしまう。

お酒を楽しむ上でエタノールの美味しさをあまり理解していないのが問題らしい。ワインってもともとぶどうジュースが美味しいのに、その糖分をエタノールに変換して美味しさを減らしてしまってるように思う。でも、その発酵過程においてできる香りは嫌いではない。

同じことは日本酒にも言える。確かに日本酒の香りはいい匂いである。酒粕も好物である。ただ味はただのエタノールと残った糖分の味しかしないのでは?人間はいかに香りに騙されるかよく知っている分、味そのものはよくわからなくなる。

蒸留酒は更に難しい。味は殆ど失われて、香りしか残ってないんじゃないだろうか。ウイスキーにしたって、香りは楽しい。ただ味はエタノールでしかないように思えてしまう。

ビールが一番おいしさの評価ができない。飲みやすいか飲みにくいかでしか判断できない。苦いのが苦手でもないので、どんなビールでも飲むことはできる。

香りも含めて味という主張はわかる。しかし、その上でエタノールが味にプラスの働きをもたらしているか、わからない。 ごく少量のエタノールが清涼感を与えることはよく知られている。製菓に用いるラム酒などはそれを狙っている。だが、特に10%を超えるエタノールは雑味に感じてしまう。これは僕の舌が悪いんだろうか。

お酒が嫌いなわけでは決してなく、人のお酒をまずくしたいとも思っていない。カクテルを作ったことがあるが、楽しかった。ただ、お酒に対して真剣に考えると、このような雑念がどうしても振り払えない。

誰か美味しいお酒を教えてほしい。

かな配列を自分のSlackの発言から作る

このエントリーはKMC Advent Calendar 2018の14日目の記事です。

adventar.org

13日目の記事は以下の記事でした。

blog.pastak.net

こんにちは。4回生になり、卒論の進捗に追われているwass80です。

キーボードの自作が流行っていますね。 自作は大変なので、今回は今あるキーボードで早く入力する方法を考えます。

tl;dr

  • とりあえず手でかな配列を作って試す。
  • 自分のSlackの発言から1-gram, 2-gramを求める。
  • 自分にとって押しやすいかな配列を焼きなましで求める。

かな入力

ローマ字での入力ではなく、50音での入力です。 多くのキーボードに書かれている「JISかな」による入力が最も普及しています。 ローマ字入力では多くが1文字2打鍵(ha, ki)ですが、 かな入力では多くは1文字1打鍵(は, き)なので有利と考えられます。

しかし、キーボードに書かれている「JISかな」は、あまり最適化されていないように感じます。 なので、この配列をいじることで、より楽なかな入力について考えます。

かな配列の種類

いろいろなカナ入力配列 様々なかな配列についてはここが詳しいです。

  • 用いるキーの数と配列
  • シフトキーの数と種類

によって様々配列が提案されています。

3段配列、4段配列

使うキーの数は主に段数で示されます。 手元の「JISかな」を見るとわかるように、 「JISかな」は上から1段目数字のキーも使って全部で4段のキーを使っています。

有名な「親指シフト」は3段配列として知られています。

FUJITSU COMPONENT LIMITED - FKB7628-801.JPG
By udfoto - 自室にて撮影, CC 表示-継承 3.0, Link

更に極端な例だと2段配列や1段配列があります。 しかしこの場合、使えるキーが20個程度かより少ない数になります。 原則1キーに1かなを対応させる、かな配列の入力をするのには困難性が伴います。

シフトキー

たとえ4段配列にして、すべてのキーをかなに対応させても、キーは足りません。 入力したい文字は84ほどあります。

ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんー

そのため、配列のモードを切り替え、別の配列を入力する方法が必要になります。

前シフト、後シフト

入力したい文字の前(または後)にシフトキーを押すことで、別の文字を入力します。 お手元の「JISかな」では「゛」「゜」のキーが後シフトです。

「か」+「゛」=「が」

となります。

同時シフト

同時シフトは英字キーボードでのシフトキーと同じものです。 シフトキーが押されている間、別の文字が入力されます。

左右シフト

シフトキーが1つでは足りない場合は、シフトキーに左右で別の役割をもたせます。 「親指シフト」ではキーを押した時、同じ側のシフトか、反対側のシフトかで別の文字が入力されます。

とりあえず手でぽちぽち作った配列

かなの頻度表(=1gram)を見ながら、とりあえず手で配列を作りました。 参考: 漢直ノート ひらがな1-gram表

f:id:wass80:20181212200331p:plain
α

仕様

  • Shiftキーは英数入力のためになるべく用いない。
  • 濁点キーを前入力する。
    • ゛+た=だ
  • 濁点キーにより大小も反転する。
    • ゛+っ=つ
  • 二文字書かれているキーはその2文字が清濁の関係とみなす。
    • ゛+め=ぬ
  • Shift ゛+ は = ぱ
  • 1+せ=8

考えたこと

  • 頻度の高い文字を押しやすい上から3段目におく。
  • 濁点キー「゛」が右手側に1つしかないため、清音を左手側に集めている。
    • 左右のキーを交互に用いると速いため。
    • 実は「JISかな」でもそのようになっている。
  • 「が」は高頻度なので、単体でキーが存在する。
  • 「っ」「ゃ」「ゅ」「ょ」が表の配列で小文字。
    • 大文字より小文字のほうが頻度が高いため。
  • あまりに使わない文字を清音の裏(濁点キーで入力)に押し込んだ。

試す

google IMEのローマ字テーブルを作りました。

https://gist.github.com/wass88/3c9e895f9aa872e07cc8c4ddfc2e5b3b/raw/38f92bbf76e4f7967a9acc5469332b792155f446/wass-arr.txt

f:id:wass80:20181212201221p:plain
ローマ字テーブル登録方法

問題点

  • 配列を覚えるのが大変です。
  • あまり頻度順に並んでいないように感じました。
  • シフトキーは両側にないとキーの配列の左右の自由度が失われます。

真面目に最適化を考える

頻度順に並んでいないように感じる理由は、参考にした1-gramが自分の入力したコーパスではないからだと考えられます。 なので、サークルのSlackから自分の発言を抜き出し、自分のコーパスを作ります。 また、2-gram(連続2文字の頻度)を参考にして、 なるべく左右の手が交互に使われる配列を目指します。

python notebookはこちらです。 Keyboard配列 · GitHub

前処理

Slackから発言を取得する

slackclientを使いました。

コード

from slackclient import SlackClient
slack_token = TOKEN
sc = SlackClient(slack_token)

def fetch_msg(page = 1, count = 100):
    try:
        res = sc.api_call(
            "search.all",
            query = "from:@wass80",
            count = count,
            highlight = False,
            page = page
        )
    except e:
        print("Retry")
        sleep(10)
        yield from fetch(page, count)
    if "messages" not in res:
        print("missing", res)
        return
    res = res["messages"]["matches"]
    for r in res:
        yield r["text"]

def fetch_all(count = 3, batch = 100):
    for i in range(1, count + 1):
        print("Fetch: %d" % i)
        yield from fetch_msg(i, batch)
        sleep(10)

with open("msg.txt", "w") as f:
    for m in fetch_all(170):
        f.write(json.dumps(m) + "\n")

発言から記号を取り除く

def remove_symbols(s):
    s = re.sub(re.compile(r"```.+```", re.MULTILINE | re.DOTALL), " ", s)
    s = re.sub(r"<[^>]+>", " ", s)
    s = re.sub(r"`[^`]+`", " ", s)
    s = re.sub(r":[^:]+:", " ", s)
    return s

remove_symbols("hoge<piyo>hoge`piyo`hoge```\npiyo\n```\nhoge\n:piyo:")
'hoge hoge hoge \nhoge\n '

読み方からひらがなに戻す

janomeを使いました。

from janome.tokenizer import Tokenizer
tk = Tokenizer()

def reading(s):
    res = ""
    for t in tk.tokenize(s):
        if t.reading != "*":
            res += t.reading
        else:
            res += " "
    return res

reading("丸竹夷に押御池")
'マルタケエビスニ '

辞書にない単語は無視されますが、あまり問題にはならないでしょう。

1-gram, 2-gramを求める

1-gram

せっかくなので、手で作ったときに参考にした1-gramと比較しました。 文字が自分の1-gramです。丸が参考にした1-gramです。 青は参考より自分の頻度が多い。赤は逆です。

f:id:wass80:20181212183103p:plain
1gram

2-gram

これは、次の項目の1重キー、2重キーの計算結果が反映されています。

f:id:wass80:20181212211533p:plain
2gram*1

配列計算

配列の定義

  • 1重キー(清音のみ)と2重キー(清濁)を定義します。
  • 前シフトキー「゛」の後、2重キーは裏の文字になります。
  • シフトキー「゛」の場所は固定。両側に配置。

2重キーの分解

逆に、表も裏もよく使うキーの場合、分解します。 「かが」→「か」「が」

2重キーの反転

裏のほうがよく使うキーの場合、反転します。 「ゆゅ」→「ゅゆ」

結果

1重キー(頻度順)

'イ', 'ン', 'ウ', 'カ', 'シ', 'ノ', 'ナ', 'タ', 'デ', 'テ', 'ル', 'マ', 'ニ', 'ガ', 'コ', 'ジ', 'リ', 'ョ', 'ア', 'ダ', 'ラ', 'オ', 'モ', 'レ', 'ヨ', 'エ', 'ヲ', 'メ', 'ミ', 'ワ', 'ム', 'ネ', 'ロ', 'ポ', 'プ', 'パ', 'ヅ', 'ペ', 'ピ', 'ヌ',

2重キー

[('キ', 'ギ'),
 ('ク', 'グ'),
 ('ケ', 'ゲ'),
 ('サ', 'ザ'),
 ('ス', 'ズ'),
 ('セ', 'ゼ'),
 ('ソ', 'ゾ'),
 ('チ', 'ヂ'),
 ('ッ', 'ツ'),
 ('ト', 'ド'),
 ('ハ', 'バ'),
 ('ヒ', 'ビ'),
 ('ブ', 'フ'),
 ('ヘ', 'ペ'),
 ('ホ', 'ボ'),
 ('ヤ', 'ャ'),
 ('ュ', 'ユ'),
 ('ー', '〜')]

1重キーの圧縮

1重キーと2重キーの合計がキーの数より多いので、 1重キーの裏に1重キーを置くことで2重キーにします。 これによって「゛」+「シ」=「ワ」など、多少理不尽なことが起こりますが、諦めます。

配列の計算

  • キーの場所をどこにするか。
  • 圧縮された1重キーの場合、裏に回ったキーの場所をどこにするか。 この2つがパラメータとなります。

配列のコスト

3種類のパラメーターをキーの場所ごとに定義しました。

self.press = [100, 10, 0, 20][y] + [1, 0, 0, 0, 1, 1, 0, 0, 0, 10, 20, 30][x]
self.finger = [1, 2, 3, 4, 4, 5, 5, 6, 7, 8, 8, 8][x]
self.hand = [0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1][x]
  • pressは押しにくさを表す重み。
  • fingerは押す指。
  • handは押す手。

最終的な配列のコストは:

  • 各キーのpressとその1_gramから次の値を合計する。
    • front = 1_gram * press * 1gram_w (表キーの押しにくさ)
    • back = 1_gram * press * 1gram_w * back_w (裏キーの押しにくさ)
  • 2_gramから次の値を合計する。
    • 同じ指を連続で使うなら finger = 2_gram * same_finger_w
    • 同じ手を連続で使うなら hand = 2_gram * same_hand_w

それぞれ重み(*_w)は何度か焼きなましして適当に決定しました。

焼きなまし

適当に生成した配列にこの2つの演算を適用します。 上で定義した配列のコストが小さくなるように焼きなましをします。

初期生成

上が表、下が裏です。

@
- - - - -
- - - - - - - - - - - -
  • コスト: 21.629534099116793,
  • 'hand': 0.39129205368876097,
  • 'finger': 0.4639484594384564,
  • 'front': 18.760037452391433,
  • 'back': 2.0142561335981406

焼きなまし後

@
- - -
- -
- - - -
- - - - - - - -
  • コスト: 15.252237067009535,
  • 'hand': 0.3088283757887919,
  • 'finger': 0.20433342691029233,
  • 'front': 13.840631230449489,
  • 'back': 0.8984440338609608

できた配列を試す

  • Google IMEのローマ字テーブルとして出力して試しました。
  • わかったこととして、4行配列は手の動きが大きすぎてやはり面倒です……。
  • 指のもつれとかは起こりにくいのかもしれないです。
  • ただ、キーを全然覚えられる気がしなかったので諦めてしまいました。

phoenix配列

やはり4段配列は手を1段目に持っていくのが面倒です。 手が動かない配列はないかと探すと、phoenix配列が良さそうでした。

phoenix配列は2段配列のアルファベット方式です。 サイトにはgoogle IME用のテーブルが用意されているので、手軽に試すことが出来ます。

phoenix Real Time Input Method

f:id:wass80:20181212204229p:plain
phoenix配列

漢字直接入力も対応しているらしいですが、流石に覚えられない自信があります。

wass-phoenix配列

せっかく自分の1-gramを求めたので、この配列も自分に最適化しました。

f:id:wass80:20181212204401p:plain
wass-phoenix

結局配列を作っても、それを覚えるコストが高すぎて、全然使いこなせません……。 なにかいい方法はあるのでしょうか。

*1:ところでこれ、公開して大丈夫なんでしょうか。完璧な電子シュレッダーによってバラバラになった情報から、元の情報の断片を作ることはできるのでしょうか。例えば、これと辞書をマッチすることで、僕が普段発言してそうな単語が割れそうじゃないですか?こわい。「あび」がちょっと多いの、絶対『メイドインアビス』のせいですよね。んなぁ。

ISUCON8 反省

:thinking_face: 学生枠参加。本戦14位/30

SNSシェアをしなかった中ではそれなりの順位っぽいですね。

https://github.com/wass88/isucon8-final/issues/2

// の後ろが事後反省。

  • /infoの改善 -まともな時系列DBを使うほうが早そう // 時間内に無理
    • キャッシュする→定期的に生成するとかを思いつくべきだった 
    • たぶんここがかなり効くんだと思う
  • 取引測度の改善
    • POST /orders でrunTradeする必要はない。
    • Tradeサーバーをgoで動かす // できなかった。 pythonでもやろうとしたがうまく行かず
    • Tradeのアルゴリズムを改善 // 時間内に無理
  • ISULOGGER の send_bulk を使う。
    • sendをまとめて1リクエストにしてくれるやつ。非同期にログを流す。
    • // Logサーバーを立てて実装した。
    • // +200点ぐらいにはなってくれた気がする。
  • /signinのBAN
    • // 実装間に合わず
    • // SNSをONにしたときに効くらしい。
  • isucon-3のインスタンスが速いらしい
  • setting DBは完全に不要。
    • // redisに置いてもらった。
  • // SNSにはほとんど手を付けていなかった、最後30分でONにしてFailして終わりだった。
    • // 確率的にONにするのは思いつかないな…

SQLの改善はutgwさんに、インフラは全部nonyleneさんにやってもらった。

僕は全体を見て最初の2時間で戦略を練っていた。

/infoの真面目な改善について話し合うべきだった。

問題はすごく良かったと思います。まだまだ手を付けられるところが多い。

Pythonで非同期な処理を書くの非常に面倒なので、次からはGoでやりたい…

毎年要求されるレベルが線形に増えていくので、それに追いつかない感じがある。頑張り。