Mongo DB Casual Talksに行ってきた

あんまりMongo DB Casual Talks のブログがないようなので、ざっくり書きます。

「MongoDBのアレをアレする」 by [twitter:@kuwa_tw] さん


  • クラスタが遅い1
    • 必要なデータを一気にインポート
    • oplogが許容範囲を超えてレプリケーションが停止
    • PrimaryShardにChunkが溜まってI/Oバウンドに
    • 負荷が高いのでBalancerは動かない
  • クラスタが遅い2
    • ShardするCollectionのShard設定漏れ
    • PrimaryShardでデータファイルが多くなりつづけてメモリマップドファイルのサイズをこえてI/Oバウンド
    • ShardしてないのでもちろんBalancerは動かない
      • 本当に突然パフォーマンスダウンする
      • PrimaryShardは余裕を持たせておく
      • Shard設定は定期的に確認、もしくはShardの設定を自動化する
  • バックアップ
    • mongos経由でAutoBalancingをoff
    • 各レプリカセットにfsync lock
    • 各mongodにmongodumpを実行してバックアップ取得
    • 各レプリカセットにfsync unlock
    • mongos経由でAutoBalancingをon
  • 障害時にみるもの
    • mongostat
      • faults : 1秒あたりのページフォルト数⇒メモリ増設もしくはサーバ増設
      • Locked% : グローバルライトロックの時間割合⇒クエリの見直し、もしくはクラスタを分ける
      • idx miss% : indexのヒット率の時間割合⇒クエリもしくはインデックスの見直し
      • qr|qw : 読み込みキュー|書き込みキューの大きさ⇒ロック増加 or クエリ増加
    • mongotop
      • アクセスが集中しているcollectionの確認
    • mongosniff
      • 最後の手段のパケットキャプチャ
      • mongosのアクセス状況、複雑のクエリを見る
    • db.adminCommand("connPoolStats")
      • Sharding環境におけるconnectionpoolの統計
    • db.serverStatus()
      • サーバの現在の状態の確認

恐らく国内では最大のMongoDBユーザであるCyberAgentさんの経験から得られる運用ノウハウ。
一つ一つはどこかで聞いた話ではあったが、まとめてあるとまだまだ色々問題ありますね。
カジュアルに100台運用はできません。
CAさんには、「今だからできる、MySQLを採用した場合とのコスト比較」とかやってほしい。
※ Fusion-io積んだMySQL10台でリプレイス可能とかだったら面白いのに。。

「Casual Compression on MongoDB」 by [twitter:@just_do_neet] さん


  • MongoDBの欠点
    • トランザクション未サポート
    • Global Lock
    • システムリソース(メモリ、ディスク)が肥大化
    • データ圧縮未対応(通信、データストア共に)
    • セキュリティ周りが弱い
  • MongoDBはHBase(Snappy圧縮)の三倍強のデータサイズ
  • BigDataを扱う環境にはあまり向かない
    • スケールするがゆえに、下手にそれなりの規模のシステムに導入するとサーバ無限増殖の刑に。。
  • フィールド名をできるだけ短く
    • BSONでデータを保持しているので、1つのドキュメントの中にフィールド情報を持つ
    • 複数のレコードが同一のフィールド名を持っていても、1レコード毎に情報を持つ
  • 特定のデータをbinary形式で保存
    • アプリケーション側で特定のフ複数のフィールドをまとめてシリアライズし、圧縮
      • 複数フィールドをMessagePackでシリアライズ+圧縮で最大2/3に圧縮。
      • 圧縮・シリアライズのオーバヘッドに注意
      • 独自binary化すると後戻りできないので注意
  • 小さい正整数の整数符号化
    • 整数符号化で保存したら、Integerよりサイズが大きくなった。。


データサイズが大きくなりがちなMongoDBで、データ圧縮ができないかというアプローチ。
安定したパフォーマンスを出すために、データがメモリに乗り切る範囲で運用するというのは、
よくとられる手法なので、データ圧縮ができるとサーバが少なくてすむので貴重なお話。
最大で2/3程まで圧縮が可能であるが、圧縮したフィールドは検索に使えなくなるので、柔軟な検索が
できなくなる弊害があるなど、使用するにはアプリケーションの特性をよく見てからということですね。

「MongoさんをAWSへお迎えする」 by [twitter:@understeer] さん



  • スナップショットでバックアップ
    • mongodをFlush&Lock
      • db.fsyncLock();
    • Filesystemをfreeze
      • xfs_freeze -f /path/to/mongo
    • 各ボリュームのスナップショット取得
      • ec2-create-snapshot -d xxx vol-xxxx
    • FilesystemのunfreezeとMongodのUnlock
      • xfs_freeze -u /path/to/mongo
      • db.fsyncUnlock();
  • スナップショットからリストア
    • 各スナップショットからボリューム作成
      • ec2-create-volume-snapshot snap-xxxx
    • 各ボリュームをアタッチ
      • ec2-attach-volume-device /dev/sdf/vol-xxxx
    • RAID、LVM復旧、MongoDB起動
mongodbを使ってみたい by [twitter:@riywo] さん

MongoDBのクエリでMySQLを使えるO/Rマッパーを作った。MongoSQL

非常に意欲作です。

MongoDBによるカジュアルなタイムラインシステムの実装 by [twitter:@hito_asa] さん


MongoDBを利用したタイムラインシステムのおはなし
タイムライン機能を作る際のフォロワーのIDを取ってきて、さらにそのフォロワーのコンテンツを
取ってくると言った処理が重いのでなんとか簡単にしたい。

  • TimeLine Design
    • 有限長
    • 最新のみ保持
    • 追記のみ
    • 常に時系列での取得
    • 追記、取得が早い
      • ユーザ毎にCAPPED COLLECTION
  • 200万コレクションの世界
    • 普通では作れないので、nssizeを変更
    • データベースのコレクションの上限が60万なので、上限に達したら新たなデータベースを作成
      • すぐSWAPする
      • mongoコンソールがsuggestで落ちる
      • GLOBAL LOCKのため、コレクションの削除で止まる
      • 応答時間が安定しない
  • 教訓
    • コレクションはたくさん作らない
    • 1インスタンスでたくさんDBを作らない
    • シビアな応答性能を求めない
    • MongoDBをカジュアルに導入しない

個人的には一番面白かった発表。是非、この路線で突っ走って貰いたい。
CAPPED COLLECTIONは、TIMELINE機能で欲しい機能のいくつかを持っているので、うまいこと
機能拡張してくれると面白そう。

カジュアルにMongoDBのBackup機能説明 by [twitter:@matsukaz] さん



  • mongexportはJSON/CSV形式でデータを出力
    • 全てのデータ型をサポートしているわけではない
      • data_binary
      • data_date
      • data_timestamp
      • data_regex
      • data_oid
      • data_ref
  • mongodumpはBSON形式でデータを出力
    • データは正しい情報のまま
    • Onlineでの実行も可能
      • 実行中はパフォーマンスに影響あり
    • ただし、小規模での利用を想定したもの
      • データは一箇所に出力される
  • officialなバックアップ手順
    • balancerを止める
    • 全PrimaryをLock
    • config情報をBackup
    • SecondaryのデータをBackup
    • 全PrimaryをUnlock
    • balancerを有効化
      • 欠点として、Lock時間が長くかかる
  • Lock時間を短くしたバージョン
    • balancerを止める
    • 全PrimaryをLock
    • config情報をBackup
    • Secondaryを落とす
    • 全PrimaryをUnlock
    • balancerを有効化
    • 落としたSecondaryをBackup
    • 落としたSecondaryを起動

うん。SecondaryをLockして、バックアップを取ろう。

カジュアルにソースコードリーディング by [twitter:@choplin ] さん



MongoDBソースコードリーディングの成果の発表。

  • 追記型
    • 更新を削除と挿入の組み合わせで実現する
    • 同時制御の処理が簡潔
    • データ容量が肥大
    • 書き込み処理の負荷
    • ガベージの発生
  • In-place Update
    • 既存のサイズを超えない場合、ドキュメントまるごとの追記を行わず、必要な値のみ書き換える
  • Padding Factor
    • In-place Updateを行うために予め、Padding領域を確保する。
      • どれだけPaddingするかのfactor
    • Default 1.0
    • Min 1.0、Max 2.0
    • Update + 0.6
    • Insert / (In-place Update?) -0.01
CasualなMongoDBのサービス運用Tips by [twitter:@nsega] さん


MongoDBを1年間運用して得たTipsを惜しまず出します。

  • Tips1:定期的な計測
    • Collection/Document数
      • db.usercollection.find.count()
      • db.usercollection.stats()
    • Shardingの偏り
      • printSahrdingSize()
    • Disk使用状況の把握
    • df -hT
  • Tips2:定期的なバックアップ
    • 停止可能な場合は、データファイルをコピーすればOK
    • 停止不可の場合は、Secondaryからバックアップ
  • Tips3:定期的なデータ最適化
    • 定期的にReparDatabaseコマンドを実施
      • mongod --repair
      • db.repariDatabase
  • Tips4:定期的なバージョンアップ
    • 性能、機能改善
    • バグfix
Casual Sucks by [twitter:@repeatedly] さん

資料はこちら

  • oplogには限界がある
    • oplog collectionはcapped collectionなので、sizeの制約がある。それを超えると。。。
  • マスターマスターで片方のデータが一瞬消える
  • クライアントの実装アプローチが違う
mongoengineでカジュアルな有向グラフ by [twitter:@bibrost] さん
  • MongoEngineを使って、カジュアルに有向グラフを扱えるPythonライブラリ作ったよ。(mongo-directedgraph)
  • MongoDBはスモールデータを扱うには、よい選択。ミドルやビッグを扱うとダメ
mongodbとfluentdの素敵な関係 by [twitter:@stanaka] さん
  • Fluentd+MongoDBでログ流してる
  • システム間を疎結合にするために、ファイルに一度出力してtail
  • タグを変えて流し直すことができるので、超便利

所感

バックアップの話が多かったのは、人柱精神溢れるMongoな人たちの運用実績が確実に増えてるということでしょう。
MongoDBの由来となったhumongous(ばかでかい)という言葉なんて、誰も知らないかのように、スモールデータ
やめとけといった話が多く出たのが印象的でした。(私も使うのであれば、スモールデータ限定で使いますが。)

風邪気味で懇親会に出れなかったのが若干心残りでしたが、次の機会に。

退職しました。

正確には、2012年2月末日を持って、約2年半お世話になった会社を退職します。
現在は有給休暇消化中です。


音楽業界というかなり特殊な業界で仕事ができたこと、ドコモMUSICストアやAndoroid向けストアの立ち上げ等
非常に稀有な経験ができたと思います。(著作権のことなんかも地味に勉強になりました。)


退職する理由は色々ありますが、データ解析をやりたかったってのが一番大きな理由です。
データがあるところに行くと胸を張って言える程の経験も知識もないですが、一歩を踏み出さないと
自分の成長はないと、去年、色んな勉強会(特にMongoDB勉強会)に参加して思いました。


3月からは遅ればせながら、ソーシャル業界でお世話になります。
現職では、テクニカルな仕事よりもプロマネやアーキテクト的な仕事にウエイトを置いていましたが、
次の職場ではデータ解析基盤の構築&運用をメインにやることになっているので、HadoopMySQL等と
戯れることになるかと思います。(直近は引越しの手伝い?かもw)

おまけ

ソーシャル転職が最近話題ですが、私は勉強会の資料やブログを見た転職エージェントからFacebook経由で
コンタクトを頂きました。
会社に直接電話してきたヘッドハンターやLinkedin経由で連絡してきた転職エージェントも数名いましたが、
会社の代表電話に自社の社名を名乗り、何度も連絡をしてくるヘッドハンターは、迷惑以外なにものでも
ないので辞めて頂きたい。(最初は電話に出なかったのですが、さすがに3回目あたりで出ざるを得ませんでした)
しかも、「XXXXで有名な人を、G社に年俸XXX万で入社させた」など個人情報を電話口で暴露し、本人の
希望も聞かずにとにかくG社とD社に入社させようとしているエージェントも居ますので、これから転職しようと
考えている人は、まずは信用できるエージェントかどうかを確認した方がよいかと思います。
転職エージェント全てが悪いという事ではないですが、お金になる所には、当然質の悪い人(会社)も居ると
いうことを認識しておいたほうが良いかと。
(今回の転職でお世話になった方は、非常に良い方でした。)

ソーシャルメディア、ソーシャルアプリが育てたNoSQL技術に参加してきました

震災の影響で2カ月程延期されていた ソーシャルメディア、ソーシャルアプリが育てたNoSQL技術 に参加してきました。
参加者がそのままスライドした影響か、ATND上では定員を大きく上回る参加あったが、実際の参加者が少なく結構席も空いていました。

MongoDBで作るソーシャルデータ新解析基盤 [twitter:@doryokujin]

  • 旧解析基盤(MongoDBとHadoopを活用)の処理フロー
  1. Data Gathering
    1. 分散するサーバから各種ログをローカルに収集
    2. 課金・登録情報の該当データをMySQLから取得
    3. ユーザゲームセーブデータをCassandraから取得
  2. Data Pre-processing(Hadoop)
    1. ログ整形
    2. フィルタリング
  3. Data Analysis(Hadoop)
    1. ユーザIDをキーにした各指標値を集計
    2. アクセスログの集計
    3. イベントの効果測定
  4. Result Data Strage(MongoDB)
  5. Data Mining
  6. Data Sharding
    • MongoDBは解析結果格納サーバとしてのみ利用
    • 集計自体はHadoopで行う
    • 大容量のログをHadoopでReductionして、MongoDBに格納
  • 新解析基盤(MongoDB、Redis、Scribeを活用)の処理フロー
  1. Data Gathering(Scribe)
    • 1時間毎にサーバからログファイルを転送
  2. Data Pre-processing
  3. Raw Data Strage(MongoDB)
    • Shard Keyにhourを指定し、Shard0 - Shard23に1つずつ割り当てるマニュアルSharding
      • Shardingの各種問題対策にもなるし、データが追加されているshardについても把握できる
    • 自動Balancerも停止
    • mongod1つに対し、1CPUしか使えないため、複数Shardを1台の物理サーバに同居
    • 解析結果格納用のShardはSSDを使い高速にする
  4. Data Analysis(MongoDB + Redis)
    • smallデータの場合
      • 24Shardを利用して、Mongo Master MR
      • デフォルトのMongo MRはMasterしか使えない
      • Map/Reduce実行中でもDBロックしないがパフォーマンスが低下するため、長時間やりたくない
    • middleデータの場合
      • insert中のShardを除く全Shard全Primary/Secondaryのmongodに直接接続
      • mapreduce/distinct/findなど実行。findの場合は別途集計処理
      • 各mongodの実行結果(key,value)を同host内のRedisに集約
    • bigデータの場合
  5. Result Data Strage(MongoDB)
  6. Data Mining
  7. Data Sharding
本番で使うための"Cassandra"ガイド [twitter:@_shimada]

  • 強み、弱み、落とし穴
    • 勝手にシャーディング
      • スケールアウトが容易
      • キーの設計を間違うと、1か所にデータが集中
    • 勝手にレプリケーション
      • 反映に掛る時間はベストエフォート
      • スレーブが反映前のデータを返すことも
    • 勝手にフェイルオーバー
      • 落ちたノードへの書き込みは自動的に他のノードが受け取り一時保管
      • ノードが復帰したらデータが書き戻される
    • スケールアウトと負荷分散
      • ノードを追加すると、データが一番多いノードからデータを半分引き取る
    • データの整合性
    • 読み書きのパフォーマンス
      • 読み出しよりも書き込みの方が早い
      • コミットログ書き出し:
      • 読み込み:書き込みの速度比、書き込みが8倍程早い
  • まとめ
    • 大量のデータを大量のサーバで捌く
    • 一部で障害が起きても全体の整合性
    • 書き込み速度重視
    • データの整合性を犠牲にして、速度を上げることができる
  • フィットするパターン
    • 大量のデータが一斉に飛んでくる
    • 大量のデータを統計処理に使いたい
      • ごく一部のデータが欠損しても全体には影響がない
    • Webサービスのログ
    • リアルタイムな統計的な処理
分散KVS “okuyama” のご紹介と、実際に利用した事例のご紹介 [twitter:@okuyamaoo]

  • 最近追加した機能
    • パーティション機能
      • 容量は可変(初期設定は不要)
      • 数の限度なし
    • ストレージ機能の強化
    • 全文検索機能
      • N-Gramと辞書方式のMIX
      • N-GramのNの部分はIndex作成、検索時に指定可能
      • 作成Indexのグルーピングが可能
  • 利用事例
    • 共有キャッシュサーバ
    • データ集約ストレージ
"memcached"とトラブルとソーシャルアプリ [twitter:@goodoo]

  • 「星空バータウン」の規模
    • ユーザ数約200万人
    • 約10億PV/月
    • 月間アクティブユーザ75万
    • ピーク時のトラフィック200Mbps
    • サーバ台数 約50台
    • PHPのセッション共有にmemcachedを使用
  • memcachedのトラブルの教訓
    • memcachedを運用する場合には-cによる接続数の制限は大きくとる(きちんと監視されていること前提)
    • Networkまわりのパラメータチューニング
      • iptablesを使用する場合は、ip_conntrack_maxの制限
    • 特定のサーバにアクセスが集中するのはリスク
  • キャッシュの考え方まとめ
    • NoSQLとDBの棲み分け
    • NoSQLの出番は?
      • 最悪データがロストしてもいいところ(セッションデータなど)
      • あくまでキャッシュとして割り切ってつかう
      • ロールバックできなくてもユーザが不利益を被らない処理に利用
"HandlerSocket": MySQLの非SQLインタフェース

  • 狙い
    • 単純なCRUD処理を高速に実行したい
      • SQL処理を省略
      • 単純な処理に適用可能な最適化
    • しかも同じデータをMySQLでも処理できるようにしたい
      • 単純かつ速度が必要な部分だけを非SQLに置き換えたい
      • SQLから少しずつ移行したい
  • mobageへの導入
    • 2010/08 本格利用開始
      • サービスを停止せずに移行
    • 導入以降トラブルは一度もなし
    • 一度HandlerSocketのプラグインを更新
  • 最初の適用箇所
    • MySQL + memcachedで構成
    • クエリは単純だが、数が膨大
    • 既存構成の問題
      • 同時接続数の問題で、mysqlの持続接続の利用が難しい
      • memcachedとのデータ同期のための仕組みが複雑で運用に負荷がかかっていた
      • ネットワークトラフィックが必要以上にでてしまっていた
  • 導入効果
  • 利点(libmysqlと比較して)
    • CPUを食わない
      • サーバ側、クライアント側のいずれも効果あり
      • 特に単純なクエリで差が大きい
    • ネットワークトラフィックが減らせる
      • 特に単純なクエリでおおきい
    • 同時接続数がほぼ無制限
      • すくなくとも65000本までは可能
      • 同時接続数を増やしても性能劣化がほとんどない
  • HandlerSocketに向いているケース
    • データサイズが小さく十分小さくメモりに乗る
    • 単純なクエリ、サーバのCPUがネック
    • 単純なクエリ、トラフィックがネック
    • 同時接続数が多すぎて、維持接続がつかえない
  • HandlerSocketに不向きなケース
    • クエリが複雑でHandlerSOcketで実現困難
    • クエリ1回あたりのCPU負荷が大きい
    • データサイズが大きくDisk IOがネック
  • 機能(参照系)
    • PKやUKを使った行取得
    • 範囲取得
    • SQLのINのような複数行取得
  • 機能(更新系)
  • libmysqlとの性能比較
    • 単純な参照クエリで数倍〜10倍
    • 取得する列数が多くなる場合に特に有効
  • なぜ早くなるか
    • SQLパース処理をしていない
      • CPU消費がすくない
    • リクエストを集約実行
      • CPU消費やディスクI/Oが少ない
    • 独自プロトコル
      • libmysqlでは、レスポンスにDB名、テーブル名、カラム名などが含まれているため、ネットワーク負荷が大きい
  • 課題
    • ビルドが面倒
    • mysqlバイナリ互換性問題
      • mysqlのバージョンやビルドオプションを代えるたびに、handlersocektをビルドする必要があうr。
  • 今後の予定
    • 不可分なread-modify-write操作のサポート
    • InnoDB以外のエンジンでの検証
      • クライアントライブラリの整備
      • スクリプトエンジンorJVMを埋め込む
まとめ&所感

doryokujinさんのMongoDBをごりっと使ったデータ解析基盤は素晴らしい。Mongo愛を感じる。
詳細は次回MongoDB勉強会でも聞けるみたいなので、ぜひ皆さま参加ください。
HandlerSocketは万能ではないが、特定用途向けには超強力な印象。InnoDBを使うので
普通にSQLでもクエリを投げれるところに安心感がある。

第3回 MongoDB勉強会に参加&発表してきました

遅くなりましたが、第3回MongoDB勉強会に参加&発表してきました。

前回の勉強会後に、doryokujinさんが発表されたshardingについての検証記事を書いてたところ、今回の発表のお話を頂いたので、
折角なのでやらせて頂くことにしました。
次のブログのネタとして考えていた、MongoDBのクエリのチューニングのアプローチ方法は、PostgreSQLなどのRDBMSと比べて
どの程度使えるのかと言う点をまとめて発表させて頂くことにしました。

MongoDB全機能解説1 [twitter:@doryokujin]

2時間ぶっ通しでの発表。充実した内容で本当に頭が下がります。
今回は、MongoDBの全機能解説ということで、MongoDBの構成、Insertとその周辺、Query、Update 、Index 、Replicationの解説です。

  • MongoDBの構成
    • mongod
      • m基本的にシングルスレッドしか使えず、多くのオペレーションに対してロックがかかる(v2.0〜v2.2で改善予定)
      • read/writeに対してDB全体に対してロックがかかる
    • Capped Collection
      • 固定サイズのcollection。古いデータから自動削除されるが、パフォーマンスが良い。
      • collectionを作る際にindexは自動で作成されない。
      • 挿入順で取得するのがパフォーマンス的には最適
      • Sharding不可
      • ログやcacheなどの用途がおすすめだが、一度作成すると容量を増やすには一旦削除する必要があるので注意。
  • Insertとその周辺
    • Bulk Insert
      • 個々のInsertより高速
      • 最適な配列サイズはデータ依存のため、環境に合わせる必要あり。大きすぎるとエラーが発生。
      • デフォルトでは結果を確認していないため、全てのInsertが成功している保証はないので、getLastErrorで確認が必要。
    • fsync
      • メモリ上のデータをディスクに書き込む
      • デフォルトでは60秒毎に実行される
      • 障害発生時には、60秒間のデータロストが発生する可能性がある。
    • Journaling
      • write-ahead-log
      • データ書き込み前に、オペレーションをjournalファイルに記述
      • 障害時にはjournalファイルからオペレーションを再実行し、リカバリを行う
      • journalファイルへの書き込みは100ms毎に実行されるため、100ms間のデータロストの可能性は以前残る。
  • Query
    • Sub Object形式は順序依存
    • Dot Notation形式のクエリが安全
  • Update
    • in-place-update
      • オブジェクトサイズが増えない場合は、その場でupdate されるため高速
      • 領域に収まらない場合は、領域が移動されるため遅くなる
  • Index
    • B-tree indexを採用
    • バックグラウンドでのindex作成が可能
  • Replicationの解説
    • 特徴
      • Master-Slave:1master - N slaveの構成
      • Replica Sets:自動フェイルオーバーなど
      • masterとslaveの間は非同期通信
      • Relicationの設定、管理、メンバー追加、削除は非常に簡単
      • slaveからの読み出しは可能(書き込みは不可)
    • Master - Slave
      • 最低2台からの構成が可能
      • Slaveの追加、撤退は容易
      • Slaveからの読み出しは可能
    • Replica Sets
      • 自動フェイルオーバー
      • メンバーの自動リカバリ
      • 最低3台から構成可能
      • Slaveからの読み出しは可能
「ソーシャルアプリのプロトタイプ制作にMongoDBを活用」〜PHP+Sleepy.Mongooseでお手軽永続化〜 [twitter:@bibrost]

前回に引き続きbibrostさんによる発表。

    • 開発初期にありがちなRDBスキーマ変更に伴うコストを低減させるために、スキーマレスなMongoDBを活用する。(車のボディ開発で行われている粘土細工に由来)
    • リリース時のタイミングでMySQLなどに移行する
    • MongoDBをそのまま使うには、まだMongoDBを保守できるエンジニアが足らない。
MongoDBチューニング [twitter:@matsuou1]

私の結論としては、MongoDBではRDBMSとほぼ同じチューニングのアプローチ方法が取れます。RDBMSでチューニング経験がある人は、
違和感なくやれると思います。むしろ、JOINがない分、簡単かと。ただ、バックエンドで使う分には十分な方法が提供されているが、
フロントエンドで使うには、実行回数が多い&ちょっとだけ遅いクエリを特定する方法が現状ないので、注意して見て行く必要があります。
この辺りは今後のバージョンアップに期待しましょう。(PostgreSQLでも8.4辺りからの実装でしたしね)
複合インデックス辺りをもう少し詳しく書く予定でしたが、直前に炎上中のプロジェクトごと投げられて時間が取れなかったので、
仕事が落ち着いたらブログでもう少し詳しく検証して行きたいと思います。

「MongoDBを使用したモバイルゲーム開発について」 [twitter:@ygenki]

既に定番となっているサイバーエージェント枠。
東京ガールズスナップは、勉強会殺しになりうる危険な存在。

  • MongoDBでよかったこと
    • 階層構造と相性が良い
    • 仕様変更に対し柔軟に対応が可能
    • バイナリデータの保存が可能
  • 課題
    • オペレーションミスでデータが消える(updateで$setをつけてないとか)
    • データ型が変わる(int → double)
    • ドキュメント設計
