cookpadホットレシピを淡々と投稿するbot

目次

  • 目的
    • OAuth対応

Basic認証からOAuthを用いた認証への変更

正規表現によるマッチングからlxmlライブラリを用いた構文解析へ。

  • 手法
    • OAuth対応
      • OAuthについて
      • OAuth対応python libraries
      • tweepyを使ったTLの取得と投稿
        • インストール
        • consumer key/secretの取得
        • access/keyの取得
      • references

TwitterのbotをOAuthに対応させる - しばそんノート
http://joshthecoder.github.com/tweepy/docs/index.html

  • その他

twitter timelineのポスト統計とか (1)

めりもに言葉を覚えさせたいなー、とりあえずはtwitterとかハイクから覚えさせればそれっぽいかな、でも、じゃあどうやって?
ということでとりあえず、まず、いったいどういう言葉が行き交っているんだろうと言うことでtwitter timelineのポスト数の推移とかをまとめてみた。

対象は11/26(木)から12/2(水)の一週間のtwitter/allegrovivaceとtwitter/merymoのタイムライン。なので、以下の話は僕(たち)が見えるtwitterのまとめ。

数字を追ったのは以下。
1) タイムライン
@allegrovivaceはfollowingが760、@merymoはfollowing 290、だいたい半分くらいかぶってるので計900ユーザくらい。
一週間に1以上発言したユーザは790ユーザ。総発言数は148.894つぶやき。

1) 単純なポスト数

  • 一日ごと
    • リプライ/RTを含まないつぶやき数とそれをしたユニークユーザ数 (tweets without mentions)
    • リプライとそれをしたユニークユーザ数 (mentions)
    • Retweetsとそれをしたユニークユーザ数 (retweets)

日付ごとの投稿数

日付ごとのユーザ

  • 一時間ごと
    • リプライ/RTを含まないつぶやき数とそれをしたユニークユーザ数 (tweets without mentions)
    • リプライとそれをしたユニークユーザ数 (mentions)
    • Retweetsとそれをしたユニークユーザ数 (retweets)

ここでMentionsは、本文文頭に.@を含むつぶやきとした。in_reply_to_はクライアントによって使っていたり使われていなかったりするため。
一方本文途中に@が出てくる場合は誰かへの言及かどうか判断が難しいため今回は考慮していない。 (人をさしてるかどうかは@につづく文字列がfollower listに存在するか調べればよい)
Retweetsは本文中に RT: あるいは QT:を含むもの。

ユーザごとにポスト数を見ると、
tweets w/o mentionsは一週間の平均で一日一人あたり最大433ポスト、平均25ポスト (中央値は12)
mentionsは一週間の平均で一日一人あたり最大323ポスト、平均8.9ポスト (中央値は8.8)

ちなみに、はてなハイクのほうは

12/4一日
総エントリ数: 4977
総ユニークID数: 1305

はてなハイク サービス終了のお知らせ

mecab with python-bindingでのメソッド

実のところ、pythonから使うのにあたっては、出力を定義するのではなく、メソッドでそれぞれの値にアクセスするのではなかったのか、って言う…。

import MeCab
txt = u"好きとか好きとか伝えたい".encode('utf8')
m = MeCab.Tagger("-Omerymo")
print m.parse(txt)
好き,4,動詞,*,*,*,*,*,○,○,○,,
とか,17,助詞,終助詞,*,*,*,*,な,ナ,ナ,,
...

n = m.parseToNode(txt)
dir(n)
...

メソッドとその説明

surface
形態素の文字列情報
id
形態素に付与される ユニークID
prev
一つ前の形態素へのポインタ
next
一つ先の形態素へのポインタ
enext
同じ位置で終わる形態素へのポインタ
bnext
同じ開始位置で始まる形態素へのポインタ
feature
CSV で表記された素性情報
length
形態素の長さ
rlength
形態素の長さ(先頭のスペースを含む)
rcAttr
右文脈 id
lcAttr
左文脈 id
posid
形態素 ID (未使用)
char_type
文字種情報
stat
形態素の種類: 以下のマクロの値
#define MECAB_NOR_NODE 0
#define MECAB_UNK_NODE 1
#define MECAB_BOS_NODE 2
#define MECAB_EOS_NODE 3
isbest
ベスト解の場合 1, それ以外 0
alpha
forward backward の foward log 確率
beta
forward backward の backward log 確率
prob
周辺確率
alpha, beta, prob は -l 2 オプションを指定した時に定義されます
wcost
単語生起コスト
cost
累積コスト
sentence_length
] : (要確認)解析対象文章の長さ? BOS nodeのみ?
begin_node_list
なんだろ?
end_node_list
なんだろ?
lpath
なんだろ?
rpath
なんだろ?
this
なんだろ?
token
なんだろ?

