amyu返信TweetPocket前から言っているように仕事の業務で、重回帰分析を用いた解析を行っているのですが、ときどき予測値がありえない値になってしまうことがあります。具体的にいうと、マイナスの値にはならないのに、予測値がマイナスの数値をだしてしまうということです。上からマイナスの場合は特定の値、例えば0にするようにということでした(実際にはもっと複雑なことを言われたのですが、ここでは単純に0とします)。み決定係数はsummary関数で求めているわけですが、予測値を変更するとなると自分で求めなければいけません。み決定係数の求め方について勉強したことを書いていこうと思います。使うデータは相変わらず、下記のニコニコ動画から取得したデータ。nicoまずは、前準備。382100データを取得して、解析しました。普段、コメント数とマイリスト数から再生数を予測するような解析をしていますが、今回はコメント数と再生数からマイリスト数を予測する解析をしていくことにします。決定係数は0.6638783、自由度調整済み決定係数は0.6638036となりました。予測値をsummary関数でみてみると、どうやら値の低い予測値はマイナスの値になっているようです。Wikipedia決定係数と自由度調整済み決定係数の求め方は、上記Wikipediaのページに書いてあります。これを参考に算出してみることに。1から、『残差二乗和』から『実測値と実測値の平均の二乗の和』を割った値を引いたものが決定係数らしい。残差と実測値の平均を求めることができたら簡単に計算できそうなので下記のようにやってみました。0.66387830.6638783とでました。この計算方法であっているようです。み決定係数の求め方も先ほど記したWikipediaのページに書いてあります。見何をやっているのかよく分かりませんので、もう少し整理してみます。ここで仮に説明変数の数をp、標本数の数をn、決定係数をR2とすると、自由度調整済み決定係数は下記のようになります。R((n-1)*R2-p)/(n-1-p)1((n-1)*R2-p)/(n-1-p)というわけで、自由度調整済み決定係数も求めてみます。説明変数の数はlmオブジェクトのrankというラベルから1を引いたものにあたり、標本数はnrow関数で取得できるので、以下のようにすると自由度調整済み決定係数も求められます。0.6638036というわけで、自由度調整済み決定係数も求めることができました。試しに、予測値がマイナスになっているものは0にして決定係数を求めてみようと思います。予測値がマイナスになっているものは0にしたベクトルを作成。382100つづいて、実測値と上記で作成した予測値の二つを含んだデータフレームを作成。72099.155番目の予測値がおかしい気がしますが、他はまああってそうです。決定係数を求めてみることに。0.664791決定係数は0.664791となり、少し増えました。み決定係数も求めると下記のようになりました。0.6647165もちろん、自由度調整済み決定係数も増えています。これは、自由度調整済み決定係数といってしまっていいのかという疑問はありますが・・・。実は、重回帰分析のやり方についてもlm関数を使わないでできないものかと勉強がてら調べてみたのですが、まだちょっとよく分かってません。仕組みをもっと分かるようになれば、何か新しい発見がある気もするのだけれども・・・。amyu返信TweetPocketRを使ってきて発見した小ネタを3つ紹介。したらもっといいやり方があるかもしれませんが、知っていたら教えて頂けると助かります。利用するデータはいつもの以下のニコニコ動画から取得したデータです。以上の水準を持つ因子にしか適用できません”というエラーが表示されることがありました。原因は単純で、質的変数(カテゴリー変数)として利用しようとしていた変数が、1つの値しかもっていないというのが原因だったようです(1だけしかないとか0だけしかないなど、数値のみの場合はこのようなエラーはでませんでした)。以下は、カテゴリーがVOCALOIDのデータのみを抜き出し、それを再生数を目的変数として、コメント数とマイリスト数とカテゴリを説明変数としようとして得られた結果です。以上の水準を持つ因子にしか適用できませんこの例の場合だと、質的変数はカテゴリーだけなので、これが原因ということは分かるのですが、質的変数が複数あった場合にいったいどれがエラーの原因になっているのか、判断できません。調べてみるとfactorという関数でカテゴリーを要素としたベクトルを作成することができると分かり、さらにlevels関数でグループ化された値のみ取得できるということがわかりました(参考:R-Source)。それを参考に作ったのが以下。"category"変数が一種類しかない列があればその列名を表示するOnlyVariablePrintという関数を作成し、カテゴリーにVOCALOIDしか入ってないデータフレームを引数にいれると、”category”という出力が得られました。やっていることは、”length(levels(factor(table[,names(table)[VarCount]])))”という箇所で、変数が何種類あるかどうか取得し、その後1つであればprint関数で名前を表示するという動きをしています。モデル式から特定の変数を除外する職場で扱っているデータは、かなりの数の変数が用意できるのですが、その中からできるかぎり精度の高い組み合わせというものを見つけなければいけません。自分は、t値をみていって最も絶対値が小さいものを除外し、そのモデル式で再度重回帰分析をして評価し、先ほどより自由度調整済み決定係数が高ければ再度t値が最も小さいものを除外して再度重回帰分析を行い、先ほどより自由度調整済み決定係数が小さければ先ほど重回帰分析を行ったモデル式が最も精度が高いと判断するようなアルゴリズムを作成しました(調べてもその方法が正しいのかどうか怪しいところなのですが、今のところ、これで問題なさそうです)。この時、モデル式から変数を除外するという作業を行わなければいけないわけですが、最初これをどうやればいいのか分かりませんでした。そこで、ふと、モデル式って文字列にしてみてもうまくいくのだろうかと思い、試してみるとできたのでなんとか解決することができました。"view~comment"上記のReduceFormulaは、引数のモデル式から指定された変数を除外したモデル式を返す関数です。今回の例では、commentとmylistを説明変数としたモデル式を作成し、commentかmylistのみを説明変数から削除するといったことを行っています。subという関数が正規表現でテキストを置換する関数です(最初に見つけた一つのみです)。前方一致の可能性があるため、除外しようとしていた変数が”~”の後につく変数だった場合、”+”の後につく変数かどうかの判断はしないようにしています(最初、if文をいれていないプログラムを書いてしまったことで、大変なことになりました)。”+”を”[+]”としているのは正規表現で判断しているためです。最初、”+”としていてうまくいかないので困りはてました。sep="")』の2パターン用意したほうがいいとは思うのですが・・・。正規表現が得意な人だともっと簡潔に書けるかもしれません。while(isプログラマ))。この時、最初から変数同士を掛けあわせた変数を用意しておくといい、なぜなら交互作用項のみの重回帰分析はできないようだから。書いてしましましたが、すみません。