GAE/Javaで、形態素解析のオープンソースを触ってみた。

というわけで、本エントリーは、google app engine java形態素解析が出来るオープンソースを使ってみたという内容。

Igoとは

Javaで実装された形態素解析器。→ Common Lisp
辞書フォーマット及び解析結果は、ほぼMeCab互換。
単機能。
Java形態素解析器としては比較的高速。
スレッドセーフ。

Igo GAE は、GAE対応版。sileさんが対応させた様である。

感想

とても簡単に形態素解析が実現できた!便利だと思った!
導入も手順さえ分かっていれば、すぐに利用することも出来る!(あまり理解できておらず、つまづきました^^;)
yahooAPIで、形態素解析が提供されているが、制限がかかっているので、
Igoは気兼ねなく使える。
(yahooの制限⇒24時間以内で1つのアプリケーションIDにつき50000件のリクエスト,1リクエストの最大サイズを100KBに制限etc)

形態素解析とは

コンピュータ等の計算機を用いた自然言語処理の基礎技術のひとつ

対象言語の文法の知識(文法のルールの集まり)や辞書(品詞等の情報付きの単語リスト)を情報源として用い、
自然言語で書かれた文を形態素(Morpheme, おおまかにいえば、言語で意味を持つ最小単位)の列に分割し、
それぞれの品詞を判別する作業を指す。

・辞書を用いて、自然言語を品詞に分けてくれたりしてくれる。
・人口無能を作成するときに、利用したりする人が多い。・・・はず。

形態素解析を利用すれば、
はてなブログの「最近言及したキーワード」的なものが作れると思ってる。
(投稿したブログ内容を形態素解析して、名詞だけを抽出すれば作れると思っている)

ということで、あまり詳しいことはわかってないんだお( ^ω^)

わかち書き(わかちがき)とは、

文章において語の区切りに空白を挟んで記述することである。
分かち書き・分ち書き・別ち書きとも表記する。

公式のindexページ

https://github.com/sile/igo-gae

ダウンロード

1.サンプル&igoのgae版のjarをダウンのロード
https://github.com/sile/igo-gae
Downloadsをクリック

2.辞書のダウンロード
http://sourceforge.net/projects/mecab/files/mecab-ipadic/2.7.0-20070801/
mecab-ipadic-2.7.0-20070801.tar.gzをクリック

インストール

1.igo-0.4.2-gae.jarをクラスパスに通す。
ダウンロードしたファイルを解凍する。
war\WEB-INF\libにあるigo-0.4.2-gae.jarをクラスパスに通す。

2.warフォルダ直下にipadic(こいつが辞書や!)を配置する。
ipadicの作成方法は下記参照

ipadic(辞書)の作成方法

以下のコマンドを打ちます。

	java -cp igo-0.4.2-gae.jar net.reduls.igo.bin.BuildDic ipadic mecab-ipadic-2.7.0-20070801 EUC-JP

IPA辞書はEUC-JPでファイルを用意しているので、ここでの指定はEUC-JP一択です。
らしいです。はい。

javadoc

恐らく下記ページの箇所
http://igo.sourceforge.jp/#api

サンプル1

http://it-tech-dm.appspot.com/igo/igo1

surface形態素の表記を返します。
feature:形態素の全情報を文字列で返します。

	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/plain; charset=UTF-8");
		
		PrintWriter out = res.getWriter();
		out.println("★ハローワールドを形態素解析★");
		out.println();
		
		Tagger tagger = new Tagger("ipadic/");
		List<Morpheme> parse = tagger.parse("ハローワールド");
		for (Morpheme morpheme:parse) {
			out.println(morpheme.surface + "⇒" + morpheme.feature);
		}
	}

もういっちょサンプル。

