機器學習模型的參數(shù),不是直接數(shù)學求解,而是利用數(shù)據(jù),進行迭代epoch,梯度下降優(yōu)化求解。
1. 線性回歸
1.1線性回歸理論
-
目標:更好的擬合連續(xù)函數(shù)(分割連續(xù)樣本空間的平面h(·))
-
ε ( i ) \varepsilon^{(i)} ε(i)是 真實值 y ( i ) y^{(i)} y(i) 與 預測值 h θ ( x ) = θ T x ( i ) h_\theta (x)=\theta^Tx^{(i)} hθ?(x)=θTx(i)之間的誤差
-
求解參數(shù) θ \theta θ :誤差項 ε \varepsilon ε服從高斯分布,利用最大似然估計,轉換為最小二乘法
-
從最小二乘法得到目標函數(shù) J ( θ ) J(\theta) J(θ),為求其最值,利用梯度下降算法,沿偏導數(shù)(梯度)反方向,迭代更新計算,求解參數(shù) θ \theta θ 。
-
梯度下降算法:BatchGD批量梯度下降、SGD隨機梯度下降、Mini-BatchGD小批量梯度下降(實用)
batch一般設為 2 5 2^5 25=64、 2 6 2^6 26=128、 2 7 2^7 27=256,越大越好
GD的矩陣運算: -
學習率lr:開始設1e-3,逐漸調(diào)小到1e-5
1.2線性回歸實戰(zhàn)
數(shù)據(jù)預處理中normalize標準化作用:對輸入全部數(shù)據(jù) X ? μ σ \frac{ X-\mu}{\sigma } σX?μ?,使得不同值域的輸入 x i x_i xi?、 x j x_j xj?分布在同一取值范圍。如 x i ∈ [ 0.1 , 0.5 ] x_i\in[0.1, 0.5] xi?∈[0.1,0.5], x j ∈ [ 10 , 50 ] x_j\in[10, 50] xj?∈[10,50],normalize使其同一值域。
prepare__for_train.py
"""Prepares the dataset for training"""
import numpy as np
from .normalize import normalize
from .generate_sinusoids import generate_sinusoids
from .generate_polynomials import generate_polynomials
def prepare_for_training(data, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):
# 計算樣本總數(shù)
num_examples = data.shape[0]
data_processed = np.copy(data)
# 預處理
features_mean = 0
features_deviation = 0
data_normalized = data_processed
if normalize_data:
(
data_normalized,
features_mean,
features_deviation
) = normalize(data_processed)
data_processed = data_normalized
# 特征變換sinusoidal
if sinusoid_degree > 0:
sinusoids = generate_sinusoids(data_normalized, sinusoid_degree)
data_processed = np.concatenate((data_processed, sinusoids), axis=1)
# 特征變換polynomial
if polynomial_degree > 0:
polynomials = generate_polynomials(data_normalized, polynomial_degree, normalize_data)
data_processed = np.concatenate((data_processed, polynomials), axis=1)
# 加一列1
data_processed = np.hstack((np.ones((num_examples, 1)), data_processed))
return data_processed, features_mean, features_deviation
linearRegressionClass.py
class LinearRegression_:
def __init__(self, data, labels, polynomial_degree=0, sinusoid_degree=0, normalize_data=True):
"""
1.對數(shù)據(jù)進行預處理操作
2.先得到所有的特征個數(shù)
3.初始化參數(shù)矩陣
"""
(data_processed,
features_mean,
features_deviation) = prepare_for_training(data, polynomial_degree, sinusoid_degree, normalize_data=True)
self.data = data_processed
self.labels = labels
self.features_mean = features_mean
self.features_deviation = features_deviation
self.polynomial_degree = polynomial_degree
self.sinusoid_degree = sinusoid_degree
self.normalize_data = normalize_data
num_features = self.data.shape[1]
self.theta = np.zeros((num_features, 1))
def train(self, alpha=0.01, num_iterations=500):
"""
訓練模塊,執(zhí)行梯度下降
"""
cost_history = self.gradient_descent(alpha, num_iterations)
return self.theta, cost_history
def gradient_descent(self, alpha, num_iterations):
"""
實際迭代模塊,會迭代num_iterations次
"""
cost_history = []
for _ in range(num_iterations):
self.gradient_step(alpha)
cost_history.append(self.cost_function(self.data, self.labels))
return cost_history
def gradient_step(self, alpha):
"""
梯度下降參數(shù)更新計算方法,注意是矩陣運算
"""
num_examples = self.data.shape[0]
prediction = LinearRegression_.hypothesis(self.data, self.theta)
delta = prediction - self.labels
theta = self.theta
theta = theta - alpha * (1 / num_examples) * (np.dot(delta.T, self.data)).T
self.theta = theta
def cost_function(self, data, labels):
"""
損失計算方法
"""
num_examples = data.shape[0]
delta = LinearRegression_.hypothesis(self.data, self.theta) - labels
cost = (1 / 2) * np.dot(delta.T, delta) / num_examples
return cost[0][0]
@staticmethod
def hypothesis(data, theta):
predictions = np.dot(data, theta)
return predictions
def get_cost(self, data, labels):
data_processed = prepare_for_training(data,
self.polynomial_degree,
self.sinusoid_degree,
self.normalize_data
)[0]
return self.cost_function(data_processed, labels)
def predict(self, data):
"""
用訓練的參數(shù)模型,與預測得到回歸值結果
"""
data_processed = prepare_for_training(data,
self.polynomial_degree,
self.sinusoid_degree,
self.normalize_data
)[0]
predictions = LinearRegression_.hypothesis(data_processed, self.theta)
return predictions
單輸入變量線性回歸:
y
=
θ
1
x
1
+
b
y=\theta^1x^1+b
y=θ1x1+b
single_variate_LinerRegression.py
import os
import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from linearRegressionClass import *
dirname = os.path.dirname(__file__)
data = pd.read_csv(dirname + "/data/world-happiness-report-2017.csv", sep=',')
train_data = data.sample(frac=0.8)
test_data = data.drop(train_data.index)
# 選定考慮的特征
input_param_name = 'Economy..GDP.per.Capita.'
output_params_name = 'Happiness.Score'
x_train = train_data[[input_param_name]].values
y_train = train_data[[output_params_name]].values
x_test = test_data[[input_param_name]].values
y_test = test_data[[output_params_name]].values
# 用創(chuàng)建的隨機樣本測試
# 構造樣本的函數(shù)
# def fun(x, slope, noise=1):
# x = x.flatten()
# y = slope*x + noise * np.random.randn(len(x))
# return y
# # 構造數(shù)據(jù)
# slope=2
# x_max = 10
# noise = 0.1
# x_train = np.arange(0,x_max,0.2).reshape((-1,1))
# y_train = fun(x_train, slope=slope, noise=noise)
# x_test = np.arange(x_max/2, x_max*3/2, 0.2).reshape((-1,1))
# y_test = fun(x_test, slope=slope, noise=noise)
# #觀察訓練樣本和測試樣本
# # plt.scatter(x_train, y_train, label='train data', c='b')
# # plt.scatter(x_test, y_test, label='test data', c='k')
# # plt.legend()
# # plt.title('happiness - GDP')
# # plt.show()
# #測試 - 與唐宇迪的對比
# lr = LinearRegression()
# lr.fit(x_train, y_train)
# print(lr.predict(x_test))
# print(y_test)
# y_train = y_train.reshape((-1,1))
# lr = LinearRegression_(x_train, y_train)
# lr.train()
# print(lr.predict(x_test))
# print(y_test)
lr = LinearRegression()
lr.fit(x_train, y_train, alpha=0.01, num_iters=500)
y_pre = lr.predict(x_test)
print("開始損失和結束損失", lr.cost_hist[0], lr.cost_hist[-1])
# iters-cost curve
# plt.plot(range(len(lr.cost_hist)), lr.cost_hist)
# plt.xlabel('Iter')
# plt.ylabel('cost')
# plt.title('GD')
# plt.show()
plt.scatter(x_train, y_train, label='Train data')
plt.scatter(x_test, y_test, label='test data')
plt.plot(x_test, y_pre, 'r', label='Prediction')
plt.xlabel(input_param_name)
plt.ylabel(output_params_name)
plt.title('Happy')
plt.legend()
plt.show()
多輸入變量線性回歸
y
=
∑
i
=
1
n
θ
i
x
i
+
b
y=\sum_{i=1}^{n} \theta^ix^i+b
y=i=1∑n?θixi+b
非線性回歸
1.對原始數(shù)據(jù)做非線性變換,如
x
?
>
l
n
(
x
)
x->ln(x)
x?>ln(x)
2.設置回歸函數(shù)的復雜度最高
x
n
x^n
xn
2.訓練調(diào)參基本功(線性回歸、嶺回歸、Lasso回歸)
構建線性回歸方程擬合數(shù)據(jù)點
2.1 線性回歸模型實現(xiàn)
準備數(shù)據(jù),預處理perprocess(標準化normalize),劃分數(shù)據(jù)集(訓練集train和測試集test),導包(sklearn或自己寫的class),實例化LinearRegression,設置超參數(shù)(lr/eopch/batch…),是否制定learning策略(學習率衰減策略),權重參數(shù)初始化init_weight(隨機初始化/遷移學習),訓練(fit或自己寫for迭代計算梯度更新參數(shù)),預測
2.2不同GD策略對比
MiniBatch梯度下降實例
theta_mini_list = []
cost_mini_list = []
batch_size = 10
n_epochs = 50
iters_per_epoch = int(num_samples / batch_size) + 1
theta = np.random.randn(num_features, 1)
# 學習率衰減策略
def learn_schedule(t):
t0 = 10
t1 = 2500
return t0/(t1+t)
def cost(X_b, y, theta):
num_features = X_b.shape[1]
num_samples = X_b.shape[0]
delta = y - np.dot(X_b,theta)
return 1/(2*num_samples) * np.sum(delta ** 2)
theta_mini_list.append(theta.copy())
loss_mini = cost(X_b, y, theta)
cost_mini_list.append(loss_mini)
epoch = 0
for i in range(1000000):
batch_mask = np.random.permutation(num_samples)[:10]
X_batch = X_b[batch_mask]
y_batch = y[batch_mask]
grads = - 1/(batch_size) * np.dot(X_batch.T, (y_batch - X_batch.dot(theta)))
alpha = learn_schedule(i)
theta -= alpha * grads
if not i%iters_per_epoch:
loss_mini = cost(X_b, y, theta)
cost_mini_list.append(loss_mini)
theta_mini_list.append(theta.copy())
epoch += 1
if epoch >= n_epochs:
break
theta_mini_list = np.array(theta_SGD_list)
theta_mini_list[-3:]
2.3多項式曲線回歸
最高次項>1
sklearn.preporcessing.PloynomialFeatures(degree=最高項次冪,include_bias=是否包含偏置項)
不同degree擬合的效果
2.4過擬合和欠擬合
訓練集數(shù)據(jù)量與過擬合風險:
數(shù)據(jù)越多,train和test的error差異越小,過擬合風險越低。(形象比喻:學生做題(train)和考試(test)的關系,學生做練習題(train_size)越多,考試(test)發(fā)揮越好,過擬合就是平時做題少,導致考試不如平時。)
多項式回歸的高次項次數(shù)與過擬合風險:
degree次數(shù)越高,過擬合風險越大。
import scipy.io
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import mean_squared_error
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
def plot_learning_curves(model, X, y):
# 切分train和val
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=0)
train_errors ,test_errors = [], []
# 每次訓練m個樣本(對比不同樣本數(shù)量下的訓練效果)
for m in range(1,len(X_train)):
# 本次訓練只需要前m個數(shù)據(jù)
model.fit(X_train[:m],y_train[:m])
# 計算訓練集和測試集預測結果,用于計算訓練集和測試集上的誤差
y_train_pre = model.predict(X_train[:m])
y_test_pre = model.predict(X_test) # 測試集要用全部數(shù)據(jù)
train_errors.append(mean_squared_error(y_train[:m], y_train_pre))
test_errors.append(mean_squared_error(y_test, y_test_pre))
# RMSE=MSE開方
plt.plot(np.sqrt(train_errors),'r-+',linewith=2,label="train")
plt.plot(np.sqrt(test_errors),'b-+',linewith=2,label="test")
plt.legend()
model = LinearRegression()
X, y = [], []
plot_learning_curves(model, X, y)
plt.xlabel('Training Size')
plt.ylabel('RMSE error')
plt.axis([0,80,0,3.3])
plt.show()
2.5正則化
正則化:在loss添加正則項(懲罰偏好,包括L1和L2),緩解過擬合。
L1正則項: L1正則化最大的特點是能稀疏矩陣,進行龐大特征數(shù)量下的特征選擇。L1是模型各個參數(shù)的絕對值之和
L2正則項:(推薦) L2正則能夠有效的防止模型過擬合,解決非滿秩下求逆困難的問題。L2是模型各個參數(shù)的平方和的開方值。
正則項的系數(shù) α \alpha α: α \alpha α稱為正則化參數(shù),如果 α \alpha α選取過大,會把所有參數(shù)w均最小化,造成欠擬合;如果 α \alpha α選取過小,會導致對過擬合問題解決不當,因此 α \alpha α的選取是一個技術活。
為了緩解線性回歸過擬合,使用正則化改進:1.嶺回歸 2.Lasso回歸
嶺回歸正則化loss:線性回歸的MSEloss + L2正則項(平方和根)
,(效果:使權重可能小,且不同權重值差異更小) 其中
α
\alpha
α是正則項懲罰力度:
l
o
s
s
=
∣
∣
y
?
X
w
∣
∣
2
+
α
?
∣
∣
w
∣
∣
2
loss = \sqrt[]{||y-Xw||^2}+\alpha*\sqrt[]{||w||^2}
loss=∣∣y?Xw∣∣2?+α?∣∣w∣∣2?
嶺回歸是加了L2正則項
的最小二乘,主要適用于過擬合嚴重或各變量之間存在多重共線性的時候,嶺回歸是有bias的,這里的bias是為了讓variance更小。
左圖表示一次線性嶺回歸,右圖表示高次非線性嶺回歸。
根據(jù)右圖可知,
α
\alpha
α越大,曲線的斜率浮動變化越大(即不同權重w差異越大)
Lasso回歸正則化loss:線性回歸的MSEloss + L1正則項(絕對值和)
,LASSO 回歸同樣是通過添加正則項來改進普通最小二乘法,不過這里添加的是 L1 正則項
。即:
l
o
s
s
=
∣
∣
y
?
X
w
∣
∣
2
+
α
?
∣
∣
w
∣
∣
loss = \sqrt[]{||y-Xw||^2}+\alpha*||w||
loss=∣∣y?Xw∣∣2?+α?∣∣w∣∣
3.分類模型評估(Mnist實戰(zhàn)SGD_Classifier)
3.1 K折交叉驗證K-fold cross validation
①切分完訓練集training和測試集testing后
②再對training進行均分為K份
③訓練的迭代將進行K輪,每輪將其中K-1份作為training,1份作為驗證機validation,邊訓練train邊驗證valid
④最后訓練和驗證的epoch結束了,再用測試集testing進行測試。
常用的K=5/10
import numpy as np
import os
import matplotlib
import matplotlib.pyplot as plt
plt.rcParams['axes.labelsize'] = 14
plt.rcParams['xtick.labelsize'] = 12
plt.rcParams['ytick.labelsize'] = 12
import warnings
warnings.filterwarnings('ignore')
np.random.seed(42)
# from sklearn.datasets import fetch_openml
# mnist = fetch_openml('MNIST original')
# 也可以GitHub下載,手動加載
import scipy.io
mnist = scipy.io.loadmat('MNIST-original')
# 圖像數(shù)據(jù) (28x28x1)的灰度圖,每張圖像有784個像素點(=28x28x1)
# print(mnist) # 字典key=data和label,數(shù)據(jù)存在對應的value中
X, y = mnist['data'], mnist['label']
# print(X.shape) # data 784 x 70000,每列相當于一張圖,共70000張圖像
# print(y.shape) # label 1 x 70000,共70000個標簽
# 劃分數(shù)據(jù),訓練集training,測試集testing,train取前60000,test取后10000
# 列切片
X_train, X_test, y_train, y_test = X[:, :60000], X[..., 60000:], y[:, :60000], y[..., 60000:]
# 訓練集數(shù)據(jù)洗牌打亂
import numpy as np
X_train = np.random.permutation(X_train)
y_train = np.random.permutation(y_train)
# 因為后面要畫混淆矩陣,最好是2分類任務:0-10的數(shù)字判斷是不是5
# 將label變?yōu)閠rue和false
y_train_5 = (y_train == 5)[0]
y_test_5 = (y_test == 5)[0]
# print(X_train.shape)
# print(y_train_5.shape)
X_train = X_train.T
X_test = X_test.T
# 創(chuàng)建線性模型SGDClassifier
from sklearn.linear_model import SGDClassifier
sgd_clf = SGDClassifier(max_iter=50, random_state=42)
# sgd_clf.fit(X_train, y_train_5) # 訓練
# print(sgd_clf.predict(X_test))
# K折交叉驗證 劃分訓練集training,驗證集validation,并訓練
# 方法一:
from sklearn.model_selection import cross_val_score
kfold=5
acc=cross_val_score(sgd_clf, X_train, y_train_5, cv=kfold, scoring='accuracy') ## cv是折數(shù)
avg_acc = sum(acc) / kfold
print("avg_acc=", avg_acc)
# 返回每折的acc:[0.87558333 0.95766667 0.86525 0.91483333 0.94425]
# 方法二
from sklearn.model_selection import StratifiedKFold
from sklearn.base import clone # K折中每折訓練時,模型帶有相同參數(shù)
kfold = 5
acc = []
skfold = StratifiedKFold(n_splits=kfold, random_state=42)
i = 1
for train_idx, test_idx in skfold.split(X_train, y_train_5):
# 克隆模型
clone_clf = clone(sgd_clf)
# 劃分訓練集training和驗證集validation
X_train_folds = X_train[train_idx]
X_val_folds = X_train[test_idx]
y_train_folds = y_train_5[train_idx]
y_val_folds = y_train_5[test_idx]
# 模型訓練
clone_clf.fit(X_train_folds, y_train_folds)
# 對每折進行預測,計算acc
y_pred = clone_clf.predict(X_val_folds)
n_correct = sum(y_pred == y_val_folds)
acc.append(n_correct / len(y_pred))
print("Split", i, "/", kfold, "Done.")
i = i + 1
# 平均acc
avg_acc = sum(acc) / kfold
print("avg_acc=", avg_acc)
3.2 混淆矩陣Confusion Matrix
分類任務,下例對100人進行男女二分類,100中,模型檢測有50人為男(實際全為男),50人為女(實際20為女 30為男)。
一個完美的分類是只有主對角線非0,其他都是0
n分類:混淆矩陣就是nxn
接上個代碼
from sklearn.model_selection import cross_val_predict
# 60000個數(shù)據(jù),進行5折交叉驗證
# cross_val_predict返回每折預測的結果的concat,每折12000個結果,5折共60000個結果
y_train_pred = cross_val_predict(sgd_clf, X_train, y_train_5, cv=kfold)
# 畫混淆矩陣
from sklearn.metrics import confusion_matrix
confusion=confusion_matrix(y_train_5, y_train_pred) # 傳入train的標簽和預測值
# 2分類的矩陣就是2x2的[[TN,FP],[FN,TP]]
plt.figure(figsize=(2, 2)) # 設置圖片大小
# 1.熱度圖,后面是指定的顏色塊,cmap可設置其他的不同顏色
plt.imshow(confusion, cmap=plt.cm.Blues)
plt.colorbar() # 右邊的colorbar
# 2.設置坐標軸顯示列表
indices = range(len(confusion))
classes = ['5', 'not 5']
# 第一個是迭代對象,表示坐標的顯示順序,第二個參數(shù)是坐標軸顯示列表
plt.xticks(indices, classes, rotation=45) # 設置橫坐標方向,rotation=45為45度傾斜
plt.yticks(indices, classes)
# 3.設置全局字體
# 在本例中,坐標軸刻度和圖例均用新羅馬字體['TimesNewRoman']來表示
# ['SimSun']宋體;['SimHei']黑體,有很多自己都可以設置
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 4.設置坐標軸標題、字體
# plt.ylabel('True label')
# plt.xlabel('Predicted label')
# plt.title('Confusion matrix')
plt.xlabel('預測值')
plt.ylabel('真實值')
plt.title('混淆矩陣', fontsize=12, fontfamily="SimHei") # 可設置標題大小、字體
# 5.顯示數(shù)據(jù)
normalize = False
fmt = '.2f' if normalize else 'd'
thresh = confusion.max() / 2.
for i in range(len(confusion)): # 第幾行
for j in range(len(confusion[i])): # 第幾列
plt.text(j, i, format(confusion[i][j], fmt),
fontsize=16, # 矩陣字體大小
horizontalalignment="center", # 水平居中。
verticalalignment="center", # 垂直居中。
color="white" if confusion[i, j] > thresh else "black")
save_flg = True
# 6.保存圖片
if save_flg:
plt.savefig("confusion_matrix.png")
# 7.顯示
plt.show()
3.3 準確率accuracy、精度precision、召回率recall、F1
sklearn.metrics中有對應的計算函數(shù)(y_train, y_train_pred)
準確率accurcy
=預測正確個數(shù)/總樣本數(shù)=
T
P
+
T
N
T
P
+
T
N
+
F
P
+
F
N
\frac{TP+TN}{TP+TN+FP+FN}
TP+TN+FP+FNTP+TN?
精度precision
=
T
P
T
P
+
F
P
\frac{TP}{TP+FP}
TP+FPTP?
召回率recall
=
T
P
T
P
+
F
N
\frac{TP}{TP+FN}
TP+FNTP?
F1 Score
=
2
?
T
P
2
?
T
P
+
F
P
+
F
N
\frac{2*TP}{2*TP+FP+FN}
2?TP+FP+FN2?TP?=
2
?
p
r
e
c
i
s
i
o
n
?
r
e
c
a
l
l
p
r
e
c
i
s
i
o
n
+
r
e
c
a
l
l
\frac{2*precision*recall}{precision+recall}
precision+recall2?precision?recall?
接上面代碼
from sklearn.metrics import accuracy_score,precision_score,recall_score,f1_score
accuracy=accuracy_score(y_train_5,y_train_pred)
precision=precision_score(y_train_5,y_train_pred)
recall=recall_score(y_train_5,y_train_pred)
f1_score=f1_score(y_train_5,y_train_pred)
print("accuracy=",accuracy)
print("precision=",precision)
print("recall=",recall)
print("f1_score",f1_score)
3.4 置信度confidence
confidence:模型對分類預測結果正確的自信程度
y_scores=cross_val_predict(sgd_clf,X_train,y_train_5,kfold,method=‘decision_function’)方法返回每個輸入數(shù)據(jù)的confidence,我們可以手動設置閾值t,對預測結果進行篩選,只有confidence_score>t,才視為預測正確。
precision, recall, threshholds = precision_recall_curve(y_train_5,y_scores)函數(shù)可以自動設置多個閾值,且每個閾值都對應計算一遍precision 和 recall
接上面代碼
# 自動生成多個閾值,并計算precision, recall
y_scores = cross_val_predict(sgd_clf,X_train,y_train_5,kfold,method='decision_function')
from sklearn.metrics import precision_recall_curve
precision, recall, threshholds = precision_recall_curve(y_train_5,y_scores)
3.5 ROC曲線
分類任務可以畫出ROC曲線:理想的分類器是逼近左上直角,即曲線下方ROC AUC面積接近1.
接上面代碼
# 分類任務,畫ROC曲線
from sklearn.metrics import roc_curve
fpr,tpr,threshholds=roc_curve(y_train_5,y_scores)
def plot_roc_curve(fpr,tpr,label=None):
plt.plot(fpr,tpr,linewidth=2,label=label)
plt.plot([0,1],[0,1],'k--')
plt.axis([0,1,0,1])
plt.xlabel('False Positive Rate', fontsize=16)
plt.ylabel('True Positive Rate', fontsize=16)
plt.figure(figsize=(8,6))
plot_roc_curve(fpr,tpr)
plt.show()
# 計算roc_auc面積
from sklearn.metrics import roc_auc_score
roc_auc_score=roc_auc_score(y_train_5,y_train_pred)
4. 邏輯回歸Logistic Regression
4.1 邏輯回歸原理
最簡單的分類算法
,因為要對樣本空間進行分類,所以決策邊界是非線性的,Sigmod函數(shù)實現(xiàn)2分類,Sotmax實習多分類
。
非線性:使用Sigmoid
函數(shù),將線性回歸值
->二分類非線性的邏輯概率
,引入非線性信息。
邏輯回歸預測函數(shù) = sigmod/Softmax(線性回歸函數(shù)) -> 二/多分類整合
二分類:
P
(
y
∣
x
;
θ
)
=
h
θ
(
x
)
y
?
(
1
?
h
θ
(
x
)
1
?
y
)
P(y|x;\theta)=h_\theta(x)^y*(1-h_\theta(x)^{1-y})
P(y∣x;θ)=hθ?(x)y?(1?hθ?(x)1?y)
利用最大似然,計算loss函數(shù)
loss梯度下降,求梯度
迭代更新參數(shù)
4.2 多分類邏輯回歸實現(xiàn)
將多分類任務拆解成多個2分類任務,如ABC三類,分別3次劃分AB、BC、AC之間的分類邊界。
5. SVM支持向量機
支持向量機(SVM)是一類按監(jiān)督學習方式對數(shù)據(jù)進行二元分類的廣義線性分類器
,其決策邊界是對學習樣本求解的最大邊距超平面
,可以將問題化為一個求解凸二次規(guī)劃
的問題。與邏輯回歸和神經(jīng)網(wǎng)絡相比,支持向量機,在學習復雜的非線性方程時提供了一種更為清晰,更加強大的方式。
支持向量機算法分類和回歸方法的中都支持線性/線性可分
和非線性/線性不可分
類型的數(shù)據(jù)類型。還可以分為硬間距
和軟間距
。
- 在
線性-線性可分
時,在原空間尋找兩類樣本的最優(yōu)分類超平面。 - 在
非線性-線性不可分
時,通過核函數(shù)
使用非線性映射將低維度輸入空間的樣本映射到高維度空間使其變?yōu)榫€性可分,這樣就可以在該特征空間中尋找最優(yōu)分類超平面。低維平面不可分,為了使數(shù)據(jù)可分,需要通過一個函數(shù)將原始數(shù)據(jù)映射到高維空間,從而使得數(shù)據(jù)在高維空間很容易可分
,需要通過一個函數(shù)將原始數(shù)據(jù)映射到高維空間,從而使得數(shù)據(jù)在高維空間很容易區(qū)分,這樣就達到數(shù)據(jù)分類或回歸的目的,而實現(xiàn)這一目標的函數(shù)稱為核函數(shù)
。 -
硬間隔
,指的就是完全分類準確,不能存在分類錯誤的情況。 -
軟間隔
,就是允許一定量的樣本分類錯誤。
SVM使用準則: n為特征數(shù),m 為訓練樣本數(shù)。
- 如果相較于m而言,n要大許多,即訓練集數(shù)據(jù)量不夠支持我們訓練一個復雜的非線性模型,我們選- 用邏輯回歸模型或者不帶核函數(shù)的支持向量機。
- 如果n較小,而且m大小中等,例如n在 1-1000 之間,而m在10-10000之間,使用高斯核函數(shù)的支持向量機。
- 如果n較小,而m較大,例如n在1-1000之間,而m大于50000,則使用支持向量機會非常慢,解決方案是創(chuàng)造、增加更多的特征,然后使用邏輯回歸或不帶核函數(shù)的支持向量機。
優(yōu)點:
- 支持向量機算法可以解決小樣本情況下的機器學習問題,簡化了通常的分類和回歸等問題。
- 由于采用核函數(shù)方法克服了維數(shù)災難和非線性可分的問題,所以向高維空間映射時沒有增加計算的復雜性。換句話說,由于支持向量計算法的最終決策函數(shù)只由少數(shù)的支持向量所確定,所以計算的復雜性取決于支持向量的數(shù)目,而不是樣本空間的維數(shù)。
- 支持向量機算法利用松弛變量可以允許一些點到分類平面的距離不滿足原先要求,從而避免這些點對模型學習的影響。
缺點:
- 支持向量機算法對大規(guī)模訓練樣本難以實施。這是因為支持向量機算法借助二次規(guī)劃求解支持向量,這其中會涉及m階矩陣的計算,所以矩陣階數(shù)很大時將耗費大量的機器內(nèi)存和運算時間。
經(jīng)典的支持向量機算法只給出了二分類的算法,而在數(shù)據(jù)挖掘的實際應用中,一般要解決多分類問題,但支持向量機對于多分類問題解決效果并不理想。- SVM算法效果與核函數(shù)的選擇關系很大,往往需要嘗試多種核函數(shù),即使選擇了效果比較好的高斯核函數(shù),也要調(diào)參選擇恰當?shù)膮?shù)。另一方面就是現(xiàn)在常用的SVM理論都是使用固定懲罰系數(shù)C,但正負樣本的兩種錯誤造成的損失是不一樣的。
MLP與SVM分類的區(qū)別:
感知機的目的是盡可能使得所有樣本分類正確,而SVM的目標是分類間隔最大化。支持向量機追求大致正確分類的同時,一定程度上避免過擬合。感知機使用的學習策略是梯度下降,而SVM采用的是由約束條件構造拉格朗日函數(shù),然后求偏導為0求得極值點。
5.1 SVM理論推導
線性硬間距:
線性軟間距:
非線性
常見核函數(shù):
詳細的:
求一個分類的超平面,距最近的點的距離越大越好。
計算 平面外一點x 到 超平面 的距離:
平面上兩個點
x
′
x^{'}
x′和
x
′
′
x^{''}
x′′滿足平面方程
w
T
x
+
b
=
0
w^Tx+b=0
wTx+b=0,其中w是法向量。
2分類SVM,決策邊界(超平面),決策方程(線性:
y
(
x
)
=
w
T
x
+
b
y(x)=w^Tx+b
y(x)=wTx+b,非線性:對x用核函數(shù)
φ
(
x
)
\varphi(x)
φ(x)變換
y
(
x
)
=
w
T
φ
(
x
)
+
b
y(x)=w^T\varphi(x)+b
y(x)=wTφ(x)+b )
SVM優(yōu)化的目標:min(樣本到超平面的距離)
(用上述方法去掉絕對值)
|
w
T
φ
(
x
i
)
+
b
w^T\varphi(x_i)+b
wTφ(xi?)+b| ->
y
i
?
y
(
φ
(
x
i
)
)
y_i·y(\varphi(x_i))
yi??y(φ(xi?)) ->
y
i
?
(
w
T
φ
(
x
i
)
+
b
)
y_i·(w^T\varphi(x_i)+b)
yi??(wTφ(xi?)+b)
目標函數(shù):①先求不同樣本點
x
i
x_i
xi?中距離最近的樣本點,②再求該樣本點與超平面(w,b)距離的最大值。③放縮變換(
y
i
?
(
w
T
φ
(
x
i
)
+
b
)
y_i·(w^T\varphi(x_i)+b)
yi??(wTφ(xi?)+b)>=1),分母->1,化簡目標函數(shù)=
max
?
w
,
b
1
∣
∣
w
∣
∣
\max_{w,b} \frac{1}{||w||}
maxw,b?∣∣w∣∣1?。④將求max->min,目標函數(shù)=
max
?
w
,
b
w
2
2
\max_{w,b} \frac{w^2}{2}
maxw,b?2w2?
即帶約束的優(yōu)化問題,條件
:
y
i
?
(
w
T
φ
(
x
i
)
+
b
)
>
=
1
y_i·(w^T\varphi(x_i)+b)>=1
yi??(wTφ(xi?)+b)>=1之下,求目標函數(shù)
:
max
?
w
,
b
w
2
2
\max_{w,b} \frac{w^2}{2}
maxw,b?2w2?文章來源:http://www.zghlxwxcb.cn/news/detail-576865.html
拉格朗日乘子法:專門解決帶約束優(yōu)化問題,將條件代入目標函數(shù)中。
引入變量
α
(
對每個
x
i
都有
α
i
)
\alpha(對每個x_i都有\(zhòng)alpha_i)
α(對每個xi?都有αi?),只需根據(jù)
α
\alpha
α進行優(yōu)化,求得
α
\alpha
α后再求為w和b。
對偶原則,min和max先后不影響。
SVM求解:變成兩步極值求解(求偏導、max變min)。
軟間隔:引入松弛變量
非線性(線性不可分):
核函數(shù):只用高斯核函數(shù)(原始特征->高斯距離特征)就可以了。文章來源地址http://www.zghlxwxcb.cn/news/detail-576865.html
5.2 非線性軟間隔SVM實戰(zhàn)
到了這里,關于唐宇迪機器學習實戰(zhàn)課程筆記(全)的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關文章,希望大家以后多多支持TOY模板網(wǎng)!