[[ノート/ノート]]~
[[ノート/R]]~
訪問者数 &counter();      最終更新 &lastmod();

*RとPythonを行き来する (2014-07-31) [#j44c3a1d]

元はといえば、[[Rで相関行列を求めたい>Rで相関行列]] なのだが、入力データを整形するのに、Pythonの方が慣れていそう、という理由。

整形が必要な理由は、文字データが含まれたフィールドがあると、関数corがエラーを返すから。
 >>> x <- read.csv("s.csv")
 >>> > cor(x)
   以下にエラー cor(x) : 'x' は数値でなければなりません

今対象とするデータには、たとえば学部の欄に「理学部」と書かれたり、選択肢A/Bに対して文字「A」や「B」が書かれているので、こういうところがエラーになるのだろう。これらの部分は、corを用いるには適当なる整形を必要とする(特にA/Bのフィールドなど)。

>参考にしたサイト
-[[バイオスタティスティクス基礎論第1回講義テキスト:http://lecture.ecc.u-tokyo.ac.jp/~aiwata/biostat_basic/text4lec1.pdf]](11ページ付近)
-[[統計ソフトRについて、wilcox.testで「Xは数値でなければなりません」と表示され...:http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q14103203824]]


整形の手段は、
-もちろん、Rのコードを書いて整形してもいいし(まあ大したことはなさそう)
-Pythonなどで整形してから一旦CSVファイルに出力して、それをRで読んでもいいし、
-相関行列をPythonで計算してもいいし、
なのである。ただ手を抜きたいだけ。 というか、連携を試してみたいだけ。

**Pythonに、PypeR(連携インタフェースパッケージ)と、更に同時に Pandas(データ解析用パッケージ)を導入する。 [#v3487b8c]

>参考にしたサイト
-[[Python と R で連携する:http://qiita.com/ynakayama/items/f84dc659f1337d71dd9e]]~
-[[データ分析ライブラリPandasの使い方:http://librabuch.jp/2013/12/pandas_python_advent_calendar_2013/]]

いずれも、
 pip install <パッケージ名>       <パッケージ名>はpyperとpandas
で終り。但し、pyperは大した処理をしないのに比べて、pandasはコンパイルをするので警告メッセージが出たりした。


**Pandasのread_csvを使う [#p60cc4bc]
>参考書 [[Pythonによるデータ分析入門:http://www.amazon.co.jp/Python%E3%81%AB%E3%82%88%E3%82%8B%E3%83%87%E3%83%BC%E3%82%BF%E5%88%86%E6%9E%90%E5%85%A5%E9%96%80-%E2%80%95NumPy%E3%80%81pandas%E3%82%92%E4%BD%BF%E3%81%A3%E3%81%9F%E3%83%87%E3%83%BC%E3%82%BF%E5%87%A6%E7%90%86-Wes-McKinney/dp/4873116554]]

>参考ページ
-[[pandasメモ:http://qiita.com/airtoxin/items/d66a22c5c7074e23be17#2-1]]
-[[pandas + matplotlib による多彩なデータプロッティング:http://qiita.com/ynakayama/items/68eff3cb146181329b48]]
-[[5. 【pandas】関連:http://oceanmarine.sakura.ne.jp/sphinx/group/group_pandas.html]]
-[[Pythonデータ解析ライブラリpandasと遊ぶ:クロス集計〜検定・残差分析まで:http://web-analytics-or-die.org/2013/07/pandas/]]
-[[大元のドキュメント:http://pandas.pydata.org/pandas-docs/stable/dsintro.html]]

Pandasのread_csvを使ってみる
 >>> import pandas
 >>> x = pandas.read_csv('s.csv')

要素の取り出し

xに対してixを使い、要素のインデックスで指定。二次元なので
 print x.ix[1:, 0:2]
   基本情報 Unnamed: 1
 1  NaN        NaN
 2   10    4432341
 3   10    4432131
 4   10    4434780
 5   10    4432094
 6   10    4432072
 7   10    4432352
 8   10    4432083

範囲指定は、普通はコロンを使うが、複数範囲を結合することはそのままでは出来ない。
それで、rangeジェネレータとリストの'+'演算を使って、こんなことをやってみる。
 print x.ix[:, range(0,2)+range(7,12)]
    基本情報 Unnamed: 1 Unnamed: 7 Unnamed: 8 Unnamed: 9 Unnamed: 10 Unnamed: 11
 0  検査ID     回答用紙番号      学部コード      学科コード      漢字大学名       漢字学部名       漢字学科名
 1   NaN        NaN        NaN        NaN        NaN         NaN         NaN
 2    10    4432341         51        523         東邦           理           化学
 3    10    4432131         51        523         東邦           理          化学
 4    10    4434780         51        523         東邦           理          化学
 5    10    4432094         51        523         東邦           理          化学
 6    10    4432072         51        523         東邦           理          化学
 7    10    4432352         51        523         東邦           理          化学
 8    10    4432083         51        523         東邦           理          化学

よしこれで、不要の欄は削ることができる。

**表のデータの書き換えをする [#ad046cd9]

表中に、2択の設問でA/Bで答えさせているものがあるが、相関行列を求める際に「文字だとダメ」というルールがあるので、表のその部分の解答結果をA->1、B->0に置き換える。

(失敗した方法)Pythonのmapを使ってみる。

 >>> def ab(v):
 ...     if v=='A':
 ...         return 1
 ...     if v=='B':
 ...         return 0
 ...     return v
 ...
 >>> list = [1, 3, 'A', 'A', 'B', 4, 2]
 
 >>> map(ab, list)
 [1, 3, 1, 1, 0, 4, 2]
のようにしてみる。

ところが、Pandasで読み込んだcsvはデータフレームで、リストではないので、
うまく関数を適用するが(つまり入力側はリストに変換しているらしい)、
出力結果はフレームになっていない。リストになる。

(「カテゴリカルデータをダミー変数化」という方法)~
>参照 > [[カテゴリカルデータをダミー変数化:http://qiita.com/airtoxin/items/d66a22c5c7074e23be17#2-12]]

get_dummies()は、A/Bで表しているような「カテゴリカルデータ(統計学を参照)」を、0/1に変換してくれる機能。
 >>> import pandas
 >>> x = pandas.read_csv('s.csv')
 >>> x.ix[2:,99]    初めに中身を見ておくと
 2                   B
 3                   A
 4                   B
 5                   B
 6                   B
 7                   A
 8                   A
 Name: Unnamed: 99, dtype: object
 
 >>> u = pandas.get_dummies(x.ix[2:,99])  これに対してget_dummiesをすると
 >>> u
    A  B
 2  0  1
 3  1  0
 4  0  1
 5  0  1
 6  0  1
 7  1  0
 8  1  0
つまり、2列分のデータを生成し、Aの列には(Aなら1、そうでなければ0)、Bの列には(Bなら1、そうでなければ0)を設定するらしい。

これの良い点はpandasのフレームを扱っている中でできること。欠点は、元の列を置き換えてくれるわけではないので、生成結果を元のフレームに追加し、形を整える必要がある(元のA/Bを書いた列を消して、その代わりにたとえばAの列を埋めるとか)。相手がフレームなので、扱いに慣れていない。

(これならいいだろう方法)~
いろいろ考えるのも面倒になったので、csvファイルの段階で変換してしまう。csvなら文字列として読んで書き換えをし、結果を書き出せば、まあ性は知れているだろう。

最大の手抜きは、csvファイルのすべてについて、Aなら0、Bなら1と置き換えること。この欠点は、たとえばタイトル行にAとかが入っていると書き換えられてしまう。理想的には、タイトル行を除いて処理すべき。データ中にももし他の欄でAを含むカテゴリカルデータがあると(たとえば、すきな果物は? Apples/Oranges/Bananas/Grapes)、Aだけを書き直してしまうだろう。

幸い、対象のデータではこのような問題はない。どうしても気になるなら、CSVをきちんと理解して(つまりエントリー要素に分けて)、単独のAからなるエントリーを1に変換する、とすれば、Applesを1pplesに変換しない。

***その他の入力準備 [#v6153216]
漢字コードは、CSVファイルの状態でnkfなどを使って変換してしまうのが楽だ。~
  [[nkfの引数:http://itpro.nikkeibp.co.jp/article/COLUMN/20060227/230849/]]

***相関行列計算と、それをCSV形式で出力すること [#bb4f0a40]
pandasでは、corrによって相関行列を求めることができる。

>[[相関係数を出すには:http://oceanmarine.sakura.ne.jp/sphinx/group/group_pandas.html#id33]]

 print x.corr()

pandasでは、その出力(フレームになっている)をCSVで吐き出すことができる。

>[[pandas.DataFrame.to_csv:http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html?highlight=csv#pandas.DataFrame.to_csv]]~
いろいろと指定できるが、あまり凝ることもない。

 (x.corr()).to_csv('output.csv')

printで吐き出すと、後で使うのにあまり具合が良くないので、CSVにした。

***おまけ CSVをExcelに取り込んだ後、相関係数が大きいところ、小さいところをマークしておく [#ud791340]

Excelの「条件付き書式」をつかう。[[条件付き書式(基本編):http://www.becoolusers.com/excel/conditional-formatting.html]]

「条件付き書式」から、「セルの強調表示ルール」を選び、そのうちの
-指定の値より大きい
-指定の値より小さい
-指定の範囲内
を使い分ければよい。たとえば相関係数が0.7以上を赤地赤文字、0.4〜0.7を赤文字のみ、-0.4〜-0.7を青文字のみ、-0.7以下を青地青文字、などできる。


トップ   編集 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS