2008-09


戻る

2008-09-01T22:44:54 (Mon)

Ruby でニューラルネットワーク 1

しばらく使ってなかったのでリハビリと暇つぶしを兼ねて (※今研究室ですることがあまりない) Ruby で RNN (Recurrent Neural Network) の実装をしてみました.

class Node
 def initialize(type, id)
  @edges = []
  @type = type
  @id = id
 end
 def add(edge)
  @edges << edge
  @edges.uniq!
 end
 def output
  if @done_calc == false then
   @done_calc = true
   @output = 0.0
   @edges.each { |i|
    @output += i.weight * i.src_node.output
   }
   @output = (1.0 / (1.0 + Math.exp(-@output)))
  end
  return @output
 end
 def set_output(val)
  @done_calc = true
  @output = val
 end
 def reset_calc
  @done_calc = false
 end
 @type #入力層,中間層,出力層の種類
 @id #それぞれの層での接点の ID
 attr_reader :type, :id
end

class Edge
 def initialize(src_node, dst_node)
  @src_node = src_node
  @dst_node = dst_node
  dst_node.add(self)
 end
 @weight
 attr_reader :src_node, :dst_node
 attr_accessor :weight
end

NN (Neural Network) の基礎になる接点 (ニューロン) と枝 (シナプス) はこれでほぼ完成です.どう使えばいいのかはまた次に.

命名規約はネット上にあったRubyコーディング規約 (shugo.net) を参考にしています.

2008-09-02T23:53:33 (Tue)

Ruby でニューラルネットワーク 2

前回の続きです.どうやってこれを使うのかを紹介.

input_node = Node.new("i", 0)
output_node = Node.new("o", 0)
edge = Edge.new(input_node, output_node)
edge.weight = 1.0

x = -5.0
x_end = 5.0
delta_x = 0.1
while x <= x_end
 input_node.set_output(x)
 output_node.reset_calc
 printf("%f %f\n", x, output_node.output)
 x += delta_x
end

入力層の接点 1 つ,出力層の接点 1 つ,その間を繋ぐ重み 1.0 の枝 1 つの超簡易 RNN がこれで出来ます.なので出力結果にはシグモイド関数がそのまま現れます.

接点の生成時に,どの層の接点かを示す "i", "c", "o", "b" を付加します.b はバイアスノードです.そして,それぞれの層の中で接点の区別を付けるためにさらに ID を設定します.バイアスは 1 つしかないのでこの ID は何をつけても関係ありません.nil にするのが無難でしょうか.

後は枝でそれぞれの接点を適切に結べば OK です.

使うときは,まず中間層と出力層の全接点の reset_calc メソッドを実行します.そして入力層に任意の入力を set_output メソッドで設定したら,あとは出力層の output メソッドを呼び出すだけで適切に計算された数値が一切の無駄なく (※同じ接点の出力を何度も計算しない) 計算されて出てきます.

ちなみに上のソースでは set_output してから reset_calc してますが,この順番はどちらが先でも関係ありません.

Composite パターンみたいなもので再帰的に接点を入力方向に向かって辿っていくことを実現しています.output メソッドの中を読むとやりたいことが分かると思うですハイ.

さて,種類と ID を各接点に振り分けたのは,RNN の保存と読み込みを実装するためです.次回はそれを管理する部分を紹介します.

2008-09-03T18:20:19 (Wed)

Ruby でニューラルネットワーク 3

続きです.今回は自らが作成した RNN をテキストファイルに保存したりそこから読み込んで構築したりする実装の紹介です.

まず,RNN の内容を以下のような形で任意のテキストファイルに保存します.

1 #入力層のノード数
2 #中間層のノード数
1 #出力層のノード数
7 #枝の総本数
i 0 c 0 1.0 #以下枝の情報を同じように書き並べる
i 0 c 1 2.0 #入力ノード 0 から中間ノード 0 への重み 1.0 の枝を表す
b c 0 1.0 #バイアスノードから中間ノード 0 への重み 2.0 の枝を表す
b c 1 1.0
c 0 o 0 1.0 #中間ノード 0 から出力ノード 0 への重み 1.0 の枝を表す
c 1 o 0 1.0
b o 0 0.05

