K近邻原理图解
示例数据集包含两个类别(0 和 1)。我使用方形(marker='s')表示类别0,圆形(marker='o')表示类别1。 k 个最近邻样本用绿色边框圈出,并在每个样本旁边添加了标注以表示它们的顺序。在添加测试样本时,我使用了菱形(marker='D')来表示一个与两个类别不同的测试样本,使用五边形(marker='P')来表示一个位于边界区域的测试样本。
import numpy as np
import matplotlib.pyplot as plt
# 生成示例数据
X = np.array([[1, 1], [1, 2], [1.5, 1.5], [1.7, 1.2], [2, 2],
[2, 3], [2.5, 2.5], [2.8, 3.2], [3, 3.5], [3.3, 3]])
y = np.array([0, 0, 0, 0, 1, 1, 1, 1, 1, 1])
# 绘制散点图
plt.scatter(X[y == 0, 0], X[y == 0, 1], marker='s', label='0', color='blue')
plt.scatter(X[y == 1, 0], X[y == 1, 1], marker='o', label='1', color='red')
# 添加测试样本
test_samples = np.array([[2.7, 3],[1.8, 1.8]])
plt.scatter(test_samples[:, 0], test_samples[:, 1], marker='x', color='green')
# 绘制k个最近邻样本
k = 3
for i, test_sample in enumerate(test_samples):
distances = np.linalg.norm(X - test_sample, axis=1) # 计算与测试样本的距离
nearest_indices = np.argsort(distances)[:k] # 找到距离最近的k个样本的索引
nearest_samples = X[nearest_indices]
if i == 0:
marker = 'D' # 第一个测试样本与两个类别不同
else:
marker = 'P' # 后两个测试样本位于边界区域
####参考教材内容,补全关键代码,重新运行####
plt.scatter(nearest_sample[:,0],nearest_sample[:,1],facecolors='none',edgecolors='green',s=200,marker=marker)
# 添加标注
for j, index in enumerate(nearest_indices):
plt.annotate(f'N{j+1}', (X[index, 0], X[index, 1]), textcoords="offset points", xytext=(0,10), ha='center')
plt.xlabel('X1')
plt.ylabel('X2')
plt.legend()
plt.show()
有监督学习模型评价指标
分类任务评价指标
def calculate_confusion_matrix(y_true, y_pred):
tp = tn = fp = fn = 0
for true, pred in zip(y_true, y_pred):
if true == 1 and pred == 1:
tp += 1
elif true == 0 and pred == 0:
tn += 1
elif true == 0 and pred == 1:
fp += 1
elif true == 1 and pred == 0:
fn += 1
return tp, tn, fp, fn
y_true = [1, 0, 1, 1, 0, 1, 0, 1, 0, 0]
y_pred = [1, 0, 1, 0, 1, 0, 1, 1, 0, 1]
tp, tn, fp, fn = calculate_confusion_matrix(y_true, y_pred)
####参考教材内容,补全关键代码,重新运行####
accuracy=(tp+tn)/(tp+tn+fp+fn)
precision=tp/(tp+fp)
recall=tp/(tp+fn)
f1_score=2*(precision*recall)/(precision+recall)
print("混淆矩阵:")
print(f"[[tn={tn} fp={fp}]")
print(f" [fn={fn} tp={tp}]]")
print("准确率accuracy:", accuracy)
print("精确率precision:", precision)
print("召回率recall:", recall)
print("F1分数f1_score:", f1_score)
from sklearn.metrics import confusion_matrix, accuracy_score, \
precision_score, recall_score, f1_score
y_true = [1, 0, 1, 1, 0, 1, 0, 1, 0, 0]
y_pred = [1, 0, 1, 0, 1, 0, 1, 1, 0, 1]
####参考教材内容,补全关键代码,重新运行####
cm=confusion_matrix(y_true,y_pred)
print("混淆矩阵:\n",cm)
####参考教材内容,补全关键代码,重新运行####
accurary=accurary_score(y_true,y_pred)
print("准确率:", accuracy)
####参考教材内容,补全关键代码,重新运行####
precision=presion_score(y_true,y_pred)
print("精确率:", precision)
####参考教材内容,补全关键代码,重新运行####
recall=recall_score(y_true,y_pred)
print("召回率:", recall)
####参考教材内容,补全关键代码,重新运行####
f1=f1_score(y_true,y_pred)
print("F1分数:", f1)
回归问题评价指标
# 真实房价和预测房价
y_true = [300, 400, 500, 600, 700]
y_pred = [350, 420, 490, 580, 680]
# 计算均方误差(MSE)
####参考教材内容,补全关键代码,重新运行####
mse=sum((true-pred)**2 for true,pred in zip(y_true,y_pred))/len(y_true)
# 计算均方根误差(RMSE)
rmse = mse ** 0.5
# 计算平均绝对误差(MAE)
####参考教材内容,补全关键代码,重新运行####
mae=sum(abs(true-pred) for true,pred in zip(y_true,y_pred))/len(y_true)
# 计算决定系数(R^2)
mean_y_true = sum(y_true) / len(y_true)
ssr = sum((true - pred) ** 2 for true, pred in zip(y_true, y_pred))
sst = sum((true - mean_y_true) ** 2 for true in y_true)
####参考教材内容,补全关键代码,重新运行####
r2=1-(ssr/sst)
# 打印结果
print("均方误差(MSE):", mse)
print("均方根误差(RMSE):", rmse)
print("平均绝对误差(MAE):", mae)
print("决定系数(R^2):", r2)
from sklearn.metrics import mean_squared_error, mean_absolute_error, r2_score
# 真实值和预测值
y_true = [300, 400, 500, 600, 700]
y_pred = [350, 420, 490, 580, 680]
# 计算均方误差(mean squared error, MSE)
####参考教材内容,补全关键代码,重新运行####
mse=mean_squared_error(y_true,y_pred)
# 计算平均绝对误差(mean absolute error, MAE)
####参考教材内容,补全关键代码,重新运行####
mae=mean_absolute_error(y_true,y_pred)
# 计算确定系数(coefficient of determination, R^2)
####参考教材内容,补全关键代码,重新运行####
r2=r2_score(y_true,y_pred)
# 打印结果
print("均方误差(MSE):", mse)
print("平均绝对误差(MAE):", mae)
print("确定系数(R^2):", r2)
综合案例:使用K近邻算法预测鸢尾花类型
import pandas as pd
import seaborn as sns
from sklearn.datasets import load_iris
# 加载鸢尾花数据集
iris = load_iris()
# 数据集基本信息
print("数据集基本信息:")
#print(iris.DESCR)
# 转换为 pandas 数据框
df = pd.DataFrame(data=iris.data, columns=iris.feature_names)
df['target'] = iris.target
# 打印数据框前 5 行
print("数据框前 5 行:")
####参考教材内容,补全关键代码,重新运行####
print(df.head())
# 数据框统计信息
print("数据框统计信息:")
####参考教材内容,补全关键代码,重新运行####
print(df.describe())
# 按目标变量绘制散点图矩阵
####参考教材内容,补全关键代码,重新运行####
sns.countplot(x='target',data=df)
# 绘制目标变量类别计数图
####参考教材内容,补全关键代码,重新运行####
sns.pairplot(df,hue='target')
总和
import pandas as pd
from sklearn.datasets import load_iris
import csv
import math
import random
from collections import Counter
# 从文件中读取数据集
def load_dataset(filename):
dataset = []
with open(filename, 'r') as file:
csv_reader = csv.reader(file)
next(csv_reader) # 跳过第一行
for row in csv_reader:
sample = [float(value) for value in row[:-1]]
label = int(row[-1])
dataset.append((sample, label))
return dataset
# 计算欧氏距离
def euclidean_distance(point1, point2):
squared_distance = 0
for i in range(len(point1)):
####参考教材内容,补全关键代码,重新运行####
squared_distance+=(point1[i]-point2[i])**2
distance = math.sqrt(squared_distance)
return distance
# K近邻算法
def k_nearest_neighbors(k, dataset, new_point):
distances = []
for sample, label in dataset:
####参考教材内容,补全关键代码,重新运行####
distance=euclidean_distance(sample,new_point)
distances.append((distance, label))
distances.sort() # 按距离排序
# 取前k个最近的距离
####参考教材内容,补全关键代码,重新运行####
k_nearest=distances[:k]
labels = [label for distance, label in k_nearest]
vote_counts = Counter(labels) # 统计每个类别的票数
predicted_label = vote_counts.most_common(1)[0][0] # 返回票数最多的类别
return predicted_label
if __name__ == "__main__":
# 加载鸢尾花数据集
dataset = load_dataset('iris_dataset.csv')
# 将数据集拆分为训练集和测试集
random.seed("zp")
random.shuffle(dataset) # 随机打乱数据集顺序
train_size = int(0.8 * len(dataset))
train_set = dataset[:train_size]
####参考教材内容,补全关键代码,重新运行####
test_set=dataset[train_size:]
# 在测试集上进行预测
correct_predictions = 0
for sample, label in test_set:
predicted_label = k_nearest_neighbors(3, train_set, sample)
if predicted_label == label:
correct_predictions += 1
####参考教材内容,补全关键代码,重新运行####
accurary=correct_prediction/len(test_set)
print(f"Accuracy: {accuracy}")
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score
# 加载鸢尾花数据集
iris = load_iris()
X = iris.data # 特征数据
y = iris.target # 目标数据
# 将数据集拆分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2,
random_state=10)
# 创建K近邻分类器模型
####参考教材内容,补全关键代码,重新运行##### 这里设置K值为3
model=KNeighborsClassifier(n_neighbors=3)
# 在训练集上训练模型
####参考教材内容,补全关键代码,重新运行####
model.fit(X_train,y_train)
# 在测试集上进行预测
####参考教材内容,补全关键代码,重新运行####
y_pred=model.predict(X_test)
# 计算准确率
accuracy = accuracy_score(y_test, y_pred)
print("准确率:", accuracy)
综合案例:使用K近邻算法预测房价
import pandas as pd
import seaborn as sns
# 读取文件,跳过前面的描述信息行
df = pd.read_csv('boston.txt', skiprows=22, delimiter='\s+')
# 提取特征名称
feature_names = ['CRIM', 'ZN', 'INDUS', 'CHAS', 'NOX', 'RM', 'AGE', 'DIS',
'RAD', 'TAX', 'PTRATIO', 'B', 'LSTAT', 'MEDV']
# 设置DataFrame的列名
df.columns = feature_names
# # 分离出data和target
####参考教材内容,补全关键代码,重新运行####
target=df['MEDV']
features=df.drop('MEDV',axis=1)
# 查看数据集的前几行
####参考教材内容,补全关键代码,重新运行####
print(df.head())
# 统计数据集中各个特征的描述性统计信息
####参考教材内容,补全关键代码,重新运行####
print(df.describe())
# 绘制特征之间的相关性热力图
corr_matrix = df.corr()
####参考教材内容,补全关键代码,重新运行####
sns.heatmap(corr_matrix,annot=False)
# 绘制房价的直方图
sns.histplot(df['MEDV'], kde=True)
# 可视化各个特征与房价的关系
sns.pairplot(df, x_vars=['CRIM', 'RM', 'AGE', 'DIS'], y_vars='MEDV', kind='scatter')
总和
import math
import random
# 计算欧氏距离
def euclidean_distance(point1, point2):
squared_distance = 0
for i in range(len(point1)):
squared_distance += (point1[i] - point2[i]) ** 2
distance = math.sqrt(squared_distance)
return distance
# 读取波士顿数据集
def load_dataset(filename):
dataset = []
with open(filename, 'r') as file:
for line in file:
data = line.strip().split()
sample = [float(value) for value in data]
dataset.append(sample)
return dataset
# 划分训练集和测试集
def split_dataset(dataset, split_ratio):
random.shuffle(dataset) # 打乱数据集顺序
train_size = int(len(dataset) * split_ratio)
train_set = dataset[:train_size]
test_set = dataset[train_size:]
return train_set, test_set
# K近邻算法(用于回归)
def k_nearest_neighbors_regression(k, train_set, new_point):
distances = []
for sample in train_set:
distance = euclidean_distance(sample[:-1], new_point[:-1])
distances.append((distance, sample))
distances.sort() # 按距离排序
k_nearest = distances[:k] # 取前k个最近的距离
total_value = sum(sample[-1] for distance, sample in k_nearest)
####参考教材内容,补全关键代码,重新运行####
predicted_value=total_value/k
return predicted_value
if __name__ == "__main__":
# 生成样本数据集
#dataset = load_dataset('data\\ch02\\boston.housing.data') #win
#dataset = load_dataset('data/ch02/boston.housing.data') #linux
dataset = load_dataset('boston.housing.data') #linux
# 将数据集划分为训练集和测试集
train_set, test_set = split_dataset(dataset, 0.8)
# 随机选择一个新的测试点
random.seed("zp")
new_point = random.choice(test_set)
# 使用K近邻算法进行回归预测
####参考教材内容,补全关键代码,重新运行####
predicted_value=k_nearest_neighbors_regression(5,train_set,new_point)
print("新测试样本:")
print(new_point[:-1]) # 打印特征值
print("预测房价中位数:", predicted_value)
print("真实房价中位数:", new_point[-1])
len(dataset[1])
import numpy as np
import pandas as pd
#from sklearn.datasets import load_boston
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsRegressor
from sklearn.metrics import mean_squared_error
# 读取波士顿数据集
def load_dataset(filename):
dataset = []
with open(filename, 'r') as file:
for line in file:
data = line.strip().split()
sample = [float(value) for value in data]
dataset.append(sample)
return dataset
# 加载波士顿房价数据集
#data = load_dataset('data\\ch02\\boston.housing.data')
#data = load_dataset('data/ch02/boston.housing.data') #linux
data = load_dataset('boston.housing.data') #linux
df = pd.DataFrame(data)
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(df.iloc[:, :-1], df.iloc[:, -1],
test_size=0.2, random_state=42)
# 构建K近邻回归模型
k = 3 # 可调节K值
####参考教材内容,补全关键代码,重新运行####
model=KNeighborsRegressor(n_neighbors=3)
####参考教材内容,补全关键代码,重新运行####
model.fit(X_train,y_train)
# 预测测试集
y_pred = model.predict(X_test)
# 计算均方误差(MSE)
####参考教材内容,补全关键代码,重新运行####
mse=mean_squared_error(y_test,y_pred)
print("均方误差(MSE):", mse)
浙公网安备 33010602011771号