http://it-tech-dm.appspot.com/igo/igo2

	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/plain; charset=UTF-8");
		String morphemeStr = "プロゴルファー石川遼選手も「聞き流すだけ」で英語が話せた!!";
		PrintWriter out = res.getWriter();
		out.println("★"+ morphemeStr + "を形態素解析★");
		out.println("文言URL:http://www.espritline.co.jp/ad_af_net205/sle42-2-h6/?PHPSESSID=4f59a3b2697dddf16d7faddc7906edad");
		out.println();
		
		Tagger tagger = new Tagger("ipadic/");
		List<Morpheme> parse = tagger.parse(morphemeStr);
		for (Morpheme morpheme:parse) {
			out.println(morpheme.surface + "\t" + morpheme.feature);
		}
	}
 
        //ダウンロードした中にもサンプルがあるので実行するべし。実行するべし。

jqueryみたいに、htmlを操作できるJavaのライブラリ「jsoup」の使い方。

このエントリーは、タイトル通り、JavaのHTMLパーサーの「jsoup」の使い方。

感想

これから、使用していこうと思う。

  • jQuery-likeということで、使い方がわかりやすい。
  • 公式サイトの説明がわかりやすい気がする・・・。
  • 何やら、現在(最新版は3ヶ月前)も開発やらサポートをしてるみたい。トップページをみたら、「バグがあったら、報告してくれよな!」って書いてる。

※他のJavaのhtmlパーサーについては、HTML Parser、Jericho HTML Parser、Java Mozilla Html Parserとかあるけど、どれも開発がとまっているみたいだ。(安定版だから?)

jsoupとは

Jquery の様な感じで、htmlを操作できるJavaのライブラリ。
オープンソース

公式のindexページ

http://jsoup.org/

ダウンロード

http://jsoup.org/download

インストール

jsoup-1.4.1.jarをクラスパスに通す。

ソースを見たければ、クラスパスに通したjarに、以下のjarを添付する。
jsoup-1.4.1-sources.jar

Javadoc

http://jsoup.org/apidocs/

公式サイトのサンプルを見て、以下の2種類のコードを書きました。
  1. javascriptっぽく操作したコード。(getElementByIdとか使った)
  2. セレクタ構文なるもののコード(初めて知った。こちらの方が①よりも正確に取れるみたい)

解析対象のページ

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
 <head>
 <meta http-equiv="content-type" content="text/html; charset=UTF-8">
  <title>Jsoup サンプル html</title> 
  <meta name="keywords" content="" /> 
  <meta name="description" content="" /> 
 </head>
 <body>
    <div id="menuLink"> 
     <ul> 
      <li class="class1"><a href="http://it-tech-dm.appspot.com/jsoup/Jsoup4">戻る</a></li> 
      <li class="class2"><a href="http://www.google.co.jp/">Google</a></li>

      <li class="class2"><a href="http://yahoo.co.jp">Yahoo</a></li> 
      <li class="class3"><a href="http://jp.msn.com/">MSN</a></li> 
      <li class="class3"><a href="http://www.atmarkit.co.jp/">@IT atmarkIT</a></li> 
      <li class="class3"><a href="http://www.taylorswift.com/">テイラースウィフト</a></li> 
      <li class="gaga"><a href="http://www.ladygaga.com/default.aspx">au IS03の人</a></li>
     </ul> 
    </div>
    <ul>
    	<li><a href="http://www.ikimonogakari.com/"><span style="color:red;">いきものがかり</span></a></li>

    	<li><a href="http://www.2ch.net/">2ちゃんねる</a></li>
    </ul>
 </body>
</html>
  1. javascriptっぽく操作したコード。(getElementByIdとか使った)

結果:http://it-tech-dm.appspot.com/jsoup/jsoup4

public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = res.getWriter();
		String url = "http://it-tech-dm.appspot.com/jsoup/sample.html";
		try {
			Document doc = Jsoup.connect(url).get();
			//aタグをすべて取得
			Elements aTags = doc.getElementsByTag("a");
			JsoupUtil.setMenu(res);
			for (Element aTag:aTags) {
				//aタグのテキスト
				out.println("aTag.text():" + aTag.text());
				out.println("<br />");
				//aタグのテキストに、任意の文字を加える
				out.println("aTag.appendText():" + aTag.appendText(":有名なサイトだよね!"));
				out.println("<br />");
				//aタグのhtmlを取得
				out.println("aTag.html():" + aTag.html());
				out.println("<br />");
				//aタグのhref属性を取得
				out.println(" aTag.attr(\"href\"):" + aTag.attr("href"));
				out.println("<hr />");
			}
			
		}catch (IOException e) {
			e.printStackTrace();
		}
	}

