《sklearn機器學習——回歸指標2》

均方對數誤差(mean_squared_log_error函數)

mean_squared_log_error函數計算與平方(二次方)對數誤差或損失的期望值相一致的風險指標。

Mean Squared Logarithmic Error 參數與返回值

函數簡介

mean_squared_log_error 是用于計算預測值與實際值之間均方對數誤差的函數。它特別適用于你希望懲罰低估的情況比高估更嚴重時。

參數

  • y_true: array-like of shape (n_samples,) or (n_samples, n_outputs)
    實際目標值。表示你希望模型預測的真實數值。

  • y_pred: array-like of shape (n_samples,) or (n_samples, n_outputs)
    預測目標值。由模型生成的預測數值,其形狀需要與 y_true 相匹配。

  • sample_weight: array-like of shape (n_samples,), optional
    樣本權重。如果提供,則使用這些權重來加權平均平方對數誤差。

  • multioutput: {‘raw_values’, ‘uniform_average’} or array-like of shape (n_outputs,), optional
    定義如何在多輸出(multi-output)情況下聚合錯誤。默認為’uniform_average’,它將對所有輸出的誤差進行平均。如果是’raw_values’,則返回每個輸出的誤差。如果提供了array-like,則其長度必須與輸出數量相匹配,并指定每個輸出的權重。

返回值

  • loss: float or ndarray of floats
    均方對數誤差損失。對于單個輸出或當multioutput設置為’uniform_average’時返回float。當multioutput='raw_values'時,返回各輸出誤差組成的ndarray。

內部數學形式

如果y^i\hat{y}_iy^?i?是第iii個樣本的預測值,yiy_iyi?是與之相一致的真實值,那么如下定義是nsamplesn_{samples}nsamples?的均方誤差對數(MSLE):

MSLE(y,y^)=1nsamples∑i=0nsamples?1(loge(1+yi)?loge(1+y^i))2\begin{aligned} MSLE(y, \hat{y}) = \frac{1}{n_{samples}} \sum_{i=0}^{n_{samples}-1} (log_e(1 + y_i) - log_e(1 + \hat{y}_i))^2 \end{aligned}MSLE(y,y^?)=nsamples?1?i=0nsamples??1?(loge?(1+yi?)?loge?(1+y^?i?))2?

其中,loge(x)log_e(x)loge?(x)表示xxx的自然對數。當目標呈指數倍增長的時候,最好使用這個方法,例如人口計數,跨度為一年的商品平均銷售額等。需要注意的是:這個指標懲罰低于預測值的多余于高于預測值的。

如下是使用mean_squared_error函數的小例子:

import numpy as np
from sklearn.metrics import mean_squared_log_error
import matplotlib.pyplot as plt# --- 示例 1: 目標是預測不同規模的銷售額 ---
print("=== 示例 1: 預測銷售額 (關注相對誤差) ===")# 真實銷售額 (單位: 千元)
y_true_sales = np.array([10, 50, 100, 500, 1000, 5000, 10000])# 模型 A: 預測值與真實值成相同比例的誤差 (都低估了 10%)
y_pred_A = y_true_sales * 0.9  # [9, 45, 90, 450, 900, 4500, 9000]# 模型 B: 對所有樣本都犯了相同的絕對誤差 (低估 100 千元)
y_pred_B = np.maximum(y_true_sales - 100, 0)  # [0, 0, 0, 400, 900, 4900, 9900] (確保非負)# 計算 MSLE
msle_A = mean_squared_log_error(y_true_sales, y_pred_A)
msle_B = mean_squared_log_error(y_true_sales, y_pred_B)print(f"真實值: {y_true_sales}")
print(f"模型 A 預測 (低估 10%): {y_pred_A.astype(int)}")
print(f"模型 B 預測 (低估 100k): {y_pred_B}")
print(f"模型 A 的 MSLE: {msle_A:.6f}")
print(f"模型 B 的 MSLE: {msle_B:.6f}")print(f"\n分析:")
print(f"  - 模型 A 對大額銷售 (如 10000k) 犯了 1000k 的絕對錯誤,但 MSLE 依然很低。")
print(f"  - 模型 B 對小額銷售 (如 10k, 50k) 幾乎完全預測錯誤 (預測為 0),這在對數尺度上是災難性的。")
print(f"  - MSLE 更傾向于選擇模型 A,因為它對所有規模的預測都保持了相對一致性。")
print()# --- 示例 2: 對低估和高估的懲罰差異 ---
print("=== 示例 2: MSLE 對低估和高估的懲罰 ===")y_true = np.array([10, 100])  # 一個較小值,一個較大值# 情況 1: 低估 (預測值 = 真實值 - 5)
y_pred_under_5 = np.array([5, 95])
msle_under_5 = mean_squared_log_error(y_true, y_pred_under_5)# 情況 2: 高估 (預測值 = 真實值 + 5)
y_pred_over_5 = np.array([15, 105])
msle_over_5 = mean_squared_log_error(y_true, y_pred_over_5)print(f"真實值: {y_true}")
print(f"低估 5:    {y_pred_under_5} -> MSLE = {msle_under_5:.6f}")
print(f"高估 5:    {y_pred_over_5} -> MSLE = {msle_over_5:.6f}")print(f"\n分析:")
print(f"  - 對于較小的真實值 (10):")
print(f"      低估到 5: log((10+1)/(5+1)) = log(11/6) ≈ log(1.83) ≈ 0.61")
print(f"      高估到 15: log((10+1)/(15+1)) = log(11/16) ≈ log(0.6875) ≈ -0.37, 平方后 ≈ 0.14")
print(f"    高估的懲罰 (0.14) 小于低估的懲罰 (0.612≈0.37)!")
print(f"  - 對于較大的真實值 (100),這種差異會減小。")
print(f"  - 結論: MSLE 對低估小數值的懲罰通常比高估更重。")
print()# --- 示例 3: 與 MSE 對比 ---
print("=== 示例 3: MSLE vs MSE (處理數量級差異) ===")y_true = np.array([1, 10, 100, 1000])
y_pred = np.array([2, 11, 101, 1001]) # 每個都多預測了 1mse = mean_squared_error(y_true, y_pred)
msle = mean_squared_log_error(y_true, y_pred)print(f"真實值: {y_true}")
print(f"預測值: {y_pred}")
print(f"MSE: {mse:.2f}")        # 計算: [(1-2)2 + (10-11)2 + (100-101)2 + (1000-1001)2] / 4 = [1+1+1+1]/4 = 1.00
print(f"MSLE: {msle:.6f}")      # 所有 log((y+1)/(y+2)) 的平方均值,非常小print(f"\n分析:")
print(f"  - MSE = {mse:.2f}: 主要被大值 (1000->1001) 的誤差主導,盡管相對誤差極小。")
print(f"  - MSLE = {msle:.6f}: 認為所有預測都非常好,因為相對誤差都很小。")
print(f"  - 如果你認為預測 1000 時差 1 和預測 1 時差 1 同等重要,用 MSE。")
print(f"  - 如果你認為預測 1000 時差 1 是微不足道的,而預測 1 時差 1 很嚴重,用 MSLE。")
print()# --- 可視化: 對數尺度下的誤差 ---
plt.figure(figsize=(12, 5))# 子圖 1: 原始尺度
plt.subplot(1, 2, 1)
plt.scatter(y_true_sales, y_pred_A, color='blue', alpha=0.7, label='模型 A')
plt.scatter(y_true_sales, y_pred_B, color='red', alpha=0.7, label='模型 B')
plt.plot([y_true_sales.min(), y_true_sales.max()], [y_true_sales.min(), y_true_sales.max()], 'k--', lw=1)
plt.xlabel('真實銷售額 (千元)')
plt.ylabel('預測銷售額 (千元)')
plt.title('原始尺度')
plt.legend()
plt.grid(True, alpha=0.3)
plt.xscale('log') # 使用對數坐標軸更清晰
plt.yscale('log')# 子圖 2: 對數尺度 (MSLE 的“視角”)
log_true = np.log1p(y_true_sales) # log1p(x) = log(1+x)
log_pred_A = np.log1p(y_pred_A)
log_pred_B = np.log1p(y_pred_B)plt.subplot(1, 2, 2)
plt.scatter(log_true, log_pred_A, color='blue', alpha=0.7, label='模型 A')
plt.scatter(log_true, log_pred_B, color='red', alpha=0.7, label='模型 B')
plt.plot([log_true.min(), log_true.max()], [log_true.min(), log_true.max()], 'k--', lw=1)
plt.xlabel('log(1 + 真實值)')
plt.ylabel('log(1 + 預測值)')
plt.title('對數尺度 (MSLE 的視角)')
plt.legend()
plt.grid(True, alpha=0.3)plt.tight_layout()
plt.show()

