筋肉で解決しないために。

日々出会うモノに対する考察をしたり、主に以下のテーマに関して書いています。 データサイエンス/人工知能/AI/機械学習/DeepLearning/Python//数学/統計学/統計処理

ナイーブベイズ分類をIrisデータセットへの実装

こんにちは、ワタルです。

はじめに

このエントリでは、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ナイーブベイズ分類を実装してみます。 サンプルデータは、Iris(アヤメ)という植物のデータで、3種類のアヤメについて、それぞれ50サンプルのデータに4つの特徴量が含まれています。

ナイーブベイズ分類をとてもかんたんに表現すると、それぞれの分類先に属する確率を計算し、確率が最も大きいクラスにそのサンプルを分類します。

数字は適当ですが、このようなイメージです。 例えば、Aさんがどのクラスに属するが分類してみたいとします。

Aさんが、クラス1に属する確率は70%、クラス2に属する確率は30%、クラス3に属する確率は50%と求めることが出来た時、Aさんはクラス1に属すると出力されます。

数学的な理解は、こちらのページがおすすめです。

第10回 ベイズ確率:機械学習 はじめよう|gihyo.jp … 技術評論社

それでは、実際に実装してみます。

おまじない

import pandas as pd
from pandas import Series,DataFrame

import matplotlib.pyplot as plt
import seaborn as sns

#Gaussian Naive Bayes のためのコード
from sklearn import datasets
from sklearn import metrics
from sklearn.naive_bayes import GaussianNB

Irisデータセットのインポート

from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
Y = iris.target

データセットの分割

#データを、テスト用とトレーニング用に分けます。

from sklearn.cross_validation import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=0)

ナイーブベイズ分類にて学習

#インスタンスの作成
model = GaussianNB()

#訓練データで学習
model.fit(X_train,Y_train)

>>>
GaussianNB(priors=None)

予測精度の確認

#分割しておいたテストデータを用いて、精度を確認します
predicted = model.predict(X_test)
expected = Y_test

print(metrics.accuracy_score(expected, predicted))

>>>
1.0

おぉ、1.0になりました。 ついでにお試しとして、データセットの分割具合を変えて、精度スコアを可視化してみましょう。

精度スコアの可視化

predict_score = []

#テストデータを10%から90%まで変化させて、そのスコアを出力します
for size in np.arange(0.1, 1,0.1): 
    X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=0,test_size = size)
    model = GaussianNB()
    model.fit(X_train,Y_train)
    predicted = model.predict(X_test)
    expected = Y_test
    predict_score.append(metrics.accuracy_score(expected, predicted))
X_test_size = np.arange(0.1, 1,0.1)
df_score = DataFrame(predict_score,columns=['predict_score'],index=X_test_size)
df_score

>>>
    predict_score
0.1    0.933333
0.2    0.966667
0.3    1.000000
0.4    0.933333
0.5    0.946667
0.6    0.944444
0.7    0.933962
0.8    0.933333
0.9    0.948148
#プロットします
plt.plot(X_test_size,predict_score,color = 'b')
plt.ylim(0.92,1.01)
plt.xlabel("test_size")
plt.ylabel("predict_score")
plt.xticks( np.arange(0.0, 1.0, 0.1) )
plt.hlines([1], 0, 1, linestyles="dashed")

plt.show()

>>>

f:id:watarumon:20180713152426p:plain

訓練データは多ければ多いほどよいわけではないことを体験することができましたね。

さいごに

今回は、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ナイーブベイズ分類を実装し、テストデータの分け方によって精度が変わる事を確認してみました。

お疲れ様でした!

それじゃー、また。

SVM(Support Vector Machines)による他クラス分類の実装と可視化

はじめに

このエントリでは、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、SVM(Support Vector Machines)を実装してみます。 サンプルデータは、Iris(アヤメ)という植物のデータで、3種類のアヤメについて、それぞれ50サンプルのデータに4つの特徴量が含まれています。

おまじない

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline

Irisデータセットのインポート

