2019年8月30日 (金)
このブログには、ソフトのインストールにまつわる覚え書きのようなものは書かないことにしているんだけど、今回はあまりに時間をかけてしまったので、なんとなく記録してしまう次第である。
Rで日本語テキストの形態素解析を行う際の定番パッケージ RMeCab が、WindowsのR 64bit環境ではうまく動かないことがある、という問題について。
以下、環境は Windows 7 x64 build 7601, R 3.6.1, Rtools 3.5.0.4である。
MeCab正規版の場合
まずはMeCabのインストール。https://taku910.github.io/mecab/ からmecab-0.996.exeをダウンロードしてインストールした。辞書はSHIFT-JIS, インストール先はC:\MeCabとした。PATHにC:\MeCab\binを追加し、コマンドラインから動作を確認。
おつぎはRMeCabのインストール。RStudioを立ち上げて
> install.packages("RMeCab", repos = "http://rmecab.jp/R")
> library(RMeCab)
> res <- RMeCabC("すもももももももものうち")
なんと、R Session Abortedとなる。なぜだー。
RMeCabをソースから再インストール。
> install.packages("RMeCab", repos = "http://rmecab.jp/R", type = "source")
すると、32bitのほうは... (以下、C:/Users/の直下のフォルダ名を伏字にしてます)
C:/Rtools/mingw_32/bin/g++ -shared -s -static-libgcc -o RMeCab.dll tmp.def Ngram.o NgramDF.o NgramDF2.o RMeCab.o RMeCabC.o RMeCabDoc.o RMeCabFreq.o RMeCabMx.o RMeCabText.o collocate.o docDF.o docMatrix2.o docMatrixDF.o docNgram2.o docNgramDF.o setMeCabMap.o -L/usr/local/lib -lmecab -LC:/PROGRA~1/R/R-36~1.1/bin/i386 -lR
installing to C:/Users/xxx/Documents/R/win-library/3.6/00LOCK-RMeCab/00new/RMeCab/libs/i386
と無事通過するんだけど、64bitのほうは
C:/Rtools/mingw_64/bin/g++ -shared -s -static-libgcc -o RMeCab.dll tmp.def Ngram.o NgramDF.o NgramDF2.o RMeCab.o RMeCabC.o RMeCabDoc.o RMeCabFreq.o RMeCabMx.o RMeCabText.o collocate.o docDF.o docMatrix2.o docMatrixDF.o docNgram2.o docNgramDF.o setMeCabMap.o -L/usr/local/lib -lmecab -LC:/PROGRA~1/R/R-36~1.1/bin/x64 -lR
C:/Rtools/mingw_64/bin/../lib/gcc/x86_64-w64-mingw32/4.9.3/../../../../x86_64-w64-mingw32/bin/ld.exe: cannot find -lmecab
collect2.exe: error: ld returned 1 exit status
DLLは生成されませんでした
ERROR: compilation failed for package 'RMeCab'
* removing 'C:/Users/xxx/Documents/R/win-library/3.6/RMeCab'
* restoring previous 'C:/Users/xxx/Documents/R/win-library/3.6/RMeCab'
Warning in install.packages :
installation of package ‘RMeCab’ had non-zero exit status
というわけで、インストールに失敗する。な・ぜ・だー。
先人の残した貴重なメモ http://shimocchi.hatenablog.jp/entry/2017/07/04/172302 を研究し、これはずいぶん手間がかかる話だ、と悟った。
まずはVisual Studio Build Tools 2017のインストール。https://visualstudio.microsoft.com/ja/thank-you-downloading-visual-studio/?sku=BuildTools&rel=15 からインストーラをダウンロードし、Visual Studio Build Tools 2017を選択。
次に、MeCabのソースをダウンロード。https://taku910.github.io/mecab/ からmecab-0.996.tar.gzをダウンロードし、C:\work\mecab-0.996に展開。
ソースコードの修正。https://qiita.com/tobesan/items/6b6f3a025fdd177ef52a の教えに従い、Makefile.msvc.in, feature_index.cpp, mecab.h, writers.cpp, common.hを修正。なお、writer.cppは、左記ページで説明されている旧コード(260行目)と実際のコードが異なっていたので悩んだが、新コードに修正した。
管理者権限でコマンドプロンプトを起動し、
>cd c:\work\mecab-0.996\src
>call "C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC\Auxiliary\Build\vcvarsall.bat" amd64
>nmake -f Makefile.msvc.in
なんかものすごくいろんなメッセージが出て怖かったのだが、とにかく、C:\work\mecab-0.996\src\libmecab.dllというファイルが生成された。
ライブラリのコピー。管理者権限で、C:\MeCab\bin\libmecab.dll を C:\Program Files\R\R-3.6.1\bin\i386 にコピー。C:\work\mecab-0.996\src\libmecab.dll を C:\Program Files\R\R-3.6.1\bin\x64 にコピー。
ふたたびRStudioを立ち上げて
> install.packages("RMeCab", repos = "http://rmecab.jp/R", type = "source”)
正常終了!
祈るような気持ちで
> library(RMeCab)
> res <- RMeCabC("すもももももももものうち")
と試してみたところ... 無情にも、やはり R Session Abortedになる。なーぜーだー。
このようにRが落ちてしまうのはR 64bit版の場合であって、32bit版ならちゃんと動作する。 RMeCabを使いたくなるたびにR を32bit版に切り替えればいいんだけど、でも、そんなの嫌じゃないですか。
R 64bitでRMeCabが動かないことがあるというのは、新発見でもなんでもない。RMeCab開発者の先生もちゃんと注記して下さっている。諦めきれない私が悪いのです。
他にもいろいろなことを試したのだが、メモは省略する。
数時間粘ってついに断念。やけになって、C:\Program Files\R\R-3.6.1\bin\ の下にコピーしたライブラリを削除し、 mecab をきれいさっぱりアンインストールし、PATHを元に戻し、C:\Users\xxx\Documents\R\win-library\3.6 のRMeCabを削除し、PCをシャットダウンし、買い物に出かけた。
MeCab 64bit版の場合
世の中には奇特な方がいらっしゃるもので、Windows 64bit 用にMeCabをビルドして下さっている方がいらっしゃることに気が付いた。
ありがたいことだ... というわけで、再挑戦。
https://github.com/ikegami-yukino/mecab/releases から mecab-64-0.993.2.exeをダウンロードしインストール。辞書はSHIFT-JIS, 話がややこしくなるのが怖くてインストール先は変更せず、C:\Program Files\MeCab のままとした。PATHにC:\Program Files\MeCab\binを追加。
コマンド・プロンプトから動作確認したがエラーとなる。しばし悩んだうえ、環境変数 MECABRC=C:\Program Files\MeCab\etc\mecabrc を定義。無事動作することを確認した。
RStudioを立ち上げ、RMeCabをインストールしてみると...
> install.packages("RMeCab", repos = "http://rmecab.jp/R")
> library(RMeCab)
> res <- RMeCabC("すもももももももものうち")
> res
[[1]]
名詞
"すもも"
[[2]]
助詞
"も"
[[3]]
名詞
"もも"
[[4]]
助詞
"も"
[[5]]
名詞
"もも"
[[6]]
助詞
"の"
[[7]]
名詞
"うち"
う...動いた....!!!
というわけで、無事に難関を突破したという喜びと、これにいったい何時間かけたんだという虚脱感で、しばし呆然とディスプレイを眺めたのであった。
なお、上記は R 64bit だけでなく R 32bitでも動く。また、install.packages("RMeCab", repos = "http://rmecab.jp/R", type = "source") は失敗する。
正直疲れましたが、ともあれ、MeCab開発者のみなさま、RMeCab開発者のみなさま、Web上で情報を提供して下さっている皆々様にお礼申し上げますです。
雑記 - 覚え書き:Windows上の R x64 で RMeCabが動かない問題
2019年8月24日 (土)
読んだものはなんでも記録しておこうということで...
阿部誠(2014) 近年のマーケティング・サイエンスのトレンド-構造モデリング. マーケティングサイエンス, 22(1), 1-4.
掲載誌の巻頭言みたいな感じの短い記事なんだけど、実証IO(っていうんでしたっけ? あのすごく難しい奴)で言うところの構造モデリングについての、わたしみたいなど素人向けの解説。とても勉強になりました。
いわく、経済学では現象をエージェントの最適化の結果にして均衡状態と捉えるのに対して、マーケティングではエージェントの行動はいまは最適じゃないからどうやって最適化するかという風に考えるし、そもそも企業は均衡を崩すことで競争優位を勝ち取るともいわれている。このちがいに注意、とのこと。なるほどー。
えーと、最近あっち方面の話を読んでると、よく「構造推定」ってのが出てきますけど、同じ話でしょうか?
まあいいや。次はChintagunta, Erdem, Rossi, Wedel (2006, Mktg.Sci.)というのを読むといいらしい。...って、おいちょっとまて、Chintaguntaって比例ハザードモデルのChitagunta? ErdemってシグナリングのErdem? RossiってAllenby-Rossi本のRossi? それにWedelってWedel&KamakuraのあのWedelだよね? あいつら、実はみんな友達であったか...
論文:データ解析(2018-) - 読了:阿部(2014) (最近の経済学でいうところの)構造モデリングとはなにか
2019年8月19日 (月)
仕事の都合で、大企業における女性管理職登用についての日本語の論文をいくつか探して読んでいたんだけど、いずれも「あれも問題だしこれも問題ですよね」というような、なんというかぬるま湯のような内容で、いささか参った。これは誰が悪いって話じゃなくて、きっとそうならざるを得ないタイプの問題なのであろう。
その中で唯一、あっこれ面白い...と思った論文についてメモ。
中川由紀子 (2013) 女性管理職育成・登用をめぐるエージェンシー理論分析 -日米間3社の事例分析-. 経営哲学, 10(2), 82-92.
いわく。
なぜ男女均等処遇が進まないのか。内閣府の男女共同参画白書のまとめでは、ワークライフバランス、女性のキャリア形成支援、意識改革、の三点が挙げられている。他にもいろんなことがいわれている。保育所が足りないとか。
ここではそういうんじゃなくて、企業の側からみてみよう。
50年代、Beckerという人は「経営者は女性労働者に対して差別的嗜好を持っている」と考えた(嗜好差別理論)。しかし上場企業であれば株主価値や利潤を犠牲にしてまで好みを貫くことはないだろう。
70年代、Arrowらは経営者が集団のステレオタイプに基づいて判断すると考えた(統計的差別理論)。たとえば、女性が平均として結婚・出産で離職しやすいから、採用を控えたり昇進させなかったりするという説明。これは、経営者から見て個々人の情報を知るためのコストが高い(と経営者が思っている)という前提での説明である。しかし実際には、統計的差別によって優秀な女性人材を失うという機会コストは大きいから、経営者が個々人についての情報の取得をさぼるとは思えない。
本稿の説明は次のとおり。
ここにあるのはエージェンシー問題だ。経営者(プリンシパル)は長期的な全体効率経営を目指してるんだけど、管理職(エージェント)は短期的・利己効率的に考えているせいで、女性登用に積極的になれない。つまりは全体効率性と個別効率性の対立だ。
とすると、エージェンシー理論からいえば解決策はふたつ、(A)経営者と管理職の情報の対称化、(B)両者の利害の一致、である。
(A)は難しいけど、(B)の方法なら2つある。(1)モニタリング・システム。つまり経営者がなんとかして管理職を統治する。(2)インセンティブ・システム。経営者がなんとかして管理職を自己統治させる。
ここからは3つの企業の比較。比べるのは、日本の総合電機メーカーA社、GE、サムソン。いずれも聞き取り調査(著者はA社とGEの人事におられた方なのだそうで、そういわれるとA社がどこだかなんとなくわかっちゃいますね...)。
A社には管理職の機会主義的な行動を抑制するメカニズムがない。いっぽうGEでもサムソンでも、モニタリングとインセンティブシステムがうまく機能している(紹介が面白かったんだけどメモ省略)。
云々。
... 全くの門外漢なので見当違いな感想かも知れないけど、女性登用をエージェンシー問題という視点からみるという発想がとても面白かった。
すごく面白かったせいなんだけど、いくつか疑問がわいたのでメモしておくと、
- 利己的な管理職が女性を登用しにくいのはなぜか。この論文での説明には、「社会的アイデンティティによる同質性再生産バイアスのせい」という説明と、「女性を登用すると離職による短期的不利益が生じる可能性があると管理職が思っているせい」という説明が混じっているような気がするんだけど、本来別の問題ではないかしらん。
- エージェンシー理論の観点からみてありうる対処のうち(A)情報の対称化については触れられていないんだけど、これは難しいんだろうか。具体的にうまくいくかどうかは別にして、360度評価みたいな多面的な評価は、組織内における情報の非対称性を減らすことにつながっていないかしらん?
- もし私が超・日本的な経営者だったとしたら(女性への差別的嗜好はないものとする)、そもそもの経営理念として統制ではなく関与を重視し、管理職をより高次な内的要因によって動機付けることでプリンシパル=エージェント関係を超えようと目論み(スチュワードシップ理論っていうんですかね)、そういう組織をどうやって作ろうかと考えたあげく社員を禅寺に連れてっちゃったりするかもしれないと思うんだけど、そういう方向の発想って、やっぱしナンセンスなんですかね?
論文:その他 - 読了:中川(2013) エージェンシー理論から見る女性管理職登用
2019年8月15日 (木)
中塚昭宏, 松川弘明(2018) 集合知メカニズムに基づく投票方式の需要予測手法に関する研究. 日本経営工学会論文誌, 69, 143-152.
需要予測のための企業内予測市場の報告。第一著者は富士ゼロックスの方。
提案手法は以下の通り。
- 予測対象商品、期間、参加者、賞品を決める。
- 「投票フォーム」を設計する。過去の実績データとかプロモーション状況とかを簡潔にまとめる。で、各商品の需要予測区間を設定し(つまり区間証券を取引するわけね)、投票券の枚数を決める(初期資金に相当する概念であろう)。予測区間は10個以内、投票券も商品あたり10枚以内とすべし、とのこと。
- 予備実験をやったり説明会をやったりして...
- 投票フォームを一斉送信し投票を求める。なんと、webサービスじゃなくて、Excelファイルのメール配布・回収でやるのである!
- 需要予測分布を求めて公開。
- 商品ごとに、予測が的中した票に付与し、ポイント合計の上位者に商品を配る。
「ある大手複写機メーカー」で実験やりました。
参加者は製造販売管理部門の31名。自社商品6個の翌月の需要をあてる。区間数10, ひとりあたり投票券10。投票フォームの送付から回収まで5日間。同じ6個の商品について、5月, 6月, 7月に、それぞれ翌月の需要を当てさせた。
結果。
従来社内で使っていた時系列分析による需要予測よりも性能がよかった。また予測分布の分散は予測誤差を捉えていた。
各参加者の成績は実施月によって異なっていて、特定の優秀な予測者群はみつからなかった。(31人全員の成績が表になっている...)
「ある予測区間に全票を突っ込む」という行動は一般職の人に多かった。かつ一般職で予測成績が悪かった。マネージャーのほうがさまざまなリスクを想定しているからだろう。(←これ面白いなあ)
云々。
ざっと目を通すつもりだったんだけど、途中からなんだか楽しくなってきてしまった。盛り上がっている様子が目に浮かぶような気がする。予備実験として「クリアケースのなかのチョコレートの数をあてる」というのをやって、参加者に集合知のパワーを見せつけた模様だ。楽しそうだなあ。
提案手法のポイントは、取引ルールを思いっきり簡略化して、ワンショットの投票形式にしたところであろう。通常の予測市場と比べてどう変わってくるのかという点が興味深いと思った。
論文:予測市場 - 読了:中塚・松川(2018) 企業内予測市場で需要予測
山田祐樹(2016) 認知心理学における再現可能性の認知心理学. 心理学研究, 59(1), 15-29.
再現可能性の危機についての意見論文。問題自体にはあんまし関心ないんだけれど、再現可能性評価のための予測市場の話が載っていたので目を通した。
いくつかメモ:
- Almenberg, Kittlitz, & Pfeiffer (2009 PLoS One), Hanson (1995 Soc.Epistemology): 科学のための予測市場の活用。両方ノーマークだった...
- Dreber, Pfeiffer, Almenberg, Isaksson, Wilson, Chen, Nosek, & Johannesson, M. (2015 PNAS): 再現可能性の予測市場をやりましたという報告。前に読んだNature Human Behaviourの論文と、著者が結構重なっている...そういえばあの論文でも予測市場やっていたから、関係があるのかも。
- 予測市場InTradeが政府に賭博とみなされて休止になったという話がちらっと書いてあるんだけど、賭博とみなされた理由のひとつはオプション取引があったからなのだそうだ。著者いわく、再現可能性の予測市場においてもオプション取引や空売りは導入すべきでないだろう、とのこと。えっ、そうなんですか? 賭博かどうかはペイオフの問題で、取引ルールとは関係ないと思ってた... Ozimek(2014)というwhite paperを見るといいらしい。
- 著者の先生いわく、そもそも再現可能性予測市場の予測性能が高いかどうかもわからない、とのこと。そりゃまあそうだ、研究の蓄積がないからね。
- 参加者にはある程度のトレーディングの経験も必要だろう、というくだりでAnderson & Sunder (1995 OBHDP), Peterson (1993 J.Econ.Behav.Org.)というのが挙げられていた。予測市場じゃないと思うけど、面白そうだ。しっかし、わたし株取引の経験とかないのに、予測市場の実験とかやっちゃって、どうもすいません。
論文:予測市場 - 読了:山田(2016) 再現可能性危機 in 認知心理学
2019年8月14日 (水)
荒川歩, 菅原郁夫(2019) 裁判員裁判を想定したフォーカスグループの効果の検証. 社会心理学研究, 34(3), 133-141.
仕事の都合で目を通した論文。
いわく、
米国では裁判の前に陪審コンサルタントを雇い、フォーカス・グループ・インタビュー(ないし質問紙調査や模擬評議)をやって、陪審員がどう反応するか、公判で何を示す必要があるか、自分たちに有利な判断をする陪審員はどんな人か(選任手続きに備えるため)、キャッチフレーズとアナロジーとかがうまく働くかどうか、などなどを調べることがある。[←へええええ!!! 最初のページからもうびっくりですよ]
しかしフォーカス・グループ(FG)の利用の有効性については検証がない。やってみましょう。
題材は次の架空の事件。被告人は職場(工事現場)でいじめを受けており、いじめていた人物に暴行を受けている際に工具で反撃し死に至らしめました。目撃者はいません。正当防衛の構成要件の一つである「急迫性の侵害」はあったでしょうか。話を簡単にするため、急迫性の侵害があったら無罪ということにする。
予備調査。
著者二名がインタビューガイドを作成、学生6名と5名の2組のFGをつくってインタビュー[詳細略]。それとは別に法科大学院生3名に調査。
結果。たとえば「違法性阻却事由」について、法科大学院生は一般人でも主旨自体は理解しているだろうと予測したが、実際の学生の一部は、本来の意味と逆の意味に捉えていた(正当防衛っぽいけど正当防衛にならないこと)。このように、一般人がどのように理解しているかはFGなしには気づきにくい。
さて、別の法科大学院生に、まず争いのない事実と検察官の主張のみを渡して弁護人の弁論を作ってもらい(A)、次にFGの発言録を渡してもう一度作ってもらった(B)。
本実験。学生31人に、争いのない事実、検察官の主張、弁護人の弁論(上記AかB)を読ませて調査票に回答させた。
結果。有罪と判断する割合に有意差はなかった。
「よくわかっていないかもしれないと思われる言葉や文章」をマークさせて文字数を数えて目的変数とし[二つの弁論はそもそも文字数が違うので、実は何を調べているのかいまいちはっきりしないんだけど]、弁論(2)x有罪無罪判断(2)のANOVAをやったら交互作用が有意で、FG情報がない群では有罪無罪判断間に文字数の差がないが、ある群では有罪判断のほうが文字数が多かった。著者ら曰く、わかりやすさには「論としてよくわかるか」と「意味が分かりやすいか」の両方が混じっていて、(後者の意味で)わかりやすいせいで有罪と判断したからこそ、有罪という立場からして(前者の意味で)なぜそのように主張できるのかがわからないところが明確になったのではないかとのこと。[おそれながら、これかなり強気な説明では...]
有罪無罪判断の確信度にも交互作用があり、FG情報あり群では無罪判断のほうが確信度が高かった。
云々...
考察。FGには有用性があるのではないか。云々。
...勉強になりましたです。
なにはともあれ、フォーカス・グループについての実験研究というのを見つけることができたのがうれしい。探してみるもんだな。
実験・分析の手続きには、ちょっと良くわからない点もあって...
予備実験で、法科大学院生に弁論を2種類つくらせるくだり、FGからの結果を見たかみてないかという違いと、1回目に書いたか2回目に書いたかという違いが交絡していると思う(仮に弁論が良くなったとして、FGの結果をみたおかげなのか、2回目に書いたからなのかの区別がつかない)。これ、普通の実験だったら結構深刻な瑕疵だと思うんだけど... でも、ここまでレアでユニークな題材だと、もはやなにもいえないっすね。
本実験の分析で、弁論を読ませてマークさせた文字数を目的変数にとり、弁論タイプと有罪無罪判断の要因にとったANOVAをしているところもなんだか不思議であった。弁論タイプ→文章の読解プロセス→有罪無罪判断 という因果関係を考えると、A→B→CかつA→CというDAGがあるときにAとCで層別してBの差を見ていることになるわけで、あたかもシンプソン・パラドクスの例題のような奇妙さがある。むしろ、弁論タイプ→読解プロセスという分析と、{弁論タイプ & 読解プロセス}→有罪無罪判断という分析をやるのが筋じゃなかろうか。(いやまてよ、もしかすると、本文中でちらっと触れられているように、有罪無罪判断は弁論理解に先行してなされるという視点での分析なのかもしれない。ひょっとして、この分野ではそういう風に考えるのだろうか? だとしたら、それってものすごく怖い話ですね。私が被告人だったら、裁判員には弁論をちゃんと読んだ上で判断してほしい...)
引用されていた研究をいくつかメモ:
- Galinsky, et al. (2008 Psych.Sci.): 説得における他者視点取得の効果
- Gillespie & Rishardson (2011 J.Soc.Psych.): 協同問題解決における他者視点取得の効果
- 常岡・高野 (2012 社心研): 他者視点取得による攻撃の抑制
論文:心理 - 読了:荒川・菅原(2019) 弁護士にとってフォーカス・グループ・インタビューは有用か
昔取ったメモのなかからR言語の自作チートシートが出てきた。2011年4月、転職をきっかけにしてRを使わなければらない羽目になり、何冊かの参考書をめくりながらとったノートである。当時はRについて全くの初心者で、右も左もわからない状態であった。
その後数か月間は折に触れて眺めては、新たに気が付いたことを追記・更新したと思うけれど、いずれ参照しなくなり、すっかり忘れ去っていた。チートシートというのはそういうものであろう。
それから8年の月日が流れ (自分で書いててショック)、いま見返してみると、いまではごく当然に思えることに新鮮な驚きを感じている形跡があったり、いまでは全く使わなくなった関数について真剣に調べていたり、それまで日々使っていたSAS言語といちいち比べていたり... なんというか、感慨深い。ああ、あのころ私は若かった... (嘘です。当時からおっさんでした)
せっかくなので、ちょっと整形してブログに載せ、供養としたい。
式
- 数値演算子は ^(ないし**), *, /, +, -, %/%(整数除算), %%(剰余)
- 演算子の優先順位がわからなくなったら
?Syntax
をみる - 代入記号として
<-
が推奨されている - 代入式を評価すると、左辺の代入後の値が戻る
- オブジェクト名はcase sensitive
- ピリオドから始まるオブジェクトはhiddenとなる
データ型
- atomicなデータ型は5つ: {NULL, logical, numeric, complex, character}
- numericはメモリ上ではintegerだったりdoubleだったりする
is.character()
etc. で型を確認as.character()
etc. で型キャスト
データ構造
- 主なデータ構造は{vector, matrix, array, list, data frame}
- scalarという構造はない。要素1のvectorとして表現する
str()
で構造とか中身の要約とかを表示- vector: ベクトル
- 要素は任意のデータ型
- ただし、あるベクトルの中の要素はすべて同じデータ型でなければならない。無理に突っ込むと一番上位の型に強制変換される
- 生成方法:
-
c()
で要素を結合して生成 numeric(length=3)
etc. でいきなり生成1:3
ないしseq(3)
でベクトル(1,2,3)を生成rep(2:4, 1:3)
でベクトル((2),(3,3),(4,4,4))を生成
-
- 生成時の注意点
c()
やnumeric()
でいきなり数値をいれた場合、メモリ上では double になる (Matroff本p.54)。ゆえにc(1,2,3) != 1:3
- コロン演算子 「:」 の挙動に注意 (Matroff本p.33)。
x==0
のとき、1:x
はc(1,0)
になってしまう。正方向にのみ動かしたかったらseq()
を使うべし。ただし、is.null(x)
のとき1:x
は NULL になるので都合がよいという面もある
length()
が長さを返す- ベクトルの加減乗除が可能。要素ごとに計算される。長さが違うときは短いほうが繰り返される。例:
t(2:4) %*% 1:3
ないしcrossprod(2:4,1:3)
が内積20を返す x[3]
がベクトルxの3番目の要素(からなるベクトル)を表す。添え字はベクトルでもよいx[-3]
はベクトルxの「3番目の要素を除く全要素」のベクトルを表すx == c(1,3,5)
のとき、x>4
はベクトル(FALSE, FALSE, TRUE)を返すので、x[x>4]
はベクトル(5)を表す- このとき、
which(x>4)
はベクトル(3)を返す。3番目の要素がヒットしたという意味 x[] <- 2
は xの全要素を2に置き換える (x <- 2
との違いに注意)- 要素に名前をつけることができる。例)
x <- c(itemA = 1, itemB=2)
。x["itemA"]
が1を返す (perlのハッシュのような感じで使えるようだ)
- 次元つきのvector (←ベクトルの特殊な場合と考える。面白いなあ)
matrix(1:6, ncol=3)
というようにして生成。→ 1列目が(1,2)になるX <- c(1:6); dim(X) <- c(2,3)
でも同じall(X == Y)
という風に比較dim(), ncol(), nrow()
が次元数、列数、行数を返すrow(), col()
は同じサイズの行列を返す。その要素は行番号ないし列番号で埋まっているX[i,j]
が要素を表すX[i,]
が行ベクトル、X[,j]
が列ベクトルを表す (気持ち悪い...)- 上の記法でアクセスすると、返ってくるのはmatrixかもしれないしvectorかもしれない。
X[1,1,drop=FALSE]
とするとXと同じ次元数のmatrixを返す - 添え字は行列でもよい。これを利用して、(行番号、列番号、値) を行としてもつ行列から表をつくることができる(cf. スペクター本のp.97)
diag(X)
は対角要素のベクトルを表す
- 任意の数の次元を持つ
array(1:12, dim=c(2,3,2))
というようにして生成
- 要素として異なる型のデータ構造を含みうる
list()
で要素を結合して生成L[3]
はリストLの3番目の要素からなるリストを返す。添え字はベクトルでもよいL[[3]]
がリストLの3番目の要素そのものを表す。それがどんな型のデータ構造かはわからない- 二重括弧添字をベクトルにすると再帰的な指定になる。例)
L <- list(1:3, c("Hello", "World"))
のとき、L[[c(2,1)]]
とL[[2]][1]
は等しい ("Hello") - 要素の名前を付けることができる。例)
L <- list(Start = 1, End = 2)
。L[["Start"]]
が 1 を返す。これをL$Start
と略記できる
- データセットを表す特殊なリスト
- 要素は同じ長さのベクトル。つまり、Rではデータセットを行構造体のベクトルとしてではなく、列ベクトルの集合として扱うわけだ
data.frame()
で要素(データセットの列ベクトル)を結合して生成- 文字は勝手にfactorにされてしまう。嫌なら
stringsAsFactors=TRUE
をつける - 要素の名前をつけることができる。例)
purchase <- data.frame( product = c("a", "b"))
$
略記も使える。例)purchase$product[2] == "b"
- [行番号、列番号] と添え字をつけてアクセスできる。
purchase[2,1] == "b"
attach()
すると変数名を直接呼べるようになる。detach()
で解放される。attach()
はデータフレームの中身を新しい環境にコピーしている。元のオブジェクトを書き換える際には、attach()
していようがいいがデータフレーム名から呼ぶこと。attach()
はまちがいのもと、つかわないほうがよい- カテゴリカル変数はfactor型として表現される。factorはatomicな型ではなく、
factor()
で生成されるオブジェクト
リストの操作
stack()
: リスト要素がすべてベクトルであるとき、それをすべて縦に結合した列と、タグ名を縦に結合した列の2列からなるデータフレームをつくる。例)stack(list(x=1:3, y=4:6, z=7:9))
データフレームの操作
- データフレームの例:
purchase <- data.frame(
product = c("apple", "cheese", "yogurt", "ham", "water"),
shop = c("drink", "daily", "daily", "meat", "drink"),
amount = c(2,3,1,5,6)
) - ソート:
order()
は順位ベクトルを返すので、purchase[order(purchase$amount) , ]
でソートしたことになる (なるほどー) - 行抽出(SASでいうサブセットif)
purchase[["shop"]] == "daily"
はベクトル(FALSE, TRUE, TRUE, FALSE, FALSE)を返すから、purchase[purchase[["shop"]] == "daily" , ]
とすればよいsubset(purchase, shop == "daily")
でもよい。subset()
は条件がNAになったときにfalse扱いしてくれる%in%
演算子をつかってベクトルと比較してもよい。subset(purchase, shop %in% c("daily","meat"))
- 分割 (SASでいう when ... output ...):
LD <- split(purchase, purchase$shop)
。LDは3つのデータフレームからなるリストになる。要素はLD$drink, LD$daily, LD$meat
となる - 縦に結合 (SASでいうset A B):
rbind(LD$drink, LD$daily)
- 横に結合 (SASでいう byなしのmerge):
cbind(1:3,11:13)
。ただし長さが同じでないといけない - マッチマージ (SASでいうby文つきのmerge):
merge(X, Y [, オプション])
- マッチキーの指定
- 指定しないと名前が共通する列すべてがマッチキーになる (SQLでいう natural join)
by=(ベクトル)
... マッチキーを指定するby.X=(ベクトル), by.Y=(ベクトル)
... データフレーム別にマッチキーを指定する- 長さ0のベクトルを指定するとデカルト積になる(SQLの cross join)
- マッチキーによる事前のソートは不要 (そりゃ助かるね)
- マージの種類の指定
all = FALSE
... マッチした行だけ (SQLの inner join)all.X = TRUE
... Xは全行、Yはマッチした行だけ (SQLの left join)all.Y = TRUE
... Xはマッチした行だけ、Yは全行 (SQLの right join)all = TRUE
... マッチしようがしまいが全行 (SQLの full join)
データの集約(スペクター本の8章)
table(X)
- Xはベクトル、リスト、データフレーム
X
にはいっているユニークな行ごとに、その行数を数えるX
に入っているベクトルの数の次元数の配列を返す。例, 3本なら3次元配列- 各次元には名前がつく。それはデータベクトルに出現する水準
exclude=NULL
引数で欠損値を含むことができるas.data.frame()
に渡すと便利addmargins()
に渡すと、各次元につきSum行を追加してくれるprop.table()
に渡すと、割合の表に変換してくれる
xtabs(formula, data=X)
: formulaの左辺はなし、ないし頻度ウェイトftable(X)
※本項は間瀬本p.181X
はふつうtable()
なりxtabs()
なりの出力X
を二次元の表にして返すrow.vars = 1:3
で、1,2,3次元が表側、残りが表頭になるwrite.ftable()
に渡すときれいなascii形式にしてくれる。いいんだかわるいんだか
- 集約のためのヒント
- グループがすでにリストの要素に分けられている → sapply, lapply
- グループが行列の行or列である → apply
- グループが一つ以上のグループ化変数で示されている
- 操作対象が単一のベクトル
- 結果はグループごとのスカラー → aggregate
- 結果はベクトル → tapply
- 操作対象が複数のベクトル → tapply, by
- 操作対象が単一のベクトル
lapply(X, FUN)
ないしsapply(X, FUN)
- ふつうXはリスト。各要素に
FUN
を適用する。例)x <- strsplit(c("Hello world", "How do you do")," ")
。length(x)
は 2 を返す。sapply(x, length)
は c(2,4)を返す - lapplyは常にリストを、sapplyは(もし可能なら)ベクトルないし行列を返す
- Xがデータフレームの場合、各列にFUNを適用する
- ふつうXはリスト。各要素に
apply(X, MARGIN, FUN)
- 配列
X
の次元MARGIN
にFUN
を適用する - 結果はベクトルないし行列
- よく使う
FUN
についてはすでに関数が用意してあるので探すこと。rowSums(), colSums(), rowMeans(), colMeans()
, etc. - sweep(X, MARGIN, STAT, FUN)のSTATに渡す。例) 列ごとに最大値を出し, 値をその列の最大値で割る:
Y <- sweep(X, 2, apply(X, 2, max) , "/")
- 配列
aggregate(X, BY, FUN)
- ふつう
X
はデータフレーム。X
の全列 についてBY
ごとにFUN
を適用 BY
はグループ分け変数のリストでなければならない。X$byvar1
なんていうのはだめ。X[c("byvar1","byvar2")]
ないしlist(v1 = X$byvar1, v2=X$byvar2)
とする。BY
の値の組み合わせ数ぶんの行を持つデータフレームを返す。BY
にNAを持っている行は無視される!
- ふつう
tapply(X, INDEX, FUN)
- ベクトル
X
について、INDEX
の値ごとにFUN
を適用 FUN
がスカラーを返したら、名前付きベクトルないし行列を返す。as.data.frame(as.table(), responseName="xxx")
に渡すとよい。responseName
を指定しないと、結果がFreqという列になってしまうFUN
がベクトルを返したら、名前付きリストを返す- 例1) INDEXがひとつ
ranges <- tapply(PlantGrowth$weight, PlantGrowth$group, range)
# 下の行でcbindとするとresultは行列になり全要素が文字列に強制変換される
result <- data.frame(
group = dimnames(ranges)[[1]],
matrix (unlist(ranges), ncol=2, byrow=TRUE) #ベクトルの長さが2だとわかってる
) - 例2) INDEXが複数
ranges = tapply(CO2$uptake, CO2[c("Type","Treatment")], range)
# rangesは2x2のmatrixで、その要素が名前なしのリストで、
# リストの要素が長さ2のベクトル。悪夢だ
result <- data.frame(
expand.grid(dimnames(ranges)),
matrix(unlist(ranges),byrow=TRUE,ncol=2)
) - FUNを指定しないと、指定したときに生成されるであろうベクトル(行列, リスト)の添え字を返す
# 中央値を格納する2x2行列。
meds <- tapply(CO2$uptake, CO2[c("Type","Treatment")], median)
# 行数ぶんのベクトル。tapplyが生成する行列の添え字を格納している。
# ここでは(1,1,1,...,3,3,3,....,2,2,2,...,1,1,1...) となる。
inds <- tapply(CO2$uptake, CO2[c("Type","Treatment")])
# それぞれの値から、そのセルの中央値を引くのは
adj.uptake <- CO2$uptake - meds[inds]
# この例は、ave()にFUNを指定しても同じことができる
adj.uptake <- CO2$uptake - ave(CO2$uptake, CO2$Type, CO2$Treatment, FUN=median
- 例1) INDEXがひとつ
- ベクトル
split(X, F)
- データフレーム
X
を、因子(のリスト)F
で分割し リストにして返す - 例) iris データセットの"Species" ごとに、残りの変数の相関行列の第一固有値を求める
# もし全体についてだったら
# eigen(cor(iris[setdiff(colnames(iris),"Species")]))$values[1]
frames <- split(iris[setdiff(colnames(iris),"Species")], iris$Species)
maxeig <- function(df) eigen(cor(df))$value1[1]
sapply(frames, maxeig) split()
のかわりに行番号をtapply()
に与える手もある。 例) iris データセットの"Species" ごとに、残りの変数の相関行列の第一固有値を求める# 話を簡単にするために、"Species"は5列目だとわかっているとしよう
# もし全体についてだったら eigen(cor(iris[-5]))$values[1]
# いま仮に行番号のベクトルがindであるとすると eigen(cor(iris[ind,-5]))$values[1]
maxeig <- function(ind, data) eigen(cor(data[ind,-5]))$values[1]
tapply(1:nrow(iris), iris[5], maxeig, data=iris)
- データフレーム
by(X, INDEX, FUN)
- データフレーム
X
について、INDEX
の値ごとにFUN
を適用 - 名前付きリストを返す
FUN
がデータフレームを返すようにすると便利- 例)
CO2$uptake
の観測数、平均値、標準偏差からなるデータフレームをつくるsumfun <- function(x) {
data.frame(n=length(x$uptake), mean=mean(x$uptake), sd=sd(x$uptake))
}
bb <- by(CO2, CO2[c("Type", "Treatment")], sumfun)
cbind(
expand.grid(dimnames(bb)), # リストbbのグループ因子をデータフレームに展開
do.call (rbind, bb) # rbindにリストbbを与え、要素ごとに処理させている。つまり縦結合
)
- データフレーム
雑記:データ解析 - 覚え書き: 私のRチートシート in 2011年4月
2019年8月 5日 (月)
知人と世間話していて、そういえば最近「なんなら」という言葉の使い方が変わってきていると思うんだけど... という話になった。うまくいえないんだけど、「もしお望みなら」というような意味合いじゃなくて、なんというか、「あえて強い言い方をすれば」というような意味で使ったりしない?と。
世情にまるきり疎いわけじゃないのよ、ごらん俺のこの鋭いアンテナを、とちょっぴり誇るような気持ちもあったんだけど、さきほど検索してみたら、「なんなら」の意味の変化はとっくに話題になっているようで、NHK放送文化研究所が先月付でコラムを公開しているのを発見した。なあんだ、気がついているのは俺だけじゃなかったのか。そりゃそうだよな。
島田泰子 (2018) 副詞「なんなら」の新用法 -なんなら論文一本書けるくらい違う-. 二松学舎大学論集, 61, 1-23.
上のコラムに載っていた紀要論文。
著者によれば、「なんなら」の従来の用例は次の5つに分類できる。
- a.申し出 (なんなら~しようか)
- b.示唆・提案 (なんなら~したらどうだ)
- c.依頼・注文 (なんなら~してくれ)
- d.妥協点の提示 (なんなら~でもいい)
- e.願望 (なんなら~たい)
で、著者の分析によれば、
I. 何(あなたの意向)が何(OK)なら
II. 何(状況的な前提)が何(許す)なら
という条件節的構造の前半を省略し、後半を「何」に置き換えて、行為への言及を和らげ聞き手の意向への尊重を含意するのが、「なんなら」の旧来の意味用法だ、とのこと。動作主が話し手ならa, 聞き手ならbかcになり、aとcの両方にまたがるのがd。eは後述する新用法の萌芽的観察ではないか、とのこと。へー。
いっぽう新用例として、著者は収集した28個の用例を示す。たとえばつばきファクトリー(アイドルグループとかかな?)の歌詞「なんなら歴史変えちまうくらいのセンセーションを起こそう」。そうそう!それそれ!こういう使い方、最近見かけますよね!
著者の分析によれば、新用法は次の3つの意味の組み合わせとして理解できる由:
- (ア) なお言えば(ついでにいうと)、あえて言うなら(言わせてもらえば)
- (イ) ややもすれば、ともすると
- (ウ) 下手すると、放っておくと、油断すると
(ア)は(事態ではなくて)話し手の言表態度に関わる用法、(イ)は事態に関わる叙述の累加、(ウ)は時間の進行に従った事態のエスカレート、をそれぞれ示している。旧用法とちがい、必ずしも配慮表現ではない。
なるほどねー。学んだところで実生活上で良いことは特にないけれど、ちょっとすっきりいたしました。学問の徳といえよう。
なお、手元の広辞苑第七版によれば(せっかく買ったんだから使わなきゃ...)
なん・なら【何なら】(副詞的に)①事によったら、都合次第では。膝栗毛「-少々は銭を出しても乗るこたアいやだ」②お望みなら。入用なら。「-お持ち帰り下さい」③気に入らなければ。わるければ。浮世風呂「大束が-この下に小束もありやす」「この品が-、別のもあります」
とのこと。①の用法がぴんとこないなあ...
論文:その他 - 読了:島田(2018) 最近の「なんなら」
2019年8月 3日 (土)
近藤博之(2011) 社会空間の構造と相同性仮説-日本のデータによるブルデュー理論の検証-. 理論と方法. 26(1), 161-177.
これも仕事の都合で読んだ奴。あとで気が付いたけど、著者は前に読んだ近藤(2014)というのと同じ人だ。
えーと、本論文の目的は、ブルデュー「ディスタンクシオン」のモデルが現在の日本社会にどこまで通用するかを検討することなのだそうであります。なお相同性仮説というのは、経済・社会関係・文化資本の総量と構成でもって世帯(?)をわけたとき、その分化が日用生活における慣習行動のちがいと対応していることをいうらしい。それって「ハビトゥスというものがあるんだよ」仮説と同じことだという理解でよろしいんでしょうか?
SSM2005データを分析する。ざっと目を通しただけだけど、分析の方法としては、文化資本・経済資本を表す項目群についてMCAの布置をクラスタ分析し、結構強気に読み込んでいくのでありました。へええ。
論文:教育 - 読了:近藤(2011) 「ディスタンクシオン」でやってた分析を日本でもやってみた
古田和久(2018) 出身階層の資本構造と高校生の進路選択. 社会学評論, 69(1), 21-36.
仕事の都合で読んだ。
進路選択の実証研究なんだけど、効いてる変数がなにか重回帰に叩き込んで調べましょうというタイプの論文とはちょっと違っていて、経済資本・文化資本・社会関係資本からなる多次元的社会階層を想定する。そうですブルデューです。ひいいい...
データは2012年のネット調査で、対照は全国の高2とその母親、801ペア。ひとり親家庭は除外。[へえ、ネットパネルってありなんだ。こういう方面の方々は標本にこだわるもんかと思ってた...]
社会階層の変数は、両親の職業・学歴、世帯年収、預貯金、文化的所有財。[あれれ?社会関係資本はどこに行っちゃったの?]
共変量は、生徒の性別、母親年齢[あれ?父親は?]、学校タイプ(普通科かどうかと偏差値の高低)。
目的変数は高校生と母親それぞれの進路希望(多項選択)。
ブルデューだからMCAをやるのがお約束だろうと思ってたのだが、この論文では社会階層の変数でLCAをかける。これには先行研究があるんだそうで、Savege, Martinという人が挙げられている。へー。
BICであたりをつけて、クラスのサイズと解釈をみて5クラス解を選択。市場調査会社のリサーチャーなみに結構強気な深読みをしてて、ちょっと心配になっちゃったけど、(1)経済・文化資本の両方が豊富なクラス、(2)文化資本が優勢なクラス、(3)中間、(4)経済資本が優勢なクラス、(5)両方が少ないクラス、となった由。
で、潜在クラスと進路希望のクロスをとったところ、(1)(2)のあいだで進路希望は似ていて、(2)と(3)の間で(2)の大学進学率が高かった。つまり文化資本があれば経済資本はあんまし効かない。云々。
共変量をいれる。目的変数として進路希望を追加教育年数に変換した値を使い、子供の希望と親の希望それぞれについて重回帰[まじか? なぜ多項選択モデルを使わない...なぜ目的変数を多変量にして一発でモデリングしない...]。子供の性別、母親年齢はもちろん、学校タイプをコントロールしても社会階層はなお効いた由。[面白いっすね。でもそれって、単に学校タイプのカテゴリが粗いからじゃないの?]
というわけで、家族の階層は多次元的だった[いわく「資本構成によっても分化している」。この分野に独特な言い回しだ]。進路希望は資本総量だけでなく資本構成によっても差があった。大学進学希望においては文化資本のほうが相対的に効く。云々。
正直、分析アプローチはかなり不思議な感じだったけど、それは私がこの分野に疎いからでありましょう... 勉強になりましたですー。