K最近鄰算法
K近鄰算法(KNN,k-Nearest Neighbor),每個樣本都可以用它的最接近的K個鄰近值來代表。
算法說明:
①輸入沒有標簽的新數據,將新數據的每個特征與樣本集中數據對應的特征進行比較,然后算法提取樣本集中特征最相似數據(最近鄰)的分類標簽。
②一般來說,只選擇樣本數據集中k個最相似的數據。k一般不大于20,最后選擇k個數據中出現次數最多的分類,作為新數據的分類。
K近鄰算法(KNN,k-Nearest Neighbor),每個樣本都可以用它的最接近的K個鄰近值來代表。
如圖所示,包圍圈上有兩個梨一個蘋果,因此問號的應該為梨。
K近鄰算法(KNN,k-Nearest Neighbor),每個樣本都可以用它的最接近的K個鄰近值來代表。
計算已知類別數據集眾多點與當前點之間的距離
按照距離遞增次序排序
選取與當前點距離最小的k個點
確定前k個點所在類別的出現頻率
返回前k個點出現頻率最高的類別作為當前點的預測分類
如圖所示K=3時?表示紅三角;當K=5時?表示藍方塊
距離度量
歐式距離
? ?歐式距離也稱歐幾里得距離,是最常見的距離度量,衡量的是多維空間中兩個點之間的絕對距離 。 ? ? ?
? ?在二維和三維空間中的歐式距離的就是兩點之間的距離。 ·
二維空間里的歐氏距離公式:
三維空間里的歐氏距離公式:
n 維空間里的歐氏距離公式:
曼哈頓距離
在平面上,坐標(x1,y1)的i點與坐標(x2,y2)的j點的曼哈頓距離為:d(i,j)=|X1-X2|+|Y1-Y2|。
鳶尾花分類
①鳶尾花特征說明: ?sepal length (cm), sepal width (cm), petal length (cm), petal width (cm)
②基于kNN算法使用sklearn實現鳶尾花分類
加載鳶尾花數據集 ?iris=datasets.load_iris()
分類的標簽 iris.target
特征 ?iris.feature_names
類別 ?iris.target_names
劃分訓練集和測試集
x_train, x_test, y_train, y_test = train_test_split(iris.data,iris.target,test_size=0.3)
訓練模型,創建實例 k=5
knn = KNeighborsClassifier(n_neighbors=5,metric="euclidean")
#n_neighbors近鄰數量
#metric距離標準(euclidean歐式距離)
#訓練 knntrain = knn.fit(x_train, y_train) print("訓練",knntrain)
訓練集得分 ?? ?train_score = knn.score(x_train,y_train)
測試集得分 ?? ?test_score = knn.score(x_test,y_test)
預測y的值 ?? ?y_pred = knn.predict(x_test)
from sklearn import datasets
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.neighbors import KNeighborsClassifier
import numpy as np
import matplotlib.pyplot as plt# 設置隨機種子,保證結果可復現
np.random.seed(0)# 單元格 2:加載鳶尾花數據集并查看
iris = datasets.load_iris()
# 可取消注釋查看數據集內容,包含數據、標簽、特征名、類別名等信息
# iris
# 查看前 10 條數據
iris.data[:10]
# 查看數據形狀(樣本數、特征數)
iris.data.shape
#(150, 4)
# 查看分類標簽
iris.target
# 查看預測結果
y_predict
# 用測試集評估模型準確率(標簽精度),score 方法會返回模型在測試集上的預測準確率
score = knn.score(x_test, y_test)
score
#0.9777777777777777
# 單元格 7:選擇最優 k 值(交叉驗證法)
# k 值搜索范圍
k_range = range(1, 31)
# 用于存儲不同 k 值對應的誤差率
k_error = []
x = iris.data
y = iris.target
k_sel = 0
min_error = 1 # 初始化最小誤差for k in k_range:knn = KNeighborsClassifier(n_neighbors=k)# 6 折交叉驗證,scoring='accuracy' 表示用準確率評估scores = cross_val_score(knn, x, y, cv=6, scoring='accuracy') # 計算誤差率(1 - 平均準確率)并添加到列表k_error.append(1 - scores.mean()) if (1 - scores.mean()) < min_error:min_error = 1 - scores.mean()k_sel = k# 輸出最優 k 值和對應的最小誤差
print("k:", k_sel, "min_error:", min_error)
k: 12 min_error: 0.020000000000000018
# 單元格 8:可視化 k 值與誤差率關系
# 繪制折線圖,x 軸為 k 值,y 軸為誤差率
plt.plot(k_range, k_error)
plt.xlabel('Value of K for KNN')
plt.ylabel('Error')
plt.show()