from sklearn import datasets

iris = datasets.load_iris()
X = iris.data
Y = iris.target

データセットの分割

from sklearn.cross_validation import train_test_split
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, random_state=3)  
#test_sizeを指定しないと0.25になります

モデル生成

今回は、SVCにおける4つのkernelを用いて、それぞれの精度を出して比較してみます。

from sklearn.svm import SVC

model_linear = SVC(kernel = 'linear')
model_poly = SVC(kernel = 'poly')
model_rbf = SVC(kernel = 'rbf')#kernelを指定しない時のデフォルトです
model_sigmoid = SVC(kernel = 'sigmoid')

モデルに学習させる

#それぞれのモデルを学習させます
model_linear.fit(X_train,Y_train)
model_poly.fit(X_train,Y_train)
model_rbf.fit(X_train,Y_train)
model_sigmoid.fit(X_train,Y_train)

>>>
SVC(C=1.0, cache_size=200, class_weight=None, coef0=0.0,
  decision_function_shape='ovr', degree=3, gamma='auto', kernel='sigmoid',
  max_iter=-1, probability=False, random_state=None, shrinking=True,
  tol=0.001, verbose=False)
#これはsigmoidのときの出力です

モデルの精度確認

テストデータを入れて、モデルの精度を確認します

from sklearn import metrics

predicted_linear = model_linear.predict(X_test)
expected_linear = Y_test
print(metrics.accuracy_score(expected_linear,predicted_linear))

predicted_poly = model_poly.predict(X_test)
expected_poly = Y_test
print(metrics.accuracy_score(expected_poly,predicted_poly))

predicted_rbf = model_rbf.predict(X_test)
expected_rbf = Y_test
print(metrics.accuracy_score(expected_rbf,predicted_rbf))

predicted_sigmoid = model_sigmoid.predict(X_test)
expected_sigmoid = Y_test
print(metrics.accuracy_score(expected_sigmoid,predicted_sigmoid))

>>>
0.9736842105263158
0.9473684210526315
0.9736842105263158
0.2894736842105263

今回の場合では、rbfとlinearの精度が高くでていることがわかりました。

モデルの可視化

最後に下記サイト、及び公式ドキュメントを参考に、ここまでで行ったモデルの可視化に挑戦してみます http://www.tsjshg.info/udemy/Lec82-83.html

from sklearn import svm

#図示できるのが2次元までなので、変数を2つに絞ります。
X = iris.data[:,:2]
Y = iris.target

#SVMの正則化パラメータ
C = 1.0  

#SVC with a Linear Kernel
svc = svm.SVC(kernel='linear', C=C).fit(X, Y)

#Gaussian Radial Bassis Function
rbf_svc = svm.SVC(kernel='rbf', gamma=0.7, C=C).fit(X, Y)

#SVC with 3rd degree poynomial
poly_svc = svm.SVC(kernel='poly', degree=3, C=C).fit(X, Y)

#SVC Linear
lin_svc = svm.LinearSVC(C=C).fit(X,Y)

#step size
h = 0.02

#X軸の最大最小
x_min=X[:, 0].min() - 1
x_max =X[:, 0].max() + 1

#Y軸の最大最小
y_min = X[:, 1].min() - 1
y_max = X[:, 1].max() + 1

#meshgridを作ります。
xx, yy = np.meshgrid(np.arange(x_min, x_max, h),np.arange(y_min, y_max, h))

titles = ['SVC with linear kernel',
          'LinearSVC (linear kernel)',
          'SVC with RBF kernel',
          'SVC with polynomial (degree 3) kernel']

for i, clf in enumerate((svc, lin_svc, rbf_svc, poly_svc)):
    
