Optimization
43422 ワード
Stochastic Gradient Descent (SGD)
1. SGD Classifier
import pandas as pd
fish = pd.read_csv('https://bit.ly/fish_csv_data')
fish_input = fish[['Weight','Length','Diagonal','Height','Width']].to_numpy()
fish_target = fish['Species'].to_numpy()
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
fish_input, fish_target, random_state=42)
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_input)
train_scaled = ss.transform(train_input)
test_scaled = ss.transform(test_input)
scikit−learnにおいて確率傾斜降下法を提供する代表分類クラスはSGDClassifier
である.SGD Classifierでオブジェクトを作成する場合は、2つのパラメータを指定します.
loss
=損失関数のタイプを指定max_iter
=実行するフォークリフトの回数を指定from sklearn.linear_model import SGDClassifier
sc = SGDClassifier(loss='log', max_iter=10, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
# 0.773109243697479
print(sc.score(test_scaled, test_target))
# 0.775
出力されたトレーニングキットとテストキットは精度が低い.確率傾斜降下法は
점진적
を学ぶことができる.訓練したモデルscを再訓練する.
型継ぎ訓練は
partial_fit()
法を採用した.この方法はfit()メソッドと同様ですが、呼び出すたびに1つのフォークでトレーニングできます.
sc.partial_fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
# 0.8151260504201681
print(sc.score(test_scaled, test_target))
# 0.85
点数はまだ低いが、エポックをもう一度実行すると精度が上がる.このモデルを複数のエポックドで訓練する必要があり,多訓練の基準が必要である.
2. Epoch and Overfitting/Underfitting
確率傾斜降下法を用いたモデルでは,エポック回数によっては不適合やオーバーフィットが生じる可能性がある.
적은 에포크 횟수
期間中に訓練したモデルは、学習が少ないためunderfitting
のモデルになった可能性が高い.逆に、
많은 에포크 횟수
期間中に訓練したモデルは訓練セットに適しており、テストセットでは点数が逆に低く、overfitting
のモデルである可能性が高い.トレーニングセットの点数はエポックが進むにつれて増加していくが、テストセットの点数はある瞬間減少する.この場所のこのモデルは
overfitting되기 시작하는 곳
です.ここでは
partial_fit()
メソッドのみを用いるが,これを行うには訓練セットのすべてのクラスのラベルをpartial fit()メソッドに渡す必要がある.import numpy as np
sc = SGDClassifier(loss='log', random_state=42)
train_score = []
test_score = []
classes = np.unique(train_target)
# -----
# 300번의 에포크 진행
for _ in range(0, 300):
sc.partial_fit(train_scaled, train_target, classes=classes)
train_score.append(sc.score(train_scaled, train_target))
test_score.append(sc.score(test_scaled, test_target))
# -----
import matplotlib.pyplot as plt
plt.plot(train_score)
plt.plot(test_score)
plt.xlabel('epoch')
plt.ylabel('accuracy')
plt.show()
100番目のフォークの後、トレーニングコースとテストコースの点数が徐々に広がった.また、エポック初期には、小さすぎたため、トレーニングセットやテストセットの点数が低かった.
エポックを100に減らして、もう一度訓練します.
sc = SGDClassifier(loss='log', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
# 0.957983193277311
print(sc.score(test_scaled, test_target))
# 0.925
SGDClassifierはスケジュールの中でフォークリフト期間中に性能が向上しなければ、これ以上訓練せずに自動的に停止する.tol
パラメータは、増加する最大値を指定します.GDClassifierのlossパラメータについては、lossパラメータのデフォルト値は
hinge
です.Hinge損失は
support vector machine(SVM)
と呼ばれる損失関数である.sc = SGDClassifier(loss='hinge', max_iter=100, tol=None, random_state=42)
sc.fit(train_scaled, train_target)
print(sc.score(train_scaled, train_target))
# 0.9495798319327731
print(sc.score(test_scaled, test_target))
# 0.925
Feature Engineering and Regularization
1. Data Preparation
前回の授業では、線形回帰(線形回帰)を訓練するために特性を使用しました.
この授業では、複数の特性を使用し、複数の特性を使用する線形回帰を多重回帰(multiple regression)と呼びます.
本例では、スズキの長さだけでなく、スズキの깊이
と두께
を同時に使用する.
また,3つの特性をそれぞれ二乗して追加し,各特性を乗算して別の特性を生成する.
このように既存の特性を用いて新しい特性を抽出する作業を특성 공학(feature engineering)
と呼ぶ.import pandas as pd
df = pd.read_csv('https://bit.ly/perch_csv_data')
perch_full = df.to_numpy()
print(perch_full)
(一部のみ)
スズキfullとスズキweightをトレーニングセットとテストセットに分けます.# target data
import numpy as np
perch_weight = np.array(
[5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0,
110.0, 115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0,
130.0, 150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0,
197.0, 218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0,
514.0, 556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0,
820.0, 850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0,
1000.0, 1000.0]
)
# -----
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target =
train_test_split(perch_full, perch_weight, random_state=42)
2. Transformer of Scikit-learn
scikit-learningは、プロパティを作成または前処理するためのさまざまなクラスを提供します.この等級を변환기(transformer)
と呼ぶ.
2つの特性で、2と3からなる例を適用する.fit()
法は新しい特性の組合せを探し,transform()
法は実際にデータを変換する.from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures()
poly.fit([[2, 3]])
print(poly.transform([[2, 3]]))
# [[1. 2. 3. 4. 6. 9.]]
2つの属性(要素)を持つサンプル[2,3]6つの属性を持つサンプル[1.2.3.6.9]に変更します.poly = PolynomialFeatures(include_bias=False)
poly.fit([[2, 3]])
print(poly.transform([[2, 3]]))
# [[2. 3. 4. 6. 9.]]
スライスの項目が削除され、特性の二乗と特性の間に乗じた港湾が追加されます.poly = PolynomialFeatures(include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
print(train_poly.shape) # (42, 9)
PolynomialFeaturesクラスはget feature names()メソッドを呼び出すと、9つのプロパティがどの入力から結合されているかを示します.poly.get_feature_names_out()
# array(['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2'
# ,'x2^2'], dtype=object)
test_poly = poly.transform(test_input)
「x 0」は第1の特性を表し、「x 0^2」は第1の特性の二乗を表し、「x 0 x 1」は第1の特性と第2の特性の積を表す.
3. Training Multiple Regression Model
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# 0.9903183436982124
print(lr.score(test_poly, test_target))
# 0.9714559911594134
テストキットの点数は向上しなかったが、スズキの長さだけを使用した場合、基準に合わない問題は発生しなかった.
さらにいくつかのプロパティを追加し、プロパティを5つの平方項に出力します.poly = PolynomialFeatures(degree=5, include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)
print(train_poly.shape) # (42, 55)
train polyアレイの列数は特性の個数である.
これらのデータを用いて線形回帰モデルを再訓練した.lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# 0.9999999999991097
print(lr.score(test_poly, test_target))
# -144.40579242684848
訓練セットの点数はほとんど完璧で、テストセットの点数は大きな負数です.
特性の個数を大幅に増やせば,線形モデルはほとんど訓練セットを完璧に学習できる.
しかし,このモデルはフィットしすぎて,テスト集中で点数が大幅に低下する.
4. Regularization
規則化は、モデルをトレーニングセットにあまり適さないようにすることです.
線形回帰モデルでは、特性を乗じた係数(または傾斜)のサイズが小さくなります.
以前の55特性訓練の線形回帰モデルの係数を制限することによって,訓練セットの点数を低減し,代わりに試験セットの点数を向上させた.
これに先立ち、scikit−learnが提供するStandardScaler
クラスを使用して、特性を표준점수
に変換し、その規模を正規化した.from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly)
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
線形回帰モデルに正規化を加えたモデルをRidge
およびLasso
と呼ぶ.Ridge
は、係数が제곱
の値に従って制限される.Lasso
係数の절대값
を基準として規定を適用する.
どちらのアルゴリズムも係数の大きさを小さくしたが,Lassoはいっそゼロになる可能性がある.
Ridge (L2 Regularization)
Ridgeモデルをtrain scaledデータで訓練した.from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# 0.9896101671037343
print(ridge.score(test_scaled, test_target))
# 0.9790693977615397
RidgeとLassoモデルを使用する場合、正規化された量を任意に調整できます.モデルオブジェクトを作成するときに、alpha
パラメータを使用して、正規化された강도
を調整します.
適切なalpha値を見つける方法の1つは、alpha値のためにR^2 값의 그래프
を描画することである.
Alpha値を変更するたびに、score()メソッドの結果を保存するリストが作成されます.import matplotlib.pyplot as plt
train_score = []
test_score = []
# alpha 값을 0.001에서 100까지 10배씩 늘려가며
# Ridge 회귀 모델을 훈련한 다음,
# 훈련 세트와 테스트 세트의 점수를 파이썬 리스트에 저장
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
# 릿지 모델을 만듦
ridge = Ridge(alpha=alpha)
# 릿지 모델을 훈련
ridge.fit(train_scaled, train_target)
# 훈련 점수와 테스트 점수를 저장
train_score.append(ridge.score(train_scaled, train_target))
test_score.append(ridge.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()
上はトレーニングコース図、下はテストコース図です.
適切なalpha値は、2つのグラフィックが最も近く、テストセットの得点が最も高い−1、すなわち0.1である.
Alpha値を0.1に設定して最終モデルを訓練します.ridge = Ridge(alpha=0.1)
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# 0.9903815817570366
print(ridge.score(test_scaled, test_target))
# 0.9827976465386926
Lasso (L1 Regularization)
from sklearn.linear_model import Lasso
lasso = Lasso()
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# 0.989789897208096
print(lasso.score(test_scaled, test_target))
# 0.9800593698421883
train_score = []
test_score = []
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
# 라쏘 모델을 만듦
lasso = Lasso(alpha=alpha, max_iter=10000)
# 라쏘 모델을 훈련
lasso.fit(train_scaled, train_target)
# 훈련 점수와 테스트 점수를 저장
train_score.append(lasso.score(train_scaled, train_target))
test_score.append(lasso.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()
Lassoモデルでは最適alpha値は1,すなわち10であった.
この値段でモデルを再訓練します.lasso = Lasso(alpha=10)
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# 0.9888067471131867
print(lasso.score(test_scaled, test_target))
# 0.9824470598706695
Lassoモデルは直接係数値を0に設定できます.
coef属性検証係数は0です.print(np.sum(lasso.coef_ == 0)) # 40
Reference
この問題について(Optimization), 我々は、より多くの情報をここで見つけました
https://velog.io/@leeeeeyeon/Optimization
テキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol
import pandas as pd
df = pd.read_csv('https://bit.ly/perch_csv_data')
perch_full = df.to_numpy()
print(perch_full)
# target data
import numpy as np
perch_weight = np.array(
[5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0,
110.0, 115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0,
130.0, 150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0,
197.0, 218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0,
514.0, 556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0,
820.0, 850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0,
1000.0, 1000.0]
)
# -----
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target =
train_test_split(perch_full, perch_weight, random_state=42)
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures()
poly.fit([[2, 3]])
print(poly.transform([[2, 3]]))
# [[1. 2. 3. 4. 6. 9.]]
poly = PolynomialFeatures(include_bias=False)
poly.fit([[2, 3]])
print(poly.transform([[2, 3]]))
# [[2. 3. 4. 6. 9.]]
poly = PolynomialFeatures(include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
print(train_poly.shape) # (42, 9)
poly.get_feature_names_out()
# array(['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2'
# ,'x2^2'], dtype=object)
test_poly = poly.transform(test_input)
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# 0.9903183436982124
print(lr.score(test_poly, test_target))
# 0.9714559911594134
poly = PolynomialFeatures(degree=5, include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)
print(train_poly.shape) # (42, 55)
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# 0.9999999999991097
print(lr.score(test_poly, test_target))
# -144.40579242684848
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly)
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# 0.9896101671037343
print(ridge.score(test_scaled, test_target))
# 0.9790693977615397
import matplotlib.pyplot as plt
train_score = []
test_score = []
# alpha 값을 0.001에서 100까지 10배씩 늘려가며
# Ridge 회귀 모델을 훈련한 다음,
# 훈련 세트와 테스트 세트의 점수를 파이썬 리스트에 저장
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
# 릿지 모델을 만듦
ridge = Ridge(alpha=alpha)
# 릿지 모델을 훈련
ridge.fit(train_scaled, train_target)
# 훈련 점수와 테스트 점수를 저장
train_score.append(ridge.score(train_scaled, train_target))
test_score.append(ridge.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()
ridge = Ridge(alpha=0.1)
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# 0.9903815817570366
print(ridge.score(test_scaled, test_target))
# 0.9827976465386926
from sklearn.linear_model import Lasso
lasso = Lasso()
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# 0.989789897208096
print(lasso.score(test_scaled, test_target))
# 0.9800593698421883
train_score = []
test_score = []
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
for alpha in alpha_list:
# 라쏘 모델을 만듦
lasso = Lasso(alpha=alpha, max_iter=10000)
# 라쏘 모델을 훈련
lasso.fit(train_scaled, train_target)
# 훈련 점수와 테스트 점수를 저장
train_score.append(lasso.score(train_scaled, train_target))
test_score.append(lasso.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()
lasso = Lasso(alpha=10)
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# 0.9888067471131867
print(lasso.score(test_scaled, test_target))
# 0.9824470598706695
print(np.sum(lasso.coef_ == 0)) # 40
Reference
この問題について(Optimization), 我々は、より多くの情報をここで見つけました https://velog.io/@leeeeeyeon/Optimizationテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol