山を登る時、ルートもわからん！頂上がどこにあるかもわからんでは遭難は確実なんじゃ！

プログラミングの勉強を始める時、最初はとても退屈で苦痛です。

まず実行環境を整えなければなりません。初心者はそこでつまづきます。たいていはここで、熟練者の助けが必要になります。

さて、何とか実行環境が整ったら、次はプログラミング言語の文法を勉強します。ところがその作業は非常に退屈で苦痛です。

「そもそもプログラミング勉強したら、何ができるようになるの？」

それを理解するためには、プログラミングを勉強しなければいけないというデッドロック。

<a href="https://www.google.com/search?q=%E5%B1%B1%E3%82%92%E7%99%BB%E3%82%8B%E6%99%82%E3%80%81%E3%83%AB%E3%83%BC%E3%83%88%E3%82%82%E3%82%8F%E3%81%8B%E3%82%89%E3%82%93%EF%BC%81%E9%A0%82%E4%B8%8A%E3%81%8C%E3%81%A9%E3%81%93%E3%81%AB%E3%81%82%E3%82%8B%E3%81%8B%E3%82%82%E3%82%8F%E3%81%8B%E3%82%89%E3%82%93%E3%81%A7%E3%81%AF%E9%81%AD%E9%9B%A3%E3%81%AF%E7%A2%BA%E5%AE%9F%E3%81%AA%E3%82%93%E3%81%98%E3%82%83%EF%BC%81&source=lnms&tbm=isch&sa=X&ved=2ahUKEwj0pYaJ_O3vAhWTfd4KHcNUBEQQ_AUoAXoECAEQAw&biw=1241&bih=690">「山を登る時、ルートもわからん！頂上がどこにあるかもわからんでは遭難は確実なんじゃ！」</a>

そう、これはPythonの勉強に限らず、コーラを飲んだらゲップが出るっていうくらい確実な宇宙の普遍的法則というべきでしょう。

そうなんですねー。

# Python で遭難しないために

Python を使うと、いろんなことができます。色々すぎて説明しきれません。そこで、たくさんある「頂上」のひとつをここでお見せしたいと思います。まずは、意味がわからなくても構いませんので、「コピペ」で頂上まで登ってみてください。以下のコードは全て Google Colaboratory という実行環境での使用を想定しています。


まずは、図を描画するときに日本語を使えるようにするための呪文を唱えておきます。


```python
!pip install japanize-matplotlib
```

    Collecting japanize-matplotlib
    [?25l  Downloading https://files.pythonhosted.org/packages/aa/85/08a4b7fe8987582d99d9bb7ad0ff1ec75439359a7f9690a0dbf2dbf98b15/japanize-matplotlib-1.1.3.tar.gz (4.1MB)
    [K     |████████████████████████████████| 4.1MB 3.4MB/s 
    [?25hRequirement already satisfied: matplotlib in /usr/local/lib/python3.7/dist-packages (from japanize-matplotlib) (3.2.2)
    Requirement already satisfied: numpy>=1.11 in /usr/local/lib/python3.7/dist-packages (from matplotlib->japanize-matplotlib) (1.19.5)
    Requirement already satisfied: pyparsing!=2.0.4,!=2.1.2,!=2.1.6,>=2.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->japanize-matplotlib) (2.4.7)
    Requirement already satisfied: python-dateutil>=2.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->japanize-matplotlib) (2.8.1)
    Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.7/dist-packages (from matplotlib->japanize-matplotlib) (0.10.0)
    Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.7/dist-packages (from matplotlib->japanize-matplotlib) (1.3.1)
    Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.7/dist-packages (from python-dateutil>=2.1->matplotlib->japanize-matplotlib) (1.15.0)
    Building wheels for collected packages: japanize-matplotlib
      Building wheel for japanize-matplotlib (setup.py) ... [?25l[?25hdone
      Created wheel for japanize-matplotlib: filename=japanize_matplotlib-1.1.3-cp37-none-any.whl size=4120276 sha256=f1117e17562a3146802c6bf230ed7c2f5db395b38a791ca1b7881a1ad4d72573
      Stored in directory: /root/.cache/pip/wheels/b7/d9/a2/f907d50b32a2d2008ce5d691d30fb6569c2c93eefcfde55202
    Successfully built japanize-matplotlib
    Installing collected packages: japanize-matplotlib
    Successfully installed japanize-matplotlib-1.1.3


# ケーススタディ１：家賃

家賃のデータを解析します。

## データ取得

まずは、データの取得を行います。


```python
import urllib.request 

url = "https://raw.githubusercontent.com/maskot1977/toydata/main/home.txt"
urllib.request.urlretrieve(url, 'data.txt')
```




    ('data.txt', <http.client.HTTPMessage at 0x7f010d549090>)



家賃のデータの中身はこんな感じです。


```python
import pandas as pd

df = pd.read_csv('data.txt', delimiter="\t")
df
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>家賃（円）</th>
      <th>徒歩（分）</th>
      <th>専有面積（㎡）</th>
      <th>築年数（年）</th>
      <th>階数（階）</th>
      <th>新築</th>
      <th>2階以上</th>
      <th>南向き</th>
      <th>駐車場</th>
      <th>オートロック</th>
      <th>エアコン</th>
      <th>バストイレ別</th>
      <th>追い焚き</th>
      <th>フローリング</th>
      <th>ペット相談可</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>88500</td>
      <td>10</td>
      <td>20.70</td>
      <td>3</td>
      <td>8</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>1</th>
      <td>86700</td>
      <td>10</td>
      <td>20.70</td>
      <td>3</td>
      <td>7</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>2</th>
      <td>87300</td>
      <td>10</td>
      <td>20.70</td>
      <td>3</td>
      <td>2</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>3</th>
      <td>88200</td>
      <td>10</td>
      <td>20.70</td>
      <td>3</td>
      <td>9</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>4</th>
      <td>170000</td>
      <td>10</td>
      <td>41.40</td>
      <td>3</td>
      <td>11</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>95</th>
      <td>88000</td>
      <td>8</td>
      <td>21.29</td>
      <td>10</td>
      <td>4</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>96</th>
      <td>88000</td>
      <td>8</td>
      <td>20.58</td>
      <td>10</td>
      <td>5</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
    </tr>
    <tr>
      <th>97</th>
      <td>88000</td>
      <td>8</td>
      <td>22.04</td>
      <td>10</td>
      <td>9</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
    </tr>
    <tr>
      <th>98</th>
      <td>88000</td>
      <td>8</td>
      <td>20.58</td>
      <td>10</td>
      <td>8</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>0</td>
    </tr>
    <tr>
      <th>99</th>
      <td>93000</td>
      <td>7</td>
      <td>22.50</td>
      <td>7</td>
      <td>2</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
      <td>0</td>
      <td>1</td>
      <td>1</td>
      <td>1</td>
      <td>0</td>
      <td>1</td>
      <td>0</td>
    </tr>
  </tbody>
</table>
<p>100 rows × 15 columns</p>
</div>


## 散布図

占有面積を横軸に、家賃を縦軸にして散布図を描いてみましょう。明らかな相関があることが分かります。


```python
import matplotlib.pyplot as plt
import japanize_matplotlib 

plt.scatter( df['専有面積（㎡）'], df['家賃（円）'], alpha=0.5)
plt.xlabel('専有面積（㎡）')
plt.ylabel('家賃（円）')
plt.show()
```

![output_7_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/ad4a8286-9220-cdee-a80a-1ef5ec43b216.png)

   
    


主要駅からの距離が、家賃に影響するかどうか調べてみましょう。駅に近ければ近いほど高い、というわけではなさそうです。


```python
import matplotlib.pyplot as plt

plt.scatter(df['徒歩（分）'], df['家賃（円）'], alpha=0.5)
plt.xlabel('徒歩（分）')
plt.ylabel('家賃（円）')
plt.show()
```

![output_9_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b6daa9c5-fd0f-d68d-7b7d-153eff4d9ee4.png)

    
    


築年数との関係も調べてみましょう。ある程度以上古くなると安くなるものの、そんなに簡単な関係ではなさそうですね。


```python
import matplotlib.pyplot as plt

plt.scatter(df['築年数（年）'], df['家賃（円）'], alpha=0.5)
plt.xlabel('築年数（年）')
plt.ylabel('家賃（円）')
plt.show()
```

![output_11_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/f1ea4f9b-6806-a2a1-2ba8-a82170776747.png)

    
    


何階建ての建物かと、家賃との関係も、緩やかな相関はあるかもしれませんが単純な話ではなさそうです。


```python
import matplotlib.pyplot as plt

plt.scatter(df['階数（階）'], df['家賃（円）'], alpha=0.5)
plt.xlabel('築年数（年）')
plt.ylabel('階数（階）')
plt.show()
```

![output_13_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/9e944e03-7e1b-f140-f8e0-0d33f23596a4.png)

    
    


これまでに調べた関係をまとめて図示すると次のようになります。


```python
import matplotlib.pyplot as plt
import japanize_matplotlib 

pd.plotting.scatter_matrix(df.iloc[:, :5], figsize=(8, 8)) 
plt.show()
```

![output_15_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/78ee4018-e1df-7984-ebca-7ad203968049.png)

    
    
## ヒストグラム

次に、１か０か（２択）しかない属性との関係を調べてみましょう。まず、新築かどうかです。新築なら家賃が高いかと言われると、どうもそういう話ではなさそうです。


```python
plt.hist(df[df['新築'] == 1]['家賃（円）'], alpha=0.5, label="新築", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['新築'] == 0]['家賃（円）'], alpha=0.5, label="中古", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_17_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/58ef4054-ade3-c67b-a399-64d028afaf88.png)

    
    


１階かどうかは、家賃とかなり関係がありそうですね。


```python
plt.hist(df[df['2階以上'] == 1]['家賃（円）'], alpha=0.5, label="2階以上", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['2階以上'] == 0]['家賃（円）'], alpha=0.5, label="1階", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_19_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/ac5d5aac-134c-7788-ca8a-64e41dc0172b.png)

    
    


南向きかどうかは、あまり関係なさそうに見えますね。


```python
plt.hist(df[df['南向き'] == 1]['家賃（円）'], alpha=0.5, label="南向き", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['南向き'] == 0]['家賃（円）'], alpha=0.5, label="南向き以外", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_21_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/dcd83689-5a5d-a6d2-c7c6-f957f0337651.png)

    
    


駐車場付きの物件は高めになる傾向がありそうです。


```python
plt.hist(df[df['駐車場'] == 1]['家賃（円）'], alpha=0.5, label="駐車場あり", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['駐車場'] == 0]['家賃（円）'], alpha=0.5, label="駐車場なし", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_23_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/a43a0e38-a4dc-be9d-aab9-38fdf316845a.png)

    
    


オートロックがついてるかどうかですが...うーん、このデータは本当に正しいのかな？と個人的には疑っています。


```python
plt.hist(df[df['オートロック'] == 1]['家賃（円）'], alpha=0.5, label="オートロックあり", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['オートロック'] == 0]['家賃（円）'], alpha=0.5, label="オートロックなし", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_25_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/5c2ddfb7-81e3-b090-bfcc-9008c711116e.png)

    
    


