generated from LufsX/Experiment-kNN
This commit is contained in:
+26
-12
@@ -6,6 +6,14 @@ import time
|
||||
id = "202210423220"
|
||||
name = "方子涵"
|
||||
|
||||
def mahalanobis_distance(x, y, cov_inv):
|
||||
"""
|
||||
计算两点之间的马氏距离。
|
||||
"""
|
||||
delta = x - y
|
||||
dist = np.sqrt(delta.dot(cov_inv).dot(delta.T))
|
||||
return dist
|
||||
|
||||
def classify(input_vector, dataSet, labels, k=3):
|
||||
"""
|
||||
KNN 分类算法。
|
||||
@@ -19,18 +27,26 @@ def classify(input_vector, dataSet, labels, k=3):
|
||||
Returns:
|
||||
- int: 预测的分类标签。
|
||||
"""
|
||||
# 计算输入向量与数据集中每个向量的欧式距离
|
||||
diffMat = np.tile(input_vector, (dataSet.shape[0], 1)) - dataSet
|
||||
sqDiffMat = diffMat**2
|
||||
sqDistances = sqDiffMat.sum(axis=1)
|
||||
distances = sqDistances**0.5
|
||||
# 获取距离最近的 k 个样本的索引
|
||||
sortedDistIndices = distances.argsort()
|
||||
# 计算数据集的协方差矩阵的逆矩阵
|
||||
cov_inv = np.linalg.inv(np.cov(dataSet.T))
|
||||
|
||||
# 初始化最近邻列表
|
||||
classCount = {}
|
||||
distances = []
|
||||
|
||||
# 计算输入向量与数据集中每个向量的马氏距离
|
||||
for vector in dataSet:
|
||||
dist = mahalanobis_distance(input_vector, vector, cov_inv)
|
||||
distances.append((dist, labels[np.where(dataSet == vector)[0][0]]))
|
||||
|
||||
# 根据距离排序
|
||||
distances.sort()
|
||||
|
||||
# 获取距离最近的 k 个样本的标签
|
||||
for i in range(k):
|
||||
voteIlabel = labels[sortedDistIndices[i]]
|
||||
# 统计每个类别的出现次数
|
||||
voteIlabel = distances[i][1]
|
||||
classCount[voteIlabel] = classCount.get(voteIlabel, 0) + 1
|
||||
|
||||
# 返回出现次数最多的类别
|
||||
sortedClassCount = sorted(classCount.items(), key=lambda x: x[1], reverse=True)
|
||||
return sortedClassCount[0][0]
|
||||
@@ -55,7 +71,6 @@ def load_dataset(directory):
|
||||
filePath = os.path.join(directory, filename)
|
||||
vector = img_to_vector(filePath)
|
||||
dataSet[i, :] = vector
|
||||
# 假设文件名的格式为 "label_number.txt"
|
||||
label = int(filename.split('_')[0])
|
||||
labels.append(label)
|
||||
return dataSet, np.array(labels)
|
||||
@@ -75,11 +90,10 @@ def img_to_vector(filename):
|
||||
lines = file.readlines()
|
||||
n = 0
|
||||
for line in lines:
|
||||
# 去除每行末尾的换行符
|
||||
line = line.strip()
|
||||
for i in range(len(line)):
|
||||
returnVect[0, n] = int(line[i])
|
||||
n = n + 1
|
||||
n += 1
|
||||
if n >= 1024:
|
||||
break
|
||||
if n >= 1024:
|
||||
|
||||
Reference in New Issue
Block a user