MeCab まとめ

  1. 単語の追加はシステム辞書かユーザー辞書に(id:udzuki:20090912:1252739982)。その際、コストを適当に指定する方法と学習させる方法とある(id:udzuki:20090912:1252740073)。
  2. すきな素性を追加できる
  3. 出力フォーマットはいろいろと定義可能(id:udzuki:20090912:1252739668)、またそうしたフォーマットはそれぞれIDで置換して出力できる(id:udzuki:20090912:1252739861)
  4. 未知語を推定するかしないか選択できる(id:udzuki:20090912:1252739917),。また、処理の方法をいろいろ指定可能 (id:udzuki:20090912:1252739948)

about Mecab (7) 単語の学習方法

学習用コーパスからパラメータ(コスト値)を推定することができます。
http://mecab.sourceforge.net/learn.html
またこんど。
例)
きまぐれ日記: Yahoo!の形態素解析をMeCabで無理やり再現してみる

about Mecab (6) 単語の追加方法

http://mecab.sourceforge.net/dic.html

辞書への単語の追加方法は「システム辞書」と「ユーザ辞書」への追加の二種類。

システム辞書への追加

辞書更新が頻繁でないときや, 解析速度を落としたくない時は, 直接 システム辞書を変更するのがよいでしょう.

  1. mecab-ipadic があるディレクトリに移動
  2. foo.csv というファイルを作成 (拡張子が .csv なら何でも可)
  3. foo.csv に単語を追加
  4. 辞書の再コンパイル + インストール

% /usr/local/libexec/mecab/mecab-dict-index -f euc-jp -t utf9
% su
# make install

ここで

ユーザ辞書への追加

システム辞書の更新は時間がかかります. 辞書の更新が頻繁な場合や, システム辞書を変更する権限が無い場合は, ユーザ辞書を作るのがいいでしょう.

  1. 適当なディレクトリに移動 (例: /home/foo/bar)
  2. foo.csv というファイルを作成
  3. foo.csv に単語を追加
  4. 辞書のコンパイル

% /usr/local/libexec/mecab/mecab-dict-index -d/usr/local/lib/mecab/dic/ipadic -u foo.dic -f euc-jp -t euc-jp foo.csv

ここで

  1. /home/foo/bar/foo.dic ができていることを確認
  2. /usr/local/lib/mecab/dic/ipadic/dicrc もしくは /usr/local/etc/mecabrc に以下を追加

userdic = /home/foo/bar/foo.dic
or) userdic = /home/foo/bar/foo.dic, /home/foo/bar2/usr.dic,/home/foo/bar3/bar.dic

  1. /usr/local/etc/mecabrc を編集する権限が無い場合は /usr/local/etc/mecabrc を ~/.mecabrc にコピーし, 上記のエントリを追加

エントリのフォーマット (活用しない語)

表層形,左文脈ID,右文脈ID,コスト,品詞,品詞細分類1,品詞細分類2,品詞細分類3,活用形,活用型,原形,読み,発音, ユーザ定義1, ユーザ定義2, ...


工藤,1223,1223,6058,名詞,固有名詞,人名,名,*,*,くどう,クドウ,クドウ

  • コストは,その単語がどれだけ出現しやすいかを示しています. 小さいほど, 出現しやすいという意味になります. 似たような単語と 同じスコアを割り振り, その単位で切り出せない場合は, 徐々に小さくしていけばいいと思います.
  • 左文脈IDは, その単語を左から見たときの内部状態IDです. 通常システム 辞書と同一場所にある left-id.def から該当する ID を選択します. -1 としておくと, mecab-dict-index が自動的に ID を付与します.
  • 右文脈IDは, その単語を右から見たときの内部状態IDです. 通常システム 辞書と同一場所にある right-id.def から該当する ID を選択します. -1 としておくと, mecab-dict-index が自動的に ID を付与します.

