目錄
- 1. 主要算法分類
- 1.1 監督學習 (Supervised Learning)
- 1.2 非監督學習 (Unsupervised Learning)
- 1.3 半監督學習 (Semi-Supervised Learning)
- 1.4 強化學習 (Reinforcement Learning)
- 1.5 遺傳算法 (Genetic Algorithm)
- 2. 選擇合適的機器學習模型
- 2.1 分類 (Classification)
- 2.2 回歸 (Regression)
- 2.3 聚類 (Clustering)
- 2.4 降維 (Dimensionality Reduction)
- 3. 使用 KNN 算法對鳶尾花 (Iris) 進行分類
- 3.1 導入庫與數據
- 3.2 數據加載
- 3.3 數據集劃分
- 3.4 模型訓練與預測
- 3.5 結果評估
- 4. 數據集的加載與生成
- 4.1 加載真實數據集并進行線性回歸
- 4.2 生成合成回歸數據并可視化
- 5. 模型屬性與方法
- 5.1 區分超參數和學習到的屬性
- 5.2 `LinearRegression`模型的核心屬性與功能
- 5.2.1 查看學習到的屬性
- 5.2.2 查看模型的超參數
- 5.2.3 評估模型性能
- 6. 特征縮放
Scikit-learn 是一個開源的 Python 機器學習庫,它為分類、回歸、聚類等經典任務提供了一整套簡潔、高效且易于使用的工具。
1. 主要算法分類
目前主流的算法可分為以下幾類:
1.1 監督學習 (Supervised Learning)
向計算機提供已標記的數據(即數據與對應的正確答案/標簽),讓其學習數據與標簽之間的映射關系。
常見的神經網絡就屬于監督學習的一種方式。
1.2 非監督學習 (Unsupervised Learning)
僅向計算機提供數據,不提供任何標簽或答案,由計算機自行探索數據內部的結構、關聯和規律。
計算機通過觀察數據間的特性,自動進行聚類或降維,總結出隱藏的模式。
1.3 半監督學習 (Semi-Supervised Learning)
結合了監督學習與非監督學習的特點,利用少量有標簽的樣本和大量無標簽的樣本共同進行訓練和分類。
1.4 強化學習 (Reinforcement Learning)
通過“試錯”來學習。將計算機(Agent)置于一個陌生的環境中,通過與環境交互獲得獎勵或懲罰,從而學習到能最大化獎勵的行為策略。
Agent自行嘗試各種行為,根據行為結果(獎勵或懲罰)不斷調整和優化策略,最終學會在特定環境下完成任務的方法。
AlphaGo便是應用強化學習的著名案例。
1.5 遺傳算法 (Genetic Algorithm)
模擬生物進化論中“適者生存,優勝劣汰”原則的一種優化算法。
過程:
- 初始化:創建一組初始解決方案(“種群”)。
- 評估:根據預設標準評估每個方案的優劣。
- 選擇:淘汰表現差的方案,選擇表現好的方案(“強者”)進行“繁殖”和“變異”。
- 迭代:重復評估和選擇過程,不斷進化出更優的解決方案或模型。
2. 選擇合適的機器學習模型
在開始選擇模型前,需要對數據進行初步評估:
數據量檢查:樣本數量 (Sample Size) 是首要的判斷依據。
- 樣本數量 < 50:當前數據量過小,訓練出的模型可能泛化能力差、準確度低。應優先考慮收集更多的數據。
- 樣本數量 > 50:可以進入下一步,根據任務類型選擇合適的算法分支。
可以將機器學習問題大致歸為以下四類:
2.1 分類 (Classification)
預測一個數據樣本屬于哪個預定義的類別。
學習類型:監督學習
2.2 回歸 (Regression)
預測一個連續的數值,而非類別。
學習類型:監督學習
2.3 聚類 (Clustering)
在沒有預先定義類別的情況下,將數據根據其內在的相似性自動分組(分簇)。
學習類型:非監督學習
2.4 降維 (Dimensionality Reduction)
減少數據中的特征(屬性)數量,同時盡可能保留最重要的信息。
學習類型:通常為非監督學習
降維并非簡單地從原有特征中挑選一部分,而是通過數學變換,將高維特征(例如,描述房價的20個因素)映射為低維的新特征(例如2個綜合因素)。新的特征是原有所有特征的綜合體現,旨在抓住數據的主要矛盾。
算法的通用性
許多機器學習算法非常靈活,稍作調整即可用于解決不同類型的問題。例如,隨機梯度下降 (SGD) 是一種基礎的優化算法,它既可以用于分類任務 (SGDClassifier
),也可以用于回歸任務 (SGDRegressor
),只是在處理和優化目標上有所不同。
特征 (Features) vs. 標簽 (Labels):
特征:描述數據點的屬性或輸入變量。在房價預測案例中,“房屋面積”、“地段”、“建造年份”等都是特征。
標簽:我們希望預測的目標變量,即正確答案。在房價預測案例中,“房屋價格”就是標簽。監督學習需要同時包含特征和標簽的數據,而非監督學習通常只使用特征。
3. 使用 KNN 算法對鳶尾花 (Iris) 進行分類
Scikit-learn 將絕大多數機器學習模型的應用流程進行了統一,掌握此模式即可觸類旁通,高效使用庫中的各種算法。其核心步驟可概括為:
導入:從 sklearn
庫中導入所需的模型
實例化:創建模型對象,可在此步驟設置模型的超參數
訓練 (Fit) :使用 .fit(X_train, y_train)
方法,將訓練集數據喂給模型進行學習
預測:使用 .predict(X_test)
方法,讓訓練好的模型對新的測試數據進行預測
3.1 導入庫與數據
import numpy as np
from sklearn import datasets
from sklearn.model_selection import train_test_split # 用于劃分數據集
from sklearn.neighbors import KNeighborsClassifier # KNN模型
numpy
: 用于高效的數值計算。
sklearn.datasets
: 包含多種可供練習的經典數據集,如此處用到的 load_iris
。
sklearn.model_selection.train_test_split
: 將數據集劃分為訓練集和測試集的標準工具。
sklearn.neighbors.KNeighborsClassifier
: 本次案例中使用的分類算法。
3.2 數據加載
首先,加載 sklearn
內置的鳶尾花數據集,并分離特征和標簽。
# 1.載入數據集
iris = datasets.load_iris()# 2.分離數據集
iris_X = iris.data # 特征
iris_y = iris.target # 標簽
特征 (iris_X) :描述樣本屬性的數據。每個樣本包含 4 個特征。
說明:鳶尾花數據集的 4 個特征分別是:花萼長度 (Sepal Length)、花萼寬度 (Sepal Width)、花瓣長度 (Petal Length)、花瓣寬度 (Petal Width)。
示例數據:
[[5.1 3.5 1.4 0.2][4.9 3. 1.4 0.2]]
標簽 (iris_y) :每個樣本所屬的類別。
說明:該數據集包含 3 個類別,分別用 0, 1, 2 表示。
數據概覽:[0, 0, ..., 1, 1, ..., 2, 2, ...]
3.3 數據集劃分
為了客觀評估模型的性能,需將數據集劃分為訓練集(用于學習)和測試集(用于評估)。
# 3.劃分數據集
X_train, X_test, y_train, y_test = train_test_split(iris_X, iris_y, test_size=0.3)
train_test_split(...)
:是 scikit-learn
庫中的一個函數,用來把數據集分成兩部分:訓練集和測試集
test_size=0.3
:這個參數表示測試集占總數據的 30%,訓練集占 70%
返回值:
X_train, X_test, y_train, y_test
函數會返回 4 個結果:
名稱 | 含義 |
---|---|
X_train | 訓練集的特征數據 |
X_test | 測試集的特征數據 |
y_train | 訓練集的標簽數據 |
y_test | 測試集的標簽數據 |
train_test_split
的作用:
防止數據泄露:模型在訓練時不應接觸到測試數據,否則評估結果會過于樂觀,無法反映其在未知數據上的真實表現。
自動打亂數據:該函數默認會隨機打亂數據順序再進行劃分。這對于機器學習至關重要,可以防止模型因數據原始排列順序(如按類別排序)而產生偏見。
3.4 模型訓練與預測
遵循 Scikit-learn 的標準流程進行模型訓練和預測。
# 4.實例化模型
knn = KNeighborsClassifier()# 5.訓練模型
knn.fit(X_train, y_train) # 訓練完成后,所有學習到的參數都保存在模型對象自身的屬性中,# 6.對測試集進行預測
predictions = knn.predict(X_test)
3.5 結果評估
將模型的預測結果與真實的測試集標簽進行對比,以評估模型效果。
print("預測結果:\n",predictions,"\n")
print("真實結果:\n",y_test,)
輸出示例:
預測結果:
[1 2 0 1 2 1 0 0 2 0 1 1 2 1 1 0 2 1 1 0 2 2 2 0 0 2 0 0 1 0 2 1 0 1 0 0 12 2 0 2 2 2 2 2] 真實結果:
[1 2 0 1 2 1 0 0 2 0 1 1 2 1 1 0 2 1 1 0 2 2 2 0 0 2 0 0 1 0 2 1 0 1 0 0 11 2 0 2 2 2 2 2]
結論:可以看到預測結果與真實結果高度相似,但可能存在個別誤差。這是機器學習的本質——模型致力于逼近真實規律,而非實現 100% 的精確復刻。如同人類會犯錯一樣,模型也存在誤差范圍。
4. 數據集的加載與生成
sklearn.datasets
為機器學習實踐提供了豐富的數據來源,主要包含兩大類數據:
真實世界數據集:
經過清洗和格式化的、源于真實世界問題的經典數據集。通常以 load_*
的形式調用,例如 load_iris()
、load_boston()
。
合成數據集:
可根據用戶指定的參數(如樣本數、特征數、噪聲水平等)動態生成具有特定統計特性的數據。通常以 make_*
的形式調用,例如 make_regression()
、make_classification()
。
4.1 加載真實數據集并進行線性回歸
使用加州房價數據集(fetch_california_housing()
) 來加載數據并應用線性回歸模型。
from sklearn import datasets
from sklearn.linear_model import LinearRegression # 線性回歸模型
from sklearn.model_selection import train_test_split# 1.加載數據集
loaded_data = datasets.fetch_california_housing()# 2.分離數據集
data_X = loaded_data.data # 特征
data_y = loaded_data.target # 標簽# 3.劃分數據集
X_train, X_test, y_train, y_test = train_test_split(data_X, data_y,)# 4.實例化模型
model = LinearRegression()# 5.訓練模型
model.fit(X_train, y_train)# 6.對測試集進行預測
predictions = model.predict(X_test[:4, :])print("預測房價:", predictions)
print("真實房價:", data_y[:4])
Scikit-learn 的標準化數據接口:
通過 load_*
加載的數據集對象,其特征和標簽分別存儲在 .data
和 .target
屬性中,這種高度統一的模式簡化了數據調用流程。
運行結果:
預測房價: [2.22492568 4.02422823 1.34033317 0.88996126]
真實房價: [4.526 3.585 3.521 3.413]
預測值與真實值存在差距
模型的預測結果與真實值不完全一致是正常的,這是機器學習的固有特性。原因包括:
模型簡化:線性回歸模型本身是一個簡化的數學抽象,可能無法捕捉所有復雜現實因素。
數據質量:原始數據可能包含噪聲或未包含所有關鍵特征。
缺少優化步驟:為了獲得更高精度,通常需要:
- 數據預處理:例如對特征進行歸一化。
- 模型調優:嘗試不同的模型或調整當前模型的超參數。
4.2 生成合成回歸數據并可視化
使用 make_regression
生成一組用于回歸分析的數據,并用 matplotlib
將其可視化。
import matplotlib.pyplot as plt# 1. 使用 make_regression 生成隨機數據
# n_samples: 樣本數量
# n_features: 特征數量
# n_targets: 目標值數量
# noise: 數據的噪聲水平,值越大,數據點越離散
X, y = datasets.make_regression(n_samples=100, n_features=1, n_targets=1, noise=10)# 2. 使用散點圖進行可視化
plt.scatter(X, y)# 3. 顯示圖像
plt.show()
make_regression
關鍵參數:
n_samples
: 生成的樣本點數量。n_features
: 每個樣本點的特征維度。noise
: 施加到數據上的高斯噪聲的標準差,用于模擬真實世界數據的不完美性。
執行上述代碼會生成一張散點圖。圖中的數據點大致沿一條直線分布,但由于設置了 noise
,點會在這條直線周圍散布,為訓練和測試回歸模型提供了一個理想的、可控的數據環境。
5. 模型屬性與方法
5.1 區分超參數和學習到的屬性
超參數:在創建模型時由用戶手動設置的參數,用于控制模型的學習過程,如LinearRegression(fit_intercept=True)
中的 fit_intercept
,使用 model.get_params()
方法查看
學習到的屬性:模型在調用 .fit()
方法、從數據中學習后所得到的內部參數,Scikit-learn 的所有學習屬性都以一個下劃線 _
結尾,例如 coef_
,在模型訓練 (.fit()
) 完成后,通過 model.attribute_
查看
5.2 LinearRegression
模型的核心屬性與功能
from sklearn import datasets
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split # 1.加載數據集
loaded_data = datasets.fetch_california_housing()# 2.分離數據集
data_X = loaded_data.data # 特征
data_y = loaded_data.target # 標簽# 3.劃分數據集
X_train, X_test, y_train, y_test = train_test_split(data_X, data_y,)# 4.實例化模型
model = LinearRegression()# 5.訓練模型
model.fit(X_train, y_train)print("模型系數 (coef_):", model.coef_)print("模型截距 (intercept_):", model.intercept_)print("模型參數 (get_params):", model.get_params())score = model.score(X_test, y_test)
print(f"模型在測試集上的 R^2 得分: {score}")
5.2.1 查看學習到的屬性
在線性回歸的數學公式 y = w_1*x_1 + ... + w_n*x_n + b
中:
model.coef_
:系數 (Coefficients), 對應于公式中的權重 w
,是一個數組,每個值代表對應特征的重要性或影響力。
model.intercept_
:截距 (Intercept), 對應于公式中的偏置項 b
,是一個標量值,代表當所有特征值都為0時,預測值的基準。
5.2.2 查看模型的超參數
model.get_params()
:以字典形式返回創建模型時設置的所有超參數。如果你沒有手動設置,則返回的是默認值。
輸出示例:{'copy_X': True, 'fit_intercept': True, 'n_jobs': None, 'positive': False}
5.2.3 評估模型性能
model.score(X, y)
:對模型進行性能評估并返回一個分數。
score
方法的打分機制:
- 對于回歸模型:返回的是 R2 (R-squared, 決定系數), 表示模型對數據變化的解釋程度。值域通常在 0 到 1 之間。
- 對于分類模型:返回的是平均準確率, 即“預測正確的樣本數 / 總樣本數”。
好的,這是根據您提供的視頻字幕和截圖資料,為您生成的一份關于特征縮放(Feature Scaling)的學習筆記。
6. 特征縮放
特征縮放是將不同特征的數值范圍調整到相似的尺度上。
當一個模型中的多個特征數值范圍(量綱)差異巨大時(例如,房屋面積為 0-2000平方英尺,而房間數量為 1-5個),優化算法(如梯度下降)的收斂過程會變得低效。未縮放的特征會導致成本函數 J(θ)
的等高線圖呈橢圓形,算法需要多次振蕩才能找到最優解(最小值點)。
在進行特征縮放后,成本函數的等高線圖會更接近圓形,使得梯度下降可以沿著更直接、更高效的路徑收斂到最優點,從而加快模型訓練速度并提升性能。
Scikit-Learn 的 preprocessing
模塊提供了多種特征縮放工具,preprocessing.scale()
的作用是將數據進行標準化,即分別處理每一列特征,使其平均值為 0,標準差為 1。
代碼示例:
from sklearn import preprocessing
import numpy as np# 創建一個特征尺度差異很大的數組
# 第1列范圍: -100 ~ 120
# 第2列范圍: 2.7 ~ 20
# 第3列范圍: -2 ~ 40
a = np.array([[10, 2.7, 3.6],[-100, 5, -2],[120, 20, 40]
], dtype=np.float64)# 使用 scale 函數進行標準化
scaled_a = preprocessing.scale(a)print("原始數據:\n", a)
print("\n標準化后的數據:\n", scaled_a)
輸出結果:
原始數據:[[ 10. 2.7 3.6][-100. 5. -2. ][ 120. 20. 40. ]]標準化后的數據:[[ 0. -0.85170713 -0.55138018][-1.22474487 -0.55187146 -0.852133 ][ 1.22474487 1.40357859 1.40351318]]
可以看到,標準化后,每一列的數值都被縮放到一個相似的范圍內。
說明:****
StandardScaler
類與scale
函數
在實際項目中,更推薦使用sklearn.preprocessing.StandardScaler
類。scale
函數會一步到位地計算并轉換整個數據集,但在劃分訓練集和測試集時,我們必須保證用訓練集的參數(均值、標準差)來轉換測試集,以防止數據泄露。StandardScaler
對象可以先在訓練數據上fit()
,然后用同一個對象去transform()
訓練集和測試集,操作更規范、安全。
特征縮放對支持向量機(SVC)分類準確率的影響:
- 生成并可視化數據
使用make_classification
生成一組具有較大尺度(scale=100
)的樣本數據。從散點圖可以看出,數據本身是線性可分的,但其特征值分布在 -400 到 400 的廣大區間內。 - 對比實驗
使用相同的 SVC 模型,在“未縮放”和“已縮放”兩種數據上分別進行訓練和評估。
直接在原始數據上訓練模型,其在測試集上的準確率僅為 48.8% 。這表明模型完全無法有效學習。
先使用preprocessing.scale()
對數據進行標準化,再進行訓練和測試,準確率大幅提升至 94.4% 。
from sklearn import preprocessing
from sklearn.model_selection import train_test_split
from sklearn.datasets import make_classification
from sklearn.svm import SVC
import matplotlib.pyplot as plt# 1. 生成數據
X, y = make_classification(n_samples=300, n_features=2, n_redundant=0, n_informative=2,random_state=22, n_clusters_per_class=1, scale=100
)# 2. 對比實驗
X_scaled = preprocessing.scale(X) # 對整個特征集進行標準化
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.3)# 3. 訓練并評估模型
clf = SVC()
clf.fit(X_train, y_train)
print("進行特征縮放后的準確率: ", clf.score(X_test, y_test))
其他縮放方法:歸一化 (Min-Max Scaling)
除了標準化,另一種常見的縮放方法是歸一化,它通過 sklearn.preprocessing.MinMaxScaler
實現。歸一化將每個特征的數值線性地縮放到一個給定的區間,默認為 [0, 1]
。其計算公式為:
X_scaled = (X - X_min) / (X_max - X_min)
當數據分布有明顯的邊界且不符合高斯分布時,歸一化是一個不錯的選擇。
哪些算法需要特征縮放?
高度敏感的算法一般需要特征縮放, 任何基于距離計算的算法(如 K-NN、K-Means)、依賴梯度下降優化的算法(如線性回歸、邏輯回歸、神經網絡)以及依賴特征方差的算法(如主成分分析 PCA)。支持向量機(SVM)對尺度也非常敏感。
基本不敏感則一般不需要: 樹模型(如決策樹、隨機森林、梯度提升樹)。因為樹模型在選擇分裂點時是基于單個特征的,不涉及特征間的距離或幅度比較,因此對尺度不敏感。