pythonでひらがな、カタカナ判定をする

一覧をリストにしてinで比較してもいいんだけど、もうちょっとスマートにやりたい。
ユニコードとかちゃんと勉強した人にとっては多分当たり前のことなんだと思う。

ひらがなの「も」
カタカナの「モ」

を判別する時、以下のように書くことが可能。

>>> 'あ'<='も'<~'ん'
True
>>> 'ア'<='モ'<='ン'
True

#こちらはもちろんFalse
>>> 'あ'<='モ'<='ん'
True
>>> 'ア'<='も'<='ン'
True

これなら簡単だが、実は「ぁ」などを判別できない

>>> 'あ'<='ぁ'<='ん'
False

ordとchrをつかって、ひらがなの範囲を調べてみる。

#'ぁ'は'あ'の一つ前
>>> ord('ぁ')
12353
>>> ord('あ')
12354

#'ぁ'より前にひらがなはない
>>> chr(ord('ぁ')-1)
'\u3040'
>>> chr(ord('ぁ')-2)
'〿'
>>> chr(ord('ぁ')-3)
'〾'

#'ん'以降を調べる
>>> chr(ord('ん')+1)
'ゔ'
>>> chr(ord('ん')+2)
'ゕ'
>>> chr(ord('ん')+3)
'ゖ'
>>> chr(ord('ん')+4)
'\u3097'
>>> chr(ord('ん')+5)
'\u3098'
>>> chr(ord('ん')+6)
' ゙'
>>> chr(ord('ん')+7)
' ゚'
>>> chr(ord('ん')+8)
'゛'
>>> chr(ord('ん')+9)
'゜'
>>> chr(ord('ん')+10)
'ゝ'
>>> chr(ord('ん')+11)
'ゞ'
>>> chr(ord('ん')+12)
'ゟ'
>>> chr(ord('ん')+13)
'゠'
>>> chr(ord('ん')+14)
'ァ'		#ここからカタカナになる

ひらがなは実用的には「ゖ」が最後、ちゃんと全部取りたいなら「ゟ」まで取れば良さそう。
(「ゟ」は「より」と読むらしい。初めて知った。)



同様にして、カタカナの範囲も調べる。

#カタカナの始まりを調べる
>>> chr(ord('ア'))
'ア'
>>> chr(ord('ア')-1)
'ァ'                         #ここから
>>> chr(ord('ア')-2)
'゠'

#カタカナの終わりを調べる
>>> chr(ord('ン')+1)
'ヴ'
>>> chr(ord('ン')+2)
'ヵ'
>>> chr(ord('ン')+3)
'ヶ'
>>> chr(ord('ン')+4)
'ヷ'
>>> chr(ord('ン')+5)
'ヸ'
>>> chr(ord('ン')+6)
'ヹ'
>>> chr(ord('ン')+6)
'ヹ'
>>> chr(ord('ン')+7)
'ヺ'
>>> chr(ord('ン')+8)
'・'
>>> chr(ord('ン')+9)
'ー'
>>> chr(ord('ン')+10)
'ヽ'
>>> chr(ord('ン')+11)
'ヾ'
>>> chr(ord('ン')+12)
'ヿ'                    #ここまで
>>> chr(ord('ン')+13)
'\u3100'

こちらも、実用レベルなら「ヶ」が最後、伸ばし棒や中黒をカタカナとして判定したい、などなら「ヿ」までをカタカナにすればいい。
(「ヿ」はコトと読む合字)


ちなみに半角のカタカナは以下の通り。

>>> chr(ord('ア')-1)
'ー'
>>> chr(ord('ア')-2)
'ッ'
>>> chr(ord('ア')-3)
'ョ'
>>> chr(ord('ア')-4)
'ュ'

...

>>> chr(ord('ア')-10)
'ァ'
>>> chr(ord('ア')-11)
'ヲ'
>>> chr(ord('ア')-12)
'・'					#半角カタカナのはじめ
>>> chr(ord('ア')-13)
'、'



>>> chr(ord('ン')+1)
'゙'
>>> chr(ord('ン')+2)
'゚'					#半角カタカナの終わり
>>> chr(ord('ン')+3)
'ᅠ'
>>> chr(ord('ン')+4)
'ᄀ'					#ここからはハングル
>>> chr(ord('ン')+5)r
'ᄁ'
>>> chr(ord('ン')+6)
'ᆪ'

「ᄀ」は「ヿ」の半角かと思ったら普通にハングルだった。難しい。


以上を踏まえて、判定するプログラムは以下の通り。