#境界線を描画します。
    plt.figure(figsize=(15,15))
    plt.subplot(2, 2, i + 1)
    plt.subplots_adjust(wspace=0.4, hspace=0.4)
    
    Z = clf.predict(np.c_[xx.ravel(), yy.ravel()])
    Z = Z.reshape(xx.shape)
    
    plt.contourf(xx, yy, Z, cmap=plt.cm.terrain, alpha=0.5,linewidths=0)
    plt.scatter(X[:, 0], X[:, 1], c=Y, cmap=plt.cm.Dark2)
    
    plt.xlabel('Sepal length')
    plt.ylabel('Sepal width')
    plt.xlim(xx.min(), xx.max())
    plt.ylim(yy.min(), yy.max())
    plt.xticks(())
    plt.yticks(())
    plt.title(titles[i])
plt.show()

>>>

f:id:watarumon:20180711154133p:plain

f:id:watarumon:20180711154144p:plain

f:id:watarumon:20180711154154p:plain

f:id:watarumon:20180711154204p:plain

さいごに

今回は、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、SVC(Support Vector Machines)を実装し、4種類のkernelを比較してみました。

お疲れ様でした!

それじゃー、また。

k近傍法やロジスティック回帰を使った多クラス分類の実装

はじめに

このエントリでは、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ロジスティック回帰を用いた多クラス分類やk近傍法を実装してみます。 サンプルデータは、Iris(アヤメ)という植物のデータで、3種類のアヤメについて、それぞれ50サンプルのデータに4つの特徴量が含まれています。

おまじない

#前処理
import numpy as np
import pandas as pd
from pandas import Series,DataFrame

#可視化
import matplotlib.pyplot as plt
import seaborn as sns
sns.set_style('whitegrid')
%matplotlib inline

#機械学習
from sklearn import linear_model
from sklearn.datasets import load_iris
from sklearn import metrics

目的とタスクの設定

目的とタスクの設定をするために、まずは元データをみてみます。

#データセットのロード
iris = load_iris()

#説明変数をXとする
X = iris.data

#目的変数をYとする
Y = iris.target
X[1:5]

>>>
array([[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]])
Y

>>>
array([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])

まずは、可視化するためにXとYをdataframeにして、seabornでプロットしてみようと思います。 これをタスク1と呼ぶことにします。

データの傾向をつかんだところで、ロジスティック回帰を実装してみます。 これをタスク2と呼ぶことにします。

最後に、k近傍法を実装し、適切なkの値について検討を行ってみます。 これをタスク3と呼ぶことにします。

タスク1

#Xをdataframeにし、カラム名をつけます
iris_data = DataFrame(X,columns=['Sepal Length','Sepal Width','Petal Length','Petal Width'])

#Yをdataframeにし、カラム名をつけます
iris_target = DataFrame(Y,columns=['Species'])
#Yの要素を名前に置き換えます
def flower(num):
    ''' 数字を受け取って、対応する名前を返します。'''
    if num == 0:
        return 'Setosa'
    elif num == 1:
        return 'Veriscolour'
    else:
        return 'Virginica'

iris_target['Species'] = iris_target['Species'].apply(flower)
iris_target.head()

>>>
Species
0  Setosa
1  Setosa
2  Setosa
3  Setosa
4  Setosa
#XとYをまとめます
iris = pd.concat([iris_data,iris_target],axis=1)
iris.head()

>>>
    Sepal Length    Sepal Width Petal Length    Petal Width Species
0  5.1    3.5    1.4    0.2    Setosa
1  4.9    3.0    1.4    0.2    Setosa
2  4.7    3.2    1.3    0.2    Setosa
3  4.6    3.1    1.5    0.2    Setosa
4  5.0    3.6    1.4    0.2    Setosa

ここまでで、可視化の前処理が終わりました。 プロットします。

sns.pairplot(iris,hue='Species')

>>>

f:id:watarumon:20180711132955p:plain

Setosaは最も特徴的な目的変数であることが見て取れます。

タスク2

ロジスティック回帰を実装します。

#ロジスティック回帰のインスタンスを作成
logreg = LogisticRegression()

#データを訓練データとテストデータに分割します。この場合ではテストが全体の40%になるようにしています。
#再現性のため引数random_stateを設定しています。実際の機械学習では用いないことが多いです。
X_train, X_test, Y_train, Y_test = train_test_split(X, Y, test_size=0.4,random_state=3)

