Reports

Twitter: @mtknnktm.

2ちゃんねるのレスの長さを測ってみた

はじめに

社会的なコミュニケーションは人間を他の動物から特徴付ける現象の一つであり,我々の社会的生活の最も重要な基盤の一つと言えます(参考: Amazon.co.jp: 生命進化8つの謎: ジョン・メイナード スミス, エオルシュ サトマーリ, John Maynard Smith, E¨ors Szathm´ary, 長野 敬: 本).
コミュニケーションは,(当然)それぞれが独立した発言ではなく,コミュニケーションの参加者が相互に強い影響を与えあった結果,創発する現象です.

それではコミュニケーションという現象はどのように創発してどのような時間発展をたどるのでしょうか?

まずコミュニケーションにおける「発言の長さ」に着目しようと思います.
「発言の長さ」はシンプルながらもその発言の特徴を表しやすいパラメータであると考えているからです.そこから上記の大きな問題について少しでもアプローチできたらおもしろいかなと思っています.

そこで,まさに言語的なコミュニケーションのログそのものである2ちゃんねるにおいて,発言(レス)の長さについて調べてみました.
結果,レスの長さによって,レスは明確に特徴付けられ分類が可能であることがわかりました.

方法

以下の板の各スレッドからレスを取得し,レスの長さの頻度分布を計測しました.

  • ニュース速報(VIP) : http://hayabusa.2ch.net/news4vip/subject.txt
    • 草といえばということで採用.計51,082件のレス.
    • 2012/07/07時点の全スレを採用.
  • 自転車: http://kohada.2ch.net/bicycle/subject.txt
    • VIPとの比較として比較的まったりっぽい趣味系の板を採用.計139,719件のレス.
    • 2012/07/07時点の一部スレを採用(全部を対象にすると時間がかかるので)

計測したレスの長さには2ちゃんねるでの表記用のHTMLタグ(brやaタグ)も含まれているため,本来の日本語としての長さよりやや大きめの値になっているので注意してください(今回は長さについては相対的に比較することを主とするので計測を簡単にするためこのようにしています).

結果

以下にレスの長さの分布について集計結果を示します.

横軸がレスの長さ、縦軸が頻度です。

VIP


自転車

興味深いことに話題が全く異なる板にも関わらず類似した特徴を持つ分布になっていました.
両者に共通する特徴として以下が挙げられます.

  • レスの長さの頻度分布に4つのピークが存在する.
    • VIPは5,20,85,190,自転車は3,20,85,200付近にピークが存在しています.
  • 最長のピーク(VIPだと190,自転車だと200)より長いレスの頻度は徐々に減少するものの,かなり長いレスも存在する.
    • まだ断言できませんがロングテール的な性質を示していると言えそうです.

おわりに

今回は2ちゃんねるレスの長さを基準にコミュニケーションのログである「レス」がどのようになっているかを調べました.
その結果,レスの長さの分布には4つのピークとロングテールの存在することがわかりました.
このことからレスの種類は,極短(ピーク1),短(ピーク2),中(ピーク3),長(ピーク4),極長(ロングテール)に分類できそうです.

次回はこの分類をベースに各分類の典型パターンを生のデータ(実際のレス内容)を見ることで観察したいと思います.


2ちゃんねるの草の長さを測ってみた

はじめに

2ちゃんねるを始め,日本のインターネットでは(笑)を「w」と略して表記することがあります.
さらにその「w」を「wwww」のように繰り返して「草を生やす」という表記をすることもあります(参考: Wとは (ダブリューとは) [単語記事] - ニコニコ大百科).
「wwww」(以後,草と呼ぶ)の長さ(「w」の繰り返し回数)はその場ののりや記入者によって決まるはずです.
その草の長さがどのように決まっているか気になったので調べてみました.

方法

以下の板の各スレッドからレスを取得し,草の長さの頻度分布を計測しました.

  • ニュース速報(VIP) : http://hayabusa.2ch.net/news4vip/subject.txt
    • 草といえばということで採用.計51,082件のレス.
    • 2012/07/07時点の全スレを採用.
  • 自転車: http://kohada.2ch.net/bicycle/subject.txt
    • VIPとの比較として比較的まったりっぽい趣味系の板を採用.計139,719件のレス.
    • 2012/07/07時点の一部スレを採用(全部を対象にすると時間がかかるので)

本来は英単語やURLに含まれるwは計測対象から除外すべきですが,今回はやっていません.
ですので次節で示す結果の草の長さが1〜3の結果は草の長さとしてはあまり適切ではありませんので注意してください.

勉強も兼ねてScalaとMongoDBでやってみました.
Scalaでダウンロード・整形して,MongoDBに保存,ダウンロード完了後,MongoDBで集計してます.

結果

以下に集計結果を示します.
データが少なく,グラフが見づらいため頻度分布ではなく累積頻度分布を示します.

まずは通常のグラフ.
横軸が草の長さ、縦軸が頻度です。

