# python_course5
## 本章の目的
1. scikit-learn ライブラリを使って簡単な機械学習のプログラムを作成できるようになること
2. scikit-learn と他ライブラリとを用い、より実践的な機械学習のプログラムを作成できるようになること
## scikit-learn で始める機械学習
### 機械学習関連の用語
#### AI (人工知能)
AI (Artificial Intelligence:人工知能) は、コンピュータを使って人間の知能を人工的に実現させる技術で、学習・推論などを行うことができます。
近年では、AI という文言を見聞きしない日はないと言っても過言ではないほど日増しに注目度が高まっています。スマートフォンアプリ内で個々のユーザーへのパーソナライズ (例:好みの音楽が表示される、興味があると思われる商品がオススメされる) にAIの技術が活用されたりしているなど、人々の日常生活にも馴染んできていると言えるでしょう。
今後は、研究開発が進む自動運転車の実用化が予想されるなど、より幅広い領域で AI の活用が進んでいくと考えられております。
一方、技術力が向上していくことで懸念されていることもあります。例えば、AI が人間の知能に到達 (シンギュラリティ:技術的特異点と呼びます) し、人間が AI に支配されるようになるのではないか、といった議論です。この他、法整備や倫理的な議論など、AI 活用に際してはまだまだ解決すべき課題がたくさんあります。
#### 機械学習
AI 技術を支えているのが 機械学習(Machine Learning) です。膨大なデータをコンピュータが学習し、推論や判断を行うことができます。
例えば、以下のようなことが研究されています。
・多くの動物の写真データを学習させ、何の動物が写っているか特定する
・過去の裁判の判例データを学習させ、適切な量刑を決定する
・過去の患者のカルテやレントゲン写真を学習させ、病名やステージなどを診断する
#### 深層学習
機械学習と深層学習 (Deep Learning) とを混同している方も多いでしょう。
深層学習は「機械学習の一部」です。ニューラルネットワークと呼ばれる、人間の神経回路の仕組みを模したプログラムを作成し、コンピュータに学習させることで学習能力を高めています。
#### 教師あり学習と教師なし学習
機械学習は大きく分けて、「教師あり学習」と「教師なし学習」に分けられます。
##### 教師あり学習
教師あり学習は、人間が与えた「入力」と「正解データ」を元にコンピュータがそれらの特徴を学習し、未知の事象に対しても判断を行えるようになるものです。先ほどの機械学習の例示は全て正解データが存在するため、教師あり学習に分類されます。
##### 教師なし学習
教師なし学習では「正解データ」が与えられず、コンピュータ自身が共通項や頻出パターンを見つけ出す学習方法です。例えば、「消費者の購買データからよく購買される商品の組合せを見出す」などは、教師なし学習に該当します。
#### 強化学習
現在の状況を把握し、次の選択を判断する、機械学習の一種です。
判断と行動する、良い行動を取ったら報酬を得る、また判断し...というサイクルを回すことでより良い判断ができるようになっていくものです。
近年、強化学習を行った囲碁のアルゴリズムが一流のプロを破ったことで一躍注目を集めましたが、それ以外にも自動運転技術の開発やエレベータの制御システムなどにも応用されています。
#### 分類と回帰
データ分析のカテゴリは 分類 と 回帰 の2つに分けられます。
##### 分類
データ解析を通して見出した特徴をベースに「これは○○だ」と判断するのが分類です。
分類によって、例えば、目、耳、鼻、毛色などの特徴を画像から読み取り、「これは猫だ」といったような判断ができるようになります。
##### 回帰
「来店回数」や「価格」といった連続的な数値について予測するのが回帰です。
回帰では、データの規則性などの法則を導くため、統計学や数学の背景知識が必要になります。
### scikit-learnとは
scikit-learn (サイキット・ラーン) は、Pythonの機械学習ライブラリです。
Pythonは機械学習や深層学習を行う上での主要なプログラミング言語ですが、その数あるライブラリの中でも、scikit-learn は非常に人気のあるライブラリです。理由としては、機械学習のほとんどの分野をカバーしていることや、初心者でも扱いやすいということが挙げられます。
もちろん、scikit-learn だけで十分という訳ではありません。機械学習のうちの特定の分野、例えば深層学習のプログラムを作成したい場合には Tensorflow や Keras といった有名なライブラリがあります。一方、これらは初心者向けとは言い難い部分があるため、まずは scikit-learn からスタートすることをオススメします。
### 機械学習の流れ
Pythonで機械学習プログラムを作成する際の流れは、次の通りです。
1. モデルの決定
2. 学習用データセットのインポート
3. データの前処理
4. データの仕分け (訓練データとテストデータ)
5. モデルを作った学習
6. 性能の評価
次項よりそれぞれのステップを見ていきます。
#### 1. モデルの決定
機械学習のロジックのことをモデル (model) と呼びます。独自のモデルを作ることもできますが、scikit-learn では様々なモデルが提供されていて、これが初心者にオススメされる理由の1つです。オリジナルのモデルを作ることもできますので、今回学習する scikit-learn からスタートし、どんどんスキルアップを目指していきましょう。
また、モデルの選び方については、scikit-learnで提供されている[チートシート](https://scikit-learn.org/0.21/tutorial/machine_learning_map/)を参考にすると良いでしょう。
ここで、モデル選択のパターンについて簡単に触れておきます。
1-1. 分類(classification)
データの分類に使われます。例えば、受信したEメールが迷惑メールか否かを見極め、分類することができます。教師あり学習に該当します。
1-2. 回帰(regression)
連続値などの値の予測に使われます。例えば、株価や価格などの予測で活用されています。教師あり学習に該当します。
1-3. クラスタリング(clustering)
データ間の類似度を見極めてグループ化する手法をクラスタリングといいます。スーパーマーケットの購買データから良く購買される商品の組合せを見出し、商品陳列に活かすといった活用ができます。教師なし学習に該当します。
1-4. 次元削減(dimensionality reduction)
データの次元数 (説明変数、パラメータの数) を減らし、入手した有限のサンプルデータから有効な学習結果を得るために重要な手法です。次元圧縮とも呼ばれますので頭の片隅に置いておきましょう。教師なし学習に該当します。
#### 2. 学習用データセットのインポート
それでは、機械学習のプログラムを作っていきましょう。
まず始めに、学習用データを取り込んでいきます。scikit-learn には、サンプルデータが用意されているので、今回はそれを使います。
本章では、植物の「アヤメ (iris)」のサンプルデータを題材として用い、データを読み込み、分類を行います。また、モデルはサポートベクトルと呼ばれる分類モデル (SVC) を使います。
JupyterLabで新規ノートブックを作成し、最初のセルで、次のコードを入力・実行します。
###### 実行コード1
```
from sklearn import datasets
irisdata = datasets.load_iris()
```
これで scikit-learn に用意されているサンプルデータを読み込めました。確認してみましょう。
###### 実行コード2
```
print(irisdata.DESCR)
```
###### 実行結果2
```
.. _iris_dataset:
Iris plants dataset
--------------------
**Data Set Characteristics:**
:Number of Instances: 150 (50 in each of three classes)
:Number of Attributes: 4 numeric, predictive attributes and the class
:Attribute Information:
- sepal length in cm
- sepal width in cm
- petal length in cm
- petal width in cm
- class:
- Iris-Setosa
- Iris-Versicolour
- Iris-Virginica
:Summary Statistics:
============== ==== ==== ======= ===== ====================
Min Max Mean SD Class Correlation
============== ==== ==== ======= ===== ====================
sepal length: 4.3 7.9 5.84 0.83 0.7826
sepal width: 2.0 4.4 3.05 0.43 -0.4194
petal length: 1.0 6.9 3.76 1.76 0.9490 (high!)
petal width: 0.1 2.5 1.20 0.76 0.9565 (high!)
============== ==== ==== ======= ===== ====================
:Missing Attribute Values: None
:Class Distribution: 33.3% for each of 3 classes.
:Creator: R.A. Fisher
:Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov)
:Date: July, 1988
<以下略>
```
DESCR プロパティに記載されている、サンプルデータの書式やデータの意味が表示されました。
変数 irisdata の dataプロパティには「Sepal Length (がく片の長さ)」、「Sepal Width (がく片の幅)」、「Petal Length (花弁の長さ)」、「Petal Width (花弁の幅)」の4つのデータが格納されています。
それらのデータを元に、「Setosa」「Versicolor」「Virginica」のうち、どの品種に当てはまるかが irisdata の target プロパティに格納されています。
target プロパティには、 Setosa、Versicolor、Virginica の文字列(品種名) ではなく、0, 1, 2 の整数が入っています。これは、Setosa = 0, Versicolor = 1, Virginica = 2 というようにインデックスで表示されることを意味しています。
ここで、用語の解説をしておきます。
```
説明変数 (特徴量): 特徴を説明するデータ
例)がく弁の長さのような、アヤメに関するデータ
目的変数: どの種類に属するかを示すデータ
例)アヤメのカテゴリ値
```
scikit-learn が提供するサンプルデータでは、data プロパティに説明変数 (特徴量)が、target プロパティに目的変数が格納されています。それぞれ中身を確認してみましょう。
###### 実行コード3
```
print(irisdata.data)
```
###### 実行結果3
```
[[5.1 3.5 1.4 0.2]
[4.9 3. 1.4 0.2]
[4.7 3.2 1.3 0.2]
[4.6 3.1 1.5 0.2]
[5. 3.6 1.4 0.2]
<以下略>]
```
###### 実行コード4
```
print(irisdata.target)
```
###### 実行結果4
```
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
2 2]
```
data、target それぞれのプロパティに格納されているデータが表示され、形式は ndarray、つまり配列になっていることがわかるかと思います。
では、それぞれの中身は何を表しているのでしょうか。次の実行コードで見ていきましょう。
###### 実行コード5
```
print(irisdata.feature_names)
print(irisdata.target_names)
```
###### 実行結果5
```
['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)']
['setosa' 'versicolor' 'virginica']
```
つまり、data の4つの列にはがく弁の長さなど、4種類のデータが格納されていること、target の値 0,1,2 は setosa などアヤメの品種を表していることがわかります。
また、data と target との対応関係についても触れておきます。
data の0番目の要素、つまり [5.1 3.5 1.4 0.2](実行結果3) は、target の0番目の要素である 0 (実行結果4)に対応しています。即ち、data の0番目は setosa ということになります。
#### 3. データの前処理
インポートしたデータがそのまま機械学習に使えれば良いのですが、実際には前処理工程が必要になると思っておいて差し支えないでしょう。また、前章の「Pandasによるデータ処理」で触れたように、この前処理が機械学習の大半の時間を占めています。
以下では、前処理工程の主な作業内容を紹介します。
##### カテゴリ変数のダミー変数化
文字列で表現される変数をカテゴリ変数 (属性変数/質的変数) と呼びます。例えば、本章でのアヤメのサンプルデータで言えば、品種名 (値: Setosa など) がそれに当たります。
また、それぞれの品種の数値化も行っていました。
| カテゴリの値 | 数値 |
| ------------ | :--- |
| Setosa | 0 |
| Versicolor | 1 |
| Virginica | 2 |
この状態でも、文字列のままよりは扱いやすいようにも思えます。
一方、機械学習のアルゴリズムによっては、このままだと「数値の大小」に意味付けしてしまいかねません。例えば、点数のように捉えるとどうでしょう。0 の Setosa よりも 2 の Virginica の方が「良い」などという評価に繋がりかねません。
そこで登場するのがダミー変数化です。数値に連続性がなく、大小によってパラメータに影響を与えません。
| カテゴリの値 | Setosa | Versicolor | Virginica |
| ------------ | :----- | ---------- | --------- |
| Setosa | 1 | 0 | 0 |
| Versicolor | 0 | 1 | 0 |
| Virginica | 0 | 0 | 1 |
このように、横軸に項目名をとり、当てはまらない場合は 0, 当てはまる場合は 1 を付して表現します。
ダミー変数化の要否は学習データの性質によります。
さらに、列を1つ減らすなどして精度を高める方法もあります。
##### 欠損値の補完
データの一部が欠損している場合、補完するか否か、補完するならどんな方法をとるか検討します。
1. 欠損値を削除する
データ数さえ確保できていれば、単純に削除してもよいでしょう。
2. 欠損値を補完する
平均値/最頻値で補完する、平均から標準偏差でばらつきを考慮して補完する、といった選択肢があります。
どの方法をとるかは、データの性質や量などを元に選択していくことになります。
ちなみに、本章で取り上げているアヤメのサンプルデータには欠損値はあるのでしょうか。「実行結果2」で見た ESCR プロパティで確認することができます。
```
Missing Attribute Values: None
→ 欠損値はありません
```
##### スケーリング
説明変数 (特徴量) の値を一定の範囲に収める変換である正規化 (Min-Max normalization) 、データを平均 0、標準偏差が 1 になるように変換する標準化 (standardization, もしくは z-score normalization) の 2 つの手法が代表的です。
前者はデータの最大値と最小値が決まっている場合や、データの分布が一様である場合に有効で、主に[0, 1]か、[-1, 1]の範囲内に収めます。一方、外れ値が存在するような場合はデータの偏りを招いてしまうので注意しましょう。
後者は最大値と最小値が決まっていない場合や、外れ値のあるデータに対して有効です。
用いるデータの性質に合わせて適切にスケーリングを行いましょう。
##### マスキングによる個人情報保護
情報社会の現代、個人情報の取扱いについては徹底した管理が求められるようになっています。皆さんも顧客情報などの個人情報流出に関するニュースを見たことがあるのではないでしょうか。
機械学習でも、個人情報を扱うことがあります。細心の注意が必要な個人を特定する情報については、マスキングという処理を行うことが一般的になっています。
##### 画像や音声の加工
ノイズを除去する、一部を切り出す、画像の場合で色の情報が不要の場合はグレースケールにするなどといった加工をします。
データ量が少ないほど学習にかかる時間が短縮されますが、削り過ぎると結果の精度に悪影響を及ぼすため、適当な調整が必要です。
##### 水増し処理
学習効果を高めるためには一定量の学習データが必要になりますが、どうしてもデータが足りないといった事態に直面することがあります。そうした場合には、水増し処理を行うこともあります。
例えば、画像データを扱っている場合、サイズの拡大/縮小、回転/反転などの操作を行ったり、あえてノイズを加えたりすることで水増しすることができます。
一方、学習データは多ければ多いほど良い、というものではなく、学習させ過ぎると適用範囲が非常に狭くなってしまうという問題が発生しかねません(過学習)。
#### 4. データの仕分け
データはその用途に応じて、訓練データとテストデータとに分けます。前者はモデルが学習するのに用いるデータ、後者は学習済みモデルの精度を評価するために使うデータです。
全てのデータをこれらに二分する場合、テストデータは全体の 2 割〜 3 割程度にすることが望ましいとされています。
訓練データは少なすぎても精度が上がらず、多すぎても先述の過学習になってしまいます。
過学習を予防する方法はいくつもありますが、テストデータの割合を考慮するだけでも充分な精度が期待できます。
また、訓練データとテストデータの分け方でも、単純に「○番目までを訓練データ、それ以降をテストデータ」というように分ける方法もあれば、ランダムに振り分ける方法もあります。ランダムの方が訓練データの偏りを排除するのには適しているでしょう。
ここで、scikit-learn でプログラムを構築する場合の慣例について触れておきます。説明変数を X 、目的変数をy とし、さらに訓練データには _train 、テストデータに _test という文字列を変数名の末尾に加えるのがよいでしょう。ランダムに振り分けるなら、scikit-learnの train_test_split() を使うのが便利です。以下はその一例です。
###### 実行コード6
```
from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(irisdata.data, irisdata.target, test_size = 0.2, train_size = 0.8, shuffle = True)
```
※ train_test_split()でshuffle = True(訓練データの割当前にランダムな並び替えを行う)というキーワード引数を指定しているため、これ以降の実行結果において、こちらのテキストに掲載されているものと多少異なる結果になる可能性があります。エラーが出ない限りは正常に処理が実行できていますので、気にせず学習を進めていきましょう。
#### 5. モデルを作った学習
いよいよ、機械学習モデルを作って学習を行っていきます。
scikit-learn が提供している機械学習モデルを活用し、冒頭のアヤメの題材でも登場した分類モデル (SVC) であるサポートベクトルを使ってみましょう。
ここでは、線形分類モデルを作成します。1行目はインポートです。。
###### 実行コード7
```
from sklearn.svm import SVC
classifier = SVC(kernel = "linear", gamma = "scale")
```
gamma="scale" のキーワード引数が置かれていますが、ひとまず「エラーを防ぐため」とだけ理解しておきましょう。
fit メソッドを実行すると、学習が行われます。
###### 実行コード8
```
classifier.fit(x_train, y_train)
```
###### 実行結果8
```
SVC(kernel='linear')
```
これで機械学習モデルが作成できました。
#### 6. 性能の評価
学習済みモデルにテストデータを入れてモデルの評価を行います。
実行には predict メソッドを使います。print() で機械学習によって得られた結果を出力してみましょう。
###### 実行コード9
```
y_pred = classifier.predict(x_test)
print(y_pred)
```
###### 実行結果9 (例)
```
[0 0 2 2 1 2 2 1 0 0 0 1 2 0 0 1 1 1 2 1 0 0 2 2 2 2 1 2 1 1]
```
※ お手元の実行結果がこれと必ず一致する訳ではありませんのでご注意ください。エラーが出ていなければOKです。
では、テストデータの y_test と比較することで学習済みモデルの性能評価を行いましょう。まずは y_test を表示してみます。
###### 実行コード10
```
print(y_test)
```
###### 実行コード10 (例)
```
[0 0 2 2 1 2 2 1 0 0 0 1 2 0 0 1 1 1 2 1 0 0 2 2 2 2 1 1 1 1]
```
このままでは比較がしにくいので、y_pred と y_test がどれくらい合致しているか、数値で表示できるようにしましょう。
性能の評価方法はいくつもあるのですが、ここでは正答率 (accuracy_score) を用います。
###### 実行コード11
```
from sklearn import metrics
print(metrics.accuracy_score(y_test, y_pred))
```
###### 実行結果11 (例)
```
0.9666666666666667
```
上記の例では、96.67%になりました。
## 機械学習実践
さて、最後に、より実践的な例題を取り上げます。
過去の人口から、未来の人口を予測する機械学習モデルを作成していきます。予測には、回帰を使います。
使用するデータは、[e-stat](https://www.e-stat.go.jp/)という日本政府の統計ポータルが提供している、5年ごとの都道府県別人口データです。
全国データから東京都のみのデータを抽出し、「ある年の人口」から「その5年後の人口」を予測する線形回帰モデルを作ります。
具体的には、1920年から1995年までの人口データを訓練データとして学習し、2000年から2015年までを予測し、予測と実際とがどのぐらい合致しているのかを確認します。
### 数値分析 - 単回帰分析
JupyterLab で新規ノートブックを作成しましょう。
#### 準備
使用するライブラリをインポートします。Pandas, NumPy, Matplotlib, scikit-learn を以下のようにインポートしましょう。
###### 実行コード1
```
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model import LinearRegression
%matplotlib inline
```
データセットも用意していますので、[こちら](https://drive.google.com/file/d/1k7oQxBLNIj3S4VQR8-k1ti0ihfr9W4Fc/view?usp=sharing&export=download)からダウンロードしてください。ダウンロードが完了したら、JupyterLab で作成した新規ノートブックと同じディレクトリにアップロードしましょう。
#### CSVデータの読み込み
アップロードしたCSVファイルを読み込み、エラーが発生していないか確認するため、head() で先頭5行を出力してみましょう (なお、CSVファイルの文字コードはUTF-8 を指定してあります)。
###### 実行コード2
```
df = pd.read_csv("jp_population.csv")
df.head()
```
###### 実行結果2

都道府県コード、都道府県名、年齢5歳階級、元号、和暦 (年)、西暦 (年)、人口 (総数)、人口 (男)、人口 (女)が表示されているのを確認しましょう。
データの件数も見て見ましょう。
###### 実行コード3
```
df.shape
```
###### 実行結果3
```
(940, 9)
```
縦 940 行、横 9 列のデータであることがわかりました。
#### 東京都のデータの抽出
それでは、東京都の人口を予想するモデルを作っていきましょう。まず、読み込んだCSVファイルから、東京都のデータだけを取り出します。
###### 実行コード4
```
tokyo = df[df["都道府県名"] == "東京都"]
tokyo.head()
```
###### 実行結果4

ここでの人口予測は、ある年の人口から5年後の人口を予想するモデルとします。つまり、1920年の人口から1925年の人口を予想する、というように、説明変数(x)を n年の人口 とし、目的変数(y)を n+5年の人口 とします。
また、説明変数 x と目的変数 y を作成します。以下のコードのように、表データから人口データを抽出します。
###### 実行コード5
```
data_size = len(tokyo.index) #東京都のデータの行数
x = tokyo.iloc[0:(data_size - 1), [6]]
y = tokyo.iloc[1:data_size, [6]]
```
確認のため、x と y の値を先頭から5件出力しておきます。
###### 実行コード6
```
print(x[0:5])
print()
print(y[0:5])
```
###### 実行結果6
```
人口(総数)
240 3699428
241 4485144
242 5408678
243 6369919
244 7346983
人口(総数)
241 4485144
242 5408678
243 6369919
244 7346983
245 3488284
```
表データは5年おきですから、xとyの値は行1つ分だけずれて格納されていることが確認できます。
#### データの前処理
今回題材に使用しているデータには欠損値も、加工の必要もないので、データの前処理についてはスキップします。
#### 訓練データとテストデータの作成
ここまでで生成した x と y を、訓練データとテストデータに分けます。訓練データは1920年〜1995年まで(配列の15番目まで)、2000年〜2015年まで(配列の16番目以降)をテストデータとします。
###### 実行コード7
```
x_train = np.array(x[:16])
x_test = np.array(x[16:])
y_train = np.array(y[:16])
y_test = np.array(y[16:])
```
#### モデルの作成と学習
次に、モデルを作って学習を行います。線形回帰モデルを作成し、訓練データを読み込ませていきます。
今回は、手軽な線形回帰のモデルの一つである LinearRegression クラスを使用します。
###### 実行コード8
```
model = linear_model.LinearRegression()
model.fit(x_train, y_train)
```
###### 実行結果8
```
LinearRegression()
```
#### 性能の評価
上記で作成したモデルの性能を評価するため、テストデータ (x_test) をこのモデルに入れ、結果を計算、出力します。
実行結果 (配列の要素) は実数値になっていますので、整数値に変換します。
正解、即ち各年の実際の人口データは CSVファイル に記載されており、既に変数 y_test に代入していますので、それも出力の上、比較します。
###### 実行コード9
```
y_pred = model.predict(x_test)
y_pred = y_pred.astype(np.uint32) #整数値に変換
print('予測した東京都の人口(2000年~2015年)')
print(y_pred)
print('実際の東京都の人口(2000年~2015年)')
print(y_test)
```
###### 実行結果9
```
予測した東京都の人口(2000年~2015年)
[[12074725]
[12513803]
[13013100]]
実際の東京都の人口(2000年~2015年)
[[12576601]
[13159388]
[13515271]]
```
#### グラフで確認する
数値での比較でも良いのですが、グラフ化することで視覚的にわかりやすいようにして比較してみましょう。まずは、実測値 (1920年〜1995年まで) と予測値 (2000年〜2015年) を連結したデータ y_pred_gr を作ります。
###### 実行コード10
```
y_pred_gr = np.concatenate([y_train, y_pred])
years = list(tokyo.iloc[1:,5])
plt.plot(years, y_pred_gr, label='Predicted', color='red')
plt.plot(years, y, label='Actual', color='blue')
plt.xlabel('Years')
plt.ylabel('Population')
plt.title("Population in Tokyo")
plt.grid(True)
plt.legend(loc = "upper left")
```
###### 実行結果10

あまり精度が良くないように感じますね。精度を高めるためには、サンプルデータ量を増やす・何らかの前処理を加える・学習モデルを変えるなどの工夫が必要です。
## まとめ
本章では、scikit-learn ライブラリを使って機械学習のプログラム作成を行いました。また、NumPyやMatplotlibといった他ライブラリとの連携にも触れることができました。入門〜実践寄りの内容まで扱っていきましたが、取り上げた以外にも画像分析など、機械学習を活用できる範囲は多岐に渡ります。ぜひ引き続き、学習の幅を広げていってください。