2.セレクタ構文なるもののコード
結果:http://it-tech-dm.appspot.com/jsoup/jsoup5

	public void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
		res.setContentType("text/html; charset=UTF-8");
		
		PrintWriter out = res.getWriter();
		String url = "http://it-tech-dm.appspot.com/jsoup/sample.html";
		try {
			Document doc = Jsoup.connect(url).get();
			//div id 「menuLink」のulタグのliタグを取得
			Elements liTags = doc.select("div#menuLink ul li");
			JsoupUtil.setMenu(res);
			for (Element liTag:liTags) {
				out.println(liTag.text());
				out.println("<br />");
			}
			
		}catch (IOException e) {
			e.printStackTrace();
		}
	}

Google カスタム検索とは

Google カスタム検索では、そのウェブサイトに合ったオーダーメイドの検索環境を実現します。

  • 単数、複数のウェブサイトやウェブページを検索範囲に指定
  • 自分のサイトに検索ボックスを設置して検索機能を提供
  • サイトに合わせて検索結果のデザインをカスタマイズ


使用してみた感想として、便利っぽい。
本当に有用なサイトだけを登録して、そこから検索をするので、今までは玉石混淆の情報があってそこから探すので、
いらない石の情報まで目に多く入ってきていた。
それが、Google カスタム検索を使用することにより、
玉の情報をより多く知れる機会が増えると思うから。


そして、登録できるページとして、
「単一のページ」「URLによるワイルドカード」「ドメイン指定」と、狭かったり広かったり登録できる。
※詳細は、参考URL「URL パターンと使用法」を見てください。


ちょっと、手こずった「ラベルで検索結果変更(最新順)」を、
自分の備忘録のため、ぺたぺた貼るだけにします。

ユーザーによる検索の絞り込みを支援する


  • 絞込みラベル名
    • 検索画面にぽっと出てくるので、わかりやすいので。
  • 検索クエリに追加する単語や語句
    • 参考URLの「検索ラベル」を参考にして




「最新順」ラベルが表示されて、クリックすると、検索結果が最新順にソートされる。

■ソート前



■ソート後


検索結果のランキングの変更(background)



赤い枠の箇所を追加。




ラベルが無くても検索結果がソートされている。

グーグルカスタム検索の、ラベルも便利!

参考URL

Twitter4jライブラリ Tweetクラスのメソッドを実際に出力する

Twitter4Jとは?

Twitter4J は Twitter APIJava ラッパです。
Twitter4J を使うと XML や HTTP に詳しくなくても容易に Twitter とインタラクトするアプリケーションを書くことが出来ます。
Twitter4J は Twitter 非公式のライブラリです。

コード概要

  • Twitter4JのTweetクラスのメソッドの出力を確認する。
  • java」という単語があるツイートを表示する。
  • getCreatedAtメソッドをUTCからJSTに変換する処理を入れてます。

(もっといい方法がありましたら、教えて下さい!)

  • class名、import文が入っていませんので、そのままコピペはできません。

コード(Java Servlet)