エントリのフォーマット (活用する語)

いそがしい,120,120,6078,形容詞,自立,*,*,形容詞・イ段,基本形,いそがしい,イソガシイ,イソガシイ
いそがし,128,128,6080,形容詞,自立,*,*,形容詞・イ段,文語基本形,いそがしい,イソガシ,イソガシ
いそがしから,136,136,6079,形容詞,自立,*,*,形容詞・イ段,未然ヌ接続,いそがしい,イソガシカラ,イソガシカラ
いそがしかろ,132,132,6079,形容詞,自立,*,*,形容詞・イ段,未然ウ接続,いそがしい,イソガシカロ,イソガシカロ
いそがしかっ,148,148,6078,形容詞,自立,*,*,形容詞・イ段,連用タ接続,いそがしい,イソガシカッ,イソガシカッ
いそがしく,152,152,6078,形容詞,自立,*,*,形容詞・イ段,連用テ接続,いそがしい,イソガシク,イソガシク
いそがしくっ,152,152,6079,形容詞,自立,*,*,形容詞・イ段,連用テ接続,いそがしい,イソガシクッ,イソガシクッ
いそがしゅう,144,144,6079,形容詞,自立,*,*,形容詞・イ段,連用ゴザイ接続,いそがしい,イソガシュウ,イソガシュウ
いそがしゅぅ,144,144,6079,形容詞,自立,*,*,形容詞・イ段,連用ゴザイ接続,いそがしい,イソガシュゥ,イソガシュゥ
いそがしき,124,124,6079,形容詞,自立,*,*,形容詞・イ段,体言接続,いそがしい,イソガシキ,イソガシキ
いそがしけれ,108,108,6079,形容詞,自立,*,*,形容詞・イ段,仮定形,いそがしい,イソガシケレ,イソガシケレ
いそがしかれ,140,140,6079,形容詞,自立,*,*,形容詞・イ段,命令e,いそがしい,イソガシカレ,イソガシカレ
いそがしけりゃ,112,112,6079,形容詞,自立,*,*,形容詞・イ段,仮定縮約1,いそがしい,イソガシケリャ,イソガシケリャ
いそがしきゃ,116,116,6079,形容詞,自立,*,*,形容詞・イ段,仮定縮約2,いそがしい,イソガシキャ,イソガシキャ
いそがし,104,104,6080,形容詞,自立,*,*,形容詞・イ段,ガル接続,いそがしい,イソガシ,イソガシ

about MeCab (5) 未知語の処理 (ii)

http://mecab.sourceforge.net/unk.html

未知語処理の定義には、char.def と unk.def という2つのファイルを変更

  • char.def
    • 未知語処理のルールです.
  • unk.def
    • 未知語に対する品詞列のテーブルです.

char.def

未知語処理の定義ファイルです. MeCab では, どの文字をどの字種として定義するか,さらに各字種に対し, どのような未知語処理を行うか細かく指定することができます.

カテゴリ名とそれに対する処理の定義

ファイルの最初には, カテゴリ名の定義と, 各カテゴリの未知語処理の動作 を定義します.

カテゴリ名 動作タイミング(0/1) グルーピング(0/1) 長さ(0,1, 2... n)

  • カテゴリ名: カテゴリの名前です.
    • HIRANA, KATAKANA.. といったカテゴリを定義します.DEFAULT と SPACE は必須のカテゴリです.
  • 動作タイミング: そのカテゴリにおいて, いつ未知語処理を動かすかを定義します.
    • 0: 既知語がある場合は, 未知語処理を動作させません
    • 1: 常に未知語処理を動かします
  • グルーピング: 未知語の候補生成方法です.
    • 0: 同じ字種でまとめません.
    • 1: 同じ字種でまとめます.
  • 長さ: 未知語の候補生成方法です.
    • 0: 全部
    • 1: 1文字までの文字列を未知語とします.
    • 2: 2文字までの文字列を未知語とします.
    • n: n文字までの文字列を未知語とします.

グルーピングと長さは同時に指定することができます.