次に両対数グラフです.
横軸・縦軸は上記と同様です。

VIP・自転車板共に,草の長さが長ければ長いほど出現頻度は低くなっており,分布の形もほぼ同様の傾向を示しています.
自転車板の方が件数が多いのは,単に対象のレス数が多い為です.

対数グラフの形状から頻度分布は指数分布であることがわかります.
ということは,草の長さはほぼ独立事象と言えそうです.
なので,おおざっぱには草の長さの決定については以下だと考えられます.

  • 草の長さは記入者によってほぼ独立に決定され,レス間の相互作用はなさそう.
    • つまり他の人が長い草を生やしていたとしても,それを見た人の草の長さには影響が無いということです.

きっと以下みたいな感じなんでしょう(適当).

 p_l \propto q(1 - q)^{(l - 1)}

  •  p_l: 長さ lの草を生やす確率
  •  q: キー「w」から指を離す確率

おわりに

今回のVIPと自転車板ではどうも他の人の草の長さが,それを見た人の草の長さにはどうもあまり影響がなさそうに見えました.
個人的にはもっと相互の影響が強いと思っていたので意外な結果でした(´・ω・`)
※: ただちゃんと主張するには,もう少し突っ込んで調べる必要があります(板・スレ間の相関とかも調べる余地ありです).

ニコニコ動画のコメントとかのほうが,他の人のコメントを見て,それのフィードバックを受けて書きこむという性質が強そうなので,そっちでやってみると面白いかもしれません.


[その他]【メモ】EclipseのEGitでgithubへのpushがうまくいかない(Auth failというエラーが出る)ので仕方なくコンソールからpushする方法

0. githubでリポジトリを作る.
1. pushしたいプロジェクトを生成して,eclipseのEGitでローカルにコミットして,2 - 4を実行する.
2. $ git remote add originとか git@github.com:【githubのID】/【プロジェクト名】.git
3. $ git remote -v
4. $ git remote push originとか masterとか

参考 類似のエラーが出ていた方

クロスドメインメッセージングのLT資料

身内でLT大会をやってみたので資料をUP.相変わらず大した資料ではないです.
HTML5API クロスドメインメッセージングについての説明です.

(メモ)サーバ上(node.js)上のJavaScriptをnode-inspectorを使ってクライアントサイドでデバッグしてみた

node-inspectorって?

node.jsのデバッグツールにnode-inspectorというものがあります.
node-inspectorはサーバサイドで実行されるJavaScriptChromeSafariデバッグしてしまおうというものです.

私が探した限りクライアント(ブラウザ)とサーバ(node.js)が同じコンピュータにある場合しか,なかったのでメモ書きします.

やり方メモ

クライアントとサーバが同居する場合については以下を参照してください.
同居しない場合についてもほとんど同じです.本記事では以下を補足する形でメモをします.

上記の記事ではデバッガには以下のアドレスでアクセスしています.

サーバとクライアントが異なる場合-は以下です.

上記の公式ドキュメントでもlocalhostではなく127.0.0.1でアクセスせよと書いてあります(そうしないとうまくいかないようです).何でなんだろう..

FuncUnitを試してみた

FuncUnitって?

WEBアプリケーションの単体テストフレームワークです.
公式ページ: FuncUnit

基本的にはjQuery風の記法でユーザのアクションを定義し,JavaScript単体テストフレームワーク QUnitでアサートするだけでユーザのアクション(テキスト入力,クリック,ドラッグアンドドロップなど)に対するアプリの動作をテストすることができます.
なので,jQueryQUnitを使ったことがある人であれば比較的簡単にテストコードを書くことができます.また,どちらも使ったことがなくても使う分にはそれほど難しいものでもないので,使ってみることをオススメします.
一回書けば延々ブラウザでポチポチする作業とはおさらばです.

また,もう一つ重要な点としてコマンドラインからテストが実行できるという点です(実行中にFirefoxやIEが立ち上がったりしますが).ということはHudsonと連携して…とか考えると夢が広がりますね.
とか思っていたら,すでに実行に移している方がいました.
java-ja.js #2でLT発表してきた(Envjsを使った単体テスト) - SEの行き着くところ…

FuncUnitは使っていないですが,動機やテスト自動化の構成はFuncUnitと似ている(かつ,本記事よりちゃんと書いてある)ので,JavaScript単体テスト自動化に興味のある方は是非読んでみてください.こちらではHudsonとの連携までしています.

FuncUnitの素

FuncUnitは以下からできています.

  • Selenium: Webアプリのテストを自動化するためのツール.ブラウザ上のユーザの動作を真似てくれます.
  • QUnit: JavaScriptのテストフレームワークQUnitで動作結果を検証します.
  • jQuery: JavaScriptのライブラリ.jQueryでユーザの動作を定義します.
  • EnvJS: JavaScriptで書かれたブラウザやDOM環境の環境をシミュレートしてくれるライブラリ.
  • Syn: ユーザの動作(イベント)をシミュレートしてくれます.

使ってみる

準備

まずは以下からFuncUnitをダウンロードして適当なフォルダに展開してください.
FuncUnit

以降ではテストコードを作成していきます.
ブラウザ上でJavaScriptを動かしたり,ポップアップウインドウを開いたりするのでAPサーバ上に配置しておくのがいいかと思います.

テストコード作成

まず,テスト対象の画面を作ってみます.
名前はmyapp.htmlとします.


<!DOCTYPE HTML>
<html>
  <head>
    <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
    <title>My Demo App</title>

    <script type='text/javascript' src='./jquery-1.4.2.js'></script>
    <script type='text/javascript'>
      $(function(){
        //ボタンを押すとテキストボックスの内容がdiv要素に書き込まれるだけのアプリケーション
        $('#btn1').click(function(e){
          $('#div1').html($('#txt1').val());
        });
      });
    </script>

  </head>
  <body>
    <h2>FuncUnit Test</h2>
    <input id="txt1" type="text" />
    <input id="btn1" type="button" value="COPY"/>
    <div id="div1"></div>

  </body>
</html>

次にユーザのアクションとそれに対するアサーションを記述します.
名前はfuncunit_test.jsとします.基本的にQUnitです.
jQueryとよく似ていますがセレクタを書く関数が '$' ではなく 'S' になっていることに注意してください.


module("myapp",{
  setup : function(){
    S.open("【myapp.htmlを配置したパス】/myapp.html")
  }
});
test("input Test", function(){
  S("#txt1").type("テスト", function(){
    same(S("#txt1").val(), "テスト","テキストボックスのタイプテスト");
  });

  S("#btn1").click(function(){
    same(S("#div1").text(), "テスト","ボタン押下テスト");
  });
});

  • S("#txt1").type("テスト", function(){…コールバック関数…});

この文がidがtxt1のコンポーネントに「テスト」をタイピングするというユーザの動作を定義しています.
この動作に対してアサートをしたい場合はコールバック関数でQUnitアサーション関数を呼び出します.

  • S("#btn1").click("テスト", function(){…コールバック関数…});

こちらはidがbtn1のコンポーネントをクリックするというユーザの動作を定義しています.
こちらも同様にコールバック関数でQUnitアサーション関数を呼び出してユーザのアクションに対するWEBアプリの動作を検証しています.

QUnit単体ではユーザのアクションを記述するのが,結構面倒なので上記のような直感的かつ簡単な書き方ができるだけでも,結構幸せになれそうです.


最後にFuncUnitの画面を作ります.
名前はfuncunit.htmlとします.ブラウザからテストを実行する場合はこの画面がテスト結果を表示します.
これはほとんどの場合,書き換える必要はないと思います.


<html>
 <head>
  <link rel="stylesheet" type="text/css" href="【FuncUnitを展開したパス】/qunit.css" />
  <title>FuncUnit Test</title>
   <script type='text/javascript' src='【FuncUnitを展開したパス】/funcunit.js'></script>
   <script type='text/javascript' src='funcunit_test.js'></script>
 </head>
 <body>
  <h1 id="qunit-header">FuncUnit Test Suite</h1>
   <h2 id="qunit-banner"></h2>
   <div id="qunit-testrunner-toolbar"></div>
   <h2 id="qunit-userAgent"></h2>
  <ol id="qunit-tests"></ol>
 </body>
</html>

以上で準備は終わりです.
いよいよ実行してみましょう.

ブラウザから実行

上で作った funcunit.html を開いてください.以下のような画面が表示されれば成功です.
見方はQUnitと同じです.
f:id:swarm_of_trials:20110130163851p:image

コンソールから実行

FuncUnitを展開したディレクトリ(envjsがあるディレクトリ)で以下を実行します.
% envjs 【funcunit.htmlを配置したパス】/funcunit.html
以下のようなに出力されれば成功です.
Firefoxの場合
f:id:swarm_of_trials:20110130163852p:image

ちなみに複数のブラウザに対して同時に実行もできます.

いかがでしたでしょうか?

私はややこしい環境構築とかなしでダウンロードしてサクっと使えてしまったことに驚きました.まだFuncUnitはβ版なので現状で実務に堪えうるかどうかは要検証ですが,まずは好感触です.

HTML5の登場によりWEBアプリにおけるJavaScriptの占める比重がどんどん大きくなっていくかと思います.非同期通信・サーバプッシュ型イベント・ローカルストレージの利用・ローカルデバイスの利用・自由に描画できる画面・マルチスレッド処理(?)などなどが入り混じったアプリケーションを,Javaよりよっぽど自由な言語で作成し,それのテストをブラウザからポチポチとやるのは悪夢以外のなにものでもありません.

ガンガン使い倒して,JavaScriptが今より複雑になってしまう前に,ブラウザポチポチからおさらばしておきましょう.