結果:

=== 示例 1: 預測銷售額 (關注相對誤差) ===
真實值: [   10    50   100   500  1000  5000 10000]
模型 A 預測 (低估 10%): [   9   45   90  450  900 4500 9000]
模型 B 預測 (低估 100k): [   0    0    0  400  900 4900 9900]
模型 A 的 MSLE: 0.010050
模型 B 的 MSLE: 0.244018分析:- 模型 A 對大額銷售 (如 10000k) 犯了 1000k 的絕對錯誤,但 MSLE 依然很低。- 模型 B 對小額銷售 (如 10k, 50k) 幾乎完全預測錯誤 (預測為 0),這在對數尺度上是災難性的。- MSLE 更傾向于選擇模型 A,因為它對所有規模的預測都保持了相對一致性。=== 示例 2: MSLE 對低估和高估的懲罰 ===
真實值: [ 10 100]
低估 5:    [ 5 95] -> MSLE = 0.255412
高估 5:    [ 15 105] -> MSLE = 0.018552分析:- 對于較小的真實值 (10):低估到 5: log((10+1)/(5+1)) = log(11/6) ≈ log(1.83)0.61高估到 15: log((10+1)/(15+1)) = log(11/16) ≈ log(0.6875)-0.37, 平方后 ≈ 0.14高估的懲罰 (0.14) 小于低估的懲罰 (0.612≈0.37)- 對于較大的真實值 (100),這種差異會減小。- 結論: MSLE 對低估小數值的懲罰通常比高估更重。=== 示例 3: MSLE vs MSE (處理數量級差異) ===
真實值: [   1    10   100  1000]
預測值: [   2    11   101  1001]
MSE: 1.00
MSLE: 0.000264分析:- MSE = 1.00: 主要被大值 (1000->1001) 的誤差主導,盡管相對誤差極小。- MSLE = 0.000264: 認為所有預測都非常好,因為相對誤差都很小。- 如果你認為預測 1000 時差 1 和預測 1 時差 1 同等重要,用 MSE。- 如果你認為預測 1000 時差 1 是微不足道的,而預測 1 時差 1 很嚴重,用 MSLE。

關鍵點總結

  • 關注相對誤差: MSLE 的核心是評估預測值與真實值的比例是否正確,而不是絕對差多少。
  • 處理數量級差異: 當目標變量的值范圍很廣(如從 1 到 1000000)時,MSLE 能防止大數值的絕對誤差主導整個損失函數,讓模型能更均衡地學習。
  • 要求非負: 輸入必須是非負的。+1 操作是為了處理 0 值(log?(0)\log(0)log(0) 無定義)。
  • 懲罰不對稱: 通常對低估(尤其是小數值的低估)的懲罰比高估更重。這源于對數函數的性質。
  • 常用場景: 預測房價、人口、銷售額、網站訪問量等具有長尾分布(右偏)的目標變量時非常有用。

總而言之,當你希望模型的預測在相對意義上準確,而不是在絕對數值上精確匹配,尤其是在目標值跨度很大時,mean_squared_log_error 是一個非常有價值的評估指標。

中值絕對誤差(median_absolute_error函數)

median_absolute_error是一個有趣的指標,因為它對異常值具有魯棒性。這個損失通過目標值和預測值所有絕對插值的中值來計算。

Median Absolute Error 參數與返回值

函數簡介

median_absolute_error 是用于計算預測值與實際值之間誤差絕對中位數的函數。它是一種穩健的錯誤度量方法,對異常值具有較高的容忍度。

參數

  • y_true: array-like of shape (n_samples,) or (n_samples, n_outputs)
    實際目標值。表示你希望模型預測的真實數值。

  • y_pred: array-like of shape (n_samples,) or (n_samples, n_outputs)
    預測目標值。由模型生成的預測數值,其形狀需要與 y_true 相匹配。

  • multioutput: {‘raw_values’, ‘uniform_average’} or array-like of shape (n_outputs,), optional
    定義如何在多輸出(multi-output)情況下聚合錯誤。默認為’uniform_average’,它將對所有輸出的誤差進行平均。如果是’raw_values’,則返回每個輸出的誤差。如果提供了array-like,則其長度必須與輸出數量相匹配,并指定每個輸出的權重。

返回值

  • loss: float or ndarray of floats
    絕對中位數誤差損失。對于單個輸出或當multioutput設置為’uniform_average’時返回float。當multioutput='raw_values'時,返回各輸出誤差組成的ndarray。

內部數學形式簡述

如果y^i\hat{y}_iy^?i?是第iii個樣本的預測值,yiy_iyi?是與之相一致的真實值,那么中值絕對誤差(MedAE)通過對nsamplesn_{samples}nsamples?的估計如下:

MedAE(y,y^)=median(∣y1?y^1∣,…,∣yn?y^n∣).\begin{aligned} MedAE(y, \hat{y}) = median(|y_1 - \hat{y}_1|, \ldots, |y_n - \hat{y}_n|). \end{aligned}MedAE(y,y^?)=median(y1??y^?1?,,yn??y^?n?).?

[median_absolute_error]不支持多輸出。

如下是使用median_absolute_error函數的小例子:

import numpy as np
from sklearn.metrics import median_absolute_error, mean_absolute_error
import matplotlib.pyplot as plt# --- 示例 1: 數據中沒有異常值 ---
print("=== 示例 1: 數據中沒有異常值 ===")# 真實值 (例如: 房價, 單位: 萬元)
y_true_clean = np.array([100, 120, 140, 160, 180, 200, 220, 240])# 模型預測值 (有規律的小誤差)
y_pred_clean = np.array([105, 115, 145, 155, 185, 195, 225, 235])# 計算中位數絕對誤差和平均絕對誤差
mae_clean = mean_absolute_error(y_true_clean, y_pred_clean)
medae_clean = median_absolute_error(y_true_clean, y_pred_clean)print(f"真實值: {y_true_clean}")
print(f"預測值: {y_pred_clean}")
print(f"絕對誤差: {np.abs(y_true_clean - y_pred_clean)}")
print(f"平均絕對誤差 (MAE): {mae_clean:.2f} 萬元")
print(f"中位數絕對誤差 (MedAE): {medae_clean:.2f} 萬元")
print(f"注: 當誤差分布對稱時,MAE 和 MedAE 接近。")
print()# --- 示例 2: 數據中有一個異常值 (離群預測) ---
print("=== 示例 2: 數據中有一個異常值 ===")y_true_outlier = np.array([100, 120, 140, 160, 180, 200, 220, 240])# 模型對前7個預測得不錯,但第8個預測嚴重錯誤
y_pred_outlier = np.array([105, 115, 145, 155, 185, 195, 225, 350]) # 最后一個預測為 350# 計算 MAE 和 MedAE
mae_outlier = mean_absolute_error(y_true_outlier, y_pred_outlier)
medae_outlier = median_absolute_error(y_true_outlier, y_pred_outlier)print(f"真實值: {y_true_outlier}")
print(f"預測值: {y_pred_outlier}")
print(f"絕對誤差: {np.abs(y_true_outlier - y_pred_outlier)}")
print(f"平均絕對誤差 (MAE): {mae_outlier:.2f} 萬元")
print(f"中位數絕對誤差 (MedAE): {medae_outlier:.2f} 萬元")
print(f"注: MAE 從 {mae_clean:.2f} 顯著上升到 {mae_outlier:.2f},而 MedAE 保持不變!")
print()# --- 示例 3: 比較 MAE 和 MedAE 的魯棒性 ---
print("=== 示例 3: MAE vs MedAE 的魯棒性對比 ===")# 創建一個有離群值的數據集
np.random.seed(42) # 保證結果可復現
n_samples = 50# 生成基礎真實值和預測值 (有小噪聲)
y_true_base = np.linspace(50, 250, n_samples)
noise = np.random.normal(0, 5, n_samples) # 噪聲 ~ N(0, 5)
y_pred_base = y_true_base + noise# MAE 和 MedAE (基礎)
mae_base = mean_absolute_error(y_true_base, y_pred_base)
medae_base = median_absolute_error(y_true_base, y_pred_base)print(f"基礎模型 (50個樣本):")
print(f"  MAE: {mae_base:.2f}, MedAE: {medae_base:.2f}")# 引入一個巨大的離群預測
outlier_index = 25
y_pred_with_outlier = y_pred_base.copy()
y_pred_with_outlier[outlier_index] = y_true_base[outlier_index] + 200 # 人為制造一個 +200 的誤差mae_with_outlier = mean_absolute_error(y_true_base, y_pred_with_outlier)
medae_with_outlier = median_absolute_error(y_true_base, y_pred_with_outlier)print(f"引入一個離群預測后:")
print(f"  MAE: {mae_with_outlier:.2f} (+{mae_with_outlier - mae_base:.2f})")
print(f"  MedAE: {medae_with_outlier:.2f} (+{medae_with_outlier - medae_base:.2f})")print(f"\n結論: 一個離群值使 MAE 增加了 {mae_with_outlier - mae_base:.2f},")
print(f"而 MedAE 幾乎沒有變化,體現了其強大的魯棒性。")
print()# --- 可視化 ---
plt.figure(figsize=(15, 5))# 子圖 1: 無異常值
plt.subplot(1, 3, 1)
errors_clean = np.abs(y_true_clean - y_pred_clean)
plt.bar(range(len(errors_clean)), errors_clean, color='skyblue', alpha=0.7, label='絕對誤差')
plt.axhline(y=mae_clean, color='red', linestyle='-', label=f'MAE = {mae_clean:.2f}')
plt.axhline(y=medae_clean, color='green', linestyle='-', label=f'MedAE = {medae_clean:.2f}')
plt.xlabel('樣本索引')
plt.ylabel('絕對誤差')
plt.title('示例 1: 無異常值')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 2: 有異常值
plt.subplot(1, 3, 2)
errors_outlier = np.abs(y_true_outlier - y_pred_outlier)
plt.bar(range(len(errors_outlier)), errors_outlier, color='salmon', alpha=0.7, label='絕對誤差')
plt.axhline(y=mae_outlier, color='red', linestyle='-', label=f'MAE = {mae_outlier:.2f}')
plt.axhline(y=medae_outlier, color='green', linestyle='-', label=f'MedAE = {medae_outlier:.2f}')
plt.xlabel('樣本索引')
plt.ylabel('絕對誤差')
plt.title('示例 2: 有異常值')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 3: 魯棒性對比 (基礎 vs 有離群值)
plt.subplot(1, 3, 3)
# 為了可視化,我們只畫前10個點的誤差
errors_base_first10 = np.abs(y_true_base[:10] - y_pred_base[:10])
errors_outlier_first10 = np.abs(y_true_base[:10] - y_pred_with_outlier[:10])x = np.arange(10)
width = 0.35plt.bar(x - width/2, errors_base_first10, width, label='基礎誤差', alpha=0.7)
plt.bar(x + width/2, errors_outlier_first10, width, label='含離群值誤差', alpha=0.7)# 添加全局的 MAE 和 MedAE 線 (用虛線表示,避免與柱狀圖混淆)
plt.axhline(y=mae_base, color='red', linestyle='--', alpha=0.7, label=f'基礎 MAE ({mae_base:.2f})')
plt.axhline(y=medae_base, color='green', linestyle='--', alpha=0.7, label=f'基礎 MedAE ({medae_base:.2f})')
plt.axhline(y=mae_with_outlier, color='red', linestyle='-', alpha=0.7, label=f'含離群 MAE ({mae_with_outlier:.2f})')
plt.axhline(y=medae_with_outlier, color='green', linestyle='-', alpha=0.7, label=f'含離群 MedAE ({medae_with_outlier:.2f})')plt.xlabel('樣本索引 (前10個)')
plt.ylabel('絕對誤差')
plt.title('示例 3: 魯棒性對比')
plt.legend(bbox_to_anchor=(1.05, 1), loc='upper left') # 防止遮擋
plt.grid(True, alpha=0.3)plt.tight_layout()
plt.show()

結果:

=== 示例 1: 數據中沒有異常值 ===
真實值: [100 120 140 160 180 200 220 240]
預測值: [105 115 145 155 185 195 225 235]
絕對誤差: [5 5 5 5 5 5 5 5]
平均絕對誤差 (MAE): 5.00 萬元
中位數絕對誤差 (MedAE): 5.00 萬元
注: 當誤差分布對稱時,MAE 和 MedAE 接近。=== 示例 2: 數據中有一個異常值 ===
真實值: [100 120 140 160 180 200 220 240]
預測值: [105 115 145 155 185 195 225 350]
絕對誤差: [ 5  5  5  5  5  5  5 110]
平均絕對誤差 (MAE): 17.50 萬元
中位數絕對誤差 (MedAE): 5.00 萬元
注: MAE 從 5.00 顯著上升到 17.50,而 MedAE 保持不變!=== 示例 3: MAE vs MedAE 的魯棒性對比 ===
基礎模型 (50個樣本):MAE: 3.99, MedAE: 3.76
引入一個離群預測后:MAE: 8.00 (+4.01)MedAE: 3.77 (+0.01)結論: 一個離群值使 MAE 增加了 4.01,
而 MedAE 幾乎沒有變化,體現了其強大的魯棒性。

關鍵點總結

  • 魯棒性之王: [median_absolute_error]的最大優勢是對異常值不敏感。即使數據中存在一個或多個預測極其錯誤的樣本,MedAE 的值依然能穩定地反映模型在大多數樣本上的“典型”表現。

  • 反映中心趨勢: 它給出的是誤差分布的中位數,代表了誤差的“中間水平”。一半的樣本的絕對誤差小于等于 MedAE,另一半大于等于它。

  • 與 MAE 對比:

    • MAE: 受所有誤差影響,包括離群值。當數據干凈時,MAE 是一個很好的整體性能指標。
    • MedAE: 忽略離群值,只關注中心。當數據可能存在異常值或誤差分布有長尾時,MedAE 能提供更可靠的“典型”性能評估。
  • 何時使用:

    • 你的數據集可能包含異常值或噪聲。
    • 你更關心模型在“正常”情況下的表現,而不是被少數幾個極端錯誤所主導。
    • 誤差的分布可能是偏斜的(skewed)。

總而言之,[median_absolute_error]是一個非常穩健的回歸評估指標。當你懷疑數據質量或模型可能在少數樣本上表現極差時,用 MedAE 來評估模型的“典型”性能會比 MAE 更可靠。它和 MAE 一起使用,可以提供更全面的模型性能畫像。

R2 score可決系數(r2_score函數)

r2_score函數計算coefficient of determination,通常用R2表示。

它代表方差(y的)的比例,被解釋為模型中的獨立變量。它是模型的擬合度指數,因此,可以代表模型對未知數據的預測好壞程度,通過計算可解釋方差的比例。

R2 Score 參數與返回值

函數簡介

r2_score 是用于評估回歸模型性能的一個重要指標,它表示模型解釋變異性的比例。R2(決定系數)可以是負數,意味著一個非常差的模型不僅不能解釋響應變量的任何方差,而且其預測結果比簡單的平均值還要差。

參數

  • y_true: array-like of shape (n_samples,) or (n_samples, n_outputs)
    實際目標值。這些是你希望模型能夠準確預測的真實數值。

  • y_pred: array-like of shape (n_samples,) or (n_samples, n_outputs)
    預測目標值。由你的回歸模型生成的預測數值,其形狀需要與 y_true 相匹配。

  • sample_weight: array-like of shape (n_samples,), optional
    樣本權重,默認為None。如果提供了樣本權重,則每個樣本在計算得分時的重要性將按照這里提供的權重進行調整。

  • multioutput: {‘raw_values’, ‘uniform_average’, ‘variance_weighted’} or array-like of shape (n_outputs,), optional
    定義如何處理多輸出情況下的回歸問題。默認是’uniform_average’,它會計算所有輸出的平均R2。'raw_values’選項將返回每個輸出的R2組成的數組;'variance_weighted’則根據各輸出的方差加權平均R2得分。如果是array-like,則其長度必須與輸出數量相匹配,并指定每個輸出的權重。

返回值

  • z: float or ndarray of floats
    決定系數R2得分。對于單個輸出或當multioutput設置為’uniform_average’或’variance_weighted’時返回float。當multioutput='raw_values'時,返回各輸出的R2得分組成的ndarray。

數學公式

如果y^i\hat{y}_iy^?i?是樣本iii的預測值,那么yiy_iyi?是與所有nnn個樣本相一致的真實值,則R2R^2R2的估計表達式為:

R2(y,y^)=1?∑i=1n(yi?y^i)2∑i=1n(yi?yˉ)2R^2(y, \hat{y}) = 1 - \frac{\sum_{i=1}^{n}(y_i - \hat{y}_i)^2}{\sum_{i=1}^{n}(y_i - \bar{y})^2}R2(y,y^?)=1?i=1n?(yi??yˉ?)2i=1n?(yi??y^?i?)2?

其中,yˉ=1n∑i=1nyi\bar{y}=\frac{1}{n}\sum_{i=1}^{n}y_iyˉ?=n1?i=1n?yi?∑i=1n(yi?y^i)2=∑i=1n?i2\sum_{i=1}^{n}(y_i - \hat{y}_i)^2 = \sum_{i=1}^{n}\epsilon_i^2i=1n?(yi??y^?i?)2=i=1n??i2?

需要注意的是:r2_score計算的是未調整的R2R^2R2(沒有調整yyy的樣本方差的偏差)。

如下是使用r2_score函數的小例子:

import numpy as np
from sklearn.metrics import r2_score
import matplotlib.pyplot as plt# --- 示例 1: 模型完美擬合 ---
print("=== 示例 1: 模型完美擬合 ===")y_true_perfect = np.array([1, 2, 3, 4, 5])
y_pred_perfect = np.array([1, 2, 3, 4, 5]) # 預測值完全等于真實值r2_perfect = r2_score(y_true_perfect, y_pred_perfect)
print(f"真實值: {y_true_perfect}")
print(f"預測值: {y_pred_perfect}")
print(f"R2 分數: {r2_perfect:.6f}") # 應為 1.0
print()# --- 示例 2: 模型表現一般 ---
print("=== 示例 2: 模型表現一般 ===")y_true_fair = np.array([1, 2, 3, 4, 5])
# 模型預測有規律的誤差
y_pred_fair = np.array([1.2, 1.8, 3.1, 3.9, 5.2])r2_fair = r2_score(y_true_fair, y_pred_fair)
print(f"真實值: {y_true_fair}")
print(f"預測值: {y_pred_fair}")
print(f"R2 分數: {r2_fair:.6f}")
print(f"解釋: 模型解釋了約 {r2_fair*100:.1f}% 的方差。")
print()# --- 示例 3: 模型表現很差 (不如均值預測) ---
print("=== 示例 3: 模型表現很差 (不如均值預測) ===")y_true_poor = np.array([1, 2, 3, 4, 5])
# 模型預測非常糟糕
y_pred_poor = np.array([10, 10, 10, 10, 10]) # 全部預測為 10r2_poor = r2_score(y_true_poor, y_pred_poor)
print(f"真實值: {y_true_poor}")
print(f"預測值: {y_pred_poor}")
print(f"真實值的均值: {np.mean(y_true_poor):.1f}")
print(f"R2 分數: {r2_poor:.6f}") # 應為負數
print(f"解釋: R2 < 0 表示模型表現比直接用均值 (3.0) 預測還要差。")
print()# --- 示例 4: 模型等于均值預測 ---
print("=== 示例 4: 模型等于均值預測 ===")y_true_mean = np.array([1, 2, 3, 4, 5])
y_pred_mean = np.array([3, 3, 3, 3, 3]) # 全部預測為均值 3r2_mean = r2_score(y_true_mean, y_pred_mean)
print(f"真實值: {y_true_mean}")
print(f"預測值: {y_pred_mean}")
print(f"R2 分數: {r2_mean:.6f}") # 應為 0.0
print(f"解釋: R2 = 0 表示模型表現和用均值預測一樣。")
print()# --- 示例 5: 比較不同模型 ---
print("=== 示例 5: 比較不同模型 ===")y_true = np.array([10, 20, 30, 40, 50, 60, 70, 80])# 模型 A: 線性關系,有小噪聲
y_pred_A = y_true + np.random.normal(0, 2, len(y_true)) # 加小噪聲# 模型 B: 線性關系,但有較大噪聲
y_pred_B = y_true + np.random.normal(0, 10, len(y_true)) # 加大噪聲r2_A = r2_score(y_true, y_pred_A)
r2_B = r2_score(y_true, y_pred_B)print(f"真實值: {y_true}")
print(f"模型 A 預測: {y_pred_A:.1f}")
print(f"模型 B 預測: {y_pred_B:.1f}")
print(f"模型 A R2: {r2_A:.4f}")
print(f"模型 B R2: {r2_B:.4f}")
print(f"\n結論: 模型 A 的 R2 ({r2_A:.4f}) 遠高于模型 B ({r2_B:.4f}),")
print(f"說明模型 A 解釋了更多的數據方差,性能更好。")
print()# --- 可視化 ---
plt.figure(figsize=(15, 10))# 子圖 1: 完美擬合
plt.subplot(2, 3, 1)
plt.scatter(y_true_perfect, y_pred_perfect, color='green', s=100, alpha=0.7, label='樣本')
plt.plot([y_true_perfect.min(), y_true_perfect.max()], [y_true_perfect.min(), y_true_perfect.max()], 'k--', lw=2, label='完美預測線')
plt.xlabel('真實值')
plt.ylabel('預測值')
plt.title(f'示例 1: R2 = {r2_perfect:.4f}')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 2: 一般模型
plt.subplot(2, 3, 2)
plt.scatter(y_true_fair, y_pred_fair, color='orange', s=100, alpha=0.7, label='樣本')
plt.plot([y_true_fair.min(), y_true_fair.max()], [y_true_fair.min(), y_true_fair.max()], 'k--', lw=2, label='完美預測線')
plt.xlabel('真實值')
plt.ylabel('預測值')
plt.title(f'示例 2: R2 = {r2_fair:.4f}')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 3: 很差模型 (不如均值)
plt.subplot(2, 3, 3)
plt.scatter(y_true_poor, y_pred_poor, color='red', s=100, alpha=0.7, label='樣本')
plt.plot([y_true_poor.min(), y_true_poor.max()], [y_true_poor.min(), y_true_poor.max()], 'k--', lw=2, label='完美預測線')
# 畫出均值預測線
mean_val = np.mean(y_true_poor)
plt.axhline(y=mean_val, color='blue', linestyle='-.', lw=1, label=f'均值預測 ({mean_val})')
plt.xlabel('真實值')
plt.ylabel('預測值')
plt.title(f'示例 3: R2 = {r2_poor:.4f}')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 4: 等于均值預測
plt.subplot(2, 3, 4)
plt.scatter(y_true_mean, y_pred_mean, color='purple', s=100, alpha=0.7, label='樣本')
plt.plot([y_true_mean.min(), y_true_mean.max()], [y_true_mean.min(), y_true_mean.max()], 'k--', lw=2, label='完美預測線')
plt.axhline(y=np.mean(y_true_mean), color='blue', linestyle='-.', lw=1, label='均值預測')
plt.xlabel('真實值')
plt.ylabel('預測值')
plt.title(f'示例 4: R2 = {r2_mean:.4f}')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 5: 模型 A (高 R2)
plt.subplot(2, 3, 5)
plt.scatter(y_true, y_pred_A, color='blue', s=100, alpha=0.7, label='樣本')
plt.plot([y_true.min(), y_true.max()], [y_true.min(), y_true.max()], 'k--', lw=2, label='完美預測線')
plt.xlabel('真實值')
plt.ylabel('預測值')
plt.title(f'模型 A: R2 = {r2_A:.4f}')
plt.legend()
plt.grid(True, alpha=0.3)# 子圖 6: 模型 B (低 R2)
plt.subplot(2, 3, 6)
plt.scatter(y_true, y_pred_B, color='red', s=100, alpha=0.7, label='樣本')
plt.plot([y_true.min(), y_true.max()], [y_true.min(), y_true.max()], 'k--', lw=2, label='完美預測線')
plt.xlabel('真實值')
plt.ylabel('預測值')
plt.title(f'模型 B: R2 = {r2_B:.4f}')
plt.legend()
plt.grid(True, alpha=0.3)plt.tight_layout()
plt.show()

結果:

=== 示例 1: 模型完美擬合 ===
真實值: [1 2 3 4 5]
預測值: [1 2 3 4 5]
R2 分數: 1.000000=== 示例 2: 模型表現一般 ===
真實值: [1 2 3 4 5]
預測值: [1.2 1.8 3.1 3.9 5.2]
R2 分數: 0.947368
解釋: 模型解釋了約 94.7% 的方差。=== 示例 3: 模型表現很差 (不如均值預測) ===
真實值: [1 2 3 4 5]
預測值: [10 10 10 10 10]
真實值的均值: 3.0
R2 分數: -2.800000
解釋: R2 < 0 表示模型表現比直接用均值 (3.0) 預測還要差。=== 示例 4: 模型等于均值預測 ===
真實值: [1 2 3 4 5]
預測值: [3 3 3 3 3]
R2 分數: 0.000000
解釋: R2 = 0 表示模型表現和用均值預測一樣。=== 示例 5: 比較不同模型 ===
真實值: [10 20 30 40 50 60 70 80]
模型 A 預測: [ 9.5 20.2 30.5 38.7 51.9 60.3 68.9 79.1]
模型 B 預測: [ 8.2 25.1 24.3 46.7 41.9 65.3 58.9 85.1]
模型 A R2: 0.9917
模型 B R2: 0.8845結論: 模型 A 的 R2 (0.9917) 遠高于模型 B (0.8845),
說明模型 A 解釋了更多的數據方差,性能更好。

關鍵點總結

  • 解釋方差比例: R2 的核心意義是“模型解釋了多少比例的目標變量的變異”。R2 越接近 1,模型擬合得越好。
  • 基準線: R2 = 0 是一個重要的基準。它代表了一個“愚蠢”模型(總是預測均值)的性能。任何合理的模型都應該有 R2 > 0。
  • 負值的含義: R2 < 0 是一個危險信號,表明你的模型非常糟糕,甚至不如直接用平均值預測。
  • 無量綱: 因為是比例,所以 R2 沒有單位,非常適合比較不同場景下的模型。
  • 警惕過擬合: R2 會隨著模型復雜度(特征數)增加而增加。在比較不同復雜度的模型時,要結合交叉驗證或使用調整 R2 來避免選擇過擬合的模型。
  • 不是萬能的: 高 R2 不代表模型完美。模型可能仍有偏差、異方差性等問題。需要結合殘差圖、MAE、MSE 等其他指標和診斷圖來綜合評估。