public void doGet(HttpServletRequest req, HttpServletResponse resp)
			throws IOException {
		resp.setContentType("text/html; charset=UTF-8");
		
		try {
			Twitter twitter = new TwitterFactory().getInstance();
			Query query = new Query("java");

			QueryResult result = twitter.search(query);
			
			Calendar cal = Calendar.getInstance(TimeZone.getTimeZone("JST"));
			PrintWriter out = resp.getWriter();
			out.println("<html>");
			out.println("<head>");
			out.println("<title>");
			out.println("Tweetクラスの出力");
			out.println("</title>");
			out.println("</head>");
			out.println("<body>");
			//out.println("result.getMaxId()::" + result.getMaxId());
			//out.println("result.getPage()::" + result.getPage());
			out.println("<hr />");
			
			
			out.println("<table border=1>");
			out.println("<tr>");

			out.println("<th>");
			out.println("getFromUser");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getFromUserId");
			out.println("</th>");
			
			
			out.println("<th>");
			out.println("getId");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getIsoLanguageCode");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getLocation");
			out.println("</th>");
			
			
			out.println("<th>");
			out.println("getProfileImageUrl");
			out.println("</th>");
			
			
			out.println("<th>");
			out.println("getSource");
			out.println("</th>");
			
			
			out.println("<th>");
			out.println("getText");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getToUser");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getToUserId");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getAnnotations");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getCreatedAt(整形済)");
			out.println("</th>");
			
			out.println("<th>");
			out.println("getGeoLocation");
			out.println("</th>");
			
			out.println("</tr>");
			DateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.JAPAN);
			for (Tweet tweet: result.getTweets()) {
				cal.setTime(tweet.getCreatedAt());
				
				Date date = new Date(cal.getTimeInMillis());
				df.setTimeZone(TimeZone.getTimeZone("JST"));
				
				out.println("<tr>");
				
				out.println("<td>");
				out.println(tweet.getFromUser());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getFromUserId());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getId());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getIsoLanguageCode());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getLocation());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getProfileImageUrl());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getSource());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getText());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getToUser());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getToUserId());
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getAnnotations());
				out.println("</td>");
				
				out.println("<td>");
				//tweet.getCreatedAt()
				out.println(df.format(date));
				out.println("</td>");
				
				out.println("<td>");
				out.println(tweet.getGeoLocation());
				out.println("</td>");
								
				out.println("</tr>");
				
			}
			
			out.println("</table>");
			out.println("</body>");
			out.println("</html>");
			
		} catch (TwitterException e) {
			e.printStackTrace();
		}
	}

Easy Captureの使い方メモ。windowsのスクリーンショット

EasyCapture
windowsで手軽にスクリーンショットが出来て、
四角い枠をつけることができるフリーソフト
元々は、去年に先輩から教えてもらった。

・ショートカットキーで、指定のファイル名で指定の場所に自動的に画像を保存するフリーソフト


http://www.forest.impress.co.jp/lib/pic/piccam/picedit/easycapture.html

・自分の使い方メモ(シンプル)

設定編
画像に沿って説明する。
赤い枠「To File」
にチェックを入れると、
ファイル名、ファイルの場所、ファイルのフォーマットを設定できる。

【Title】:ファイル名
【Start at】:連番
【Image save path】:ファイルの場所
【Image Format】:ファイルの種類


ショートカットーキー一覧
ちなみに、赤い枠のショートカットキーを良く使っている。
というか、これしか使えていないのだ。

ラジコのバックグランド再生とお笑いのポッドキャスト

iPhoneアプリradikoが登場してからというもの、
僕はこのアプリの魅力に取り憑かれている。

なんてたって、radioを聞きながら、rssリーダーのアプリや2ちゃんねるブラウザを起動できたりする。

俗にいう、バッググラウンド再生である。

とても素晴らしい。特におすすめのラジオ番組があるというわけではないが、だらだらと聞き流している。


恥ずかしながら
最初、このバッググラウンド再生が出来なかった。
というのも僕はiPhoneiPodを利用していなかったからだと思う。

radikoアプリを起動しては、
番組を選択。
右上にある「menu」から「バックグラウンド再生」を選択。
safariが起動する。
少しすると、番組が聞ける。

ここまで僕はいつも出来た。

さて、ここから、左上の「完了」というのを押すと、
バックグラウンド再生が出来ると思っていた。だって、他に画面に何も出てきていなかったから。

僕は悩んだ。

悩んだ挙げ句、いつもアプリを閉じる時に使用していた、画面の下の方にある「□」を押してみた。


出来た。念願のバックグランド再生が出来た。


とは言うものの、帰り道は、
僕は地下鉄を利用しているので、
あまりradikoを使用出来ていなかった。

地下鉄でも聞けるラジオ・・・それがpodcastだった。

というわけで、以下の番組を見つけて、家でダウンロードして、地下鉄でもラジオを聞いている。

番組のジャンルは「お笑い」

トータルテンボスのぬきさしならナイト
・JUNK アンタッチャブルの番組
・JUNK 山里亮太(南海キャンディーズ)の番組


では、寝ます。