今の時代、エアコンがあるのが普通で、エアコンのない物件は安いようですね。


```python
plt.hist(df[df['エアコン'] == 1]['家賃（円）'], alpha=0.5, label="エアコンあり", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['エアコン'] == 0]['家賃（円）'], alpha=0.5, label="エアコンなし", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_27_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/440b25a9-29af-e26a-89c3-7014f140d8e3.png)

    
    


バストイレ別についても同様。


```python
plt.hist(df[df['バストイレ別'] == 1]['家賃（円）'], alpha=0.5, label="バストイレ別", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['バストイレ別'] == 0]['家賃（円）'], alpha=0.5, label="ユニットバス", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_29_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/93a33b8a-b601-9c4c-f97b-5f320ac2e179.png)

    
    


追い焚きがついてる物件は高めになるようです。


```python
plt.hist(df[df['追い焚き'] == 1]['家賃（円）'], alpha=0.5, label="追い焚きあり", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['追い焚き'] == 0]['家賃（円）'], alpha=0.5, label="追い焚きなし", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_31_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/6138678a-0b18-1a45-6614-8a2e68c5303a.png)

    
    


フローリングは、あるのが普通で、うーん、この分布はどう解釈すればいいんだ。


```python
plt.hist(df[df['フローリング'] == 1]['家賃（円）'], alpha=0.5, label="フローリングあり", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['フローリング'] == 0]['家賃（円）'], alpha=0.5, label="フローリングなし", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_33_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/399e180a-e523-8ee3-a2ab-9b0f18bd8967.png)

    
    


