スポンサーリンク

Windowsで「kakasi」のコマンドを使い,日本語文章を単語に分解,ローマ字変換する方法 (kakasiで形態素解析するWindowsバッチのサンプルコード)


Windowsで「kakasi(カカシ)」という形態素解析のツールを使う方法。

  • 漢字をひらがなに変換したり,
  • 漢字かな交じりの文章を,ローマ字読みに変換したり,
  • 日本語の文章を,単語ごとに分解したり

といった本格的なテキスト処理が,フリーソフトで簡単に実行できる。


例えば,こんなかんじ。

(例その1)

echo 庭には二羽ニワトリがいる。 | kakasi -w

↓  ★文章を解析して単語に分解してくれる!

庭 には 二羽 ニワトリ がいる 。


(例その2)

echo 庭には二羽ニワトリがいる。 
   | kakasi -w 
   | kakasi -Ja -Ha -Ka -Ea

↓  ★アルファベットの読みに変換してくれる!

niwa niha niwa niwatori gairu .


(例その3)

echo 漢検一級に出題される超難しい漢字の例として,
   「邏卒」「衍義」などがあります。 
    | kakasi -JH

↓ ★漢字をひらがなに自動変換してくれる!

かんけんいっきゅうにしゅつだいされるちょうむずかしい
かんじのれいとして,「らそつ」「えんぎ」などがあります。

Windows上でこういうことができるフリーソフト「kakasi」の導入方法と,

コマンドの具体的な使い方や,応用例を以下で紹介する。




(1)Windowsへの「kakasi」の導入方法

導入は非常に簡単で,ツールをダウンロードしてPATHを通すだけ。


なお,WindowsマシンはふつうのWindows7とする。
32ビットでもいいし,64ビットでもいい。(一応XPでもOK)

まずKAKASI本体を取得する。

下記のページにアクセス。

http://www.namazu.org/win32/


kakasi-2.3.4.zipをダウンロードし,
解凍して現れるkakasiフォルダをCドライブ直下に置く。


コンパネ>システム>詳細設定>環境変数
で,システム環境変数を編集。

Pathに C:\kakasi\bin; を追加。


新規作成で,変数名は KANWADICTPATH

値は C:\kakasi\share\kakasi\kanwadict


もうひとつ新規作成で,変数名は ITAIJIDICTPATH
値は C:\kakasi\share\kakasi\itaijidict


これだけでkakasiの導入が完了した。

PCを再起動する必要はない。


(2)コマンドプロンプト上で,kakasiの動作テスト

kakasiをWindowsコマンドプロンプトから動作させてみる。


まず,漢字かな交じり文の分かち書き(単語分解)。

kakasiの -w オプションで単語分解してくれる。


echo 庭には二羽ニワトリがいる。 | kakasi -w

庭 には 二羽 ニワトリ がいる 。


echo 東京特許許可局 | kakasi -w

東京 特許 許可 局


echo コボルエンジニアがこの先生きのこるには | kakasi -w

コボルエンジニア がこの 先生 きのこるには

※参考:

この先生きのこるにはとは (コノセンセイキノコルニハとは) [単語記事] - ニコニコ大百科
http://dic.nicovideo.jp/a/%E3%81%93%E...


きのこる先生のエンジニア転職指南(1):元プログラマのWeb企業人事、エンジニアのアピール下手を嘆く (1/2) - @IT
http://www.atmarkit.co.jp/ait/article...


きのこる先生とは - 意味/元ネタ/使い方|AA
http://netyougo.com/aa/4716.html


次に,文字の変換。オプションに文字の種類を2つ渡す。


漢字(J)をひらがな(H)に変換:


echo 東京特許許可局 | kakasi -JH

とうきょうとっきょきょかきょく


echo 漢検一級に出題される超難しい漢字の例として,「邏卒」「衍義」などがあります。 | kakasi -JH

かんけんいっきゅうにしゅつだいされるちょうむずかしいかんじのれいとして,「らそつ」「えんぎ」などがあります。