>>> def judge(c):
...    if 'ぁ' <= c <= 'ゟ':
...        print('ひらがな!')
...    elif 'ァ' <= c <= 'ヿ':
...        print('カタカナ!')
...    elif '・' <= c <= '゚':
...        print('カタカナ!')

2017/09/11-09/17

相変わらずじみーーーに体調が優れない一週間。
気だるさというか、季節の変わり目にありがちな体調75%くらいですって感じの微妙なやつ。

週の前半は仕事で使ってるchainerのcrf1dを理解する必要があって、真面目に読んだりいじくりまわしたりした。
やっと理解できた嬉しさから、使い方だけでもシェアしようと思って記事にしたりしてた。
crfの直前にsoftmax入れると数値がダメダメになる、という点でハマってたんだけど、同じ点で仕事先の人が詰んでて親みを感じる。
人がハマるポイントに例外なくハマってる自分がちょっと嬉しい。

仕事先で流行ってるのか、みんなのど痛かったりだるそうにしてたりしてて、職場パンデミックみたいなのはやっぱりあるんだろうなあという気持ちに。
大きい会社だと部署丸々機能停止したりしそうで、インフルの季節とか本当に大変なんだろうな。


chainer力がぐんぐん向上した一週間で、他にも悩んでたことを研究室の先輩に伺ったところ一瞬で解決するなど、改めて先人の偉大さを感じる。
基本的にはプログラミングも数学も雑魚なので、できることからひとつひとつやっていって手数を増やしていきたい。

そういえばゲーム系で働いている知人たちも人工知能に興味ある的なことを昔言ってたようないってなかったような気がするので、いつかまたお酒飲んだ時にそういった情報を共有できたらなと思う。
過去のつながりが有益なフィードバックをもってまた素晴らしいものに変わって行くのなら、それがいちばん素敵なことだと思う。


自分の研究は進捗ダメですって感じでつらい。
進捗報告ってどの程度すればいいのかがいまだに分かっておらず、やってみてダメでした、をどの程度報告するべきなのかなと悩む。

考えただけのもの報告しても、じゃあそれやってみてって言われておわりだし、
考えてやってみてダメでしたって報告しても、じゃあ引き続き考えてって感じだし、

成果ごとに報告してるとしんどいので、やっぱり時間決めてこれやってました、これ考えてました、来週はこれやります、みたいな感じで報告した方が精神衛生上よろしいんじゃないだろうか。


最近このキーボードが欲しくてたまらないんだけど、お金がないので悩み中。
インターンで二ヶ月頑張ったし、これくらいの出費は許されると思うんだけど、やっぱりキーボードに三万近く出せるかと言われるとうーんってなっちゃう。
、、、ということを、仕事先の人に相談してみたら、「お金ってそういう使い方するものでしょ」って言われて少し元気でた。

最終週終わったらポチろっと。

奈良の研究室の画面と、macを繋ぐ変換アダプタみたいなのも買わないといけないし、ちゃくちゃくとお金の使い道が決まる。
いや、稼いだお金の半分以上は学費に回すと決めてるので無駄遣いはできないけど。


日曜日、台風接近の中ディズニーシーに行ってきた。
せっかく東京にいるので、東京らしいアミューズメントもあっていいかなと思って行った。千葉だけど。

雨降るしスニーカーだとびちょびちょになって不愉快かなと思ってサンダルで行った。大失敗。
足冷えるわ一瞬で浸水するわ不愉快以外の何物でもなかった。皆さんにおかれましては、雨の日はどうせ浸水するしサンダルの方が得でしょとかおもわず、しっかりスニーカを履いて出かけられますよう。


二週間くらいかけて通勤時間に読んでたPaulo CoelhoのThe Alchemistを読了。
友人から氏の作品は美しいよと聞いていたんだけど、まさしく美しいという感じだった。
はぇ〜って思いながら読んでた。英語も難しくはないので、ぜひ皆さん読んで。

作中に錬金術師が追い求める賢者の石ってのが出てくるんだけど、そういえば理論系言語学者の追い求める普遍文法も賢者の石なのかもなあと思ったりする。
それが本当に存在するかどうかは保留して、あったらいいなを前提に追い求める姿っていう意味で、言語学者も錬金術師も一緒だよなあと改めて感じる。
昔、鋼の錬金術師っていう漫画を読んでた頃には、こんなこと考えもしなかったのになあ。

最近英語力をあげようと思って洋書を読むようにしてるんだけど、みごと読書にはまってしまった。
奈良に帰る前に新宿紀伊国屋で何冊か洋書買って帰ろうっと。

2017/09/04-09/10

自分のやってる研究的なのが、ちょっとだけ進捗が出て嬉しい一週間だった。
まあ、githubの操作ミスってデータぶっ飛んだから全部コード書き直しっていう残念なこともあったけど。

基本的にびみょーーーに体調が悪くて、仕事も気づいたら一週間経っててなんかなんも生産してないなあという気持ち。

月曜日には学部時代の友人とお酒を飲む。
英文科出身の友人とお酒を飲んで、久しぶりにああーこれが文系だよなあ最高ってなってた。
とかいって、大して数学やってるわけでもないし昔から何が変わったってわけでもないんだけどね。
各々が自分の生活をこつこつ送ってるんだなあと人間味を感じた。

お酒といえば金曜日には研究室の同期と新宿でお酒した。
奈良で出会った岡山出身の友人と新宿で飲むっていう、こういうエキゾチック()な出会いや交友をしてみると、大人になってしまったんだなあという感じ。
久しぶりに自然言語処理についてがっつり話しができたのでとても楽しかった。

インターンさせていただいてる会社も自然言語処理なんだけど、やっぱり同じ年代の人が少ないし、同期で同い年の人と長時間じっくり話すってのが一番モチベーションに繋がると思う。
もちろん、諸先輩がたに啓示を受けるのもモチベーションに繋がるんだけど、あれって外的動機付けに若干近い気もするし。


そういえばニコニコ動画からニコレポがきて、ニコレポメールやめるよ〜って追記がついてた。
あれってフォロー通知とかもなくなっちゃうのかな。
たまに動画がバズった時にフォロー通知ががつがつきて、その度に、お、どれどれって動画の様子を確認しに行くのが楽しみだったので、ちょっと残念。
シミュレーション動画も作らないとなあと思ってる。最近蛇使いにジョブチェンジしつつあってjava力がめっきり落ちてるし、いいリハビリになるかも。

といっても、特にアイディアがないから何もできないけど。

あのシミュレーション動画については、だれか好きな人が真面目に研究して学会とかで発表してくれたら面白いな、と思ってた。
そしたら先日の某学会で、あの動画に比較的近いことをやろうとしてる方がいて、そろそろ波が来たかな?とワクワクした。

僕は特に学術的に考えて作ってるわけじゃないし、妄想したものをそのまま動かしてるだけなので、ぜひみんな類似品作ってたくさんシミュレーション動画界隈を賑わせて欲しい。
ついでに僕の曲もたまには聞いてほしい。

本日は以上です。

【chainer】 crf1d, CRF1dの使い方

chainerのlinks.CRF1dとfunctions.crf1dの使い方メモ。
crfと同様に系列を扱うNStepLSTMとかと同じ気分で使うと事故る。

概要

  • functions.crf1d(cost, xs, ts)

遷移スコア、タグスコア、正解ラベルをそれぞれ受け取って、最適パスをVariableのlistで返す。
遷移スコアは

\ 1,2,3
1 . . .
2 . . .
3 . . .

って感じの行列で、例えばタグ1から2への遷移スコアを5にするなら以下のようにする。

\ 1,2,3
1 . 5 .
2 . . .
3 . . .

他のスコアも適当に埋めて渡せばいい。

  • links.CRF1d(xs, ts)

最適な遷移スコアをヒューリスティックに探すのはしんどいので遷移スコアを学習する。
中でfunctions.crf1dを呼ぶので入出力は同じ形。

入力(xsの形)