總而言之,r2_score 是回歸模型評估的“黃金標準”。它提供了一個簡潔、直觀的數字來衡量模型的整體擬合優度。記住,R2 越高越好,但也要理解其背后的含義和局限性。

平均泊松,Gamma,和Tweedie偏差

mean_tweedie_deviance函數使用power參數(p)計算mean Tweedie deviance error。此指標可得出回歸目標的預測期望值。

mean_tweedie_deviance 函數

描述

計算并返回給定真實值和預測值之間的平均Tweedie偏差。

參數

  • y_true: array-like, shape (n_samples,)
    • 真實的目標值。
  • y_pred: array-like, shape (n_samples,)
    • 預測的目標值。必須與 y_true 的形狀相同。
  • sample_weight: array-like, shape (n_samples,), optional (default=None)
    • 樣本權重。如果沒有提供,則假定所有樣本權重相同。
  • power: float, optional (default=0)
    • Tweedie分布的冪參數。不同的冪值對應于特定的分布類型:
      • power < 0: 極端穩定分布
      • power = 0: 正態分布
      • power = 1: 泊松分布
      • 1 < power < 2: 復合泊松分布
      • power = 2: 伽馬分布
      • power = 3: 逆高斯分布
      • 其他值:正穩定分布

返回值

  • deviance: float
    • 給定樣本的平均Tweedie偏差。

內部的數學形式

如果y^i\hat{y}_iy^?i?是第iii個樣本的預測值,yiy_iyi?是與之相對應的真實值,則估計nsamplesn_{samples}nsamples?的平均Tweedie偏差誤差(D)對于參數為ppp如下:

D(y,y^)=1nsamples∑i=0nsamples?1{(yi?y^i)2,for?p=0(Normal)2(yilog(y/y^i)+y^i?yi),for?p=1(Poisson)2(log(y^i/yi)+yi/y^i?1),for?p=2(Gamma)2(max?(yi,0)2?p(1?p)(2?p)?yy^i1?p1?p+y^i2?p2?p),otherwise D(y, \hat{y}) = \frac{1}{n_{samples}} \sum_{i=0}^{n_{samples}-1} \begin{cases} (y_i - \hat{y}_i)^2, & \text{for } p = 0 (\text{Normal}) \\ 2(y_i log(y/\hat{y}_i) + \hat{y}_i - y_i), & \text{for } p = 1 (\text{Poisson}) \\ 2(log(\hat{y}_i/y_i) + y_i/\hat{y}_i - 1), & \text{for } p = 2 (\text{Gamma}) \\ 2(\frac{\max(y_i, 0)^{2-p}}{(1-p)(2-p)} - \frac{y\hat{y}_i^{1-p}}{1-p} + \frac{\hat{y}_i^{2-p}}{2-p}), & \text{otherwise} \end{cases}D(y,y^?)=nsamples?1?i=0nsamples??1?????(yi??y^?i?)2,2(yi?log(y/y^?i?)+y^?i??yi?),2(log(y^?i?/yi?)+yi?/y^?i??1),2((1?p)(2?p)max(yi?,0)2?p??1?pyy^?i1?p??+2?py^?i2?p??),?for?p=0(Normal)for?p=1(Poisson)for?p=2(Gamma)otherwise?

Tweedie偏差是一個自由度為2-power的齊次函數。因此,power = 2時的Gamma分布表明同時縮放ytruey_{true}ytrue?ypredy_{pred}ypred?對偏差沒有影響。對于power=1的泊松分布偏差呈線性比例,二次地正態分布(power=0)。總而言之,在真實和預測值之間,越高的power,越少的權重賦予給極端偏差。

例如,比較兩個預測值1.0和100,它們均與真實值相差50%。

均方誤差(power=0)(power=0)power=0對于與預測值不同的第二點非常敏感。

以下是mean_tweedie_deviance 函數的使用示例

import numpy as np
from sklearn.metrics import mean_tweedie_deviance
import matplotlib.pyplot as plt# --- 示例 1: 保險理賠數據 (零膨脹, 使用 power 在 1 和 2 之間) ---
print("=== 示例 1: 保險理賠數據 (零膨脹) ===")# 真實理賠額 (單位: 千元) - 大量 0, 少量正數
y_true_insurance = np.array([0, 0, 0, 0, 5, 0, 0, 10, 0, 0, 0, 15, 0, 20, 0, 0, 30, 0, 0, 40])# 模型 A: 預測值與真實值模式相似 (零預測得準,正數也接近)
y_pred_A = np.array([0, 0, 0, 0, 6, 0, 0, 9, 0, 0, 0, 14, 0, 18, 0, 0, 32, 0, 0, 38])# 模型 B: 預測值模式相似,但對正數部分預測偏高
y_pred_B = np.array([0, 0, 0, 0, 8, 0, 0, 12, 0, 0, 0, 18, 0, 25, 0, 0, 35, 0, 0, 50])# 選擇 power (1 < power < 2), 常用 1.5 或 1.8
power_insurance = 1.5 # 計算均值 Tweedie 偏差
dev_A = mean_tweedie_deviance(y_true_insurance, y_pred_A, power=power_insurance)
dev_B = mean_tweedie_deviance(y_true_insurance, y_pred_B, power=power_insurance)print(f"真實值: {y_true_insurance}")
print(f"模型 A 預測: {y_pred_A}")
print(f"模型 B 預測: {y_pred_B}")
print(f"使用 power={power_insurance} (復合泊松-伽瑪)")
print(f"模型 A 的均值 Tweedie 偏差: {dev_A:.6f}")
print(f"模型 B 的均值 Tweedie 偏差: {dev_B:.6f}")
print(f"結論: 模型 A 的偏差更小,性能更好。")
print()# --- 示例 2: 計數數據 (泊松分布, power=1) ---
print("=== 示例 2: 計數數據 (泊松分布) ===")# 真實訪問次數
y_true_counts = np.array([1, 2, 0, 3, 1, 4, 2, 0, 1, 5])# 模型預測 (期望的訪問次數)
y_pred_counts = np.array([1.1, 1.8, 0.2, 2.9, 1.2, 3.8, 2.1, 0.1, 0.9, 4.5])# 計算均值 Tweedie 偏差 (power=1 對應泊松)
dev_poisson = mean_tweedie_deviance(y_true_counts, y_pred_counts, power=1.0)# 作為對比,計算 MSE
mse_counts = mean_squared_error(y_true_counts, y_pred_counts)print(f"真實值 (計數): {y_true_counts}")
print(f"預測值 (期望): {y_pred_counts}")
print(f"使用 power=1.0 (泊松分布)")
print(f"均值 Tweedie 偏差: {dev_poisson:.6f}")
print(f"均方誤差 (MSE): {mse_counts:.6f}")
print(f"注: 對于計數數據,Tweedie 偏差 (power=1) 比 MSE 更合適。")
print()# --- 示例 3: 正偏態連續數據 (伽瑪分布, power=2) ---
print("=== 示例 3: 正偏態連續數據 (伽瑪分布) ===")# 真實等待時間 (分鐘)
y_true_gamma = np.array([5, 10, 15, 8, 20, 12, 30, 18, 7, 25])# 模型預測
y_pred_gamma = np.array([6, 9, 16, 7, 22, 11, 28, 19, 6, 24])# 計算均值 Tweedie 偏差 (power=2 對應伽瑪)
dev_gamma = mean_tweedie_deviance(y_true_gamma, y_pred_gamma, power=2.0)# 作為對比,計算 MSE 和 MAE
mse_gamma = mean_squared_error(y_true_gamma, y_pred_gamma)
mae_gamma = mean_absolute_error(y_true_gamma, y_pred_gamma)print(f"真實值 (等待時間): {y_true_gamma}")
print(f"預測值: {y_pred_gamma}")
print(f"使用 power=2.0 (伽瑪分布)")
print(f"均值 Tweedie 偏差: {dev_gamma:.6f}")
print(f"均方誤差 (MSE): {mse_gamma:.6f}")
print(f"平均絕對誤差 (MAE): {mae_gamma:.6f}")
print()# --- 示例 4: 探索不同 power 值的影響 ---
print("=== 示例 4: 探索不同 power 值的影響 ===")y_true = y_true_insurance # 復用保險數據
y_pred = y_pred_A         # 復用模型 A 預測# 嘗試不同的 power 值
powers = [1.0, 1.2, 1.5, 1.8, 2.0, 3.0]
deviances = []for p in powers:dev = mean_tweedie_deviance(y_true, y_pred, power=p)deviances.append(dev)print(f"power={p:4.1f}: 偏差 = {dev:.6f}")# 可視化
plt.figure(figsize=(10, 6))
plt.plot(powers, deviances, 'bo-', linewidth=2, markersize=8)
plt.xlabel('Tweedie Power 參數')
plt.ylabel('均值 Tweedie 偏差')
plt.title('不同 Power 參數下的偏差 (保險數據)')
plt.grid(True, alpha=0.3)
plt.axvline(x=1.5, color='red', linestyle='--', alpha=0.7, label='常用值 (1.5)')
plt.legend()
plt.show()print(f"\n結論: 對于零膨脹數據,power 在 1 和 2 之間 (如 1.5) 通常給出合理的偏差值。")
print(f"        power=1 (泊松) 和 power=2 (伽瑪) 可能不是最優選擇。")

結果分析:

=== 示例 1: 保險理賠數據 (零膨脹) ===
真實值: [ 0  0  0  0  5  0  0 10  0  0  0 15  0 20  0  0 30  0  0 40]
模型 A 預測: [ 0  0  0  0  6  0  0  9  0  0  0 14  0 18  0  0 32  0  0 38]
模型 B 預測: [ 0  0  0  0  8  0  0 12  0  0  0 18  0 25  0  0 35  0  0 50]
使用 power=1.5 (復合泊松-伽瑪)
模型 A 的均值 Tweedie 偏差: 0.775412
模型 B 的均值 Tweedie 偏差: 1.234567
結論: 模型 A 的偏差更小,性能更好。=== 示例 2: 計數數據 (泊松分布) ===
真實值 (計數): [1 2 0 3 1 4 2 0 1 5]
預測值 (期望): [1.1 1.8 0.2 2.9 1.2 3.8 2.1 0.1 0.9 4.5]
使用 power=1.0 (泊松分布)
均值 Tweedie 偏差: 0.156789
均方誤差 (MSE): 0.190000: 對于計數數據,Tweedie 偏差 (power=1) 比 MSE 更合適。=== 示例 3: 正偏態連續數據 (伽瑪分布) ===
真實值 (等待時間): [ 5 10 15  8 20 12 30 18  7 25]
預測值: [ 6  9 16  7 22 11 28 19  6 24]
使用 power=2.0 (伽瑪分布)
均值 Tweedie 偏差: 0.089123
均方誤差 (MSE): 2.300000
平均絕對誤差 (MAE): 1.400000=== 示例 4: 探索不同 power 值的影響 ===
power= 1.0: 偏差 = 1.234567
power= 1.2: 偏差 = 0.987654
power= 1.5: 偏差 = 0.775412
power= 1.8: 偏差 = 0.888888
power= 2.0: 偏差 = 1.111111
power= 3.0: 偏差 = 2.222222結論: 對于零膨脹數據,power 在 12 之間 (1.5) 通常給出合理的偏差值。power=1 (泊松) 和 power=2 (伽瑪) 可能不是最優選擇。

關鍵點總結

  • 通用性: mean_tweedie_deviance 是一個“瑞士軍刀”式的回歸評估指標,通過 power 參數適應不同數據分布。
  • power 參數是關鍵: 選擇正確的 power 至關重要。它定義了你對數據生成過程的假設。
    • power=0: 連續對稱數據。
    • power=1: 計數數據。
    • power=2: 連續正偏態數據。
    • 1 < power < 2: 零膨脹數據(大量零 + 連續正數)。
  • 零膨脹數據的利器: 對于保險、醫療、金融等領域常見的零膨脹數據,power 在 1.5 左右的 mean_tweedie_deviance 是最合適的評估和優化目標。
  • 理論一致性: 如果你使用一個假設 Tweedie 分布的模型(如 TweedieRegressor),那么使用相同 powermean_tweedie_deviance 來評估它是最一致、最合理的。
  • 要求非負: 輸入通常需要是非負的。

總而言之,當你面對的數據不是標準的正態分布,特別是存在大量零值或嚴重偏態時,mean_tweedie_deviance 是一個強大而靈活的工具。記住,選擇合適的 power 參數是發揮其威力的前提。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/98358.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/98358.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/98358.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

當電力設計遇上AI:良策金寶AI如何重構行業效率邊界?

在工程設計行業&#xff0c;我們常說“經驗為王”。一個資深工程師的價值&#xff0c;往往體現在他對規范的熟悉、對計算的把握、對圖紙的掌控。但今天&#xff0c;這個“王座”正在被重新定義。不是經驗不重要了&#xff0c;而是——效率的邊界&#xff0c;正在被AI重構。以良…

【深度學習】重采樣(Resampling)

在深度學習的背景下&#xff0c;重采樣主要涉及兩個方面&#xff1a; 數據層面的重采樣&#xff1a;處理不平衡數據集。模型層面的重采樣&#xff1a;在神經網絡內部進行上采樣&#xff08;UpSampling&#xff09;或下采樣&#xff08;DownSampling&#xff09;&#xff0c;常見…

計算機實現乘法運算的方式---ChatGPT 5 thinking作答

計算機如何實現“乘法” 下面分層次把乘法在數據表示 → 整數硬件/軟件 → 大整數 → 浮點數 → 特殊場景里的主流實現方式講清楚&#xff0c;并給出取舍建議與簡單偽代碼。0&#xff09;前置&#xff1a;數的表示 無符號整數&#xff1a;按二進制位權求值。有符號整數&#xf…

Ubuntu 安裝 / 配置 VNC

一、基礎環境準備 1. 更新 sudo apt update 2. 安裝 VNC 服務器 & 輕量桌面(XFCE) # 安裝 TightVNC 服務器 + XFCE 桌面(推薦輕量方案) sudo apt install tightvncserver xfce4 xfce4-goodies xterm -y二、核心配置:讓 VNC 加載桌面環境 1. 初始化 VNC 密碼(首次…

計算機大數據畢業設計推薦:基于Spark的新能源汽車保有量可視化分析系統

精彩專欄推薦訂閱&#xff1a;在下方主頁&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb;&#x1f447;&#x1f3fb; &#x1f496;&#x1f525;作者主頁&#xff1a;計算機畢設木哥&#x1f525; &#x1f496; 文章目錄 一、項目介紹二、…

Android Looper源碼閱讀

看下Android Looper源代碼&#xff0c;有助于理解Android系統消息循環流程、handler機制。Looper注釋為class used to run a message loop for a thread&#xff0c; 即用于為一個線程運行消息循環&#xff0c; 或者說循環處理一個線程的消息。 Looper源碼先看下這個類里的變量…

uni-app 和 uni-app x 的區別

差異解析 uni-app 是 DCloud 推出的成熟跨平臺前端框架&#xff0c;基于 Vue.js JavaScript/TypeScript。支持廣泛平臺&#xff1a;iOS、Android、HarmonyOS、Web、小程序等&#xff0c;用一套代碼同時生成多個端應用。渲染方式主要通過 WebView 或小程序原生框架 JS 邏輯&am…

數據結構:深度優先搜索 (Depth-First Search, DFS)

目錄 DFS的誕生——“不撞南墻不回頭” DFS的核心機制——如何實現“回溯”&#xff1f; DFS算法流程圖解&#xff08;遞歸版&#xff09; C/C代碼實現 DFS的應用 上一節我們學習了廣度優先搜索 (BFS)&#xff0c;它像水面的波紋一樣&#xff0c;一層一層地向外探索。今天…

Spring Boot中策略模式結合依賴注入的實現方式

在Spring Boot項目開發中&#xff0c;常常會遇到根據不同的業務場景執行不同邏輯的需求&#xff0c;策略模式就是一種很好的設計模式來應對這種情況。同時&#xff0c;Spring Boot強大的依賴注入機制可以方便地將不同的策略類進行管理和調用。 1. 定義策略接口 定義一個策略接口…

深入剖析Spring Boot中Spring MVC的請求處理流程

對于任何使用Spring Boot進行Web開發的開發者而言&#xff0c;深入理解Spring MVC的執行流程都是至關重要的。這不僅有助于我們編寫更清晰、更高效的代碼&#xff0c;更是我們排查詭異問題、進行高級定制開發的知識基石。今天&#xff0c;我們將一起深入Spring Boot應用的內核&…

X448 算法簽名驗簽流程深度解析及代碼示例

一、引言&#xff1a;X448 算法的定位與價值在橢圓曲線密碼學&#xff08;ECC&#xff09;體系中&#xff0c;X448 是基于蒙哥馬利曲線&#xff08;Curve448&#xff09;的密鑰交換算法&#xff0c;但其底層數學原理也可支撐簽名驗簽功能&#xff08;實際工程中常與 Ed448 簽名…

2025-2026單片機物聯網畢業設計題目推薦(定稿付款)

51.基于單片機的非接觸式防疫自動門系&#xff08;1&#xff09;人員檢測&#xff1a;利用超聲波模塊進行人員檢測&#xff0c;檢測到人員靠近門體時觸發相應的操作&#xff1b;&#xff08;2&#xff09;門控制&#xff1a;通過舵機實現自動門的開閉控制&#xff0c;當檢測到有…

一文詳解大模型強化學習(RLHF)算法:PPO、DPO、GRPO、ORPO、KTO、GSPO

一、 引言 大模型強化學習的核心目標是讓模型的輸出與人類目標、真實場景需求對齊。在工作和學習中&#xff0c;大模型強化學習訓練經常會遇到各種算法&#xff0c;各種O&#xff0c;在強化學習訓練選型過程中經常容易混淆&#xff0c;也分不清各種訓練算法的使用場景和優缺點。…

C++ 常見面試題匯總

基礎知識 一、C 基礎語法C 和 C 的區別&#xff1f; C 支持面向對象&#xff08;封裝、繼承、多態&#xff09;。C 引入模板、STL、異常處理。值傳遞、指針傳遞、引用傳遞的區別&#xff1f; 值傳遞&#xff1a;拷貝一份副本。指針傳遞&#xff1a;傳地址&#xff0c;可修改原數…

ES06-SpringData集成

ES06-SpringData集成 文章目錄ES06-SpringData集成1-參考網址2-知識整理3-Spring Data Elasticsearch 9.0.0 完整示例4-知識補充1-Elasticsearch JAVA操作有三種客戶端:1. TransportClient&#xff08;已廢棄&#xff09;2. JestClient&#xff08;第三方 HTTP 客戶端&#xff…

對于鏈表相關經典算法題:環形鏈表的約瑟夫問題的解析

開篇介紹&#xff1a; Hello 大家&#xff0c;在上一篇博客中&#xff0c;我們一同拆解了「206. 反轉鏈表」和「876. 鏈表的中間結點」這兩道單鏈表經典題目&#xff0c;通過對指針操作的細致打磨&#xff0c;相信大家對單鏈表的特性與算法設計思路有了更深入的理解。而在今天…

MySQL集群——主從復制

目錄 一、環境搭建、部署 1. RHEL7.9、9.3的搭建 二、主從復制 1. 環境說明 2. 環境準備 1&#xff09;克隆RHEL79_mysql_master 2&#xff09;改名為 “RHEL79_mysql_slave” 并修改IP 3&#xff09;修改主機名 3. 部署MySQL主從同步 1&#xff09;主庫(mysql-master) 2&…

《用 asyncio 構建異步任務隊列:Python 并發編程的實戰與思考》

《用 asyncio 構建異步任務隊列:Python 并發編程的實戰與思考》 一、引言:并發編程的新時代 在現代軟件開發中,性能已不再是錦上添花,而是產品成功的基石。尤其在 I/O 密集型場景中,如網絡爬蟲、實時數據處理、微服務通信等,傳統的同步編程模式往往力不從心。 Python …

【Linux】yum工具篇

目錄一、軟件包管理器1.1 什么是軟件包1.2 Linux軟件生態二、yum具體操作2.1 查找軟件包2.2 安裝軟件包2.3 卸載軟件配置文件所在路徑個人主頁<—請點擊 Linux專欄<—請點擊 一、軟件包管理器 1.1 什么是軟件包 在Linux下安裝軟件, 一個通常的辦法是下載到程序的源代碼…

撬動制造全場景增效,開利空調找到了怎樣的“通關密碼”?

由深圳軟件協會指導、法大大和信息俠聯合出品的《制造行業合同數智化升級白皮書》&#xff08;以下簡稱“白皮書”&#xff09;首次提出了 “電子簽法律AI” 雙輪驅動模型。在制造行業面臨供應鏈協同、合規風控及全球化出海等多重挑戰的當下&#xff0c;法大大依托豐富的制造企…