ペット相談可かどうかは、意外と、家賃との関係はなさそうに見えます。


```python
plt.hist(df[df['ペット相談可'] == 1]['家賃（円）'], alpha=0.5, label="ペット相談可", ec='navy', bins=15, range=(50000, 200000))
plt.hist(df[df['ペット相談可'] == 0]['家賃（円）'], alpha=0.5, label="ペット相談不可", ec='navy', bins=15, range=(50000, 200000))
plt.legend()
plt.xlabel('家賃（円）')
plt.ylabel('件数')
plt.show()
```

![output_35_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/2bd04422-4572-a2e1-cb13-f1df8f944e58.png)

   
    


以上の話は、賃貸物件に詳しい方が見れば、ツッコミどころが多いかもしれません。私は賃貸の専門家ではありませんので、すみません。とりあえず、データ解析の例をお見せしてみました。

## 回帰直線

解析をさらに進めてみましょう。次は「回帰直線」です。家賃が占有面積と強い正の相関があることがわかったので、占有面積から家賃を予測する回帰直線を描いてみましょう。


```python
import matplotlib.pyplot as plt
import japanize_matplotlib 
from sklearn import linear_model

model = linear_model.LinearRegression()
model.fit(df['専有面積（㎡）'].values.reshape(len(df),1), df['家賃（円）'].T) # 予測モデルを作成
plt.scatter( df['専有面積（㎡）'], df['家賃（円）'], alpha=0.5)
plt.plot(df['専有面積（㎡）'], model.predict(df['専有面積（㎡）'].values.reshape(100,1)))
plt.xlabel('専有面積（㎡）')
plt.ylabel('家賃（円）')
plt.show()
```

![output_37_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/281b8166-55e6-2395-0b4e-56925100f8b3.png)

    
    


この回帰直線が、南向き物件か否かで、どう違ってくるか調べてみましょう。


```python
import matplotlib.pyplot as plt
import japanize_matplotlib 
from sklearn import linear_model

df1 = df[df['南向き'] == 1]
df2 = df[df['南向き'] == 0]

model1 = linear_model.LinearRegression()
model1.fit(df1['専有面積（㎡）'].values.reshape(len(df1),1), df1['家賃（円）'].T) # 予測モデルを作成
plt.scatter(df1['専有面積（㎡）'], df1['家賃（円）'], alpha=0.8)
plt.plot(df1['専有面積（㎡）'], model1.predict(df1['専有面積（㎡）'].values.reshape(len(df1),1)), label="南向き")

model2 = linear_model.LinearRegression()
model2.fit(df2['専有面積（㎡）'].values.reshape(len(df2),1), df2['家賃（円）'].T) # 予測モデルを作成
plt.scatter(df2['専有面積（㎡）'], df2['家賃（円）'], alpha=0.8)
plt.plot(df2['専有面積（㎡）'], model2.predict(df2['専有面積（㎡）'].values.reshape(len(df2),1)), label="南向き以外")

plt.xlabel('専有面積（㎡）')
plt.ylabel('家賃（円）')
plt.legend()
plt.show()
```

![output_39_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/9d5c5388-5cad-b55b-ecc1-0600c3aaa4bd.png)

    
    


ペット相談可能物件かどうかで比べてみましょう。


```python
import matplotlib.pyplot as plt
import japanize_matplotlib 
from sklearn import linear_model

df1 = df[df['ペット相談可'] == 1]
df2 = df[df['ペット相談可'] == 0]

model1 = linear_model.LinearRegression()
model1.fit(df1['専有面積（㎡）'].values.reshape(len(df1),1), df1['家賃（円）'].T) # 予測モデルを作成
plt.scatter(df1['専有面積（㎡）'], df1['家賃（円）'], alpha=0.8)
plt.plot(df1['専有面積（㎡）'], model1.predict(df1['専有面積（㎡）'].values.reshape(len(df1),1)), label="ペット相談可")

model2 = linear_model.LinearRegression()
model2.fit(df2['専有面積（㎡）'].values.reshape(len(df2),1), df2['家賃（円）'].T) # 予測モデルを作成
plt.scatter(df2['専有面積（㎡）'], df2['家賃（円）'], alpha=0.8)
plt.plot(df2['専有面積（㎡）'], model2.predict(df2['専有面積（㎡）'].values.reshape(len(df2),1)), label="ペット相談不可")

plt.xlabel('専有面積（㎡）')
plt.ylabel('家賃（円）')
plt.legend()
plt.show()
```