toggter [twitter:@kimukou_26]

まとめ&所感

全機能解説は本当にすばらしい。気をつける必要があるポイントが多数記載されているため、非常に有用。
Replicationについての検証は後でやってみたいと思う。そろそろ、ちゃんとした検証用サーバが欲しい・・・。

今回、初めて発表させて頂いたが、「発表するとフォロワー増えるよね。ポポポポーン」を実感しました。
まずは、情報を発信することが大事ですね。

第13回R勉強会@東京に行ってきた

前回に引き続き、第13回R勉強会@東京(#TokyoR)に参加してきました。
今回はついに60人が参加。エンジニア以外の人が多いので、いつもと違う色んな話が聞けて楽しい。

線形判別分析[twitter:@isseing333]

  • ロジスティック回帰分析は、線形か?非線形か?

R と .NET Framework[twitter:@kos59125]

資料は こちら を参照。

  • Rを.NetFrameworkから操作するためのライブラリ R.NET についてのお話。
  • パッケージなんかも普通に使える。
  • ユーザと開発者を募集中。

Rで学ぶロバスト推定 [twitter:@sfchaos]

  • 分析データに外れ値がつきもの
    • ロバスト推定とは、外れ値を除外せずに、受ける影響を小さくして頑健なモデルを推定する方法

とりあえずデータをそのまま線形回帰分析しても、望ましい結果が得られないので、何かしらの対処が必要。

  • ロバスト推定
    • M推定法
      • 線形回帰の場合は、全ての点を同じ重みで考えているが、M推定では、モデルへの当てはまりが悪い点の重みを引く巣設定することにより影響を小さくする。
      • 残差に関する外れ値についてはロバストだが、説明変数に関する外れ値については、ロバストでないという問題がある。
      • MM推定を使うと、説明変数に関する外れ値についてもロバスト
      • 最新の手法が入っているrobustbaseパッケージのlmrob関数を使っても同様の結果が得られる。
      • 高次元のデータに対しては、2次元のデータのように視覚的にはずれ値を検出できる訳ではないので、大変。

Rで地理空間分析 地理データのとりあつかい@酒井

  • 地理空間データ分析で苦労するところ
    • 地物・イベントとその場所を表現したデータ
    • 集めるのはたいへん
    • 集めたあと視覚化するのがたいへん
    • どのように視覚化するといいのか考えるのがたいへん
    • 視覚化したあとの解釈がたいへん

商業施設計画に利用するモデリング技術(1998)

説明がしづらいモデルは人気がない。(意思決定者が統計に詳しい訳ではないので、直感的な分かりやすさが求められる)

  • 地理空間データの特徴
    • 分布そのものに何らかの意味がある
    • 空間パターンのコンテキスト(文脈)を読み意思疎通をするためには「相手」と「自分」の認識の差を理解する必要がある。

 

  • ビジネス地理空間分析の手法
    • 地理的集計分析(商圏分析など)
    • 点プロセス分析
    • 領域最適化分析
    • クラスター分析
  • 空間データをdataframeみたいに・・・
    • 空間データ
      • Points
      • Lines
      • Polygons
    • 地理空間データ
      • 投影法
    • sp packageのクラス
      • SpatiaPoints
      • SpatialPointsDataFrame

YjdnJlpパッケージとTokyo.R翻訳プロジェクトの紹介[twitter:@yokkuns]

YjDnJlpについての発表は第2回さくテキの内容とほぼ同じ。(テキストが退職ブログになってた以外は・・・。)

形態素解析はYjdnJlpパッケージとMeCabを使用しても大きな差はでないが、特徴語抽出については、以下の2段階のフェーズで行われるため大きな差がでる。
・キーワードをカウント
コーパス内でどれくらい使われる語かをみて、スコアを算出。
 どのコーパスを使うかで、結果に大きく影響がでる。(Yahooのコーパスは不明・・・)

togetter [twitter:@kimukou_26]


まとめ

  • 最近は、発表前日に資料を書くのが流行。
  • CRANの読み方は、「シーラン」派と「クラン」派が壮絶な戦いを繰り広げている。迂闊な発言は危険。
  • もう少しRの勉強が進んだら、パッケージ本を読みたい。Bigmemoryとか気になる。
  • 地理空間を扱うのはPostGISが有名だが、MongoDBも忘れて貰ったら困るぜよ。

MongoDBのShardingを試してみた。その3 障害発生時の挙動について

今回はMongoDBのSharding環境にて、各サーバが停止した場合の挙動について検証してみたいと思います。

検証環境

今回の検証環境も前回と同じ環境を使います。

mongosサーバ

最初はmongosサーバです。
早速、mongosサーバを落としてみましょう。

[matsuou1@testsvr mongodb]$ kill -2 14973

次に、mongosサーバに接続してみます。

[matsuou1@testsvr mongodb]$ ./bin/mongo localhost:10000/logdb
MongoDB shell version: 1.8.0
connecting to: localhost:10000/logdb
Tue Apr 19 23:51:28 Error: couldn't connect to server localhost:10000 shell/mongo.js:81
exception: connect failed

当然と言えば当然ですが、mongosサーバへの接続に失敗します。

まとめ

想定通り、mongosサーバに接続できなくなりました。
各shardには問題なく接続でき、クエリの実行も可能ですが、複数shardをまたがるようなクエリの実行は出来なくなります。
下手な構成な場合は単一障害点となりうるので、基本的にはwebサーバやアプリサーバなど実際にアプリケーションが動作するサーバで
実行させて、プロセスの死活監視を行い、障害が発生したらプロセスの再起動を行う感じの運用になるのではないでしょうか。
mongosは、単なるルーティングプロセスでデータの管理はしないので、復旧時に特に気を使う必要はないかと思います。

shardサーバ

次は、3つあるshardサーバのうち1つを落としてみます。

shard3のプロセスIDを確認し、落としてみます。

[matsuou1@testsvr mongodb]$ kill -2 18436

試しにカウントを取ってみましたが、エラーとなります。

> db.logs10.count()
Tue Apr 19 14:45:54 uncaught exception: count failed: {
        "assertion" : "DBClientBase::findOne: transport error: localhost:10003 query: { count: \"logs10\", query: {} }",
        "assertionCode" : 10276,
        "errmsg" : "db assertion failure",
        "ok" : 0
}
> db.logs10.count()
Tue Apr 19 14:45:57 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }

shard keyでアクセスし、shard3以外のshardのみにアクセスする場合は、クエリ―は実行可能

