2019年1月31日: SKILL、マップ系関数のまとめ

# 2019年1月31日: SKILL、マップ系関数のまとめ

2019年1月31日 11時38分

<p>SKILL にあるマップ系の関数の特徴をまとめてみた。というかこれまで <code>mapcar</code> しか使ったことがなかったけど。</p>

<h2>マップ系関数</h2>
<table>
<tr>
<th rowspan="2" colspan="2">
</th>
<th colspan="2">ユーザー関数に与えられる値</th>
<th rowspan="2">戻り値</th>
<th rowspan="2">備考
</th>
</tr>
<tr>
<th>要素</th>
<th>リスト
</th>
</tr>
<tr>
<th rowspan="3">ユーザー関数が返すべき値
</th>
<th>有効な値であれば何でもよい</th>
<td><code>mapcar</code></td>
<td><code>maplist</code></td>
<td>ユーザ関数が返した値を要素とするリスト</td>
<td>
</td>
</tr>
<tr>
<th>リスト</th>
<td><code>mapcan</code></td>
<td><code>mapcon</code></td>
<td>ユーザー関数が返したリストを連結したもの</td>
<td>
<ul><li>
<code>(concatenate (mapcar ...))</code> とか <code>(concatenate (maplist ...))</code> と等価だけど、それらを最適化したもの。</li></ul>
</td>
</tr>
<tr>
<th>値を返さなくてもよいし返してもよい</th>
<td><code>mapc</code></td>
<td><code>map</code></td>
<td>第2引数で与えられたリスト</td>
<td>
<ul>
<li>値を生成するための
ものではないから、関数というよりも手続き。</li>
<li>特殊フォーム<code>foreach</code> の拡張版のようなもの。<code>foreach</code> と違って複数のリストを受容できる。</li>
<li>戻り値のリストを生成しない分だけ <code>mapcar</code> とか <code>maplist</code> よりも効率が良い。</li>
</ul>
</td>
</tr>
</table>

<h2>他に</h2>

<p>この他に <code>mapinto</code> という関数がある。</p>

<p><code>(mapinto <var>dst</var> <var>function</var> <var>src1</var> <var>src2</var> …)</code></p>

<p>という形で使う。リスト <code><var>src1</var></code>、リスト <code><var>src2</var></code>、… のそれぞれの要素を <code><var>function</var></code> に適用した結果をリスト <code><var>dst</var></code> の対応する位置に破壊的に代入して、<code><var>dst</var></code> を返すんだ。与えるリストの長さは違っていてもいい。一番短いリストの長さまでしか代入されない。</p>

<p>等価のコードはこんな感じ。</p>

```
(begin
  (while (and dst src1 src2 ...)
    (setcar dst (funcall function (car src1) (car src2) ...))
    (setq dst (cdr dst))
    (setq src1 (cdr src1))
    (setq src2 (cdr src2))
             :
  )
  dst
)
```
:::

<hr>

:::note
# 2016年2月24日: 最小二乗法 -- 多項式、行列

2016年2月24日 23時09分

<p>何年も前に最小二乗法を勉強した時にノートに書いたやつを Qiita に起こしてみた。<br>
</p><h2>概要</h2><br>
測定とかで求められた $D$ 個のデータ、

<p>$$\{(x_1, y_1),\ (x_2, y_2),\ \dots,\ (x_D, y_D)\}$$</p>

<p>があって、このデータを $f(x)$ で近似する場合を考える。ここで近似する関数 $f(x)$ の関数形を、例えば、</p>

<p>$$f(x)=a_2x^2+a_1x+a_0$$</p>

<p>とか、</p>

<p>$$f(x)=a_0{\mathrm e}^{a_1x}$$</p>

<p>とかと仮定しておいて、パラメータ $a_j$ をデーターから決定するということ。当たり前けど、パラメータはテケトーに決めるのではなく、与えられたデータとのずれ（差）が最小になるように決定する。</p>