# xs for crf1d
# batch size = 2
# batch = [(x,x,x), (x,x)]
[
1st :((1,0,0),(1,0,0))
2nd :((0,1,0),(0,1,0))
3rd :((0,0,1)
]

[]はリスト、()はVariableかnumpyのarray。
リストのインデックスが各時刻、行列がバッチ内の各タグスコア。

実際のコードだと以下のような感じ。
links.CRF1dを使っているが、functionsの方を使うなら上で述べた行列を第一引数に渡せばいい。

>>> import chainer
>>> from chainer import links as L
>>> import numpy as xp

>>> crfL = L.CRF1d(3) #tag sizeを3に設定

#縦方向が時刻
>>> xs = [xp.array([[1,0,0]], xp.float32), 
	  xp.array([[0,1,0]], xp.float32), 
	  xp.array([[0,0,1]], xp.float32)]

>>> crfL.argmax(xs)[1] #.argmaxはscoreとpathのタプルを返す
[array([0], dtype=int32), 
 array([1], dtype=int32), 
 array([2], dtype=int32)]
# batch処理の場合はこう。
# 長さ3の系列を二つまとめて入力。
# タグサイズは3
>>> xs = [xp.array([[1,0,0],[0,0,1]], xp.float32),
...       xp.array([[0,1,0],[0,1,0]], xp.float32),
...       xp.array([[0,0,1],[1,0,0]], xp.float32)]
>>> crfL.argmax(xs)[1]
[array([0, 2], dtype=int32), 
 array([1, 1], dtype=int32), 
 array([2, 0], dtype=int32)]


#可変長なbatch入力をするときは長い順にソートする必要がある。
>>> xs = [xp.array([[1,0,0],[1,0,0]], xp.float32),
...       xp.array([[0,1,0],[0,1,0]], xp.float32),
...       xp.array([[0,1,0]], xp.float32)]
>>> crfL.argmax(xs)[1]
[array([0, 0], dtype=int32), 
 array([1, 1], dtype=int32), 
 array([1], dtype=int32)]

入力(tsの形)

教師データもxsと同じで、縦にして大きい順に横に並べる。

# ts for crf1d
# batch size = 2
# batch = [(x,x,x), (x,x)]
1st :[(0,0)]
2nd :[(1,1)]
3rd :[(2)]
# input
>>> xs = [xp.array([[1,0,0],[1,0,0]], xp.float32),
...       xp.array([[0,1,0],[0,1,0]], xp.float32),
...       xp.array([[0,1,0]], xp.float32)]

# teacher
>>> ts = [xp.array([0,0],xp.int32),
...       xp.array([1,1],xp.int32),
...       xp.array([2],xp.int32)]

>>> crfL(xs, ts)
<variable at 0x10ea6cac8> # variableがかえってくる
>>> crfL(xs, ts).data
array(1.87861168384552, dtype=float32)

ちなみに僕が混乱したのは、同じ系列を扱うNStepLSTMの入力が以下のようだから。

xs = [(1,2,3),
      (1,2,3,4,5),
      (1,2,3,4)]
len(xs): batch Size

BiLSTMでのリストがバッチサイズを表しているのに対して、crf1dのリストは各時刻の入力を表している。
超紛らわしい。


(余談)
CRFを使うときにsoftmaxを噛ませると学習できないので、pre-trainingとかしてるひとは気をつけてね!
functions使うときにスコアをある程度正規化してから渡したいなぁ〜とか思ってると、普通に学習できなくて死ぬ。


わかりづらいとか、間違いとかあったらコメントでお願いします。

2017/08/27-09/03

いろいろやってることはあるんだけど、仕事内容なので書けないと言うのが辛い。
さっさと奈良に戻りたいぞー。

インターンも折り返して、やっと慣れてきた。
仕事終わりに吉祥寺あたりでディナーして帰るくらいの余裕を持てるようになった。

くだんのインターンでも中間報告をさせていただいて、いろいろと意見をもらえたのでとてもありがたい。
こうやって、微力ながら自分のやってることが人の役に立つかもしれないって言うシーンに立ち会えただけでも、このインターンに参加した意義はあると思う。
結局、自分がやってることがなんかの役に立つのか?っていう漠然とした不安を消し去りたいと言うのが目標だったし、とても良い経験をさせていただいてる。

これがよくある天下りインターンだと、なんだかよくわからない論文を読まされて、なんだかよくわからないまま実装して、発表して、技術力がつきました、みたいなつかみどころのないものになってたのかもしれない。
改めて、のびのびとやらせてもらえてありがたい限り。

会社で論文読み会をやるということで、未熟ながら僕からも一本論文を紹介させていただいた。
ぶっちゃけ言語処理っていうとみんな機械翻訳とか、対話とか、要約とか、そういうのばっかり目がいくよね。
僕はもっとニッチなところが好きなので、比較的浮き気味な論文選択。
ただ、僕の面倒を見てくれてる方が同じジャンルで論文紹介をしていたので、僕もできるだけわかりやすくスライドを作ることにした。
教育学部出身の強みとか、スライドのわかりやすさくらいしかないのでそこは気をつけていきたい。

土曜日、学部時代のゼミの先生宅でパーティということで誘っていただく。
大学院から分野を変えてしまった僕は、恩師に顔向けしていいものかって感じなのだけど、その辺は好きにしてって雰囲気を作ってくれてるのはとても素敵だと思う。
もとより個人主義で、ゼミも個人主義の人が集まってるのでとても居心地が良い。
久しぶりに尖った人たちと一緒にいて、感化された気持ち。
自分も研究者としてこの人たちに並べるようにならなきゃと今週のお気持ち引き締めを行う。

ちなみにお酒を飲みすぎてニキビに酒灼けにと散々な日曜日を過ごした。
立川のららぽーとをぶらぶらしたけど、あそこ楽しいね。
半日いたけど、まだ回りきれてない。
東京生まれだと、あーいう大きいショッピングモールというものに縁がないのでとても楽しくてしょうがない。

夜は立川北口の回転寿司、三千円もかからずにお腹いっぱい寿司が食べられたのでとても満足。
奈良に戻ると魚が高いので、今のうちに食べためしておきたい。

来週は飲み会が二つ予定されてる。
東京にいるのは九月末までなので、もし一緒にお酒飲みたいって人がいたらぜひお早めに。

2017/08/21-08/27

東京にいる間しかPSO2できないよなあと気づいて、手元にあるパソコンにPSO2をインストールして久しぶりにプレイした。
なんというか、色々変わっててびっくりした。
オンラインゲームって本当に少しやってないだけでものすごく置いていかれるよね。

とりあえずヒーローって職業が追加されてたのでツインマシンガンぱしぱしして遊んでた。
もうキャップ解放にもついていけないというか、80解放の条件えぐすぎでしょ。

ゆるくプレイしたいだけなので、もう若くない。ていうか時間がない。


でもまあ、基本的にPSOシリーズは大好きなので、なんだかんだ文句を言いながらしっかりお金だす。
ストーリーだけでも追うつもりだし、サービス終了までしっかり付き合うつもり。


久しぶりに学部時代の友人に会った。
母校のすぐ目の前にある、よく行ってたカフェで無言で勉強するだけの仲で、とても良い関係だと思ってる。
彼とは今後もずっと研究者仲間として仲良くしたいなあと感じる。

そういう感じの、濃い友人が何人かいればいいやというタイプなので、誰彼構わず遊んで騒ごう、というのはあまり好きじゃなかったり。

土曜日の夜には高校時代の友人とお酒を飲む。
あんなにお酒飲んだのいつぶりだろう。
天真爛漫という言葉がぴったりの女友達が、相変わらず破天荒だったので変わらないなあという感じ。

傷心の友人も、仕事帰りの友人も、真面目に社会人やっててすごいし、改めて自分は尖った生き方してるなあと感じる。
僕は僕でしっかり行けるところまで行かないとね。

日曜日、久しぶりに研究の進捗が出た。
なんだかんだ言って、インターンで平日は潰れるし、土日は誰かに時間を取られてしまうので一ヶ月ぶりに自分の研究のために集中力をガンぶりできた。
昼間の一番集中できる時間に、カフェとかで真面目に考えられるのは素敵だね。

自分のピークタイムを何に使うか、スケジュール感を持って生活しないと。

2017/08/14-08/20

祖父母と親戚に会うための家族旅行に同伴する。
毎年富山の祖父母家に集まるんだけど、祖父母ともに恒例になってきてみんなで旅行できるチャンスもそうないしってことで、今年は長野一泊弾丸旅行。

僕は運転手でした。

実は妹が数日前まで塾の合宿で長野にいて、僕は僕で一昨年に長野にゼミ合宿で行ってて、本当にアクセスがいいというかお手軽な観光地なんだなあ長野、と感じる。
数ヶ月ぶりにハンドル握って、善光寺あたりの狭い道を頑張って運転したので夜ご飯とかお風呂とか最高だった。
労働してこその大浴場。

翌日は軽井沢のアウトレットをぶらぶら。
あいにくの雨で、しかもうちの家族はウィンドウショッピングができない人ばっかりなのでつまらなかったらしい。
僕は大好きなタケオキクチで服買えたのでるんるんだったけど。

長野駅らへんから軽井沢の近くまで車で行ったんだけど、大雨で非常に怖かった。
悪天候の高速道路ってやだよねー、トラックの水しぶきで前見えないし風に煽られるし。
命が惜しいし家族を載せてたので80キロでのろのろ走ってた。
だいたいヤマトの後ろとかにくっついてれば安全運転ができる。


夏休みらしい夏休みは以上で、あとは普通にインターン先で仕事してた。
週末、なんかよくわからないけどC++を勉強しようと思い立って、適当に入門書を買って眺める。
想像以上に面白い言語だったので、食わず嫌いってよくないなと痛感する。
なんで今まで警戒してたんだろう。


日曜日、原宿から表参道、渋谷へとてくてく散歩。
牛カツのお店でお昼、牛タンのお店で夕飯というリッチで胃もたれする食生活を送る。
東京に来てから高いものばっかり食べてて財布は薄くなるし見た目は太くなるし、幸せなんだかわからない。

まあ、美味しいもの食べるのは幸せだからなんでもいいか。