#訓練データを使って学習させます。
logreg.fit(X_train, Y_train)

テストデータを用いて、モデルの精度を確認します。

Y_pred = logreg.predict(X_test)

# 精度を比較してみます
print(metrics.accuracy_score(Y_test,Y_pred)

>>>
0.933333333333

60%の訓練データ、40%がテストデータにて、ロジスティック回帰でモデルを作成した場合では、93%の精度が得られました。

タスク3

k近傍法によるモデルを実装し、適切なkの値について検討を行ってみます。

from sklearn.neighbors import KNeighborsClassifier

#k=1のとき、つまりもっとも近いサンプルの分類がその分類と等しいと予測するモデルです
#インスタンスを作ります
knn = KNeighborsClassifier(n_neighbors = 1)

#訓練データを使って学習させます
knn.fit(X_train,Y_train)

#テストデータで予測をします
Y_pred = knn.predict(X_test)

#精度を調べてみます
print(metrics.accuracy_score(Y_test,Y_pred))

>>>
0.9666666666666667

最後に、kの値を任意に変化させてプロットすることで、適切なkの値について検討してみます。

k_range = range(1, 90)
accuracy = []

for k in k_range:
    knn = KNeighborsClassifier(n_neighbors=k)
    knn.fit(X_train, Y_train)
    Y_pred = knn.predict(X_test)
    accuracy.append(metrics.accuracy_score(Y_test, Y_pred))
print (type(accuracy))
print (type(k_range))

>>>
<class 'list'>
<class 'range'>

kの変化をk_rangeに、精度の変化をaccuracyというlistにすることができました。

plt.plot(k_range, accuracy)
plt.xlabel('K')
plt.ylabel('Testing Accuracy')

>>>

f:id:watarumon:20180711133007p:plain

値を確認してみます。

df = DataFrame(accuracy,columns=['accuracy'],index=k_range)
df[50:60]

>>>
    accuracy
51 0.850000
52 0.850000
53 0.850000
54 0.900000
55 0.833333
56 0.850000
57 0.816667
58 0.500000
59 0.500000
60 0.500000

今回の訓練データとテストデータの分け方では、k=57とk=58に大きな差があることがわかりました。

さいごに

今回は、機械学習のサンプルデータとしてよく用いられるIrisのデータに対して、ロジスティック回帰を用いた多クラス分類やk近傍法を実装することができました。

お疲れ様でした!

それじゃー、また。

searborn入門第3回目、「ヒートマップとクラスターマップ」

こんにちは、ワタルです。

さっと見て、「あぁそうだったそうだった」と確認できるハンドブックのような存在を目指して。

searborn入門第3回目、「ヒートマップとクラスターマップ」です。

はじめに

このエントリでは、seabornのサンプルデータを用いてヒートマップとクラスターマップを描く手法について学びます。 以下の関数を学習することができます。

sns.load_dataset("flight_dframe")(サンプルデータの取得)
dataframe.pivot('a','b','c')(ピボットテーブルに形成)
seaborn.heatmap()(ヒートマップを描く)
seaborn.clustermap()(クラスターマップを描く)

おまじない

import numpy as np
from numpy.random import randn
import pandas as pd

from scipy import stats

import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline

サンプルデータの取得

#Seabornにサンプルデータがあります。
flight_dframe = sns.load_dataset("flight_dframe")

または、Githubから取得することもできます。 https://github.com/mwaskom/seaborn-data/blob/master/flights.csv

csvの場合は、pd.read_csv("tips.csv")で読み込むことができます。

取得したdataframeを表示します。

flight_dframe.head()

>>>
    year    month   passengers
0  1949   January     112
1  1949   February    118
2  1949   March       132
3  1949   April       129
4  1949   May         121

dataframe.pivot('a','b','c')(ピボットテーブルに形成)

第一引数は、index 第二引数は、columns 第三引数は、values を意味しています。

flight_dframe = flight_dframe.pivot('month','year','passengers')
flight_dframe

>>>
    year    1949   1950   1951   1952   1953   1954   1955   1956   1957   1958   1959   1960
month                                               
April       129    135    163    181    235    227    269    313    348    348    396    461
August      148    170    199    242    272    293    347    405    467    505    559    606
December    118    140    166    194    201    229    278    306    336    337    405    432
February    118    126    150    180    196    188    233    277    301    318    342    391
January     112    115    145    171    196    204    242    284    315    340    360    417
July        148    170    199    230    264    302    364    413    465    491    548    622
June        135    149    178    218    243    264    315    374    422    435    472    535
March       132    141    178    193    236    235    267    317    356    362    406    419
May         121    125    172    183    229    234    270    318    355    363    420    472
November    104    114    146    172    180    203    237    271    305    310    362    390
October     119    133    162    191    211    229    274    306    347    359    407    461
September   136    158    184    209    237    259    312    355    404    404    463    508
December    118    140    166    194    201    229    278    306    336    337    405    432

seaborn.heatmap()(ヒートマップを描く)

#引数cmapは色の指定
カラーコードはこちら
https://matplotlib.org/examples/color/colormaps_reference.html
#annotにTrueを指定するとそれぞれの値を表示します
#fmtは出力フォーマットを指定しています
sns.heatmap(flight_dframe,cmap='OrRd', annot=True, fmt='d')

>>>

f:id:watarumon:20180703183456p:plain

中心を指定して、色を変える

ここでは、April,1955を中心に描いてみます。

sns.heatmap(flight_dframe, center=flight_dframe.loc['April ',1955],cmap='bwr')

>>>

f:id:watarumon:20180703183509p:plain

seaborn.clustermap()(クラスターマップを描く)

ここでは、データを規格化した結果を描画します。 これは、似たものを分類するクラスター分析を行った結果になります。

sns.clustermap(flight_dframe,cmap='OrRd', standard_scale=1)

f:id:watarumon:20180703183524p:plain

今回は、少し短いですが、seabornのサンプルデータを用いてヒートマップとクラスターマップを描く手法について学びました。

お疲れ様でした!

それじゃー、また。

seaborn入門2_「回帰とプロット」

こんにちは、ワタルです。

さっと見て、「あぁそうだったそうだった」と確認できるハンドブックのような存在を目指して。

searborn入門第2回目、「回帰とプロット」です。

はじめに

このエントリでは、seabornのサンプルデータを用いて様々な回帰曲線を描く手法について学びます。 以下の関数を学習することができます。

tips = sns.load_dataset("tips")(サンプルデータの取得)
sns.lmplot("x","y",dataframe)(単回帰曲線の可視化)
sns.lmplot("x","y",dataframe,
                   scatter_kws={'marker':'o', 'color':'indianred'},
                   line_kws={'linewidth':1, 'color':'blue'})(様々な引数)
fig, (axis1,axis2) = plt.subplots(1,2,sharey =True)(複数のグラフを同時にプロットする)

おまじない

import numpy as np
from numpy.random import randn
import pandas as pd

from scipy import stats

import matplotlib as mpl
import matplotlib.pyplot as plt
import seaborn as sns

%matplotlib inline

サンプルデータの取得

#Seabornにサンプルデータがあります。
tips = sns.load_dataset("tips")

または、Githubから取得することもできます。

csvの場合は、pd.read_csv("tips.csv")で読み込むことができます。

取得したdataframeを表示します。

tips.head()

>>>
  total_bill tip sex smoker day time sise
0  16.99  1.01   Female  No  Sun Dinner  2
1  10.34  1.66   Male    No  Sun Dinner  3
2  21.01  3.50   Male    No  Sun Dinner  3
3  23.68  3.31   Male    No  Sun Dinner  2
4  24.59  3.61   Female  No  Sun Dinner  4

seaborn.lmplot("x","y",dataframe)(単回帰曲線の可視化)

seabornを用いることで、簡単に単回帰曲線を可視化することができます。

sns.lmplot("total_bill","tip",tips)

>>>

f:id:watarumon:20180702165335p:plain

グラフの様々な引数

プロット点や線の色などを指定することもできます。

sns.lmplot("total_bill","tip",tips,
                   scatter_kws={'marker':'o', 'color':'indianred'},
                   line_kws={'linewidth':1, 'color':'blue'})
>>>

f:id:watarumon:20180702165347p:plain

引数order(多項式回帰の可視化)

seabornでは、多項式回帰も簡単に描くことが出来ます。

sns.lmplot("total_bill", "tip", tips, order=4,
           scatter_kws={"marker": "o", "color": "indianred"},
           line_kws={"linewidth": 1, "color": "blue"})

f:id:watarumon:20180702165357p:plain

引数fit_reg(散布図の可視化)

fit_reg=Falseを指定することで、散布図のみを描画することができます。

sns.lmplot("total_bill", "tip", tips,fit_reg=False)

>>>

f:id:watarumon:20180702165409p:plain

離散的な値の散布図の可視化

lmplotでは、離散的な値でも問題なく可視化することができます。

#チップの割合を表す、tip_pectを計算した後、描画します

tips["tip_pect"]=100*(tips['tip']/tips['total_bill'])
sns.lmplot("size", "tip_pect", tips)

>>>

f:id:watarumon:20180702165423p:plain

引数x_estimator(特定の推定量とその回帰を可視化)

引数x_estimatorでは、x 軸の各値に指定された関数を実行し、その返り値をプロットします。 そのプロットに対する回帰を可視化することができます。

#関数に平均を指定してみます
sns.lmplot("size", "tip_pect", tips, x_estimator=np.mean);

>>>

f:id:watarumon:20180702165437p:plain

引数hue(色合いを変える)

hueとは、色合い/色調という意味の英単語で、hueを指定することで、うまく色分けして可視化することができます。

sns.lmplot("total_bill", "tip_pect", tips, hue="sex",markers=["x","o"])

>>>

f:id:watarumon:20180702165449p:plain

グラフの分割表示

複数のグラフを同時に表示することも簡単にできます。 subplots( )の第一引数はグラフの行数を、第二引数はグラフの列数をあらわしています。

fig, (axis1,axis2) = plt.subplots(1,2,sharey =True)

sns.regplot("total_bill","tip_pect",tips,ax=axis1)
sns.violinplot(y='tip_pect', x='size', data=tips.sort('size') ,ax=axis2)

f:id:watarumon:20180702165600p:plain

今回は、seabornのサンプルデータを用いて様々な回帰曲線を中心としたデータ可視化手法について学びました。

お疲れ様でした! 次回はこちら

watarumon.hatenablog.com

それじゃー、また。

seaborn入門_「様々なデータの可視化手法」

こんにちは、ワタルです。

さっと見て、「あぁそうだったそうだった」と確認できるハンドブックのような存在を目指して。

pandas入門第1回目、「様々なデータの可視化手法」です。

はじめに

このエントリでは、以下の関数を学習することができます。

pyplot.hist(data)
seaborn.jointplot(data1,data2)
seaborn.distplot(data)
seaborn.boxplot(data)
seaborn.violinplot(data)

おまじない

import numpy as np
from numpy.random import randn
import pandas as pd

#描画のためのライブラリです。
import matplotlib.pyplot as plt
import seaborn as sns

# ブラウザ内に画像を埋め込むための命令です
%matplotlib inline

ヒストグラムをプロットする

ヒストグラムを描くことで、データの概要をつかむことができます。

#正規分布に従う乱数を作ります。
dataset1 = randn(100)

plt.hist(dataset1)
#デフォルトは、bins=10
#binsというのは、ヒストグラムの棒の数

>>>
(array([ 2.,  2.,  6., 19., 16., 23., 16.,  9.,  4.,  3.]),
 array([-2.4821785 , -1.99590527, -1.50963205, -1.02335882, -0.5370856 ,
        -0.05081237,  0.43546086,  0.92173408,  1.40800731,  1.89428053,
         2.38055376]),

f:id:watarumon:20180630182347p:plain

引数color

#データセットをもう一つ作ります。
dataset2 = randn(80)

#引数colorで色を指定することができます
plt.hist(dataset2,color='indianred')

>>>
(array([ 3.,  6., 10., 15., 25., 11.,  8.,  1.,  0.,  1.]),
 array([-2.53975366, -1.9111417 , -1.28252975, -0.65391779, -0.02530583,
         0.60330612,  1.23191808,  1.86053004,  2.48914199,  3.11775395,
         3.7463659 ]),

f:id:watarumon:20180630182400p:plain

引数normed

plt.hist(dataset1, normed=True)

>>>
(array([ 0.24336855,  0.2704095 ,  0.2163276 ,  0.2163276 ,  0.40561425,
         0.40561425,  0.3244914 ,  0.29745045,  0.18928665,  0.13520475]),
 array([-1.7284242 , -1.35861471, -0.98880522, -0.61899573, -0.24918624,
         0.12062325,  0.49043274,  0.86024223,  1.23005172,  1.59986121,
         1.9696707 ]),
 <a list of 10 Patch objects>)

f:id:watarumon:20180630182424p:plain

2つのヒストグラムを同時にプロットする

複数のヒストグラムを同時にプロットすることもできます。

plt.hist(dataset1,normed=True,alpha=0.5,bins=20)
plt.hist(dataset2,normed=True,alpha=0.5,bins=20, color='indianred')

>>>
(array([0.03977016, 0.07954033, 0.03977016, 0.19885082, 0.07954033,
        0.3181613 , 0.35793147, 0.23862098, 0.47724196, 0.51701212,
        0.23862098, 0.19885082, 0.07954033, 0.23862098, 0.03977016,
        0.        , 0.        , 0.        , 0.        , 0.03977016]),
 array([-2.53975366, -2.22544768, -1.9111417 , -1.59683573, -1.28252975,
        -0.96822377, -0.65391779, -0.33961181, -0.02530583,  0.28900014,
         0.60330612,  0.9176121 ,  1.23191808,  1.54622406,  1.86053004,
         2.17483601,  2.48914199,  2.80344797,  3.11775395,  3.43205993,
         3.7463659 ]),
 <a list of 20 Patch objects>)

f:id:watarumon:20180630183332p:plain

sns.jointplot(data1,data2)結合分布表示

先ほどよりデータ点を増やして、それぞれをx軸、y軸におき、同時にプロットすることもできます。 これによって、データの粗密を感じることができます。

data1 = randn(1000)
data2 = randn(1000)

# 同時分布(結合分布)
sns.jointplot(data1,data2)

>>>
<seaborn.axisgrid.JointGrid at 0x1a1d155cc0>

f:id:watarumon:20180630183343p:plain

引数kind

引数にkind='hex'を与えると、六角形で表示されます。

sns.jointplot(data1,data2,kind='hex')

>>>

f:id:watarumon:20180630183354p:plain

カーネル密度推定のプロット

カーネル密度推定 - Wikipedia

ここでは、ヒストグラムカーネル密度推定を同時にプロットしてみます。 引数で色やラベルを指定することもできます。

sns.distplot(data1,
             kde_kws={'color':'indianred','label':'KDE PLOT'},
             hist_kws={'color':'blue','label':"HISTOGRAM"})
>>>

f:id:watarumon:20180630183451p:plain

seaborn.boxplot(data)箱ひげ図のプロット

boxplotというメソッドでは、日本語でいう箱ひげ図を描くことができます。

箱ひげ図 - Wikipedia

sns.boxplot(data1)

>>>

f:id:watarumon:20180630183504p:plain

seaborn.violinplot(data)バイオリン図を描く

violinplotは、boxplotの様な外形をしつつ、カーネル密度推定の情報量を兼ね備えたものになります。

バイオリン図 - Wikipedia

sns.violinplot(data1)

>>>

f:id:watarumon:20180630183515p:plain

終わりに

今回は、様々なデータの可視化方法について学びました。

お疲れ様でした!

次回はこちら

watarumon.hatenablog.com

それじゃー、また。

多重回帰分析の実装、そして儚さ。

こんにちは、ワタルです。

はじめに

今回は、多重回帰分析について、理論的な仕組みを理解できるよう解説しつつ、実装してみようと思います。 さらに、その実装がseabornであれば1行で終わってしまう儚さを体験しつつ、seabornにおける多重回帰分析のメソッドを学びたいと思います。

数学的に厳密には正しくない説明になっている箇所もあるかと思います。説明に違和感を覚える方がいましたら是非勉強させていただきますので、コメントを頂けましたらと思います。

目的

今回は、以下のデータ群に対して、基底関数として3次項までの多項式基底を用い、推定モデルを算出することが目的になります。

f:id:watarumon:20180628202613p:plain

線形回帰とは

計算に入る前に簡単に線形回帰について解説してみたいと思います。

まず、回帰とは、与えられたデータに適した関数を求める手法のことで、線形回帰とは、回帰分析の中の1つの手法のことを指します。

線形回帰の中でも、基底関数に多項式基底を用いた手法を多重回帰分析と呼びます。

ちなみに、基底関数に1次元項までの場合、単回帰分析と呼びます。

多重回帰分析の実装

さあ実装していきます。

まずはおまじないです。

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
import seaborn as sns

データ群を確認します。

X = np.array([0.02, 0.12, 0.19, 0.27, 0.42, 0.51, 0.64, 0.84, 0.88, 0.99])
t = np.array([0.05, 0.87, 0.94, 0.92, 0.54, -0.11, -0.78, -0.89, -0.79, -0.04])
plt.scatter(X,t)

f:id:watarumon:20180628202613p:plain

天下り的ですが、ここで、3次関数っぽいなという感覚から今回は、3次多項式基底を用いることを思いつきます。 簡単のため、正規化項や過学習については、他のwebページに譲ることとします。

思いついたモデルは、係数w_0,w_1,w_2,w_3が4×1の行列Wとすると、その解tの行列Tを用いて、このように記述することができます。

XW = T

ここで、Xの要素を求めるphi(x)を求めます。

def phi(x):
    return [1, x, x**2, x**3]
PHI = np.array([phi(x) for x in X])

次に、二乗誤差を算出するために、Xの転置行列で左から積を取り、 さらに左からその逆行列の積を取ることで、Wを求めます。

W = (X^{T}X)^{-1}X^{T}T

w = np.linalg.solve(np.dot(PHI.T, PHI), np.dot(PHI.T, t))

最後にプロットします。

def f(w, x):
    return np.dot(w, phi(x))
xlist = np.arange(0, 1, 0.01)
ylist = [f(w, x) for x in xlist]
plt.plot(xlist, ylist)
plt.plot(X, t, 'o')

f:id:watarumon:20180628202719p:plain

ここまでで、よくできた重回帰モデルができました。

seabornを用いて多重回帰分析の実装

次にseabornを用いて、ここまでの計算を1から行ってみます。

おまじないは同じなので省略します。

X = np.array([0.02, 0.12, 0.19, 0.27, 0.42, 0.51, 0.64, 0.84, 0.88, 0.99])
t = np.array([0.05, 0.87, 0.94, 0.92, 0.54, -0.11, -0.78, -0.89, -0.79, -0.04])
sns.regplot(X,t,order=3)

f:id:watarumon:20180628202733p:plain

終わってしまいました。。。

このように、regplotに引数(order=3)をしたことで、3次項までの重回帰分析を行うことができます。

終わりに

今回は、多重回帰分析について、理論的な仕組みを理解しつつ、seabornにおける多重回帰分析のメソッドを学びました。

この様に、seabornやscikit-learnを用いると、あっという間に計算出来てしまいますが、一度くらいはせこせこと実装してみると勉強になると思います。