波士頓房價預測
# CRIM、連續型、城鎮人均犯罪率
# ZN、連續型、住宅用地中占地面積
# INDUS、連續型、城鎮非零售商用土地占比
# CHAS、離散型、查爾斯河虛擬變量(是否鄰近河流)
# NOX、連續型、一氧化氮 (NO) 濃度
# AGE、連續型、1940年前建成的自住單位比例
# DIS、連續型、距波士頓5個就業中心的加權距離
# RAD、連連續型、徑向高速公路可達性指數
# TAX、每萬美元房產稅率
# PTRATIO、連續型、城鎮師生比例
# LSTAT、連續型、低收入人群占比
#RM、連續型、住宅平均房間數
import numpy as np # 關鍵修復:導入numpy并簡寫為np
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score
import matplotlib.pyplot as plt# 加載數據集(適配新版sklearn)
boston = fetch_openml(name='boston', version=1, as_frame=True)
X = pd.DataFrame(boston.data, columns=boston.feature_names)
y = pd.Series(boston.target, name='MEDV') # 目標變量:房價中位數(千美元)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 使用黑體顯示中文
plt.rcParams['axes.unicode_minus'] = False # 解決負號顯示問題
import seaborn as sns
import matplotlib.pyplot as plt
# 繪制特征相關性熱力圖
corr_matrix = X.join(y).corr()
sns.heatmap(corr_matrix, annot=True, fmt=".2f", cmap='coolwarm')# annot在單元格內顯示數值
plt.title("特征與房價相關性")
plt.show()
# 將數據轉換為均值為 0、標準差為 1的標準正態分布
from sklearn.preprocessing import StandardScaler
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, r2_score# 劃分訓練集/測試集
X_train, X_test, y_train, y_test = train_test_split(X_scaled, y, test_size=0.2, random_state=42)# 訓練與評估
lr = LinearRegression()
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)print(f"線性回歸性能:")
print(f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred)):.2f}")#反映預測值與真實值的絕對偏差
print(f"R2: {r2_score(y_test, y_pred):.4f}") # 衡量模型擬合優度
from sklearn.ensemble import RandomForestRegressor
from sklearn.pipeline import Pipeline# 構建流水線(標準化+模型)
pipeline = Pipeline([('scaler', StandardScaler()),('regressor', RandomForestRegressor(random_state=42))
])# 訓練與評估
pipeline.fit(X_train, y_train)
y_pred_rf = pipeline.predict(X_test)
print(f"隨機森林初始性能:")
print(f"RMSE: {np.sqrt(mean_squared_error(y_test, y_pred_rf)):.2f}")
print(f"R2: {r2_score(y_test, y_pred_rf):.4f}")
plt.figure(figsize=(10, 6))
plt.scatter(y_test, y_pred, alpha=0.6, color='blue')
plt.plot([y.min(), y.max()], [y.min(), y.max()], 'r--', lw=2)#X軸與Y軸范圍
plt.xlabel('真實價格(千美元)')
plt.ylabel('預測價格(千美元)')
plt.title('真實值 vs 預測值')
plt.grid(True)
plt.show()
residuals = y_test - y_pred
plt.figure(figsize=(10, 6))
plt.scatter(y_pred, residuals, alpha=0.6, color='green')
plt.axhline(y=0, color='r', linestyle='--')
plt.xlabel('預測值')plt.ylabel('殘差')
plt.title('殘差分布圖')
plt.show()