※ネタ元:

【読める?】漢検1級の漢字が異次元すぎる・・・何だこれ・・・ - かれっじライフハッキング
http://college2ch.blomaga.jp/articles...

  • ら‐そつ 【×邏卒】 1 見回りの兵卒。巡邏兵。2 明治初期の警察官の称。のち、巡査と改称。
  • えん‐ぎ 【×衍義】 意味をおし広めて詳しく説明すること。また、その説明されたもの。「六諭(りくゆ)―」


漢字(J)だけをアルファベット(a)に変換:


echo 東京特許許可局 | kakasi -Ja

toukyoutokkyokyokakyoku


echo こんにちは世界! | kakasi -Ja

こんにちはsekai!


echo コボルエンジニアがこの先生きのこるには | kakasi -Ja

コボルエンジニアがこのsenseiきのこるには


次に,漢字かな交じり文をアルファベットに変換するには,

漢字をアルファベットに変換し,同時にひらがなもアルファベットに変換する。

文末の句読点もアスキー文字に変換したければ,-Ea とする。

オプションは同時に複数指定できる:


echo 0.9999...を無限桁まで続けた場合の極限値は,1に等しい。 | kakasi -w | kakasi -Ja -Ha -Ea

0.9999... wo mugen keta made tsuduke ta baai no kyokugenchi ha , 1 ni hitoshii .


echo こんにちは世界! | kakasi -Ja -Ha

konnichihasekai!


カタカナ(K)と漢字の混じった文語文は,ものすごく読みづらいので,

まずカタカナをひらがなに直し,さらに分かち書きすると読みやすい:


echo 日本臣民ハ法律命令ノ定ムル所ノ資格ニ應シ均ク文武官ニ任セラレ及其ノ他ノ公務ニ就クコトヲ得 | kakasi -KH | kakasi -w

日本 臣民 は 法律 命令 の 定む る 所 の 資格 に 應 し 均 く 文武 官 に 任せ られ 及 其の 他の 公務 に 就く こと を 得

※ネタ元:

日本国憲法は当初、文語体・漢字カタカナ交じり文で書かれていた - モジログ
http://mojix.org/2013/02/26/kenpou-ko...

  • 漢字とカタカナだけで、句読点もない上に、言い回しも漢文調なので、わかりにくい
  • これに対して、「国民の国語運動連盟」という団体が「法令の書き方についての建議」という提案書を作って、総理大臣(幣原喜重郎)に出した。なんと、カナモジカイと山本有三が中心になり、そこにローマ字会やエスペラント学会など、さまざまな国語改革運動の団体が加わったものだった
  • 政府はこれを受け入れようとしなかったが、GHQが支持したというのだ。GHQは<日本語表記のローマ字化まで視野に入れていた>ので、これを支持した


漢字,ひらがな,カタカナの混じった分を,分かち書きしつつアルファベットに変換:


echo 庭には二羽ニワトリがいる。 | kakasi -w | kakasi -Ja -Ha -Ka -Ea

niwa niha niwa niwatori gairu .


全角数字は,半角数字になる場合もあるが,単語の一部として読みがなに展開されることもある。

のばす音「ー」は,アスキー文字のハット「^」に変換される。

