Julia 入門07 -- R と比較して（回帰分析のグラフのプロット）

以下は，R 入門のために書かれた

https://ai-trend.jp/programming/r-beginner/r-beginner/

を，Julia ではこんな風になるよということで書いたものである。

R の入門というページは多く存在する。

R に入門しようとしている人 ... Julia にしませんか？

---


# 回帰分析のグラフのプロット

直線回帰分析を行った後で，撒布図および回帰直線を描く。

Julia はプロットを行うバックエンドが複数あるが，今回はデフォルトのバックエンドを使う。

いつものように，プロットのためのパッケージを使用するためのおまじないをしておく。[^1]

ついでに，GLM, DataFrames も。

[^1]: 最初は準備に時間がかかるので，がまんして待つ。


```julia
using Plots, GLM, DataFrames
```

テストデータをデータフレームで用意する。[^3]

[^3]: めんどくさそうに定義している（相関があるようなデータ）が，普通に x, y を用意すればよい。


```julia
generate(n=50; v=10) = vec(sum(hcat(randn(50, 10), w), dims=2))
w = randn(50, 10)
x = generate()
y = generate()
df = DataFrame(x=x, y=y);
```

散布図を描く関数は `scatter()` である。散布図の横軸，縦軸の変数を指定するだけで，他には何も指定する必要はない。


```julia
scatter(df.x, df.y) # , label="original data", legend=:bottomright)
```

さすがに殺風景なので，オプションを付け加えてみる。以下では行を分けて書いているが，改行する必要はない。<br>
多くのオプションがあるので，詳しくは https://docs.juliaplots.org/latest/generated/attributes_plot/ を参照するとよい。

```julia
scatter(df.x, df.y,
    markercolor=:red,       # マーカーの色　:blue, :black など，大抵の色は英単語で指定できる
    markerstrokewidth=0,    # マーカーの縁取り線（書きたくないので 0 を指定する）
    markerstrokecolor=:red, # マーカーの縁取り線（マーカーの色と同じにする）
    label="original data",  # 描画要素のラベル
    legend=:bottomright,    # ラベルの描画位置　:top, :bottomo, :right, :left およびそれらの結合
    xlabel="variable x",    # x 軸の名前
    ylabel="variable y",    # y 軸の名前
    title="Scattergram and regression line", # 図のタイトル
    )
```



タイトルは描いたが，まだ回帰直線を描いていない。

Julia の Plot は，現在の図に新しい要素を描き加えるようにして図を作成していく。<br>
2 点 (x1, y1) と (x2, y2) を通る回帰直線は `plot([x1, x2], [y1, y2])` で描くことができるが，描き加えるということを示すために `plot()` ではなく `plot!()` を使う。

まずは回帰直線の傾きと切片を求めよう。


```julia
results = lm(@formula(y ~ x), df)
```




    StatsModels.DataFrameRegressionModel{LinearModel{LmResp{Vector{Float64}}, DensePredChol{Float64, LinearAlgebra.Cholesky{Float64, Matrix{Float64}}}}, Matrix{Float64}}
    
    Formula: y ~ 1 + x
    
    Coefficients:
    ────────────────────────────────────────────────────
                 Estimate  Std.Error   t value  Pr(>|t|)
    ────────────────────────────────────────────────────
    (Intercept)  0.210274   0.624497  0.336709    0.7378
    x            0.660628   0.138615  4.76592     <1e-04
    ────────────────────────────────────────────────────




```julia
intercept, slope = coef(results);
predict(x) = intercept + slope * x # 予測値を求める関数を定義する
```




    predict (generic function with 1 method)



`x` の最小値と最大値を x1, x2 として，そのときの y1, y2 を求める


```julia
x1, x2 = extrema(x) # 最大値と最小値を求める関数
y1, y2 = predict.([x1, x2]);
```




    2-element Vector{Float64}:
     -8.973245906714823
      6.5966509759227945



いよいよ回帰直線を描く。


```julia
plot!([x1, x2], [y1, y2],
    color=:blue,
    label="regression line")
```



実は，`scatter()` には回帰直線を描くオプションがある。`smooth=true` を指定してやればよい。[^2]

[^2]: 第1，第2引数は x 座標ベクトル，y 座標ベクトルであるが，3 番目以降のオプションは順不同で指定できる。


```julia
scatter(df.x, df.y,
    markercolor=:red,　markerstrokewidth=0,
    label="original data", legend=:bottomright,
    xlabel="variable x", ylabel="variable y", 
    title="Scattergram and regression line",
    smooth=true, color=:brown)
```




回帰直線の傾きと切片を図中に描くこともできる。この場合も，「図に追加する」ので `annotate()` ではなく `annotate!` を使う点に留意する。<br>
`text()` の第1引数は文字列，第2引数以降は，文字色，アラインメント，フォントサイズなどを順不同で指定できる。


```julia
annotate!(-10, 5, text("slope: $(round(slope, digits=5))\nintercept: $(round(intercept, digits=5))", :blue, :left, 8))
```![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653782/7990fa32-00ea-420d-94ca-b0b0a1361f7b.png)




描画した結果をファイルに保存するには `savefig()` を使う。<br>
ファイル形式は保存ファイル名の拡張子で自動的に決まる。`.png` か `.pdf` か `.svg` が望ましい。


```julia
savefig("fig.png")
savefig("fig.pdf")
savefig("fig.svg")
```

一連の描画手順を関数としてまとめておくと，簡単な関数呼び出しでいつも自分の好みのグラフを描くことができる。
![fig.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1653782/97a76793-5e1b-2fcb-e570-5d1987b19222.png)