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