> db.logs10.find({ uid : "f26AKDmNMkIXXXXt"})
{ "_id" : ObjectId("4da7d407af13de0b7c6XXXX0"), "month" : "2010/02", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/02/28 16:00:51", "path" : "/?pid=P07K&sid=E74D&uid=1", "device" : "940P" }
{ "_id" : ObjectId("4da7d407af13de0b7c6c35cd"), "month" : "2010/02", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/02/28 16:01:12", "path" : "/", "device" : "940P" }
{ "_id" : ObjectId("4da7d407af13de0b7c6c369d"), "month" : "2010/02", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/02/28 16:06:06", "path" : "/index.html", "device" : "940P" }
{ "_id" : ObjectId("4da7d44aaf13de0b7c7aa66d"), "month" : "2010/03", "uid" : "f26AKDmNMkIXXXXt", "timestamp" : "2010/03/31 16:51:34", "path" : "/?pid=P07K&sid=E74D&uid=1", "device" : "940P" }
障害中に実行可能なクエリのまとめ

shard環境では、targetedとglobalの2つのタイプのクエリに分けられます。
targetedは、最小限のshard(多くの場合は1つのみ)にアクセスし、globalはほぼ全てのshardにアクセスします。
つまり、このタイプの違いによって、障害中に実行可能かどうかが分かれることになります。
クエリのタイプについては、マニュアルの Operation Types を参照してください。

  • targetedクエリ

  • 実行可能なクエリの例

・shard keyを指定して、落ちているshard以外のshardの検索
・shard keyを指定して、落ちているshard以外のshardのアップデート
・インサート

  • globalクエリ

  • 実行不可能なクエリの例

・shard keyを指定して、落ちているshardのデータの検索
・shard keyを指定しない検索

まとめ

shard障害が発生すると、障害shardを参照するクエリは実行エラーとなるが、問題ないshardへのshard keyを使用したクエリは実行可能。
アプリへの影響が大きいので、基本的にはReplica set を構成し、冗長化を行うべきです。

configサーバ

最後に、configサーバが落ちた場合についてです。
先ほどと同じように、configサーバを落としてみます。

[matsuou1@testsvr mongodb]$ kill -2 27480

この状態で、以下の操作を行ってみます。

  • shardの追加、削除

まずは、shard4を新たに起動します。

[matsuou1@testsvr mongodb]$ ./bin/mongod --shardsvr --port 10005 --dbpath /tmp/mongodb/shard4 --logpath /tmp/mongodb/log/shard4.log &

adminサーバより、addshardコマンドを実行します。

[matsuou1@testsvr mongodb]$ ./bin/mongo localhost:10000/admin
MongoDB shell version: 1.8.0
connecting to: localhost:10000/admin
> db.runCommand( { addshard : "localhost:10005" } );
Wed Apr 20 00:48:51 uncaught exception: error { "$err" : "socket exception", "code" : 11002 }

想定通りにエラーとなります。クラスタメタデータを管理するサーバが落ちているので当然ですよね。

  • 大量データロード

次に大量のデータをロードし、chunkがどのようになるか確認します。

1行のみ入れてあるcollectionに対し、100万行程のアクセスログをインポートしてみます。

logdb.logs12 chunks:
				shard0000	1
			{ "timestamp" : { $minKey : 1 } } -->> { "timestamp" : { $maxKey : 1 } } on : shard0000 { "t" : 1000, "i" : 0 }

chunkの分割や移動は行われなくなるため、色々大変となるところの検証を行うつもりでいたのですが、
shardやmongosが大量のExceptionを吐いて、mongoimportが激遅に。。。

shardのログ

Wed Apr 20 01:24:23 [initandlisten] connection accepted from 127.0.0.1:46419 #53871
Wed Apr 20 01:24:23 [conn53871] end connection 127.0.0.1:46419
Wed Apr 20 01:24:23 [initandlisten] connection accepted from 127.0.0.1:46421 #53872
Wed Apr 20 01:24:23 [conn53846] end connection 127.0.0.1:46369

mongosのログ

Wed Apr 20 01:25:57 [conn2] DBException in process: socket exception
Wed Apr 20 01:25:57 [conn2] ~ScopedDBConnection: _conn != null
Wed Apr 20 01:25:57 [conn2] DBException in process: socket exception
Wed Apr 20 01:25:57 [conn2] ~ScopedDBConnection: _conn != null
Wed Apr 20 01:25:57 [conn2] DBException in process: socket exception

わざわざ、configサーバを落とした状態でmongoimportする人はなかなかいないと思いますが、エラー吐きまくりな状態になるのでやめておいたほうが無難です。時間があったら、もう少し調査&最新版で検証してみます。

まとめ

configサーバ障害が発生すると、システムのメタデータはリードオンリーになるため、shardの追加、削除などは出来なくなります。
システムは機能し続けますが、chunkの分割や移動は行われなくなるため、このタイミングで大量のデータロードを行うとmigrateできないために、アンバランスなshardができてしまう可能性があります。(マニュアルより。。。)

また、configサーバが落ちている場合は、クラスタメタデータが必要なためmongosサーバが起動できません。
configサーバと同時にmongosサーバも落ちた場合は、先にconfigサーバ復旧後にmongosサーバを復旧させる必要があります。

マニュアルでは、ダメージは大きくないよと記載されていますが、意外なところで思わぬバグ等を踏む可能性もあるので、可能な限り早く復旧しましょう。

全体まとめ

今回は、sharding環境構成する3つのサーバに対し、それぞれ障害が発生した場合にどういう現象が発生するか検証してみました。
障害発生時に焦るよりは、障害発生時にどのような状況になるのかを事前に把握し、速やかに復旧させたいですね。
障害が発生しない、または、きちんと冗長構成を取っておくのが良いのは、間違いないのですが。

色々、踏み込めてない気がするので、時間があれば後で追記するかもしれません。

Rで線形単回帰分析

次回のTokyo.Rの開催が近づいてきたので、前回の復習を兼ねてRで回帰分析をやってみます。

今回は最も単純な線形単回帰分析を行います。

回帰分析の流れ

  1. 回帰式を求める意義があるか検討する(説明変数と目的変数のグラフを作成する等)
  2. 回帰式を求める
  3. 回帰式の精度を確認する
  4. 回帰係数の検定を行う
  5. 信頼区間と予測区間を求める

回帰式を求める意義があるか検討

無相関なデータに対しても、数学的には回帰式が求められるため、検討しておくことは重要です。

データはマンガでわかる統計学 回帰分析編のデータを使用してみます。
ある喫茶店のアイスティーの売り上げとその日の最高気温についてのデータです。

> norns
     temperture icetea
8/22         29     77
8/23         28     62
8/24         34     93
8/25         31     84
8/26         25     59
8/27         29     64
8/28         32     80
8/29         31     75
8/30         24     58
8/31         33     91
9/01         25     51
9/02         31     73
9/03         26     65
9/04         30     84
相関係数の確認
  • 1 から 1 の間の実数値をとり、1 に近いときは正の相関があるといい、-1 に近ければ負の相関があるという。

0 に近いときは相関は弱い。
相関係数は順序尺度であり間隔尺度ではないので、例えば「相関係数が0.2と0.4であることから、後者は前者より2倍の相関がある」などと
言うことはできない。

Rではcor関数を使用して、単相関係数を算出することができる。

> cor(norns$temperture, norns$icetea)
[1] 0.906923

今回は1に近いので、強い正の相関関係があると考えられる。

散布図の確認

散布図をplotし、回帰直線を引く意味がありそうかどうかを確認します。

> plot(norns)

大体、右肩上がりとなっているため、回帰直線を引く意味がありそうな散布図と考えられる。

回帰分析

ここまでデータについて確認してきましたが、回帰分析をやる意味がありそうなので、早速回帰分析をやってみましょう。
回帰分析は、lm関数を使うことで簡単にできます。

まずは、lm関数の書式を確認します。

lm関数
  • 書式

lm(formula, data, subset, weights, na.action,method = "qr", model = TRUE, x = FALSE, y = FALSE, qr = TRUE,singular.ok = TRUE, contrasts = NULL, offset, ...

  • 引数
引数名 必須 説明
formula 当てはめられるモデルのシンボリックな記述式
data モデル中の変数を含むオプションのデータフレーム
subset   当てはめ過程で使われる観測値の部分集合を指定
weights   当てはめ過程で使われるオプションの重みベクトル
na.action   データが NA を含むときそれを処理する関数
method   使われるメソッド
model   x, y, qr 論理値.もし TRUE なら当てはめの成分 (モデルフレーム,モデル行列,目的変数,分解) が返される
singular.ok   論理値. もし FALSE なら特異な当てはめはエラーとされる
contrasts   オプションのリスト
offset   これは当てはめの途中で,線形予測子に含められるべきことが事前に知られている成分を指定するのに使える
  • formulaの書式について
  1. y~x
  2. y~x-1

1は、通常の線形単回帰分析で使用するが、2は定数項がない場合に使用する。
自動車のガソリンの消費量と走行距離など、説明変数が0の場合、目的変数が必ず0になる強い仮定がある場合にのみ使用する。

  • 戻り値
戻り値名 説明
coefficients 係数の名前付きベクトル
residuals 残差,つまり目的変数から当てはめ値を引いたもの
fitted.values 当てはめられた平均値
rank 当てはめ線形モデルの数値計算によるランク
weights (重みつき当てはめだけに該当) 指定された重み
df.residual 残差自由度
call 呼出し式
terms 使われた terms オブジェクト
contrasts (関係するときだけ) 使われた対比
xlevels (関係するときだけ) 当てはめで使われた因子の水準の記録
y もし要求されたなら使われた目的変
x もし要求されたなら使われたモデル行列
model もし要求されたなら (既定),使われたモデルフレーム
実行結果

では、実際にlm関数を使って、回帰分析をやってみます。

> norns.lm <- lm(icetea~temperture , data=norns)
> summary(norns.lm)
Call:
lm(formula = icetea ~ temperture, data = norns)

Residuals:
   Min     1Q Median     3Q    Max 
-8.037 -5.693  2.094  4.409  8.225 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -36.3612    14.6873  -2.476   0.0292 *  
temperture    3.7379     0.5012   7.457 7.66e-06 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 5.709 on 12 degrees of freedom
Multiple R-squared: 0.8225,	Adjusted R-squared: 0.8077 
F-statistic: 55.61 on 1 and 12 DF,  p-value: 7.661e-06 

コード自体は2行しかないので、実行は超簡単です。
分析結果のサマリは、summary関数で見ることができます。

以下、summaryの各項目について見て行きましょう。

Residuals

残差の四分位数
(四分位数とは、分布の左側からの相対頻度の合計値(累積相対頻度)が 25%、50%、75% になる値のこと)

   Min     1Q Median     3Q    Max 
-8.037 -5.693  2.094  4.409  8.225 
Coefficients
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -36.3612    14.6873  -2.476   0.0292 *  
temperture    3.7379     0.5012   7.457 7.66e-06 ***

Estimate:係数
Std.Error:標準誤差
t value:t値
pr(>|t|):p値

回帰分析においては y=a+bx において b=0 となることはあってならず、b=0となると y=a となり、x は y に影響を与えないことになってしまいます。
それでは回帰分析が成立しないので(ここでいう b=0 のことを帰無仮説とよぶ)、b=0となることを棄却できるかどうか考えなくてはなりません。

そこで p値を見ます。p値は帰無仮説が発生する確率なので、0.01以下ならばその推定値は99%の有意水準、0.1以下ならば90%の有意水準ということになります。

また、有意であるならば横に *(星)がつきます。何パーセントかは
Signif. codes: 0 `***' 0.001 `**' 0.01 `*' 0.05 `.' 0.1 ` ' 1
をみればわかります。

つまり、星は'***'で、p値が小さければ小さいほど良いということです。

Multiple R-squared , Adjusted R-squared
Multiple R-squared: 0.8225,	Adjusted R-squared: 0.8077 

Multiple R-squared:寄与率、決定係数
Adjusted R-squared:調整済み寄与率、調整済み決定係数
寄与率には説明変数が多くなる程、値が大きくなる欠点があるので、自由度調整済み寄与率を使用する。
(線形単回帰分析では、そんなに気にする必要はないが、重回帰分析では意識して扱う必要がある。)

これは1に近いほど予測値と観測値が近くなることを表し、モデルの正確性を表す。

値に対する基準はないが、「0.5以上」を一つの目安として扱う。

回帰式

上記結果から以下の回帰式が得られる。

y = 3.7379x -36.3612

plotしてみると、こんな感じになる。

> plot(norns)
> abline(norns.lm , lwd=1 , col="blue")


予測値

回帰式で計算される値を予測値(推測値)は、summary関数では返却されない。
予測値を返すためには、predict関数を用い算出する。

> norns.predict <- predict(norns.lm) # 予測値

> norns.residuals <- residuals(norns.lm) # 残差

> data.frame(norns, norns.predict , norns.residuals)
     temperture icetea norns.predict norns.residuals
8/22         29     77      72.03744        4.962555
8/23         28     62      68.29956       -6.299559
8/24         34     93      90.72687        2.273128
8/25         31     84      79.51322        4.486784
8/26         25     59      57.08590        1.914097
8/27         29     64      72.03744       -8.037445
8/28         32     80      83.25110       -3.251101
8/29         31     75      79.51322       -4.513216
8/30         24     58      53.34802        4.651982
8/31         33     91      86.98899        4.011013
9/01         25     51      57.08590       -6.085903
9/02         31     73      79.51322       -6.513216
9/03         26     65      60.82379        4.176211
9/04         30     84      75.77533        8.224670

得られた回帰式の妥当性の検証

残差を視覚的に分析するために、回帰診断図を表示してみます。
回帰診断図は、回帰分析結果をplotすることで表示できます。

> par(mfrow=c(2,2))
> plot(norns.lm)

以下に、それぞれのグラフが何を示しているかを確認しましょう。

残差とフィット値のプロット(左上)

横軸が予測値、縦軸が残差。
残差の全体像を概観するために使用する。

残差の正規Q-Qプロット(右上)

データの正規性考察するために使用する。
データが正規分布に従っている場合は、直線上に並ぶ。

残差の平方根プロット(左下)

残差の変動状況を考察するために使用する。
標準化した残差の絶対値の平方根を縦軸にし、予測値を横軸にした散布図。

残差と影響力プロット(梃子値とクック距離)(右下)

1つのデータがモデルの当てはまりへの影響力を測るために使用する。
クックの距離が0.5を超えると影響力あり、1を超えると特異に大きい。
横軸は梃子値で、縦軸は標準化した残差。点線でクックの距離0.5を示している。

信頼区間と予測区間を求める

  • 信頼区間とは、「測定・解析を全く同じやり方で100回繰り返したら、95回は回帰直線はこの範囲を通ると考えられる」区間のことです。

信頼区間は、predict関数にinterval="confidence"を指定することで求められる。

> norns.con <- predict(norns.lm , interval="confidence")

> plot(x.plot , norns.con[,1] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="")
> par(new=T)
> plot(x.plot , norns.con[,2] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="red")
> par(new=T)
> plot(x.plot , norns.con[,3] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="blue")
> par(new=T)
> plot(norns$temperture , norns$icetea , type="p",xlim=c(23,35),ylim=c(40,110),ylab="icetea" ,xlab="temperture")

グラフで見るとこんな感じです。

この結果からいえることは、例えば、同じやり方で気温が32度の日のアイスティー売り上げの平均値を見てみると、95%の確率で78.69 〜 87.81の間に収まりますということになります。

  • 予測区間とは、「新たな測定を100回繰り返したら、95回はこの範囲に収まると考えられる」区間のことです。

予測区間は、predict関数にinterval="prediction"を指定することで求められる。

> new <- data.frame(temperture= seq(23 , 35 , 1 ))
> norns.pre <- predict(norns.lm , new , interval="prediction")
> plot(x.plot , norns.pre[,1] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="")
> par(new=T)
> plot(x.plot , norns.pre[,2] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="red")
> par(new=T)
> plot(x.plot , norns.pre[,3] , type="l",xlim=c(23,35),ylim=c(40,110),ylab="" , xlab="" , col="blue")
> par(new=T)
> plot(norns$temperture , norns$icetea , type="p",xlim=c(23,35),ylim=c(40,110),ylab="icetea" ,xlab="temperture")

この結果から言えることは、例えば、気温が32度の日のアイスティー売り上げは、95%の確率で70.00 〜 96.49の間に収まりますということになります。

単位根検定

ランダムウォーク(単位根過程)同士を回帰分析すると、見せかけの回帰が発生するため、単位根検定を行い、変数が単位根でないかどうか確認しておく。
使用するのはPhillips-Perron検定。

> PP.test(norns2[,1])

	Phillips-Perron Unit Root Test

data:  norns2[, 1] 
Dickey-Fuller = -8.0442, Truncation lag parameter = 2, p-value = 0.01

> PP.test(norns2[,2])

	Phillips-Perron Unit Root Test

data:  norns2[, 2] 
Dickey-Fuller = -6.0224, Truncation lag parameter = 2, p-value = 0.01

それぞれのp-valueが0に近いため単位根過程ではなく、問題なさそう。

回帰式から定数項をはずした場合

次に、回帰式から定数項をはずした場合についても、やってみます。
formulaで指定する式を代えるだけなので簡単です。

> norns2.lm <- lm(icetea~temperture - 1 , data=norns)
> summary(norns2.lm)

Call:
lm(formula = icetea ~ temperture - 1, data = norns)

Residuals:
    Min      1Q  Median      3Q     Max 
-11.591  -4.358  -1.103   5.888   8.890 

Coefficients:
           Estimate Std. Error t value Pr(>|t|)    
temperture  2.50366    0.06149   40.72 4.26e-15 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1 

Residual standard error: 6.742 on 13 degrees of freedom
Multiple R-squared: 0.9922,	Adjusted R-squared: 0.9916 
F-statistic:  1658 on 1 and 13 DF,  p-value: 4.263e-15 

サマリを確認してみても、定数項は表示されいないです。
得られる回帰式は以下の通り。

y = 2.50366x
注意点

定数項をはずした場合(formula=y~x-1)の寄与率が、定数項を含んだ場合(formula=y~x)の寄与率より
高くなる場合もあるが、ある場合とない場合で計算方法が違っているので比較はできない。
実際に今回の場合は、前者の寄与率が0.9916、後者の寄与率0.8077がとなっているが、Residualsを見ても
散布図+回帰式を見ても後者の方が精度が高い。

    Min      1Q  Median      3Q     Max 
-8.037   -5.693   2.094   4.409   8.225 (formula=y~x-1)
-11.591  -4.358  -1.103   5.888   8.890 (formula=y~x)

青:定数項なし、赤:定数項あり

参考文献

Rによるデータサイエンス データ解析の基礎から最新手法まで

Rによるデータサイエンス データ解析の基礎から最新手法まで

マンガでわかる統計学 回帰分析編

マンガでわかる統計学 回帰分析編

まとめ&所感

今回は、Rで線形単回帰分析を定数項がある場合とない場合でやってみました。
教科書通りといえばその通りなのですが、手順として正しいのか、他のステップが抜けてたりしないのか等はよく分かってないのが実情です。
(我ながら怪しいなぁと思いながら記述してるところも・・・)

こんな感じでlm関数使えますのではなく、実際の業務としてどこまでやるべきか、どこまで求められるかをきちんと押さえたいところです。
Web系の業界では、あんまりそこまで求められないのか・・・?

間違いや不足などがありましたら、ご指摘頂けると助かります。

Tokyo.R#13までに、重回帰分析、非線形回帰分析まで復習したいが、果たして・・・。