(※#で始まるコメントは,実際は書いてはいけない.ここでは説明のために書いてあるだけ)

これで以下の図のような RNN が出来上がります.



そして,恐らく今回一番難解な,そのテキストファイルと RNN 構造の変換の部分の実装を以下に示します.

class Rnn
 def initialize(filename)
  file = File.open(filename, "r")
  @input_nodes = Array.new(file.gets.to_i) { |i|
   Node.new("i", i)
  }
  @central_nodes = Array.new(file.gets.to_i) { |i|
   Node.new("c", i)
  }
  @output_nodes = Array.new(file.gets.to_i) { |i|
   Node.new("o", i)
  }
  file.gets #destroy the information of edge total
  @bias = Node.new("b", nil)
  @edges = []
  file.each { |i|
   if i =~ /(([ic])\s+(\d)|b)\s+([co])\s+(\d)\s+(.*)/ then
    src_node = nil
    if $1 == "b" then
     src_node = @bias
    else
     if $2 == "i" then
      src_node = @input_nodes[$3.to_i]
     elsif $2 == "c" then
      src_node = @central_nodes[$3.to_i]
     end
    end
    dst_node = nil
    if $4 == "c" then
     dst_node = @central_nodes[$5.to_i]
    elsif $4 == "o" then
     dst_node = @output_nodes[$5.to_i]
    end
    edge = Edge.new(src_node, dst_node)
    edge.weight = $6.to_f
    @edges << edge
   end
  }
  @bias.set_output(-1.0)
 end
 def save(filename)
  file = File.open(filename, "w")
  file.puts @input_nodes.length.to_s
  file.puts @central_nodes.length.to_s
  file.puts @output_nodes.length.to_s
  file.puts @edges.length.to_s
  @edges.each { |i|
   edge = i.src_node.type
   if i.src_node.type != "b" then
    edge = format("%s %d", edge, i.src_node.id)
   end
   edge = format(
    "%s %s %d %f",
    edge, i.dst_node.type, i.dst_node.id, i.weight
   )
   file.puts edge
  }
 end
end

@input_nodes, @central_nodes, @output_nodes, @bias, @edges というメンバを持つ Rnn というクラスを作りました.あとは initialize メソッドでテキストファイルの内容を適切に読んでいって,各メンバを適切に初期化するわけです.

(※枝の総本数情報を破棄するのは,不要だからです.ではなぜテキストファイルにそんなものが書いてあるのかというと,そもそもこのテキストファイルの仕様の方が Ruby 版 RNN を作る前の C++ 版で決まっていたからです.そちらでは枝の本数が先駆けて取得出来たほうが楽だったのです.)

save メソッドはその逆で,Rnn クラスの現在の構造を同様の形式でテキストファイルに出力します.

もうこれを詳細に解説するのは不可能に近いかと(^^; 長過ぎて面倒臭過ぎるw

とにかく,これで構造に関する情報のやりとりは整備されました.

あとこれを実際に関数として使うために,中間ノードと出力ノードの reset_calc を全て実行していくメソッドと,入力ノードに値をセットして出力ノードから output を取得するメソッドを実装しなければなりませんが,それはかなり簡単なので次にまわします.

ちなみにテキストファイルの方で構造に関するミス (例 : 出力ノードがない,入力層と出力層が断絶している,存在しないノードに枝が繋がろうとしている,等) があっても,それらの検出はしません.nil 参照が恐らく起こってエラーで止まります.そこのエラー処理まで考えるほど大したものを作っているわけでもないので,省略します (※単に面倒臭いだけというのも大きい).

まぁ仮に作るとしても,テキストファイルのミスを検出した時点で例外を投げるだけで十分だと思いますが (※深く考えずにしている発言なのでそうじゃないかもしれません(^^;).

次回は先ほど言った Rnn クラスを使い物になるようにするためのメソッドの実装と,それのおまけで簡単な入力補助スクリプトの実装を紹介しようと思います.

2008-09-04T22:59:40 (Thu)

Ruby でニューラルネットワーク 4

前回紹介した Rnn クラスに reset_calc メソッドと output メソッドを実装します.

class Rnn
 #initialize, save メソッドを省略
 def reset_calc
  @output_nodes.each { |i| i.reset_calc }
  @central_nodes.each { |i| i.reset_calc }
 end
 def output(input)
  @input_nodes.each_index { |i|
   @input_nodes[i].set_output(input[i])
  }
  ret = Array.new(@output_nodes.length) { |i|
   @output_nodes[i].output
  }
  return ret
 end
end

前から思ってたことですけど,each メソッドの書き方って気持ち悪いくらい気持ちいいですよね?分からないかな?(^^; だって { |i| #色々な処理 } という“処理”を引数で渡せるんですよ?そしてその処理のスコープの外側にあるローカル変数も簡単に使用出来るんですよ.関数ポインタや関数オブジェクトだとかいうチャチなもんじゃ断じてねぇですよ.

さて,これが出来てしまえばあとは Rnn クラスのインスタンスを作って適当な入力を与えて出力を取得するだけです.

で,その入力を適切に与えてやるというのが結局 Rnn クラスを用いるスクリプト内に記述してやらなければならないわけで,それを何度も書き直していると案外大変です.

なので実行時の引数から入力値に関する情報を必要な分だけ与えてやる別の Ruby スクリプトを紹介します.これは NN とは関係ないです.

require "rnn.rb"

if $*.length == 0 then
 exit
end

x = 0.0
x_end = 0.0
delta_x = 0.1
if $*.length >= 2 then
 x = $*[1].to_f
 if $*.length >= 3 then
  x_end = $*[2].to_f
  if $*.length >= 4 then
   delta_x = $*[3].to_f
  end
 else
  x_end = x
 end
end

rnn = Rnn.new($*[0])

while x <= x_end
 rnn.reset_calc
 printf("%f %f\n", x, rnn.output([x])[0])
 x += delta_x
end

第一引数に,RNN の構造を示すファイルのファイル名を,第二引数に入力値を入力します.すると出力値が得られます.第二引数のデフォルト値は 0.0 です.

グラフに出力などを行いたいときは,第二引数と第三引数で入力値の範囲を決定します.刻み幅を第四引数で決定します.第三引数のデフォルト値は第二引数と同じ値,第四引数のデフォルト値は 0.1 です.

ええ,そうです.残念ながら 1 入力 1 出力です.複数入力,複数出力にしたい場合は,自分で改造して下さい (ぉ というか,引数の処理自体もかなりいい加減な実装なので,宿題程度の問題のみでの利用ということで.多分ほとんどの人はこんなもんわざわざ晒さないと思います(^^; あくまで私のリハビリということでw

最後はこれを GA に使うために各枝の重みをベクトルとして取り出せればいいでしょう.

面倒くさければ attr_accessor :edges と書くだけでもいいでしょうし,メソッドをきちんと作りたければ

def get_weight_vector
 return Array.new(@edges.length) { |i|
  i = @edges[i].weight
 }
end
def set_weight_vector(weights)
 @edges.each_index { |i|
  @edges[i].weight = weights[i]
 }
end

とでも書けばいいでしょう.ちなみに自分はきちんとメソッド派です.

とりあえずこれで Ruby で NN 日記は終了です.また何か間違いを見つけたら修正しておきます(^^;

2008-09-06T22:48:59 (Sat)

ぼちぼちぼちと

とりあえず難関だと思われてたところのうちの 1 つが出来たりした感じ.

まぁ私は難関を先に作って,時間だけが掛かる簡単なところを盛大に後回しにするからいつも大変なことになるのですが.

難しいことの方がやりがいがあるのでこうなるのです (^ω^) 真似などなさいませぬよう.

2008-09-08T03:34:56 (Mon)

コミトレ 12 に行ってました

本日,日帰りで大阪までコミトレに一般参加で行ってました.

ひだまりスケッチとらき☆すた本を相変わらず漁っていたのですが,特にひだまりの方がアニメ化の影響でしょうか,結構な数のサークルがありました.お陰で戦利品の数がコミケより若干多いとか(^^; でもローゼンメイデンはやっぱり少なかったです(^^; …ローゼン本を本気で漁るならやはりコミケ 1 日目なんですね.冬は頑張ろう…!

コミトレ終了後は,いつものドリアな面々と相変わらずサイゼリアへ行き夕食 (兼昼食).

その後は同じメンバーで日本橋へお買い物に行ってました.

さて,その日本橋でボークスに入ったときのことなのですが,らき☆すたのねんどろいどシーズン 2 の中古品が結構目に付きました.自分はこれでひよりの夏服バージョンを発売当初に数千円使って引き当てていたのですが,冬服バージョンを引き当てるまでの財力がそのときなかったので,夏服だけでとりあえず満足していました.

しかしボークス店内には「ひより冬服」などと言う感じで盛大にネタバレされた中古品がいくつも置いてあるではないですかw しかも冬服夏服合わせて 10 体以上はw それも夏服に至っては原価割れした値段でw

というわけで,冬服 3 体,夏服 2 体を救助してきました (←アホ).その品をレジに持って行ったとき,レジに居た 2 人の店員さんになんと以下のようなことを言われてしまいました.

「ひよりへの愛が溢れていますね(^^」

流石にまとめて買い過ぎたようでしたwwww でもまぁ合わせて 2 千円ちょいなので金銭的には大した買い物ではないといえばないですが.でも店員さんにこんな風にネタにされたことは初めてでしたし,楽しかったので良しとします.

他にもゲーマーズ限定版表紙のらき☆すた 6 巻を買ったり.あ,その後でアニメイトで通常版 6 巻も買いました.ゲーマーズはポイントカードを持ってない + アニメイトのポイントは割がいい + アニメイト限定のおまけ冊子が付いて来る,という理由から.

で,今戦利品の処理をある程度終えたところですが,なんというかひだまりスケッチの漫画のネタのクオリティがどの本もかなり高かったです.皆愛に溢れてるなぁ,と (´∀`) 嬉しい限りです.…これがアニメが無くても続いてくれればお兄さんはもっと嬉しいのですが (ノ∀`)

とまぁ,そんな感じでまたまた非常に楽しい一日でした.お会いした方々,イベント関係者の方々は本当にお疲れ様でした m(_ _)m

2008-09-11T15:24:19 (Thu)

酷道走ってきた

すっごく久しぶりに酷道ラリーをしてきました.今日走ったのは国道 193 号線の海部から神山までの区間です.

この国道 193 号線というのは,個人的には大きく 4 つの区間に分けられると思います.南から順に「海部~那賀」「那賀~神山」「神山~山川」「脇町~高松」という感じに.それぞれの区間に峠が存在し,それぞれの区間の切れ目ごとに国道 195 号線,438・439 号線,192 号線が横切っていて,それなりに大きな交差点となるわけです.

で,今まで「神山~山川」「脇町~高松」区間を走ったことはあったのですが,それ以南を走ったことはありませんでした.しかし先輩から「海部からの道がヤバイ」と聞かされたことや,438 号線の神山付近を走っているときに垣間見える 193 号線の南方面への別れ道 (※この別れ道というのが,それと知らなければ気付けないほど小さい) などを見て,酷道ドライバーとしてそのうち走ってみたいなぁ,と思っていたのです.

で,今日朝からサモを連れて (アニメイトに行くと偽って連れまわしましたw ほんとごめんよ) 行って来たわけです.

走ってみた感想としては,これが本物の酷道でした,というようなものでした… いや,もうほんと「海部~那賀」区間は死ぬかと思いました.ヘアピンカーブこそ少なかったものの,小刻みなカーブのまぁ多いこと多いこと.あと一応全区間舗装は (何とか) されていましたが,落石が非常に多いのでちょっと気を抜くと路上の小石でガクン!です.あ,もちろんガードレールはほとんどありません.二車線とか都市伝説です.民家もないです.しかもそれが峠 (霧越峠) を上り始めてから下り終わるまでほぼずっと続くのです.本当の意味での『心細さ』というものを味わいたいなら,ガソリンを減らしてこの道を一人で走るといいと思います.絶対私は嫌ですが.

そして少し広い 195 号線付近に出て,次の「那賀~神山」区間を走りました.まぁここは,標高が高いだけ,って感じでしたね (※感覚が麻痺してます.今思うと十分酷道でしたハイ).この区間の峠 (土須峠) はほんと標高高かったです.今地図を確認してみたら 1050 だそうでw お陰で景観は素晴らしかったですよ.ここはヘアピンが多かったかも.

で,神山付近に下りてきたところで,サモがマジ眠たそうだったので更に 193 号線を北上するのを断念して帰路につきました.本来の予定ではここから高松に行く予定だったのです.まぁそれでアニメイトに行こうと思っていたわけで,厳密にはサモを最初から騙すつもりは無かったということでw

今回のドライブで,自分は他人に対してもう間違いなく「酷道ドライバーになった」と言えるだろうと実感しました.今まで酷道だと思っていた道がかなり生っちょろかったということも分かりました.サモの例えを借りると「LV を最高にしてラスボスを楽勝で倒したのでいきがってたら裏ダンジョンを見つけたので入ってみたところ,そこのランダムエンカウントの雑魚敵に殺されそうになった」という感じです.

2008-09-12T23:05:25 (Fri)

国道 193 号線動画

先日の自分自身の酷道 193 号線ドライブにちなんで,ニコ動で他の方の 193 号線の走ってみた動画を探してみました.以前は 1 つしかなかったなかったのですが,今年の夏とつい先週ほどに 2 つほど新しく投稿されたのがあるようで,それらを含めて紹介します.







投稿が古い順です.

いずれも終点の方からのスタートなのはたまたまです.なぜ皆そうなんでしょうか?(^^;

地理的に同じ道でも,走る時期によって工事の有無の差があったり天気が違ったりで,色々な車載動画を見るのは非常に楽しいです.

2008-09-13T23:32:33 (Sat)

カービィフロンティア



この人の作った過去動画は全部見ていました.実に卑劣な振り込めない詐欺です.さらに評価されるべき.

ロマサガとカービィとか名作のミックスにもほどがあるっちゅーもんですわ (^ω^)

私個人がもう新しく一つ興味を持ったのがこれが DX ライブラリを用いた作品だということ.やっぱり 2D ゲームを作るのにはあれで十分ですね.まぁちょっと凝ったエフェクトかけようと思ったらしんどかったりはしますが… (モザイクとか特に)

2008-09-14T14:55:02 (Sun)

Twitter bot with Ruby 作成奮闘記 1

ゲーム作るよりも面白そうと感じたので Twitter bot を作ろうと思い立ちました (※無名サークルなので無害です).

方針としては
・Ruby が好きなので Ruby でやる
・さくらインターネットのレンタルサーバの cron で動かす (常駐プロセスにはしない)
 ‐※というよりどのサービスでも常駐は不可能
  (参考 : http://www.sakura.ne.jp/rentalserver/matrix.html)
・とにかく楽してやる

まず「twitter bot ruby」でググって調べていると,twitter への投稿や TL の取得を容易にするためのライブラリを入手するとよい,ということになり,そのライブラリたちを入手するために RubyGems というものをインストールすることになりました.

…ここから先は色々あったので書きません.結論から言うと結局何も出来ませんでした.参考にしたサイトやブログも余りに多過ぎて把握しきれません.だから正確に言うとここから先にあった色々なことは書かないじゃなくて書けないのです.面倒臭いだけと言ってしまえばそうですが…(^^;

失敗の原因を最も簡単な一言で言ってしまえば,Windows でやってたから,なんでしょうけどねぇw 多分 Linux でやってたら余裕だったと思うですよ.

ということで,次は Linux マシンでチャレンジしてみます(^^; 成功したら(笑)また How to をまとめようと思いますw

2008-09-15T13:09:58 (Mon)

Twitter bot with Ruby 作成奮闘記 2

twitter ライブラリのインストールは成功したっぽいです.

まず RubyGems のインストールですが,こちらはさほど問題無く成功していました.ということで,以下に簡単にやり方をメモしておきます.

環境は Windows XP Professional SP3 です.ruby そのものは mswin32 を入れてたはずです (※もう何年か前のことなので忘れました(^^;).

まずは RubyGems のインストールです.RubyGems Manuals に行き,downloads のページから rubygems-*.*.*.tgz もしくは .zip をダウンロードします.現時点での最新バージョンは 1.2.0 でした.

それをどこかに解凍して,start.rbsetup.rb を実行します.もちろん ruby を使ってです.(ruby start.rbsetup.rb をコマンドラインで実行しろってことっスよ)

[2008-09-16T09:01 追記]

何故か start.rb とか書いてた(^^; setup.rb の間違いです.

[追記ここまで]

そうすると,zlib.dll がねーよ,と言われて失敗すると思います.言われなかったら先に進んで下さい.私は言われました.

てことで zlib.dll を入手するために zlib Home に行き,zlib compiled DLL をダウンロードします.ページを少しスクロールしたところにあります.分からなければ "zlib compiled dll" でページ内検索して下さい.

それを解凍したら,中に zlib1.dll というのファイルがあるはずですので,zlib.dll にリネームしてから "Ruby のインストールディレクトリ"\bin\ に放り込みます.

そうすれば ruby start.rb を実行出来るようになるでしょう.

ちなみに zlib に関する情報はコチラのエントリを参考にしました.なんと "zlib.dll" でググったら一番に出てきます(^^; 皆同じところで詰まるようですねw

ということで RubyGems が使えるようになりました.あとは Ruby Twitter Gem簡易リファレンス (Greenbear Laboratory) に従って gem install twitter を実行します.

…が,また DLL がねーよと怒られてしまいます.恐らく SSLEAY32.DLL が無いと言われるかと.これも言われなかったら次に進みます.

で,しょうがないのでまた DLL を探します.ココの情報に従って,合計 6 つの DLL ファイルと 1 つのアプリケーションらしきものをインストールします.あー面倒.

とりあえず,zlib と同じ要領で導入するのが "ssleay32.dll", "libeay32.dll", "readline.dll", "pdcurses.dll", "gdbm.dll", "incov.dll" の 6 つです.先ほどのページのリンク先から,とりあえず mswin32 と名の付く一番バージョンの新しいものを落としましょう.そして先ほどと同じディレクトリに放り込みましょう.

あとは ActiveTcl もよく存在理由の分からないシロモノですがインストールしちゃいましょう.

(※もうこの辺はかなり適当にやっちゃってる,とりあえず動けばいいだろうという対症療法的なものなので,何か大変なことが起こっちゃっても私ゃ知ったこっちゃありませんよ?)

で,ようやくマトモに RubyGems が動くようになりました.ここで参考にしたページはココココです.

しかし,まだダメです.えぇ,まだです.gem install twitter と入力しても失敗してる臭いメッセージが出ました.昨日はここで投げ出してたのです.

ところが今日,その後の斜線が引っ張ってあるコマンド (gem install hpricot --source http://code.whytheluckystiff.net) を実行してからだと成功しました (多分).

"Ruby のインストールディレクトリ"\lib\ruby\gems\1.8\gems\ に hpricot-0.6.161 というディレクトリは,そのコマンドを実行する前から存在していました.そして hpricot 0.5 とは相性が悪いため (中略) (0.6なら大丈夫かな?) という記述があったため,ここには問題ないと思っていたのです.

が,そのコマンドを実行したあとに,同じ階層に hpricot-0.6-x86-mswin32\ というディレクトリが生成されていました.hpricot が何者なのかはまったく分かりませんが (※調べてないので),とりあえず,これが出来た後の gem install twitter コマンドは正常に終了したっぽいです.

ところが,まだまだダメです.えぇ,まだです.まだまだです.

今度は先ほどの Greenbear Laboratory にあったサンプルコードを書いてみても動かないのです.もういい加減にせえやと.エラーメッセージは test.rb:4: uninitialized constant Twitter (NameError) という感じに.

とりあえず公式リファレンスの RubyGems の項を見て,require 'twitter' ではなくて require 'rubygems' gem 'twitter' と書き直してるのですが,先述のように動きません.あ,もちろん mail と pass のところをそのまま写してるなんてミスはしてませんよ?きちんと存在するアカウントのものに書き直してます.

ということで今回はここまで.

最初に言ったじゃないですか.ライブラリのインストールには成功したって.誰も TL の取得や POST に成功したなんて言ってませんがな (ノ∀`)

[2008-09-15T15:05 追記]

やっぱりインストールそのものに失敗している可能性が出てきました.もし正常にインストールされているなら使えて然るべきだ,と.

どうせ動かす環境そのものはさくらインターネットの FreeBSD のサーバですし,自宅のメインマシン (Windows) でテスト出来りゃ便利かなぁ,くらいの気持ちでいただけなので,明日学校の Linux マシンで動かしてみましょう.

2008-09-17T02:33:47 (Wed)

Twitter bot with Ruby 作成奮闘記 3

今日の結果報告.結論から言うと成功しました.

学校のマシン (Vine Linux 4.2) にて実験した結果.

・apt-get install rubygems で RubyGems をインストール
・gem コマンドを正常に使えるように準備する 詳細は RubyGems のインストールを参照のこと
・テストコード (コチラを参照) の 1 行目を
  require 'rubygems'
  require 'twitter'
 に変更して実行
・成功 \(^o^)/

なんということでしょう.超簡単ではありませんか.

apt 関連コマンドが使えるのは Vine Linux だけなので他の Linux 環境の人はどうすればいいのか分かりません.…多分普通に ruby setup.rb を実行すればいいのでしょうね.

どうも Vine Linux ではソースコードから ruby setup.rb によるインストールを行うとエラーが出るようなのです.rdoc なんちゃらが見つからないとかそんな感じの.対処療法的にその rdoc なんちゃらを探してきて入れることで解決したという方も見かけたのですが,対症療法的なので個人的にお勧めしません.(参考 : Vine Linux に RubyGems をインストールすると rdoc/rdoc 無いよエラー (ふにょい日記))

あと,実は Windows でも動いていたのです.2 行目を先日『gem 'twitter'』と書くと言いましたが,require と書けば Windows の方でも問題なく動作しました.一体ココ (Ruby のリファレンスマニュアル) に書いてある gem 'hogehoge' と言うのは何者なのでしょう…?

ということで,成功したので約束通り How to をまとめます.

なお,以下 ruby\ というディレクトリに Ruby のインタプリタ等一式がインストールされているものとします (このディレクトリに bin\ doc\ lib\ man\ MANIFEST README.1st があるカタチです).

・RubyGems のソースコードをダウンロードする (RubyGems Manuals の downloads から)
・zlib.dll がないのでダウンロードして (zlib Home Site の zlib compiled DLL から) ruby\bin\ にコピー
 ※zlib1.dll になっているので zlib.dll にリネームすること!
・ruby setup.rb を実行
・6 つの dll と 1 つのアプリケーションをインストール
※この工程はもしかしたら不要なのかも知れません.
 ‐ココに行く (ダウンロードするもの一式へのリンクが揃っているため)
 ‐Porting Libraries to Win32 というリンクから "ssleay32.dll", "libeay32.dll", "readline.dll", "pdcurses.dll", "gdbm.dll" をダウンロード
  ※mswin32 と名の付く一番バージョンの新しいものに私はしました.
 ‐iconv-1.8.win32.zip をダウンロード
 ‐dll ファイルを ruby\bin\ にコピー
 ‐ActiveTcl をダウンロードしてインストール
・gem install hpricot --source http://code.whytheluckystiff.net を実行する
・gem install twitter を実行する
・テストコードを Linux のとき同様 1 行目を
  require 'rubygems'
  require 'twitter'
 と書き換える
・成功 \(^o^)/

ということで,これで晴れて Twitter の TL 取得や POST が出来るようになりました.

あとはこれをライブラリごとさくらインターネットのサーバに乗せて動作チェックです.まだこれは試していません.

そして UTF-8 の扱いを覚えて,RSS から Followings の発言を取得する方法を覚えて,Twitter 検索にキーワードを投げてその結果を取得する方法などを覚えて,ついでに buzztter からも発言を取得する方法を覚えて…

そしてネタを実装して cron の設定を行えば,理屈では bot が出来ているハズです.

一つ山は越したので,残りの工程も頑張ってみましょう (^ω^)

comments

紀行 (2008-09-17T10:15:24)

Linuxの有名どころはaptみたいなパッケージ管理ソフトがあるから多分そんな苦労しないはず

か (2008-09-17T12:48:27)

mjd-?

apt は Vine だけってどっかに書いてたのを鵜呑みにしてたっスわ(^^; 情報が古かったのかしら?色んな Linux にあるのね.知らなかったw

か (2008-09-18T08:49:06)

あーあーあーあー

"apt みたいな"

か.やっぱり apt は何にでもあるわけじゃないと.

問題は RubyGems が apt 以外のパッケージ管理ソフトでインストール出来るようになってるかどうかじゃのう (´ω`)

none (2009-12-11T15:33:36)

apt は Debian系のパッケージ管理コマンドでしょ?

2008-09-18T08:36:06 (Thu)

スイーツ「パソコンくらいタダで直せよオタクども」

スイーツ「パソコンくらいタダで直せよオタクども」 (ワラ速)

今までこの手の輩に遭遇したことはありませんが,もし遭遇したらコメント No.4874 に類することの実行を考えてみようwwww

comments

紀行 (2008-09-18T09:32:56)

スィーツレベル高けぇw
んで、ベストアンサーはもっと高けぇww

か (2008-09-18T13:09:07)

>何故ならパソコンを趣味にしている人はお金がかかるので、少しでも生活を楽にするためにたかろうとするからです。

…きっと昔詐欺か何かにあって人を信じられなくなってるんだね… (´ω`)

2008-09-19T22:50:32 (Fri)

Twitter bot with ruby 作成奮闘記 4

TL 等の取得結果をそのまま表示すると,日本語の部分が &#12345; みたいな表記になってしまい,これではどうやっても文字として解釈することが出来ずに途方に暮れていました.

しかし諦めなければ何とかなるもので,ググる先生に尋ねる単語を色々変えた結果,"twitter ruby utf-8" でこのエントリに辿り着きました.そしてここの decode_utf 関数を参考にして,見事取り扱い可能な文字列に変換出来ました.

ほんと Greenbear にはお世話になりっ放しっスな(^^;

ちなみにこの関数をコピペするだけではまだ不十分で,正規表現の部分を

/&#([\d]{4,5});/ → /&#(\d{3,5});/

と直す必要があります.

{3,5} にしたのは,数字の部分が 3 桁のときもあったからです.

[\d] を \d にしたのは,[ ] を使う意味がないからです.修正しなくても動きますが,無意味なことはするべきではないでしょう.[ ] の本来の働きは,“[ ] の中のいずれか一つ”ですから.

あとは [ ] で囲んで Array クラスのインスタンスとして,pack メソッド (こんなの存在初めて知ったよw) を用いて,一文字分ずつ文字として置換してます.言わなくても分かってる人がほとんどだと思うけど,さっきの [ ] は正規表現のソレで,今回の [ ] は配列のソレですからね.

で,とりあえず自宅の Vine Linux 4.2 で動かそうと思ったら,今度はそれにて twitter ライブラリを使用したコードが動きませんでした… orz require 'twitter' したところで,どうも依存しているライブラリファイルが存在しないみたいで落ちるのです (多分).またインストールか何かにどこかで失敗してるみたいです.

学校のだと動いたのに,どうしてまったく同じバージョンの家のマシンだとこういうことが起こりますかね? (´ω`) IT という世界はほんとときどき理不尽です.

2008-09-22T01:52:23 (Mon)

無題としか言いようがない

土日にブログに書くネタが出来ないとか,どんだけ非生産的な休日の過ごし方してるんだ自分 (´ω`)

童謡「むすんでひらいて」の歌詞って (ハムスター速報 2ろぐ)

こけしに魅了される若い女性が増えている 「こけしは奥が深い…」-鳴子温泉 (越えられない壁( ゚д゚))


2008-09-23T00:42:21 (Tue)

こなたんファンタジー第十一話キター





新作来ました!うp主ありがとう!頑張った!感動した!ほんと応援してるよ!

この先どういう場所に行ってどういう人物と会うかは FF4 の本筋から分かるんですが,どういうストーリーが展開されるのかが本当に気になるようになってきましたねw 相変わらず演出の上手いうp主様です.

それにしてもひよりんが一段と輝くハナシでしたねw

2008-09-24T00:44:55 (Wed)

次世代兵器





なんという技術力の無駄遣いwwww

愛すべき馬鹿たちですね (^ω^)

2008-09-24T00:52:17 (Wed)

lambda とか Proc とかに関する記事

関数オブジェクト、クロージャ、カリー化 (Netsphere Laboratories)

Ruby試行003 Procとか (アホメモ)

ファーストクラスの関数(Part 6) (関数プログラミングへの招待)

Rubyのlambda,proc関数の使い方が良く分かりません。 「こういうときに使うと便利」という例があれば教えてください。

Haskellは難しくない--こともある。 (404 Blog Not Found)

2008-09-25T00:06:57 (Thu)

REXML の使い方とか

REXML:RubyによるXML処理 (japan.internet.com)

RubyでXML操作 (Netsphere Laboratories)

たのしいXML (万葉の想い)
※なんとも意外なジャンルのページです(^^; しかし分かりやすくていいです.

2008-09-26T23:35:08 (Fri)

XML 読み取りメモ

REXML 使えば簡単に出来るとのことですが,どうも一筋縄では使用方法が理解出来なかったので実例を交えてメモを.

とりあえず私の Twitter の RSS を例にします.

まず

doc = REXML::Document.new(File.open('hoge.xml'))

で XML ファイルを DOM ツリーとかにする?んだっけか?まぁよく分からないけど,読めるようにすると.

この doc を辿って行けば要素が読めるのですが…

まぁなんせややこしいのです.ということで実例.

・rss/channel/ の item の descripton の内容 (text) を全て表示する
 (方法 1)
 doc.elements.each('rss/channel/item') { |i|
  puts i.elements['description'].text
 }

 (方法 2)
 doc.elements['rss/channel/'].elements.each { |i|
  if i.name == 'item' then
   puts i.elements['description'].text
  end
 }

ということで [] の使い方と elements の意味がハッキリ分かるのに手間取ります.手間取らなかった人は自分が天才だと思っていいんじゃないですかね?保障はしませんがw each メソッドの引数も盲点というか.

てことで変に応用してこんな風にも.

 (応用 1)
 doc.elements['rss'].elements['channel'].elements.each { |i|
  if i.name == 'item' then
   puts i.elements['description'].text
  end
 }

 (応用 2)
 doc.elements['rss'].elements['channel'].elements.each('item') { |i|
  puts i.elements['description'].text
 }

ちなみに再帰的な構造を再帰的に読む方法は分かりません.方法は先日紹介したページを見る感じありそうなのですが,未調査です.まぁ実用はこれで問題ないかと.

2008-09-27T23:58:01 (Sat)

夏目総集編



夏目の可愛さに気付いてない人が多過ぎる.

アニメ第二期は良い薬になるかもしれぬ… (^ω^)

2008-09-29T19:06:24 (Mon)

中国が日本に行う嫌がらせと変わらないじゃないか

このっ、バカ共が! (松浦晋也のL/D)

先入観や偏見を持って物事を見るのは良くないとその口で言っていた連中が所詮この程度ですよ.

「正しい判断は正しい情報と正しい分析の上に初めて成立する」のです.

戻る