![output_41_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/26625959-2203-8f59-6d9a-09c1ebea3472.png)

    
    


さて、問題は、これらの結果をどう解釈するかですけれども。占有面積や家賃の分布は一様ではなくて、２５平米、１０万円付近に固まった分布をしているので、解釈は慎重にしたほうがいいような気がします。

# ケーススタディ２：偽札

次のデータは、ある紙幣の縦の長さ、横の長さなどを計測したものです。

## データ取得


```python
import urllib.request 

url = "https://raw.githubusercontent.com/maskot1977/ipython_notebook/master/toydata/sbnote_dataJ.txt"
urllib.request.urlretrieve(url, 'data.txt')
```




    ('data.txt', <http.client.HTTPMessage at 0x7f00f9d5ca50>)




```python
import pandas as pd
df = pd.read_csv('data.txt', delimiter="\t")
data = df.iloc[:, :-1]
target = df['class']
data
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>length</th>
      <th>left</th>
      <th>right</th>
      <th>bottom</th>
      <th>top</th>
      <th>diagonal</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>0</th>
      <td>214.8</td>
      <td>131.0</td>
      <td>131.1</td>
      <td>9.0</td>
      <td>9.7</td>
      <td>141.0</td>
    </tr>
    <tr>
      <th>1</th>
      <td>214.6</td>
      <td>129.7</td>
      <td>129.7</td>
      <td>8.1</td>
      <td>9.5</td>
      <td>141.7</td>
    </tr>
    <tr>
      <th>2</th>
      <td>214.8</td>
      <td>129.7</td>
      <td>129.7</td>
      <td>8.7</td>
      <td>9.6</td>
      <td>142.2</td>
    </tr>
    <tr>
      <th>3</th>
      <td>214.8</td>
      <td>129.7</td>
      <td>129.6</td>
      <td>7.5</td>
      <td>10.4</td>
      <td>142.0</td>
    </tr>
    <tr>
      <th>4</th>
      <td>215.0</td>
      <td>129.6</td>
      <td>129.7</td>
      <td>10.4</td>
      <td>7.7</td>
      <td>141.8</td>
    </tr>
    <tr>
      <th>...</th>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
      <td>...</td>
    </tr>
    <tr>
      <th>195</th>
      <td>215.0</td>
      <td>130.4</td>
      <td>130.3</td>
      <td>9.9</td>
      <td>12.1</td>
      <td>139.6</td>
    </tr>
    <tr>
      <th>196</th>
      <td>215.1</td>
      <td>130.3</td>
      <td>129.9</td>
      <td>10.3</td>
      <td>11.5</td>
      <td>139.7</td>
    </tr>
    <tr>
      <th>197</th>
      <td>214.8</td>
      <td>130.3</td>
      <td>130.4</td>
      <td>10.6</td>
      <td>11.1</td>
      <td>140.0</td>
    </tr>
    <tr>
      <th>198</th>
      <td>214.7</td>
      <td>130.7</td>
      <td>130.8</td>
      <td>11.2</td>
      <td>11.2</td>
      <td>139.4</td>
    </tr>
    <tr>
      <th>199</th>
      <td>214.3</td>
      <td>129.9</td>
      <td>129.9</td>
      <td>10.2</td>
      <td>11.5</td>
      <td>139.6</td>
    </tr>
  </tbody>
</table>
<p>200 rows × 6 columns</p>
</div>


## 散布図

分布を見てみましょう。すると、どうやらこの紙幣は２つのグループから成るように見えます。


```python
pd.plotting.scatter_matrix(data, figsize=(8, 8)) 
plt.show()
```

![output_46_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/538e20e2-5851-95c0-0e69-5824ac85b0cb.png)

    
    
## 正解ラベル

実際その通りで、本物の紙幣と、偽物の紙幣（偽札）が混じったデータになります。本物か偽物かで色分けすると、次のようになります（どっちがどの色か忘れました）。


```python
pd.plotting.scatter_matrix(data, figsize=(8, 8), c=list(target)) 
plt.show()
```

![output_48_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/bf44bdd7-536f-537f-0e96-abb257b70ea4.png)

    
    
## 教師なし機械学習

では、本物か偽物かを区別する方法は作れないものでしょうか？いくつか方法はあります。一つは「教師なし機械学習」と呼ばれる手法で、クラスターというグループに自動で分割する手法です。その中で「k-means」という手法を試してみましょう。


```python
from sklearn.cluster import KMeans 

