1. def __init__(self, k=3): 這個 __init__ 是所有的 class 都可以用嗎?
是的,__init__ 是 Python 中一個特殊的方法,被稱為構造函數(Constructor)。
- 用途: 它是創建類的新實例(對象)時自動調用的方法。它的主要作用是初始化新創建對象的屬性。
- 並非強制: 所有的
class都可以定義__init__,但並非必須。如果一個類沒有定義__init__,Python 會默認提供一個空的構造函數。 - 記憶點: 只要你想在創建對象時設置它的初始狀態(比如這裏的
值),就應該定義
__init__。
2. 為什麼 self.X_train = None 初始化使用的是 None,不是 []? None 初始化是一個表格嗎?
None 在 Python 中有非常特殊的含義,它不是表格,也不是空列表。
None的含義:
None是 Python 語言中一個特殊的常量,表示空值(Null Value)或缺失值。- 它表示缺少值,表示該變量沒有指向任何對象。
- 為什麼使用
None:
- 在
__init__中,我們知道X_train將在稍後的fit方法中被賦值為 PyTorch 張量。在初始化階段,我們還沒有數據,所以用None表示該屬性目前還沒有值。 - 如果初始化為
[](空列表),那麼這個屬性的類型就是list。後續代碼可能需要檢查類型或者處理類型轉換的邏輯會變得複雜。用None表示一個尚未被賦值的佔位符,是一種更清晰和通用的做法。
- 數據結構與初始化對比:
|
數據結構/值
|
Python 表示
|
含義
|
|
無值/缺失值
|
|
缺少值(佔位符)
|
|
空列表
|
|
有值的(列表)集合,但集合內無元素
|
|
空數值
|
|
數值 0
|
|
空字典
|
|
有值的(字典)集合,但集合內無鍵值對
|
3. self.X_train 這裏的 self 是什麼含義,為什麼我經常看到有的類就會括號寫 self?
self 是 Python 類方法中一個約定俗成的特殊參數,它代表實例自身(The instance itself)。
self的含義:
self永遠是類方法的第一個參數。- 當你創建一個對象(例如
knn_torch = KNearestNeighborsClassifierTorch(k=3))時,PyTorch 會在調用方法時自動把這個新創建的對象(即knn_torch本身)作為self參數傳遞進去。
- 用途:
self.X_train:這表示訪問或創建一個屬於當前對象實例的屬性X_train。這樣,不同的KNN對象可以存儲它們各自的訓練數據。def __init__(self, k=3)::括號中的self只是一個佔位符,表示這個方法是作用於對象自身的。你在實際調用時(比如KNearestNeighborsClassifierTorch(k=3))不需要顯式傳入它。
- 記憶點:
self就是對象自己。方法內部要操作對象自己的屬性時,必須用self.屬性名。
4. self.X_train 這個命名是本身庫裏面的還是我自己創建的?
這個命名是您自己創建的。
self.後面的任何名稱(例如X_train,k,device)都是由程序員(也就是您)在類定義時自由命名的。- Python 或 PyTorch 庫不會強制您必須使用
X_train這個名稱。您可以使用self.training_features或self.data_x等任何合法名稱,只要您在類內部保持一致即可。 - 約定俗成: 命名為
X_train只是遵循了數據科學和機器學習社區的慣例,即X代表特徵,train代表訓練集。
5. isinstance 是啥意思?
- 英文詞源和解釋:
- isinstance 是 Python 的一個內置函數,由 is 和 instance 組成。
- Instance (實例):源自拉丁語 instantia(存在,狀態)。在這裏指一個對象是某個類(或類型)的實例。
- 解釋:
isinstance(object, classinfo)用於檢查一個對象object是否是指定類型classinfo的一個實例。
- 在代碼中的作用:
if isinstance(X_train, np.ndarray):
X_train = torch.from_numpy(X_train).float()
- 作用: 檢查輸入參數
X_train是否是 NumPy 的數組 (np.ndarray)。 - 目的: 如果是 NumPy 數組,則執行轉換步驟 (
torch.from_numpy()),確保後續的 PyTorch 代碼可以順利運行。這增強了代碼的兼容性。
6. from_numpy().float(): 轉換為特徵張量。特徵張量我記得是一羣矩陣連在一起?只能 float?可以 from_numpy().int(): 嗎?
這是一個關於 PyTorch 張量類型的關鍵問題。
A. 特徵張量(Feature Tensor)
- 定義: 在 PyTorch 中,張量(Tensor)是核心數據結構,它是一個多維數組。特徵張量就是存儲你的輸入特徵數據(例如鳶尾花的四個測量值)的多維數組。
- “一羣矩陣連在一起”: 您的理解是正確的,一個
的特徵張量可以看作是
B. 為什麼特徵數據通常是 float?
float()/torch.float32(默認): 用於存儲連續的、實數值數據。
- 原因: 機器學習中的特徵(如身高、温度、距離等)通常是連續的浮點數。
- 核心原因: 深度學習和梯度下降算法需要進行求導和高精度運算。在 PyTorch 中,只有浮點類型的張量才會被默認跟蹤梯度並參與自動求導(Autograd)。即使對於 KNN 這種無需訓練的算法,特徵數據也通常保持為浮點數,以確保距離計算(涉及減法、平方、開方)的精度。
C. 可以使用 from_numpy().int() / torch.int 嗎?
- 可以,但僅用於特定數據。
int()/torch.int32或long()/torch.int64用於存儲離散的、整數值數據。- 常見用途: 標籤(Label)(如類別 0, 1, 2)、索引(Index)、或者計數(Count)。
- 代碼中的例子:
# 標籤數據使用 long (64位整數)
y_train = torch.from_numpy(y_train).long()
- KNN 代碼中,
y_train(類別標籤)就是使用long()進行轉換的。特徵數據 (X_train) 應該使用float(),而標籤數據 (y_train) 應該使用long()。