[機械学習]機械学習教科書Ch 03-(1)

6349 ワード

第三章機械学習分類モデルの旅


ペンシルデータセット


datasets.load iris()を使用してペン花データセットをロードする
from sklearn import datasets
import numpy as np

iris = datasets.load_iris()
X = iris.data[:, [2, 3]]
y = iris.target

print('클래스 레이블:', np.unique(y))
test size=0.3 70%のトレーニングデータを30%のテストデータに分割(階層化)
from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, random_state=1, stratify=y)
データ特性を変換するツールはSikittrunの前処理モジュールである.
プロパティの標準化StandardScalerで定義したフィット(Fit)を標準化スコア(StandardScaler)に変更し、transformに変換します.
from sklearn.preprocessing import StandardScaler

sc = StandardScaler()
sc.fit(X_train)
X_train_std = sc.transform(X_train)
X_test_std = sc.transform(X_test)
プロパティを変換するときにサンプルがどのクラスであるかを知る必要はありません.そのためfitに入力データのみを提供しますが、指導学習では常にターゲットデータをfitに渡す必要があります.
誤分類のサンプル個数計算→予測とテストの異なる個数処理→sumをtrueとして処理し,個数を加算する.
y_pred = ppn.predict(X_test_std)
print('잘못 분류된 샘플 개수: %d' % (y_test != y_pred).sum())
典型的な分類問題では、誤った分類ではなくパーセントで分類します!->せいどで計算する
コースコースでは精度scoreで計算できます.
また、Sikittrunの分類クラスはモデルクラスに得点方法を提供します!
だから精度を計算するために.
from sklearn.metrics import accuracy_score

print('정확도: %.3f' % accuracy_score(y_test, y_pred))
または精度を下に計算
print('정확도: %.3f' % ppn.score(X_test_std, y_test))
分類日は精度
回帰日はr²けいさんち
予測時にクラスラベルは返されません.
予測された確率を返し、返される確率がどれほど強いかを確認します->論理回帰
回帰と書いてありますが、回帰ではなく、分類モデルです.

論理回帰を用いたクラス確率モデリング


ロジック回帰アルゴリズム


オズビー:特定のイベントが発生する確率が成功確率pの場合、p/{1−p}で計算します.
logit(P)=log(p/{1-p})

範囲によっては、論理関数は-infからinfの間の値を有するため、線形方程式として使用することができる.

つまりpを再整理すれば.

この関数を信号関数またはロジャーズ関数と呼びます.
Pythonコードを使います.

def sigmoid(z):
    return 1.0 / (1.0 + np.exp(-z))
信号関数は0と1の間で値をとるので,確率で考えやすい.

信号関数の応用はアダリンアルゴリズムの活性化関数が線形関数(恒等関数)であるようにした.
Logistic Regressionの場合、信号関数としてアクティブ関数が使用されます.信号活性化関数により,任意の実数値を0と1の間に圧縮し,これは確率である!結果が0.5以上の場合は陽性とみなされ、小さい場合は陰性とみなされる

学習ロジックコスト関数の重み


論理原価関数の定義




y=1の場合Φ(z)損失を最小限に抑えるために1に近づくべきである.
y=0の場合Φ(z)0に近づくと,損失が最小化される.
今では傾斜降下法で問題を解くことができます.
class LogisticRegressionGD(object):
    """경사 하강법을 사용한 로지스틱 회귀 분류기

    매개변수
    ------------
    eta : float
      학습률 (0.0과 1.0 사이)
    n_iter : int
      훈련 데이터셋 반복 횟수
    random_state : int
      가중치 무작위 초기화를 위한 난수 생성기 시드

    속성
    -----------
    w_ : 1d-array
      학습된 가중치
    cost_ : list
      에포크마다 누적된 로지스틱 비용 함수 값

    """
    def __init__(self, eta=0.05, n_iter=100, random_state=1):
        self.eta = eta
        self.n_iter = n_iter
        self.random_state = random_state

    def fit(self, X, y):
        """훈련 데이터 학습

        매개변수
        ----------
        X : {array-like}, shape = [n_samples, n_features]
          n_samples 개의 샘플과 n_features 개의 특성으로 이루어진 훈련 데이터
        y : array-like, shape = [n_samples]
          타깃값

        반환값
        -------
        self : object

        """
        rgen = np.random.RandomState(self.random_state)
        self.w_ = rgen.normal(loc=0.0, scale=0.01, size=1 + X.shape[1])
        self.cost_ = []

        for i in range(self.n_iter):
            net_input = self.net_input(X)
            output = self.activation(net_input)
            errors = (y - output)
            self.w_[1:] += self.eta * X.T.dot(errors)
            self.w_[0] += self.eta * errors.sum()
            
            # 오차 제곱합 대신 로지스틱 비용을 계산합니다.
            cost = -y.dot(np.log(output)) - ((1 - y).dot(np.log(1 - output)))
            self.cost_.append(cost)
        return self
    
    def net_input(self, X):
        """최종 입력 계산"""
        return np.dot(X, self.w_[1:]) + self.w_[0]

    def activation(self, z):
        """로지스틱 시그모이드 활성화 계산"""
        # 대신 from scipy.special import expit; expit(z) 을 사용할 수 있습니다.
        return 1. / (1. + np.exp(-np.clip(z, -250, 250)))

    def predict(self, X):
        """단위 계단 함수를 사용하여 클래스 레이블을 반환합니다"""
        return np.where(self.net_input(X) >= 0.0, 1, 0)
        # 다음과 동일합니다.
        # return np.where(self.activation(self.net_input(X)) >= 0.5, 1, 0)
セキレンはロジス回帰モデルを訓練し、線形モデルのsklearnを持っている.linear modelライブラリにLogisticRegressionクラスをインポートする
LogisticRegressionオブジェクトを生成し,fitを用いて訓練データと目標データを入れる(Sikittrunは複数のクラスをうまくサポートしているので,3つのクラスを入れる),決定境界から見るとほぼ同等の精度で3つの結果が見られる.
from sklearn.linear_model import LogisticRegression

lr = LogisticRegression(C=100.0, random_state=1)
lr.fit(X_train_std, y_train)

plot_decision_regions(X_combined_std, y_combined,
                      classifier=lr, test_idx=range(105, 150))
plt.xlabel('petal length [standardized]')
plt.ylabel('petal width [standardized]')
plt.legend(loc='upper left')
plt.tight_layout()
# plt.savefig('images/03_06.png', dpi=300)
plt.show()

コンプライアンス


まっすぐな左の直線と曲がった右の直線から見ると
左側は小さすぎて一致し,オフセットが大きいことを示した.
右側は誇張が適当で、分散性が大きい.
適切すぎると、モデルを少し変更したり、新しいサンプルを追加したりすれば、意思決定界は大きく変化します.
したがって,中間のように各クラスのほぼ位置傾向をうまく反映できるグラフは,分散と偏向のバランスの取れた決定である.
モデルが高すぎると、制限が増加し、高すぎる適用性が低下します.
小さすぎると、制限を低減し、より複雑なモデルを作成します.これらの制限を行うのは,上のコードのLogisticRegression(C=100.0.C)である.

C値が小さいほど制限が大きくなるので重み付け値は小さくなります.(簡易型番)
C値が大きいほど制限が緩やかになるので重み付け値が大きくなる.