kmeans_model = KMeans(n_clusters = 2).fit(data)
pd.plotting.scatter_matrix(data, figsize=(8, 8), c=kmeans_model.labels_) 
plt.show()
```

![output_50_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/a2146ca1-9371-d1c3-6780-c455c7e0d666.png)

    
    


同じような結果が得られましたね。k-meansによる分類と、実際の正解データがどのくらい違うのか、混合行列を計算してみましょう。


```python
from sklearn.metrics import confusion_matrix # 混合行列

# 予測結果と、正解（本当の答え）がどのくらい合っていたかを表す混合行列
pd.DataFrame(confusion_matrix(kmeans_model.labels_, list(target)), index=['predicted 0', 'predicted 1'], columns=['real 0', 'real 1'])
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>real 0</th>
      <th>real 1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>predicted 0</th>
      <td>100</td>
      <td>0</td>
    </tr>
    <tr>
      <th>predicted 1</th>
      <td>0</td>
      <td>100</td>
    </tr>
  </tbody>
</table>
</div>



なんと、完全一致でした。

## 教師あり機械学習

次に、「教師あり機械学習」の一種である「ロジスティック回帰」を使ってみたいと思います。先程の「K-mean」では、「正解ラベル（本物か偽物か）」の情報を用いずに分類したのに対して、以下の「ロジスティック回帰」では、「正解ラベル（本物か偽物か）」の情報を用いて分類します。


```python
from sklearn.linear_model import LogisticRegression # ロジスティック回帰
model = LogisticRegression(max_iter=530000) #モデルの生成
model.fit(data, list(target))
pd.plotting.scatter_matrix(data, figsize=(8, 8), c=model.predict(data)) 
plt.show()
```

![output_54_0.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/211162/b3bee474-bc07-702a-1065-6768e584d667.png)

    
    



```python
from sklearn.metrics import confusion_matrix # 混合行列

# 予測結果と、正解（本当の答え）がどのくらい合っていたかを表す混合行列
pd.DataFrame(confusion_matrix(model.predict(data), list(target)), index=['predicted 0', 'predicted 1'], columns=['real 0', 'real 1'])
```




<div>
<style scoped>
    .dataframe tbody tr th:only-of-type {
        vertical-align: middle;
    }

    .dataframe tbody tr th {
        vertical-align: top;
    }

    .dataframe thead th {
        text-align: right;
    }
</style>
<table border="1" class="dataframe">
  <thead>
    <tr style="text-align: right;">
      <th></th>
      <th>real 0</th>
      <th>real 1</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <th>predicted 0</th>
      <td>99</td>
      <td>0</td>
    </tr>
    <tr>
      <th>predicted 1</th>
      <td>1</td>
      <td>100</td>
    </tr>
  </tbody>
</table>
</div>



惜しい！１個だけ、外してしまいました。

以上の解析結果は、ロジスティック回帰よりもk-meansのほうが優れている、ということではありません。データの分布の形によって、どの手法が適しているかは変わります。

# 終わりに

以上、プログラミング初学者が陥りがちな「プログラミングで何ができるの？」というデッドロックを回避するために、ケーススタディを２つお見せしました。最初は「コピペ」だけで大丈夫です。「頂上」（何ができるか）がイメージできたら、次は、その詳細を理解したり、個別の目的のために改変したりできるように「ルート」を進んでいきましょう。