アルファベットになるとローマ字読みなので,「ん」の後にアポストロフィ(')が入ったりする。

かぎカッコは,半角丸カッコになる。


echo 「第3セクター」とか「単位」などの語もローマ字転記されます。 | kakasi -w | kakasi -Ja -Ka -Ha -Ea

( daisan sekuta^ ) toka ( tan'i ) nadono go mo ro^ma ji tenki saremasu .

「しゃ・しゅ・しょ」などの小さな「ゃゅょ」は,音節に応じて正しいローマ字に変換される。


echo アインシュタイン・ポドルスキー・ローゼン | kakasi -Ka -Ea

ainshutain.podorusuki^.ro^zen


小さな「ァィゥェォ」は,音の変換が不要とみなされた場合,大きな「アイウエオ」としてローマ字に転写されるようだ。

また「〜」(波形)は「~」(チルダ)になり,「…」(三点リーダ)はピリオド3つになる。


echo ぁぁ ゅぅぅっ ゃゎぁ… っゅ ゎ ぃゃゃゎ | kakasi -Ha -Ea

aa yuuutsu yawaa... tsuyu wa iyayawa


echo サバディ〜… サバダッサ サンサンサバディ〜… 君かい? 唐獅子かい? | kakasi -Ja -Ka -Ha -Ea

sabadei~... sabadassa sansansabadei~... kunkai? karajishikai?

※ネタ元:

セクシーコマンドー部 主題歌 ‐ ニコニコ動画:GINZA
http://www.nicovideo.jp/watch/sm11931018

  • サバディ〜 サバダッササンサンサバディ〜 君かい? 唐獅子かい?


注意点として,特殊文字や環境依存文字(数字のIとか丸数字)なんかは,kakasiで処理できない。

echo 特殊文字のテスト:(ここに特殊文字のIなどを記載) | kakasi -Ja -Ha -Ka -Ea

tokushumojinotesuto:??????


半角カナも,文字化けや謎の挙動の原因となり,処理は苦手なようだ。

echo ノシ (・ω・) ボソッ・・・ | kakasi -Ha -Ja -Ka -Ea

hyou (・ヌanE) namidashinu


半角カナや環境依存文字は,Windows的な発想の文字だ。

kakasiはもともとUNIXのツールだから,Windows的な文字を処理できなくても不思議ではない。

UNIX・Linuxの処理しやすい文字を使うようにしよう。


ちなみに,-p オプションをつければ,変換の候補を1つではなく複数表示してくれる。

漢字かなまじり文をローマ字変換するソフト"kakasi"...
http://detail.chiebukuro.yahoo.co.jp/...

  • echo "中島愛" | kakasi -Ja -p
  • (出力結果:{nakashima|nakajima}{ai|mana})


(3)応用:kakasiを使った「日本語ファイル名の一括リネームバッチ」

ここまでで,kakasiコマンドの基本的な使い方がわかった。

このコマンドを使って,Windowsで動く実用的なバッチを作ってみよう。


題材として取り上げるのは,「フォルダツリー内の全ファイルのリネーム」。

日本語のファイル名を,すべて半角の英数字だけに変換してくれる。


どうしてこういうリネーム処理が必要なのかというと,

GoogleやAppleなどの国際的なサービスやツールを使う場合,

ファイル名が日本語だとトラブルが多いため。


たとえば,グーグル社のクラウドである「Googleドライブ」で,

iPadやiPhoneから「Googleドライブ」上のファイルを開き,

別のアプリでファイルを開きなおしたいとする。


もしファイル名が日本語だと,この操作が不可能なのだ。


日本語名のPDFをGoogleドライブで開いたら,iBooksに「送る」で開きなおすことができない。

自由に操作できるのは,Googleドライブ上で半角英数字のファイル名のみ。

iOS6にしたらGoogle Drive上のファイルをiBooksで開けない | Apple サポートコミュニティ
https://discussionsjapan.apple.com/th...

  • google driveにアップするPDFファイルのファイル名は半角英数にしてみてください。
  • ただし、google driveにアップした後、google drive上で名前を変更してもダメです。 必ずアップする前のファイルのファイル名を半角英数に変えてみてください。

こんなとき,Googleドライブにアップロードしてある超・大量のファイル全てを,
アルファベットでリネームしなおさなければならない。


しかも,Googleドライブ上でリネームしても効果がない。

アップロードする前に,日本語ではなく半角アルファベットのファイル名にしておく必要があるのだ。


そういう理由で,
「フォルダツリー内の全ファイル(たとえばPDF)を,日本語名からアルファベットに一括リネーム」
という処理が必要になる。


kakasiがあれば,それをバッチ処理で自動化できる。


フォルダツリーの最上層で,以下のファイルを リネーム.bat という名前で保存し,ダブルクリックすればよい。

@if(0)==(0) ECHO OFF

rem このファイルをWSHで実行しなおす
cscript.exe //nologo //E:JScript "%~f0" "%~dp0" >out.log
@pause

GOTO :EOF
@end

/*
	カレント以下の全サブフォルダで,
	フォルダ内のPDFのファイル名を
	日本語から英数字にリネームするバッチ
	
	※リネームにはkakasiを使用。事前に導入のこと
*/



// ------------- ライブラリ関数 -------------


function log(s){ WScript.Echo(s); }

//
function err(s){ WScript.StdErr.WriteLine(s); log(s); }
	// リダイレクトされずにコンソールにも表示される


// ベンチ用
function tic(){
	tic.startTime = new Date().getTime();
}
function tac(){
	var ms = new Date().getTime() - tic.startTime;
	tac.time_span = ms / 1000;
}
function how_many_seconds(){ // 計測時間が何秒だったかを返す
	return tac.time_span;
}


// 配列のイテレータ
Array.prototype.each = function( func ){
	for( var i = 0; i < this.length; i ++ ){
		func.call( this, this[i], i ); 
	}
	return this; // チェインを継続
};

// map
Array.prototype.map = function( func ){
	var _arr = [];
	this.each(function( item, ind ){
		_arr.push( func.call( _arr, item, ind ) );
	});
	return _arr;
};


// コマンド実行結果を行ごとに配列として取得
// http://language-and-engineering.hatenablog.jp/entry/20081225/1230198688
function exec_cmd( str_cmd, params ){
	var current_dir    = ( params ) ? params.current_dir : null;
	var wait_while_net = ( params ) ? params.wait_while_net : null;

	var ws = WScript.CreateObject("WScript.Shell");
	
	// 必要ならカレントフォルダをセット
	if( current_dir ){
		ws.CurrentDirectory = params.current_dir;
	}
		//err( "カレントフォルダ:" + ws.CurrentDirectory + ", コマンド:" + str_cmd );

	// コマンド実行
	var proc = ws.Exec( "cmd /c " + str_cmd );
	
	// もしメール送信など通信系のコマンドであれば,終了まで待つ
	if( wait_while_net ){
		while( proc.Status == 0 ){
			WScript.Sleep(100);
		}
		// http://language-and-engineering.hatenablog.jp/entry/20100913/p1
	}
	
	// 出力を取得
	var str_out = proc.StdOut.ReadAll();
	
	// 末尾の空行を削除
	var arr = str_out.split("\r\n");
	arr.pop();
	
	return arr;
}



// ------------- メイン処理 -------------


// リネームされたPDFの数
var renamed_pdf_count = 0;

// 時間計測開始
tic();

// すべてのサブフォルダを列挙
var dirs = exec_cmd( "dir /a:D /s /b" );
dirs.each(function(dir_path){
		err(dir_path);
	
	// リネームすべきPDFがここに存在するか?
	
	// ファイル名の特徴で判断
	// 英数字ではない文字を含むようなPDF
	var target_files = exec_cmd( 'dir /b *.pdf | findstr "[^a-z0-9]"', {
		current_dir : dir_path
	});
	
	// 結合すべきPDFがあれば
	if( target_files.length > 0 ){
			//err("リネーム対象のPDFあり:" + dir_path);
			//err(target_files.join("\n"));
		
		// 全PDFについて
		target_files.each(function( file_name_ja ){

			// リネーム後の英数字ファイル名を求める
			
			// kakasiのコマンド
			var kakasi_command = 'echo '
				+ file_name_ja 
				+ ' | kakasi -w '
					// まず分かち書き。英数字の羅列だけだと読みづらいから
				+ ' | kakasi -Ja -Ka -Ha -Ea ' 
					// 次に,漢字・かな・カナ・記号をすべてアスキーに
			;
			
			// kakasi実行
			var kakasi_out = exec_cmd( kakasi_command, {
				current_dir : dir_path
			})[0]; // 出力行の最初の行を取り出す
			
			// 新ファイル名
			var new_name = kakasi_out;

			// Windowsのファイル名に使えない文字は直しておく
			new_name = new_name
				.replace( new RegExp('[\\\\/:\\*\\?"<>|]', "g"), "" )
				// 使えるけど紛らわしい文字を置換
				.replace( new RegExp("['\\^\\+~]", "g"), "-" )
			;
			
			// 空白などを調整
			var new_name = new_name
				.replace(/ *$/g, "") // 末尾に空白があれば削除
				.replace(/ /g, "_") // その他の空白は埋めておく
				.replace(/_+/g, "_")
				.replace(/_*\._*/g, ".")
			;
			
			
			// リネーム処理
			
			// リネームコマンド
			var rename_command = 'ren "'
				+ file_name_ja
				+ '" "'
				+ new_name
				+ '"'
			;
				err( rename_command );
			
			// 実行
			exec_cmd( rename_command, {
				current_dir : dir_path
			});
			renamed_pdf_count ++;
			
			
			// リネーム前のファイル名をテキストとして同じ場所に残す
			// (日本語ファイル名を探せたほうが,ファイル検索の時に便利だから)
			var make_txt_command = 'echo.> "' // 中身は空
				+ file_name_ja
				+ '.txt"'
			;
			// 実行
			exec_cmd( make_txt_command, {
				current_dir : dir_path
			});
			
		});
		
	}
});

tac();

err("全処理が完了しました。");
err("経過時間:" + how_many_seconds() + "秒");
err("リネームされたPDFの総数:" + renamed_pdf_count );


手元の環境で実行すると,下記のような出力になった。

ren "Google入社試験.pdf" "Google_nyuushashiken.pdf"
ren "RDBMS解剖学.pdf" "RDBMS_kaibougaku.pdf"
ren "J2EEパターン_2.pdf" "J2EE_pata-n_dai_2_han.pdf"
ren "Javaデザインパターン入門_マルチスレッド編.pdf" "Java_dezainpata-n_nyuumon_maruchisureddo_hen.pdf"
ren "ソースコードリーディングJavaの設計と実装.pdf" "so-suko-dori-deingu_Java_no_sekkei_to_jissou.pdf"
ren "リファクタリング・ウェットウェア.pdf" "rifakutaringu.uettouea.pdf"
ren "PHPサイバーテロの技法.pdf" "PHP_saiba-tero_no_gihou.pdf"
ren "メタプログラミングRuby.pdf" "metapuroguramingu_Ruby.pdf"
ren "大学院入試問題集_工学系.pdf" "daigakuinnyuushi_mondaishuu_kougakukei.pdf"
ren "大学院入試問題集_理学系.pdf" "daigakuinnyuushi_mondaishuu_rigakukei.pdf"
ren "コンパイラの理論.pdf" "konpaira_no_riron.pdf"
ren "情報・符号理論の基礎.pdf" "jouhou.fugouriron_no_kiso.pdf"
ren "情報通信トラヒック.pdf" "jouhoutsuushin_torahikku.pdf"
ren "有限オートマトンと正規言語.pdf" "yuugen_o-tomaton_to_seikigengo.pdf"
ren "非線形波動・岩波現代物理学.pdf" "hisenkei_hadou.iwanami_gendaibutsurigaku.pdf"
ren "CDエクスプレス・カンボジア語.pdf" "CD_ekusupuresu.kanbojia_go.pdf"
ren "パンジャーブ語基礎1500.pdf" "panja-bu_go_kiso_1500.pdf"
ren "モンゴル語四週間.pdf" "mongoru_go_yonshuukan.pdf"
ren "CDエクスプレス現代ヘブライ語.pdf" "CD_ekusupuresu_gendai_heburai_go.pdf"
ren "新ラテン文法.pdf" "shin_raten_bunpou.pdf"
ren "証券外務員一種・問題集2012.pdf" "shouken_gaimu_in_isshu.mondaishuu_2012.pdf"
ren "日本の様式建築.pdf" "nippon_no_youshiki_kenchiku.pdf"
ren "源氏物語の時代.pdf" "genjimonogatari_no_jidai.pdf"

・・・・

全処理が完了しました。
経過時間:19.582秒
リネームされたPDFの総数:509

500個ほどのPDFファイルを,たった20秒でリネーム完了している。

なんて便利なツールだ。

これで,Googleドライブ上のPDFをiBooksでも読めるようになった。


ちなみに,半角英数字だと検索でファイル名が探しづらいのでは?
という疑問がわくが,それもちゃんと対策済み。


バッチのソースコード中では
「リネーム前のファイル名をテキストとして同じ場所に残す」
という部分がある。


(本の日本語ファイル名).txt

という空のテキストファイルを,そのつど同じフォルダ上に生成しているため,
もとのファイル名が失われずに思い出せるようにしてあるのだ。


自分がどの本を持っているのか,書名・タイトルから調べたくなったときにも,この運用なら困らずにすむ。


結論および補足説明

プログラミングで,高度な「情報の処理」をどんどんつきつめると,

いつか必ず「テキスト処理」にいきつく。

自然言語処理である。


そこでは,日本語の自然テキストをうまく処理して,

意味のある情報を抜き出し,有用なデータに加工しなければならない。


その場合,第一歩として必要になる前処理が:

  • 文章を単語に分解すること。(英語の場合はスペースで区切れるが,日本語はそう簡単には行かない)
  • 漢字のつづりを,ひらがなやアルファベットの音価に変換して,扱いやすくすること。(英語の場合はもとから扱いやすい文字セットのまんまで加工が不要)

こうした日本語特有のテキスト処理を手軽に果たす上で,kakasiはものすごく役立つ。


そして,ここを通過すると,もっと詳しい解析がしたいというフェーズになる。

  • 分解された個々の単語が,何の品詞なのか,どういう活用形なのかを見極めたい。(=文法を意識した形態素解析)
  • 単語ごとの正確な意味の組み合わせから,文章の全体としての意味を機械的に判定したい。(=意味解析)

などなど,だんだん人工知能の担当分野にシフトしてゆく。

これはまた別のツールが色々あるので別の機会に。


テキスト処理の情報科学的な理論面を学びたい場合は,

下記のリンクで入手できる大学の講義ノート類を参照。

「自然言語処理論」の講義ノートPDF。形態素解析や文脈自由文法,知能機械による言語処理の扱い
http://language-and-engineering.hatenablog.jp/entry/20140511/NaturalLanguageP...


形式言語とオートマトンの講義ノートPDF。コンパイラや状態機械による言語処理の理論
http://language-and-engineering.hatenablog.jp/entry/20140625/FormalLanguagesA...



関連する記事:

あなたが正規表現の中級者か判別する10問テスト (文字列処理の必須知識)
http://language-and-engineering.hatenablog.jp/entry/20131028/RegExpProgrammin...


Word文書を解析して,英単語の出現回数を統計出力するバッチ (英文の用語索引を自動生成)
http://language-and-engineering.hatenablog.jp/entry/20120808/WordCountProgram


「ラムダ計算」を独学で学習するための,講義ノートやPDFのリンク集 (復習用の問題付き)
http://language-and-engineering.hatenablog.jp/entry/20130313/LambdaCalculusBa...


JavaScriptの動かないコード (中級編) 正規表現で同じ文字の連続を検出したい - 置換前パターン中での後方参照
http://language-and-engineering.hatenablog.jp/entry/20080927/1222508705


大学の「情報理論」(暗号理論を含む) の講義ノートPDF。代数学を使った情報量・符号化・通信路の理論
http://language-and-engineering.hatenablog.jp/entry/20140519/InformationTheor...