<h2>説明</h2>

<p>与えられたデータとのずれ $S$ を、</p>

<p>$$S=\sum_{i=1}^D\left(y_i-f(x_i)\right)^2$$</p>

<p>で定義する。</p>

<p>このずれ $S$ は $a_j$ によって大きくも小さくもなる。</p>

<p>$S$ が最小である場合、$S$ は $a_j$ に対して、谷底、つまり極小になってる。</p>

<p>とゆーわけで、この時、</p>

<p>$$\frac{\partial S}{\partial a_j}=0$$</p>

<p>になってるけど、これはデータ $\{(x_i,y_i)\}$ と近似関数 $f(x)$ とのズレ $S$ が最小である場合に $a_j$ が満たしてなきゃダメな方程式。</p>

<h2>多項式を使う近似</h2>

<p>近似関数 $f(x)$ を多項式で表す場合について考える。つまり…</p>

<p>$$f(x)=\sum_{j=0}^Fa_jg_j(x)$$</p>

<p>ってことね。</p>

<p>で、これをさっきの条件式にぶっ込むと左辺は…</p>

<p>$$<br>
\begin{array}\newline<br>
\displaystyle\frac{\partial S}{\partial a_j}<br>
&amp;=\displaystyle\frac{\partial}{\partial a_j}\displaystyle\sum_{i=1}^D\left(y_i-f(x_i)\right)^2\newline<br>
&amp;=\displaystyle\frac{\partial}{\partial a_j}\displaystyle\sum_{i=1}^D\left(y_i-\displaystyle\sum_{p=0}^Fa_pg_p(x_i)\right)^2\newline<br>
&amp;=\displaystyle\sum_{i=1}^D\frac{\partial}{\partial a_j}\left(y_i-\displaystyle\sum_{p=0}^Fa_pg_p(x_i)\right)^2\newline<br>
&amp;=\displaystyle\sum_{i=1}^D\frac{d\left(y_i-\displaystyle\sum_{p=0}^Fa_pg_p(x_i)\right)^2}{d\left(y_i-\displaystyle\sum_{p=0}^Fa_pg_p(x_i)\right)}\cdot\frac{\partial\left(y_i-\displaystyle\sum_{p=0}^Fa_pg_p(x_i)\right)}{\partial a_j}\newline<br>
&amp;=\displaystyle\sum_{i=1}^D2\left(y_i-\displaystyle\sum_{p=0}^Fa_pg_p(x_i)\right)\cdot\left(-g_j(x_i)\right)\newline<br>
&amp;=2\cdot\displaystyle\sum_{i=1}^D\left(-y_ig_j(x_i)+\displaystyle\sum_{p=0}^Fa_pg_p(x_i)g_j(x_i)<br>
\right)\newline<br>
&amp;=2\cdot\left(-\displaystyle\sum_{i=1}^Dy_ig_j(x_i)+\displaystyle\sum_{p=0}^Fa_p\displaystyle\sum_{i=1}^Dg_p(x_i)g_j(x_i)\right)<br>
\end{array}<br>
$$</p>

<p>で、こいつが $0$ でないとダメってことだから…</p>

<p>$$2\cdot\left(-\displaystyle\sum_{i=1}^Dy_ig_j(x_i)+\displaystyle\sum_{p=0}^Fa_p\displaystyle\sum_{i=1}^Dg_p(x_i)g_j(x_i)\right)=0$$</p>

<p>つまり、</p>

<p>$$\displaystyle\sum_{p=0}^Fa_p\displaystyle\sum_{i=1}^Dg_p(x_i)g_j(x_i)=\displaystyle\sum_{i=1}^Dy_ig_j(x_i)$$</p>

<p>でなきゃダメってこと。</p>

<p>で、この左辺は行列の積として書けるから…</p>

