Pythonのunicodedata.normalize('NFKC', x)で正規化される文字一覧
Pythonのunicodedata.normalize('NFKC', x)で正規化されて変わる文字ってどんなのがあるんだろうと思って一覧を作ってみました。
https://gist.github.com/ikegami-yukino/8186853
左が変更前の文字、右が変更後の文字(アラビア文字は左右が逆になります)、括弧内の数値はUnicode IDを表します。
(自分がわかる範囲の)ほとんどの変換結果は納得できますが、一つだけ [65374] 〜 から [126] ~に変換されるのはどうかなあと思いました。たとえばインタ〜ネットがインタ~ネットになったり。normalizeする前に〜をーに変換する前処理を加えた方がよさそう。
あとこの変換結果の前後を逆にして、メートルを㍍にするような変換テーブルを作るとTwitterみたいな文字数制限のあるとき用の文章を作るときの文字数節約に使えるかも。
Wikipedia見出しリストから不要な見出しをカットする
検索サイトで「wikipedia mecab」と検索するとWikipediaの見出しリストを整形してMeCab用辞書として使う記事が何件かhitします。
しかし、Wikipediaの見出しは形態素解析用に作られたわけではないので、形態素として扱うと不都合になることがあります。
たとえば、文書から名詞だけを抽出して文書をカテゴリに分類したいといったときに、「ロシアの音楽」という文字列を「ロシアの音楽/名詞」と解釈するよりも「ロシア/名詞 の/助詞 音楽/名詞」と解釈したほうが汎化できるので嬉しいです。
そのため不要な見出しを除去する処理を行うことにします。
まず、見出しリストをざっと見て「<国名>の法律」「<歌手>のディスコグラフィ」などの「AのB」パターンが多いことに着目しました。
そこで、AのBパターンをざっくりと抽出します。
#! /usr/bin/env python # -*- coding: utf-8 -*- from collections import Counter import re suffixes = Counter() re_anob = re.compile(u'(?P<A>.+[^の])の(?P<B>[^の].+)') re_hiragana = re.compile(u'[ぁ-ゖ]+') def extract_anob(text): match = re_anob.match(text) if match and is_valid_b(match.group('B')): suffixes[match.group('B')] += 1 def is_valid_entry(entry): return False if '_(' in entry else True def is_valid_b(b): return False if re_hiragana.match(b) else True if __name__ == '__main__': import optparse parser = optparse.OptionParser() parser.add_option("-f", "--filename", help="the path of input file") (opts, args) = parser.parse_args() for line in open(opts.filename, 'r'): line = line.strip().decode('utf8') if is_valid_entry(line): extract_anob(line) for k,v in suffixes.most_common(200): print k,v
AのBパターンのBの出現回数上位200件がこちら。
一覧 2256 戦い 1581 人物一覧 596 登場人物 467 歴史 452 法則 322 国旗 280 国歌 261 定理 256 国章 238 スポーツ 221 作品 199 通貨 198 地方行政区画 157 鉄道 156 音楽 153 大統領 150 世界遺産 149 軍事 146 冒険 145 廃校一覧 145 オールナイトニッポン 143 選手一覧 140 行政区画 131 航空 128 物語 125 映画 120 政治 120 同位体 117 野球 116 首相 116 政党 114 メジャーリーグベースボール 113 ワールドシリーズ 112 楽曲一覧 111 国会 110 海戦 101 宝塚歌劇公演一覧 99 ディスコグラフィ 93 日本公開映画 90 年度別成績一覧 90 世界 88 手紙 86 MLBオールスターゲーム 81 関係 80 経済 79 交通 79 逆襲 78 大冒険 77 政党一覧 77 ゲームタイトル一覧 77 年表 77 連続ドラマ 76 伝説 75 時間 75 バレーボール 73 原理 73 エピソード一覧 72 歴代選手・スタッフ一覧 71 式内社一覧 69 反乱 69 アニメ 68 奇跡 66 F1世界選手権 65 ロードレース世界選手権 65 日本シリーズ 64 ユニフォーム 64 パラドックス 61 NBA 61 教育 61 登場人物一覧 61 権利 60 恋人 59 秘密 58 合戦 56 事件簿 56 女性史 54 郡一覧 52 虐殺 52 料理 52 高等学校一覧 52 ユーロビジョン・ソング・コンテスト 52 資格者配置路線 52 アメリカ合衆国上院議員 51 国鉄 50 有名人一覧 50 廃止市町村一覧 50 MLBドラフト 49 空軍 49 悲劇 48 廃園一覧 48 NFL 48 原則 47 登場キャラクター 47 ナショナルリーグチャンピオンシップシリーズ 46 肖像 46 市町村章一覧 46 野望 46 地理 45 文化 45 アメリカンリーグチャンピオンシップシリーズ 45 県道一覧 45 騎士 44 日々 43 文学 42 テーマ 41 世界ラリー選手権 41 誓い 41 公式 41 大学一覧 41 ニュース 40 灯台一覧 40 海軍 39 二級水系一覧 39 比較 39 日本競馬 38 方程式 37 国・地域別メダル受賞数一覧 37 王様 37 少女 37 時代 37 博物館 36 季節 36 オールナイトニッポンR 36 野鳥一覧 36 町名 36 中で 35 陸軍 35 自由 35 天使 34 観光地 34 カメラ製品一覧 34 人々 34 女王 33 議会 33 森公園 33 殺人 33 和約 33 科学 32 自転車競技 32 チーム記録 32 警察 31 陰謀 31 大統領一覧 31 部屋 31 歴代監督一覧 31 祈り 31 下で 30 促進に関する法律 30 問題 30 花嫁 30 政変 30 日本 30 NBAドラフト 30 サッカー選手一覧 30 約束 29 迷宮 29 記憶 29 リスト 28 韓国シリーズ 28 競馬 28 呪い 28 宇宙飛行 28 元素 28 相撲 28 ラジオ 27 事件 27 JSL 27 図書館一覧 27 聖母 27 スーパーバイク世界選手権 26 ワイン 26 渡し 26 作品一覧 26 神話 26 日記 26 青春 26 理論 26 用語一覧 26 宗教 25 女神 25 挑戦 25 憲法 25 ユーロ硬貨 25 電車 25 秘宝 24 殿堂 24 戦争 24 企業一覧 24 通り 23 兵器 23 結婚 23 Jリーグ 23 全日本F3選手権 23 王国 23 サッカー 23 復讐 23 誕生 22 紋章 22 アリス 22
右の数字は出現回数です。
このうち一語の固有名詞として扱ったほうがいいもの(たとえば、**の冒険とか**の紋章とか)を人手で判断しました。
判断の補助としてmarisa-trieを使ってsuffixの検索を行うスクリプトを使いました。
#! /usr/bin/env python # -*- coding: utf-8 -*- import marisa_trie import os def is_valid_entry(entry): if '_(' in entry: return False return True def build_trie(filename): reversed_entries = [] for line in open(filename, 'r'): line = line.strip().decode('utf8') if is_valid_entry(line): reversed_entries.append(line[::-1]) trie = marisa_trie.Trie(reversed_entries) trie.save('wikipedia_reverse.marisa') if __name__ == '__main__': import optparse parser = optparse.OptionParser() parser.add_option("-f", "--filename", help="the path of input file") (opts, args) = parser.parse_args() if not os.path.exists('wikipedia_reverse.marisa'): build_trie(opts.filename) trie = marisa_trie.Trie() trie.load('wikipedia_reverse.marisa') while True: text = raw_input('>').decode('utf8') for i in trie.keys(text[::-1]): print i[::-1]
こうした作業によってできたリストがこちらです。見出しリストをMeCab用辞書に整形するときにこれを読み込んでlist型にして'文字列'.endswith(wikipedia_stop_suffixes)とかやって不要な見出しを弾くといいと思います。
一覧 の登場人物 の歴史 の国旗 の国歌 の国章 のスポーツ の作品 の通貨 の鉄道 の音楽 の大統領 の世界遺産 の軍事 のオールナイトニッポン の航空 の映画 の政治 の同位体 の野球 の首相 の政党 のメジャーリーグベースボール のワールドシリーズ の国会 のディスコグラフィ の日本公開映画 のMLBオールスターゲーム の関係 の経済 の交通 の年表 の連続ドラマ のバレーボール のアニメ の奇跡 のF1世界選手権 のロードレース世界選手権 の日本シリーズ のユニフォーム のパラドックス のNBA の教育 の女性史 の料理 のユーロビジョン・ソング・コンテスト の資格者配置路線 のアメリカ合衆国上院議員 の国鉄 のMLBドラフト の空軍 のNFL の登場キャラクター のナショナルリーグチャンピオンシップシリーズ の地理 の文化 のアメリカンリーグチャンピオンシップシリーズ の文学 の世界ラリー選手権 のニュース の海軍 の比較 の日本競馬 のオールナイトニッポンR の町名 の陸軍 の観光地 の女王 の議会 の科学 の自転車競技 のチーム記録 の警察 の促進に関する法律 の問題 の政変 のNBAドラフト のリスト の韓国シリーズ の宇宙飛行 の元素 の相撲 の年のラジオ の事件 のJSL のスーパーバイク世界選手権 の憲法 のユーロ硬貨 の電車 の戦争 の通り の兵器 のJリーグ の全日本F3選手権 のサッカー
今回のスクリプトや結果はgistにも置いてます。
https://gist.github.com/ikegami-yukino/8042385
ただ、これだけだとまだまだ不要見出し残ってるので、あとでまた何か書くかも。
SWIGによるOLLのPythonバインディング
SWIGによってオンライン機械学習ライブラリOLLをPythonで使うモジュールを公開しました( ´ ▽ ` )ノ
https://pypi.python.org/pypi/oll
前回のファイルを経由するのとは違ってSWIGでOLLを使うので効率的です。
pipが入っていれば以下のコマンドでインストールできます(要C++コンパイラ)。
$ pip install oll
ソースコードは以下URLにて公開しています。
https://github.com/ikegami-yukino/oll-python
PythonでOLLを使う
オンライン機械学習ライブラリのOLLをPythonで使うためのクライアントモジュールを公開しました!
https://pypi.python.org/pypi/oll_client
これはPythonでoll_lineの入出力を扱うモジュールです。
swigとかよくわからないのでoll_lineへの入力は標準入力を、出力はファイルから読み込むという強引な実装で、一時ファイルを生成するかっこ悪い感じになってます
もっと効率的なOLLモジュールを作ったのでそっちを推奨します。http://d.hatena.ne.jp/expectorate/20131011/1381518642
ソースコードは以下URLにて公開しています。
https://gist.github.com/ikegami-yukino/6102212
ショートカットキーで漢字をひらがなに変換 for Mac
MacのAutomatorから「選択した文字列から漢字をひらがなに変換する」サービスを作ってショートカットキーで呼び出す方法を紹介します。
実行にはMeCabとnkfのインストールが必要になります。
手順
- Automatorの起動
- [Ctrl]と[Space]同時押しで出てくるSpotlightからAutomatorって入れると早い
- サービスを作る
- ユーティリティ > "シェルクスクリプトを実行"というアクションを選んで右のあいてることろにドラッグアンドドロップ
- 以下のコマンドを入力
- パスは適宜変更してください
echo $1| /usr/local/bin/mecab -E "" --node-format="%f[7] "| /opt/local/bin/nkf -w --hiragana
- "選択されたテキストを出力で置き換える"にチェック
- "入力の引渡し方法"を”引数として”にする
- 名前をつけて保存
- ショートカットキーの設定
- "システム環境設定" を開いて、"キーボード"項目の"キーボードショートカット"タブをクリック
- 左カラムのサービスを選ぶと右カラムにさっき保存したサービスがあるので、すきなショートカットキーを設定
Mountain Lionに入れるもの
備忘録
開発環境
Xcode Command Line Tools
ライブラリ
sudo pip install beautifulsoup4 sudo pip install matplotlib sudo pip install python-tumblpy sudo pip install tweepy easy_install flickrapi
エディタ
MacVim KaoriYa
ChocolatePapaya
茶色くて見やすいvim用テーマ
http://vim.sourceforge.net/scripts/script.php?script_id=1922
MacVimへの適用
$ mkdir ~/.vim $ mkdir ~/.vim/colors $ cp ~/Downloads/ChocolatePapaya.vim ~/.vim/colors/ $ echo colorscheme ChocolatePapaya > .gvimrc
その他
AppCleaner
BetterTouchTool
Lyrics Master
MendeleyDesktop
TotalSpaces
f.lux
it makes the color of your computer's display adapt to the time of day, warm at night and like sunlight during the day.
TNEF's Enough
TNEF's Enough allows Macs to read and extract files from Microsoft TNEF stream files. The files are usually received by SMTP based e-mail programs from Microsoft Exchange and Microsoft Outlook users.
VLC
VLCはフリーなマルチプラットフォーム対応のマルチメディアプレイヤーであり、DVD、オーディオCD、VCDや様々なストリーミングプロトコルを再生可能なフレームワークです。
AppStoreから入手
- Echofon
- The unarchiver
- WinArchiver Lite
- Microsoft Remote Desktop
- スケッチ風ドロー
コマンドラインツール
Byobu
Byobu is a GPLv3 open source text-based window manager and terminal multiplexer.
Pythonで少し速くひらがな・カタカナ・半角・全角文字を相互変換する
NLPをやってると文字の正規化処理でひらがな・カタカナ・半角・全角変換することがあります。
そこでPythonでひらがなからカタカナ、カタカナからひらがな、半角文字から全角文字、全角文字から半角文字に高速変換するライブラリjctconvをPyPIにアップしました。
https://pypi.python.org/pypi/jctconv/
そこでjctconvと既存の文字種変換モジュールで比較してみました。
# -*- coding: utf-8 -*- # 他のひらがなカタカナ変換と比較 if __name__ == '__main__': import time loop = 100000 print u'ひらがなからカタカナに変換' text = u'ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをんァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ' # jctconv(わたしのスクリプト) import jctconv start = time.clock() for i in xrange(loop): jctconv.hira2kata(text) print '\tjctconv:', print time.clock()-start # http://d.hatena.ne.jp/mohayonao/20101213/1292237816 import mohayonao start = time.clock() for i in xrange(loop): mohayonao.katakana(text) print u'\tmohayonaoさん:', print time.clock()-start # https://github.com/yuka2py/cnvk import cnvk start = time.clock() for i in xrange(loop): cnvk.convert(text, cnvk.HIRA2KATA, cnvk.Z_KATA) print '\tcnvk:', print time.clock()-start # http://pypi.python.org/pypi/jcconv/0.1.6 import jcconv start = time.clock() for i in xrange(loop): jcconv.hira2kata(text) print '\tjcconv:', print time.clock()-start print u'\n半角から全角に変換' text = u'アイウエオあいうえお' # jctconv(わたしのスクリプト) import jctconv start = time.clock() for i in xrange(loop): jctconv.normalize(text,'NFKC') print '\tjctconv:', print time.clock()-start # https://github.com/yuka2py/cnvk import cnvk start = time.clock() for i in xrange(loop): cnvk.convert(text, cnvk.Z_KATA) print '\tcnvk:', print time.clock()-start # http://pypi.python.org/pypi/jcconv/0.1.6 import jcconv start = time.clock() for i in xrange(loop): jcconv.half2kata(text) print '\tjcconv:', print time.clock()-start # http://pypi.python.org/pypi/jcconv/0.1.6 import zenhan start = time.clock() for i in xrange(loop): zenhan.h2z(text) print '\tzenhan:', print time.clock()-start # http://pypi.python.org/pypi/jcconv/0.1.6 import unicodedata start = time.clock() for i in xrange(loop): unicodedata.normalize('NFKC', text) print '\tunicodedata:', print time.clock()-start
MacBook Air2012全部載せ(Intel Core i7 2.0Ghz / DDR3-8GB)で実行
結果
ひらがなからカタカナに変換 jctconv: 5.259766 mohayonaoさん: 8.502345 cnvk: 15.094356 jcconv: 34.587817 半角から全角に変換 jctconv: 0.421827 cnvk: 6.358533 jcconv: 29.451795 zenhan: 1.638667 unicodedata: 0.251975
素のunicodedata以外に勝ったヽ(´ー`)ノ