KANJI 0 0 2
SYMBOL 1 1 0
NUMERIC 1 1 0
ALPHA 1 1 0
HIRAGANA 0 1 2

カテゴリとcodepointの互換定義 (?)

次に, 各カテゴリがUCS2のコードポイントのどこに該当するか定義します.

codepoint デフォルトカテゴリ名 互換カテゴリ名1 互換カテゴリ名2 ..

もしくは,

low_codepoint..high_codepoint デフォルトカテゴリ名 互換カテゴリ名1 互換カテゴリ名2 ..

0x0009 SPACE
0x30A1..0x30FF KATAKANA
0x30FC KATAKANA HIRAGANA # ー
コードポイントは UCS2(Unicode)を 0x から始まる16進数で記述します.

最初のカテゴリは, そのコードポイントのデフォルトカテゴリです. さらに, 互換カテゴリを列挙することができます. 上記の例では, 長音記号「ー」 は, デフォルトではカタカナですが, 平仮名を互換カテゴリとして持ちます. グルーピング動作の時に互換カテゴリは同じグループとしてみなされます.

記述例

DEFAULT 0 1 0 # DEFAULT is a mandatory category!
SPACE 0 1 0
KANJI 0 0 2
SYMBOL 1 1 0
NUMERIC 1 1 0
ALPHA 1 1 0
HIRAGANA 0 1 2
KATAKANA 1 1 0
KANJINUMERIC 1 1 0
GREEK 1 1 0
CYRILLIC 1 1 0

# SPACE
0x0020 SPACE # DO NOT REMOVE THIS LINE, 0x0020 is reserved for SPACE
0x00D0 SPACE
0x0009 SPACE
0x000B SPACE
0x000A SPACE

# ASCII
0x0021..0x002F SYMBOL
0x0030..0x0039 NUMERIC

...

# KATAKANA
0x30A1..0x30FF KATAKANA
0x31F0..0x31FF KATAKANA # Small KU .. Small RO
0x30FC KATAKANA HIRAGANA # ー

unk.def

未知語用の辞書です.

DEFAULT,0,0,0,記号,一般,*,*,*,*,*
SPACE,0,0,0,記号,空白,*,*,*,*,*
KANJI,0,0,0,名詞,一般,*,*,*,*,*
KANJI,0,0,0,名詞,サ変接続,*,*,*,*,*
HIRAGANA,0,0,名詞,一般,*,*,*,*,*
HIRAGANA,0,0,0,名詞,サ変接続,*,*,*,*,*
HIRAGANA,0,0,0,名詞,固有名詞,地域,一般,*,*,*
...

表層の部分を char.def で定義したカテゴリ名とした辞書ファイルです. 各カテゴリに対してどのような素生列を付与するかを定義します. 1つのカテゴリに複数の素性を定義してもかまいません. 学習後, 適切なコスト値が 自動的に与えられます.

数字の連続を1つの形態素とする

a) 辞書 (*.csv ファイル)から数字のエントリを削除します。 ipadic の場合は、Noun.number.csv の中から、アラビア数字のエントリを消去します。
b) char.def を修正し、数字の連続が未知語になるようにします。

NUMERIC 1 1 0

c) unk.def を修正し、数字のコストを小さくします。 4カラム目のコスト値を 0以下の小さい値に設定します。

NUMERIC,1204,1204,0,名詞,数,*,*,*,*,*

d) 辞書をコンパイルします。

% /usr/local/libexec/mecab/mecab-dict-index

ASCII 文字列は、スペース/タブのみで分割する (kakasiと同一動作)

a) 辞書 (*.csv ファイル)からアスキー文字列を含むのエントリを削除します。
b) char.def を修正し、スペース、記号を除く文字を同一字種(ASCII)にマッピ ングします。他のエントリも同時にチェックし、0x0021..0x007E の領域を 他の字種にマッピングしないようにしてください。

ASCII 1 1 0

0x0021..0x007E ASCII

c) unk.def を修正し、ASCIIのコストを小さくします。 4カラム目のコスト値を 0以下の小さい値に設定します。

ASCII,1192,1192,0,名詞,サ変接続,*,*,*,*,*

d) 辞書をコンパイルします。

% /usr/local/libexec/mecab/mecab-dict-index