<p>$$\left(\begin{matrix}\displaystyle\sum_{i=1}^Dg_0(x_i)g_j(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_j(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_j(x_i)\end{matrix}\right)\left(\begin{matrix}a_0\newline a_1\newline\vdots\newline a_F\end{matrix}\right)=\displaystyle\sum_{i=1}^Dy_ig_j(x_i)$$</p>

<p>…ってなる。</p>

<p>で、$j$ は $0$ から $F$ まであって、それを全部書き出すとぉ…</p>

<p>$$\left(\begin{matrix}\displaystyle\sum_{i=1}^Dg_0(x_i)g_0(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_0(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_0(x_i)\newline\displaystyle\sum_{i=1}^Dg_0(x_i)g_1(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_1(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_1(x_i)\newline\vdots&amp;\vdots&amp;\ddots&amp;\vdots\newline\displaystyle\sum_{i=1}^Dg_0(x_i)g_F(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_F(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_F(x_i)\end{matrix}\right)\left(\begin{matrix}a_0\newline a_1\newline\vdots\newline a_F\end{matrix}\right)=\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_ig_0(x_i)\newline\displaystyle\sum_{i=1}^Dy_ig_1(x_i)\newline\vdots\newline\displaystyle\sum_{i=1}^Dy_ig_F(x_i)\end{matrix}\right)$$</p>

<p>だもんでっ、</p>

<p>$$\left(\begin{matrix}a_0\newline a_1\newline\vdots\newline a_F\end{matrix}\right)=\left(\begin{matrix}\displaystyle\sum_{i=1}^Dg_0(x_i)g_0(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_0(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_0(x_i)\newline\displaystyle\sum_{i=1}^Dg_0(x_i)g_1(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_1(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_1(x_i)\newline\vdots&amp;\vdots&amp;\ddots&amp;\vdots\newline\displaystyle\sum_{i=1}^Dg_0(x_i)g_F(x_i)&amp;\displaystyle\sum_{i=1}^Dg_1(x_i)g_F(x_i)&amp;\dots&amp;\displaystyle\sum_{i=1}^Dg_F(x_i)g_F(x_i)\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_ig_0(x_i)\newline\displaystyle\sum_{i=1}^Dy_ig_1(x_i)\newline\vdots\newline\displaystyle\sum_{i=1}^Dy_ig_F(x_i)\end{matrix}\right)$$</p>

<p>となる。</p>

<h3>直線近似</h3>

<p>次に、具体的な応用例として、近似関数 $f(x)$ の関数形を、</p>

<p>$$f(x)=a_1x+a_0$$</p>

<p>とする場合の近似のことを考えてみるっ。</p>

<p>つまり、$g_j(x)=x^j$ で $F=1$ ってことだから…</p>

<p>$$<br>
\begin{array}\newline\left(\begin{matrix}a_0\newline a_1\end{matrix}\right)&amp;=\left(\begin{matrix}\displaystyle\sum_{i=1}^Dx_i^0x_i^0&amp;\displaystyle\sum_{i=1}^Dx_i^0x_i^1\newline\displaystyle\sum_{i=1}^Dx_i^1x_i^0&amp;\displaystyle\sum_{i=1}^Dx_i^1x_i^1\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_ix_i^0\newline\displaystyle\sum_{i=1}^Dy_ix_i^1\end{matrix}\right)\newline<br>
&amp;=\left(\begin{matrix}\displaystyle\sum_{i=1}^D1&amp;\displaystyle\sum_{i=1}^Dx_i\newline\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_i\newline\displaystyle\sum_{i=1}^Dy_ix_i\end{matrix}\right)\newline<br>
&amp;=\left(\begin{matrix}\displaystyle D&amp;\displaystyle\sum_{i=1}^Dx_i\newline\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_i\newline\displaystyle\sum_{i=1}^Dy_ix_i\end{matrix}\right)<br>
\end{array}<br>
$$</p>

<p>ってなるっ。</p>

<h3>2次曲線近似</h3>

<p>次の応用例として、近似関数 $f(x)$ の関数形を、</p>

<p>$$f(x)=a_2x^2+a_1x+a_0$$</p>

<p>とする場合の近似のことを考えてみるっ。</p>

<p>つまり、$g_j(x)=x^j$ で $F=2$ ってことだから…</p>

<p>$$<br>
\begin{array}\newline\left(\begin{matrix}a_0\newline a_1\newline a_2\end{matrix}\right)&amp;=\left(\begin{matrix}\displaystyle\sum_{i=1}^Dx_i^0x_i^0&amp;\displaystyle\sum_{i=1}^Dx_i^0x_i^1&amp;\displaystyle\sum_{i=1}^Dx_i^0x_i^2\newline\displaystyle\sum_{i=1}^Dx_i^1x_i^0&amp;\displaystyle\sum_{i=1}^Dx_i^1x_i^1&amp;\displaystyle\sum_{i=1}^Dx_i^1x_i^2\newline\displaystyle\sum_{i=1}^Dx_i^2x_i^0&amp;\displaystyle\sum_{i=1}^Dx_i^2x_i^1&amp;\displaystyle\sum_{i=1}^Dx_i^2x_i^2\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_ix_i^0\newline\displaystyle\sum_{i=1}^Dy_ix_i^1\newline\displaystyle\sum_{i=1}^Dy_ix_i^2\end{matrix}\right)\newline<br>
&amp;=\left(\begin{matrix}\displaystyle\sum_{i=1}^D1&amp;\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2\newline\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2&amp;\displaystyle\sum_{i=1}^Dx_i^3\newline\displaystyle\sum_{i=1}^Dx_i^2&amp;\displaystyle\sum_{i=1}^Dx_i^3&amp;\displaystyle\sum_{i=1}^Dx_i^4\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_i\newline\displaystyle\sum_{i=1}^Dy_ix_i\newline\displaystyle\sum_{i=1}^Dy_ix_i^2\end{matrix}\right)\newline<br>
&amp;=\left(\begin{matrix}D&amp;\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2\newline\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2&amp;\displaystyle\sum_{i=1}^Dx_i^3\newline\displaystyle\sum_{i=1}^Dx_i^2&amp;\displaystyle\sum_{i=1}^Dx_i^3&amp;\displaystyle\sum_{i=1}^Dx_i^4\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^Dy_i\newline\displaystyle\sum_{i=1}^Dy_ix_i\newline\displaystyle\sum_{i=1}^Dy_ix_i^2\end{matrix}\right)\newline\end{array}<br>
$$</p>

<h2>指数近似</h2>

<p>次は指数近似。これは近似関数 $f(x)$ の関数形を、</p>

<p>$$f(x)=a_0{\mathrm e}^{a_1x}$$</p>

<p>とする場合の近似のこと。</p>

<p>だけど、このままでは解けないので、両辺の対数をとって、</p>

<p>$$\log_ef(x)=\log_ea_0+a_1x$$</p>

<p>として、パラメータを、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
A_0=\log_ea_0\newline<br>
A_1=a_1<br>
\end{array}<br>
\right.<br>
$$</p>

<p>に置き換えて、近似関数 $F(x)$ を、</p>

<p>$$<br>
\begin{array}\newline<br>
F(x)&amp;=\log_ef(x)\newline<br>
&amp;=A_0+A_1x<br>
\end{array}<br>
$$</p>

<p>にした場合の問題として解ける。</p>

<p>ただ、データの方も、</p>

<p>$$Y_i=\log_ey_i$$</p>

<p>ってしなきゃダメ。</p>

<p>とゆーわけで、</p>

<p>$$\left(\begin{matrix}A_0\newline A_1\end{matrix}\right)=\left(\begin{matrix}D&amp;\displaystyle\sum_{i=1}^Dx_i\newline\displaystyle\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^2\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^DY_i\newline\displaystyle\sum_{i=1}^D Y_ix_i\end{matrix}\right)$$</p>

<p>が求まって、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
a_0={\mathrm e}^{A_0}\newline<br>
a_1=A_1<br>
\end{array}<br>
\right.<br>
$$</p>

<p>が求まる。</p>

<h2>確率密度分布近似</h2>

<p>次は確率密度分布近似。これは近似関数 $f(x)$ の関数形を、</p>

<p>$$f(x)=a_0{\mathrm e}^{a_2x^2}$$</p>

<p>とする場合の近似のこと。</p>

<p>だけど、このままでは解けないので、両辺の対数をとって、</p>

<p>$$\log_ef(x)=\log_ea_0+a_2x^2$$</p>

<p>として、パラメータを、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
A_0=\log_ea_0\newline<br>
A_2=a_2<br>
\end{array}<br>
\right.<br>
$$</p>

<p>に置き換えて、近似関数 $F(x)$ を、</p>

<p>$$<br>
\begin{array}\newline<br>
F(x)&amp;=\log_ef(x)\newline<br>
&amp;=A_0+A_2x^2<br>
\end{array}<br>
$$</p>

<p>にした場合の問題として解ける。</p>

<p>ただ、データの方も、</p>

<p>$$Y_i=\log_ey_i$$</p>

<p>ってしなきゃダメ。</p>

<p>とゆーわけで、</p>

<p>$$\left(\begin{matrix}A_0\newline A_2\end{matrix}\right)=\left(\begin{matrix}D&amp;\displaystyle\sum_{i=1}^Dx_i^2\newline\displaystyle\sum_{i=1}^Dx_i&amp;\displaystyle\sum_{i=1}^Dx_i^4\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^DY_i\newline\displaystyle\sum_{i=1}^D Y_ix_i^2\end{matrix}\right)$$</p>

<p>が求まって、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
a_0={\mathrm e}^{A_0}\newline<br>
a_2=A_2<br>
\end{array}<br>
\right.<br>
$$</p>

<p>が求まる。</p>

<h2>累乗近似</h2>

<p>次は累乗近似。これは近似関数 $f(x)$ の関数形を、</p>

<p>$$f(x)=a_0x^{a_1}$$</p>

<p>とする場合の近似のこと。</p>

<p>だけど、このままでは解けないので、両辺の対数をとって、</p>

<p>$$\log_ef(x)=\log_ea_0+a_1\log_ex_1$$</p>

<p>として、パラメータを、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
A_0=\log_ea_0\newline<br>
A_1=a_1<br>
\end{array}<br>
\right.<br>
$$</p>

<p>に置き換えて、近似関数 $F(x)$ を、</p>

<p>$$<br>
\begin{array}\newline<br>
F(x)&amp;=\log_ef(x)\newline<br>
&amp;=A_0+A_1X<br>
\end{array}<br>
$$</p>

<p>にした場合の問題として解ける。</p>

<p>だけど、データのほおも、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
X_i=\log_ex_i\newline<br>
Y_i=\log_ey_i<br>
\end{array}<br>
\right.<br>
$$</p>

<p>に置き換える。</p>

<p>とゆーわけで、</p>

<p>$$\left(\begin{matrix}A_0\newline A_1\end{matrix}\right)=\left(\begin{matrix}D&amp;\displaystyle\sum_{i=1}^DX_i\newline\displaystyle\sum_{i=1}^DX_i&amp;\displaystyle\sum_{i=1}^DX_i^2\end{matrix}\right)^{-1}\left(\begin{matrix}\displaystyle\sum_{i=1}^DY_i\newline\displaystyle\sum_{i=1}^D Y_iX_i\end{matrix}\right)$$</p>

<p>が求まって、</p>

<p>$$<br>
\left\{<br>
\begin{array}\newline<br>
a_0={\mathrm e}^{A_0}\newline<br>
a_1=A_1<br>
\end{array}<br>
\right.<br>
$$</p>

<p>が求まる。</p>