目錄
一、機器學習評估的基本概念
1.1?評估的定義與目標
1.2?常見評估指標
1.3?訓練集、驗證集與測試集的劃分
二、分離數據集
2.1 分離訓練數據集和評估數據集?
2.2 k折交叉驗證分離?
2.3 棄一交叉驗證分離?
2.4 重復隨機評估和訓練數據集分離
三、交叉驗證技術
3.1 K折交叉驗證的原理與實現
3.2 留一法交叉驗證
3.2.1 留一法交叉驗證的優缺點
3.3 分層交叉驗證
一、機器學習評估的基本概念
機器學習評估是指通過一系列指標和方法來衡量模型在特定任務上的表現。評估的目的是確保模型不僅在訓練數據上表現良好,還能在未見過的數據上保持穩定的性能。
1.1?評估的定義與目標
評估是指通過系統化的方法和指標對模型性能進行量化分析,旨在判斷模型在特定任務中的表現是否符合預期。其核心目標包括驗證模型的泛化能力(即對未見數據的預測準確性)、識別過擬合或欠擬合問題、比較不同算法的優劣,并為模型優化提供依據。
1.2?常見評估指標
常用的評估指標包括:準確率、精確率、召回率、F1分數、ROC曲線和AUC值等;
- 準確率(Accuracy):模型預測正確的樣本占總樣本的比例。
from sklearn.metrics import accuracy_scorey_true = [0, 1, 1, 0, 1]
y_pred = [0, 1, 0, 0, 1]
accuracy = accuracy_score(y_true, y_pred)
print(f"Accuracy: {accuracy}")
?
- 精確率(Precision):模型預測為正類的樣本中,實際為正類的比例。
from sklearn.metrics import precision_scorey_true = [0, 1, 1, 0, 1]
y_pred = [0, 1, 0, 0, 1]
precision = precision_score(y_true, y_pred)
print(f"Precision: {precision}")
?
- 召回率(Recall):實際為正類的樣本中,模型預測為正類的比例。
from sklearn.metrics import recall_scorey_true = [0, 1, 1, 0, 1]
y_pred = [0, 1, 0, 0, 1]
recall = recall_score(y_true, y_pred)
print(f"Recall: {recall}")
- F1分數(F1 Score):精確率和召回率的調和平均數,用于平衡兩者。
from sklearn.metrics import f1_scorey_true = [0, 1, 1, 0, 1]
y_pred = [0, 1, 0, 0, 1]
f1 = f1_score(y_true, y_pred)
print(f"F1 Score: {f1}")
- ROC曲線(Receiver Operating Characteristic Curve):通過不同閾值下的真正類率和假正類率繪制的曲線。
- AUC值(Area Under Curve):ROC曲線下的面積,用于衡量分類器的整體性能。
1.3?訓練集、驗證集與測試集的劃分
請點擊鏈接跳轉至之前的機器學習的基本知識篇,有詳細介紹訓練集、驗證集與測試集的劃分
這里就不做贅述了
https://love-xin.blog.csdn.net/article/details/143162589?spm=1011.2415.3001.5331https://love-xin.blog.csdn.net/article/details/143162589?spm=1011.2415.3001.5331
二、分離數據集
常用的分離數據集方法有:分離訓練數據集和評估數據集、k折交叉驗證分離、棄一交叉驗證分離、重復隨機評估和訓練數據集分離。
2.1 分離訓練數據集和評估數據集?
將數據集劃分為訓練集和評估集是最基礎的分離方法。通常采用70%-30%或80%-20%的比例分配。訓練集用于模型訓練,評估集用于驗證模型性能。
這種方法的優勢在于簡單直接,適用于大規模數據集。但需要注意數據分布的均衡性,避免因隨機劃分導致評估偏差。
使用scikit-learn
實現分離訓練數據集和評估數據集:
from pandas import read_csv
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression# 導入數據
filename = 'Sklearn\pima_data.csv' #(注意自己數據集的路徑)
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)# 將數據分為輸入數據和輸出結果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
test_size = 0.33
seed = 4
X_train, X_test, Y_traing, Y_test = train_test_split(X, Y, test_size=test_size, random_state=seed)
model = LogisticRegression(max_iter=3000)
model.fit(X_train, Y_traing)
result = model.score(X_test, Y_test)
print("算法評估結果:%.3f%%" % (result * 100))
執行結果為:80.315%
2.2 k折交叉驗證分離?
k折交叉驗證將數據集分為k個大小相似的子集。每次使用k-1個子集作為訓練集,剩余1個子集作為驗證集,重復k次。最終性能取k次驗證的平均值。這種方法充分利用數據,適合中小規模數據集。典型k值為5或10,需注意k值過大會增加計算成本。
使用scikit-learn
實現k折交叉驗證:
from pandas import read_csv
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import KFold# 導入數據
filename = 'Sklearn\pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)# 將數據分為輸入數據和輸出結果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
n_splits=10
seed=4
kfold=KFold(n_splits=n_splits,random_state=seed,shuffle=True)
model=LogisticRegression(max_iter=3000)
result=cross_val_score(model, X,Y,cv=kfold)
print("結果:%.3f%% (%.3f%%)"%(result.mean()*100, result.std()*100))
執行結果為:77.729% (4.617%)
2.3 棄一交叉驗證分離?
棄一交叉驗證是k折交叉驗證的特例,k等于樣本數量。每個樣本單獨作為驗證集,其余樣本用于訓練。這種方法提供無偏估計,但計算復雜度高,僅適用于極小樣本量場景。需注意樣本代表性,避免異常值影響整體評估。
使用scikit-learn
實現棄一交叉驗證???????:
from pandas import read_csv
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import LeaveOneOut# 導入數據
filename = 'Sklearn\pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)# 將數據分為輸入數據和輸出結果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
loocv = LeaveOneOut()
model = LogisticRegression(max_iter=3000)
result = cross_val_score(model, X, Y, cv=loocv)
print("算法評估結果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100))
執行結果為:77.604% (41.689%)
2.4 重復隨機評估和訓練數據集分離
另外一種對K折交叉驗證的用法是隨機分離數據成訓練數據集和評估數據集,但是重復這個過程多次,就如同交叉驗證分離。
下面的例子就是將數據按照67%/33%分離,重復這個過程10次:
from pandas import read_csv
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import cross_val_score
from sklearn.model_selection import ShuffleSplit# 導入數據
filename = 'Sklearn\pima_data.csv'
names = ['preg', 'plas', 'pres', 'skin', 'test', 'mass', 'pedi', 'age', 'class']
data = read_csv(filename, names=names)# 將數據分為輸入數據和輸出結果
array = data.values
X = array[:, 0:8]
Y = array[:, 8]
n_splits = 10
test_size = 0.33
seed = 4
kfold = ShuffleSplit(n_splits=n_splits, test_size=test_size, random_state=seed)
model = LogisticRegression(max_iter=3000)
result = cross_val_score(model, X, Y, cv=kfold)
print("結果:%.3f%% (%.3f%%)" % (result.mean() * 100, result.std() * 100))
執行結果為:75.945% (2.626%)
三、交叉驗證技術
3.1 K折交叉驗證的原理與實現
K折交叉驗證(K-Fold Cross Validation)是一種評估機器學習模型性能的統計方法,通過將數據集劃分為K個子集(“折”),依次使用其中K-1個子集作為訓練數據,剩余1個子集作為驗證數據,重復K次并計算平均性能指標。
使用scikit-learn
實現K折交叉驗證:
import numpy as np
from sklearn.model_selection import KFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
from sklearn.metrics import accuracy_score# 加載數據
data = load_iris()
X, y = data.data, data.target# 初始化模型和K折劃分器
model = RandomForestClassifier()
kf = KFold(n_splits=5, shuffle=True, random_state=42)# 存儲每輪得分
scores = []for train_index, val_index in kf.split(X):X_train, X_val = X[train_index], X[val_index]y_train, y_val = y[train_index], y[val_index]model.fit(X_train, y_train)y_pred = model.predict(X_val)scores.append(accuracy_score(y_val, y_pred))# 輸出平均準確率
print(f"Mean Accuracy: {np.mean(scores):.4f} (±{np.std(scores):.4f})")
執行結果為:Mean Accuracy: 0.9600 (±0.0249)
3.2 留一法交叉驗證
留一法交叉驗證(Leave-One-Out Cross-Validation, LOOCV)是一種特殊的交叉驗證方法,適用于小樣本數據集。其核心思想是每次從數據集中留出一個樣本作為測試集,其余樣本作為訓練集,重復這一過程直到所有樣本都被作為測試集一次。
3.2.1 留一法交叉驗證的優缺點
優點:
- 無偏估計:由于每次訓練集幾乎包含所有樣本(僅少一個),模型的評估結果更接近真實性能;
- 適用小樣本:特別適合樣本量極少的情況(如N<100)。
缺點:
- 計算成本高:需要訓練模型N次,對于大數據集(N較大)時效率極低;
- 方差較高:每次訓練集僅相差一個樣本,可能導致評估結果波動較大。
使用Python和scikit-learn實現留一法交叉驗證的示例:
from sklearn.model_selection import LeaveOneOut, cross_val_score
from sklearn.linear_model import LogisticRegression
from sklearn.datasets import load_irisdata = load_iris() # 加載數據集
X, y = data.data, data.targetmodel = LogisticRegression(max_iter=200) # 初始化模型
loo = LeaveOneOut() # 初始化留一法交叉驗證
scores = cross_val_score(model, X, y, cv=loo, scoring='accuracy') # 計算交叉驗證得分
print(f"Mean Accuracy: {scores.mean():.4f}")
執行結果為:Mean Accuracy: 0.9667
3.3 分層交叉驗證
分層交叉驗證(Stratified Cross-Validation)是一種在交叉驗證過程中保持數據集中各類別比例一致的技術。它特別適用于分類問題,尤其是當數據集中的類別分布不均衡時。通過分層交叉驗證,可以確保每一折的訓練集和驗證集中各類別的比例與原始數據集一致,從而提高模型評估的準確性。
使用scikit-learn
庫中的StratifiedKFold
類來實現分層交叉驗證:
from sklearn.model_selection import StratifiedKFold
from sklearn.datasets import load_iris
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score# 加載數據集
data = load_iris()
X = data.data
y = data.target# 初始化分層交叉驗證
skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)# 初始化模型
model = LogisticRegression(max_iter=200)# 進行交叉驗證
accuracies = []
for train_index, test_index in skf.split(X, y):X_train, X_test = X[train_index], X[test_index]y_train, y_test = y[train_index], y[test_index]model.fit(X_train, y_train)y_pred = model.predict(X_test)accuracies.append(accuracy_score(y_test, y_pred))# 輸出平均準確率
print(f"平均準確率: {sum(accuracies) / len(accuracies):.4f}")
執行結果為:0.9667