2007年3月アーカイブ

Pythonでコーディングするネタとして、キーワード抽出に手をつけてみました。"キーワード抽出"のアルゴリズムや作法などに詳しくないので、以下のページをなぞる形で実装しました。
[を] 形態素解析と検索APIとTF-IDFでキーワード抽出

MeCabの用意

MacPorts経由で以下をインストールしました。

  • mecab
  • mecab-ipadic-eucjp
  • mecab-ipadic-sjis
  • mecab-ipadic-utf8
  • mecab-jumandic-eucjp
  • mecab-jumandic-sjis
  • mecab-jumandic-utf8
  • py-mecab
辞書を根こそぎインストールしていますが、"port search mecab"の結果であきらかに(今回は)不要であろうもの以外は全て入れておきました。
また、細かい事は考えず、/opt/local/etc/mecabrcで"dicdir = /opt/local/lib/mecab/dic/ipadic-utf8"としておきました。

pYsearch

DF値を求めるための自前のデータベースは無いので、Yahooのウェブ検索Webサービスを使います。楽をするために、Python用のSDKとして利用出来るpYsearchというモジュールをインストールしました。
Python Cheese Shop : pYsearch 3.0

母集団が手元に無いと難しい?

今回は、"キーワード抽出"の手順を体験する事が目的だったので、Yahooの検索APIを利用して済ませましたが、実際に何かしらのサービスや機能として提供する事を考えると、母集団の確保が結構なキモににるのでしょうか。
TF-IDFと異なる指標(?)を利用したキーワード抽出もあるのかな?

あべ晋三のホームページへようこそ!! Open ボタンをクリックしてください。
画像の左上のところはわざとなのでしょうか?

# ps -aux
# df
# du -h
# free -tk
# netstat -r
# less /etc/crontab
# chkconfig --list
# l

PowerBookと一緒に写ってる事を考えると、ねらいのような気もします。ITなんとかを進めていた気もしますし。

まあ、どうでもいいんですけど。


。。。ひょっとしなくても、これ偽物サイト?

どのようにすればよいのでしょうか?

例えば、文章中の単語の出現回数をカウントして出現回数で単語を並び替えたい場合、など。

>>> D = {'w1': 100, 'w2': 10, 'w3': 1000}
>>> L = zip(D.keys(), D.values())
>>> L
[('w3', 1000), ('w2', 10), ('w1', 100)]
>>> L.sort(lambda x, y: cmp(x[1], y[1]))
>>> L
[('w2', 10), ('w1', 100), ('w3', 1000)]

ディクショナリをリストに変換して、リストのsortメソッドに比較関数を与えて並び替えてみましたが、どうなんでしょう?

"The Python Challenge"挑戦中

The Python Challenge』というものがあるらしく、早速手をつけてみました。

プログラムを書いてクイズを解くゲームのようです。『「Pythonicな方法」を学ぶための教材』でしょうか。

今はLevel 4です。英語力が無いので問題の意図がいまいち掴めませんが、のんびりやっていく事にします。


Level 6で断念。問題を解く事よりも問題を理解する事の方が難しかったです。

ProFontWindowsからM+に乗り換えてみました。
M+ OUTLINE FONTS

日本語はMacではヒラギノ(Winではメイリオ)を使い続けておいて、英数字で"M+ M Type-2(regular)"を使うようにしました。ProFontWindowsは字面が面白くて好きですが、等幅でないようで微妙にコードが揃わないので諦めました。

会社でもフォント変えないと。


会社のWindowsではM+がうまいこと設定できなかったので、ProFontWindowsTweakedにしてみました(前はたぶんTweakedじゃないほう)。
(outlineの)M+はiso8859-1(欧文?)が無いんですね。OSXでいけたのは何でしょう?勘違いかな?


家のMacでは欧文にM+を使って日本語をosaka等幅にしました。

OSアップデートでCarbonEmacsのフォント設定がおかしくなりました。
error: No fonts match `-apple-m+ 2m regular-medium-r-normal--14-*-*-*-*-*-mac-roman'
osaka等幅にしとけってことかな。

どうでも良くなって来たので、carbon-font.elとntemacs-font.elの標準を利用するようにしました。文字の大きさについて時間があればいじろうと思います。

粘ってmakeしてみたら使えるようになりました。"m+ 2m medium"にしたからでしょうか?一応、regularにしても問題なく立ち上がるのでそこが原因だとは思えないのですが。
一回りして、"m+ 2m medium"x"ヒラギノ角"の組み合わせになりました(サイズは14)。

どうやらPythonではタプルのリストとして結果が返る関数が多い(?)ようなので、この辺の事情(?)を知っておかないと間違い続ける気がします。

例えば、httplib.HTTPResponseのgetheadersメソッドはHTTPレスポンスヘッダをタプルのリストで返します。辞書で返ってくれば、素直にheaders['location']などとして取得出来ますが、タプルの場合にどうしたら良いのか分かりません。

>>> L = [('a', 1), ('b', 2), ('c', 3)]
>>> s = 'b'
>>> for e in L:
...     if e[0] == s:
...         print e[1]
... 
2

分からないので、とりあえずはforとifでごまかしています。

>>> H = dict(L)
>>> s = 'b'
>>> print H[s]
2

分からないので、とりあえずdictに型変換してごまかしてみます。

タプルのリストのまま簡単に特定のタプル要素のn番目の値を取り出す方法はあるのでしょうか?

キーと値のペアからなる配列をタプルのリストとして表現するのは、シーケンス操作に何かしらの利点があるという事なのでしょうか?

レスポンスコードを表す定数を(pydocの)ドキュメントから調べきれなかったので、無理矢理ひねり出してみました。

pydocで調べられると思いますが、「pythonのトレーニングだ!」と考え見切り発車で書いてみました。本当にレスポンスコードなのか分かりませんが、100から599までならそれっぽいだろうと。

恥ずかしながら、未だにこの程度の理解です。

import httplib
 
http_response_code_list = {}
for name in dir(httplib):
    value = eval('httplib.'+name)
    if type(value) == type(1) and value in range(100, 599):
        http_response_code_list[value] = name
http_response_code_keys = http_response_code_list.keys()
http_response_code_keys.sort()
for key in http_response_code_keys:
    print '%03d: %s' % (key, http_response_code_list[key])
 
## ---- begin output ----
## 101: SWITCHING_PROTOCOLS
## 102: PROCESSING
## 200: OK
## 201: CREATED
## 202: ACCEPTED
## 203: NON_AUTHORITATIVE_INFORMATION
## 204: NO_CONTENT
## 205: RESET_CONTENT
## 206: PARTIAL_CONTENT
## 207: MULTI_STATUS
## 226: IM_USED
## 300: MULTIPLE_CHOICES
## 301: MOVED_PERMANENTLY
## 302: FOUND
## 303: SEE_OTHER
## 304: NOT_MODIFIED
## 305: USE_PROXY
## 307: TEMPORARY_REDIRECT
## 400: BAD_REQUEST
## 401: UNAUTHORIZED
## 402: PAYMENT_REQUIRED
## 403: FORBIDDEN
## 404: NOT_FOUND
## 405: METHOD_NOT_ALLOWED
## 406: NOT_ACCEPTABLE
## 407: PROXY_AUTHENTICATION_REQUIRED
## 408: REQUEST_TIMEOUT
## 409: CONFLICT
## 410: GONE
## 411: LENGTH_REQUIRED
## 412: PRECONDITION_FAILED
## 413: REQUEST_ENTITY_TOO_LARGE
## 414: REQUEST_URI_TOO_LONG
## 415: UNSUPPORTED_MEDIA_TYPE
## 416: REQUESTED_RANGE_NOT_SATISFIABLE
## 417: EXPECTATION_FAILED
## 422: UNPROCESSABLE_ENTITY
## 423: LOCKED
## 424: FAILED_DEPENDENCY
## 426: UPGRADE_REQUIRED
## 443: HTTPS_PORT
## 500: INTERNAL_SERVER_ERROR
## 501: NOT_IMPLEMENTED
## 502: BAD_GATEWAY
## 503: SERVICE_UNAVAILABLE
## 504: GATEWAY_TIMEOUT
## 505: HTTP_VERSION_NOT_SUPPORTED
## 507: INSUFFICIENT_STORAGE
## 510: NOT_EXTENDED
## ---- end output ----
 

。。。あれ、レスポンスコードの説明句(?)を大文字にしてスペースをアンダースコアで置換したら良かっただけですか?(pydocが)英語だったから見逃してた?

Firefox2.0になってからRSSをブラウザで開く事を避けていたわけですが、先ほどFeedburnerのフィードを開いてしまいました。

で、スタイルが適用されていたので「なにごと?」と思ってよく見てみれば、HTMLなんですね。Referer付きのリクエストを受けるとHTMLを返すようですが、これはFeedburnerのデフォルトでしょうか。

HORNET's TALK.. : FeedBurnerでFirefox2.0のフィードプレビューを無効にする
↑これでしょうか?

Refererを消すと(ダイレクトアクセスだと)普通にFirefoxにスタイルが打ち消されるので"always"では無く、きっとデフォルトの"often"な挙動なんでしょう。

このネタは結構前にどこかで聞いた気がしますが、覚えていないのでメモとして残してみました。

注)Ver.0.72をPHP5.1.6の環境で動かしています。

MagpieRSSのrss_parse.inc内では、xml_set_element_handler関数を利用してXMLをパースしますが、どうやらRSS系については属性をうまく処理していないようです。対応できている属性は、rss要素のversion属性とchannel要素やitem要素rdf:aboutのみ。Atomではいろいろと対応しているようです。

enclosure要素から{url,length,type}を取得したかったので、feed_start_elementの中をいじることで無理やり対応させました。

Index: rss_parse.inc
===================================================================
--- rss_parse.inc	(revision XXXX)
+++ rss_parse.inc	(working copy)
@@ -187,7 +187,13 @@

                 $this->current_item['about'] = $attrs['rdf:about']; 
             }
         }
-        
+        // **** enclosure ****
+        elseif ( 

+        $this->feed_type == RSS and
+        $el == 'enclosure' )
+        {
+            $this->current_item['enclosure'] = $attrs;
+        }
         // if we're in the default namespace of an RSS feed,
         //  record textinput or image fields
         elseif ( 

@@ -270,7 +276,6 @@
     
     function feed_end_element ($p, $el) {
         $el = strtolower($el);

-        
         if ( $el == 'item' or $el == 'entry' ) 
         {
             $this->items[] = $this->current_item;

今回はソースをいじって対応しましたが、いっそ別のライブラリを探したほうがいいのでしょうか?

プロフィール

このアーカイブについて

このページには、2007年3月に書かれたブログ記事が新しい順に公開されています。

前のアーカイブは2007年2月です。

次のアーカイブは2007年4月です。

最近のコンテンツはインデックスページで見られます。過去に書かれたものはアーカイブのページで見られます。