内容:
使用PCA方法对lris数据集的4维数据降为2维,并以K近邻学习比较降维前后的分类结果,实验中分别取K=5﹑7与9。
一、数据集(150)
具体数据如下(如果不能运行,尝试在末尾加回车)
5.1 3.5 1.4 0.2 1
4.9 3 1.4 0.2 1
4.7 3.2 1.3 0.2 1
4.6 3.1 1.5 0.2 1
5 3.6 1.4 0.2 1
5.4 3.9 1.7 0.4 1
4.6 3.4 1.4 0.3 1
5 3.4 1.5 0.2 1
4.4 2.9 1.4 0.2 1
4.9 3.1 1.5 0.1 1
5.4 3.7 1.5 0.2 1
4.8 3.4 1.6 0.2 1
4.8 3 1.4 0.1 1
4.3 3 1.1 0.1 1
5.8 4 1.2 0.2 1
5.7 4.4 1.5 0.4 1
5.4 3.9 1.3 0.4 1
5.1 3.5 1.4 0.3 1
5.7 3.8 1.7 0.3 1
5.1 3.8 1.5 0.3 1
5.4 3.4 1.7 0.2 1
5.1 3.7 1.5 0.4 1
4.6 3.6 1 0.2 1
5.1 3.3 1.7 0.5 1
4.8 3.4 1.9 0.2 1
5 3 1.6 0.2 1
5 3.4 1.6 0.4 1
5.2 3.5 1.5 0.2 1
5.2 3.4 1.4 0.2 1
4.7 3.2 1.6 0.2 1
4.8 3.1 1.6 0.2 1
5.4 3.4 1.5 0.4 1
5.2 4.1 1.5 0.1 1
5.5 4.2 1.4 0.2 1
4.9 3.1 1.5 0.1 1
5 3.2 1.2 0.2 1
5.5 3.5 1.3 0.2 1
4.9 3.1 1.5 0.1 1
4.4 3 1.3 0.2 1
5.1 3.4 1.5 0.2 1
5 3.5 1.3 0.3 1
4.5 2.3 1.3 0.3 1
4.4 3.2 1.3 0.2 1
5 3.5 1.6 0.6 1
5.1 3.8 1.9 0.4 1
4.8 3 1.4 0.3 1
5.1 3.8 1.6 0.2 1
4.6 3.2 1.4 0.2 1
5.3 3.7 1.5 0.2 1
5 3.3 1.4 0.2 1
7 3.2 4.7 1.4 2
6.4 3.2 4.5 1.5 2
6.9 3.1 4.9 1.5 2
5.5 2.3 4 1.3 2
6.5 2.8 4.6 1.5 2
5.7 2.8 4.5 1.3 2
6.3 3.3 4.7 1.6 2
4.9 2.4 3.3 1 2
6.6 2.9 4.6 1.3 2
5.2 2.7 3.9 1.4 2
5 2 3.5 1 2
5.9 3 4.2 1.5 2
6 2.2 4 1 2
6.1 2.9 4.7 1.4 2
5.6 2.9 3.6 1.3 2
6.7 3.1 4.4 1.4 2
5.6 3 4.5 1.5 2
5.8 2.7 4.1 1 2
6.2 2.2 4.5 1.5 2
5.6 2.5 3.9 1.1 2
5.9 3.2 4.8 1.8 2
6.1 2.8 4 1.3 2
6.3 2.5 4.9 1.5 2
6.1 2.8 4.7 1.2 2
6.4 2.9 4.3 1.3 2
6.6 3 4.4 1.4 2
6.8 2.8 4.8 1.4 2
6.7 3 5 1.7 2
6 2.9 4.5 1.5 2
5.7 2.6 3.5 1 2
5.5 2.4 3.8 1.1 2
5.5 2.4 3.7 1 2
5.8 2.7 3.9 1.2 2
6 2.7 5.1 1.6 2
5.4 3 4.5 1.5 2
6 3.4 4.5 1.6 2
6.7 3.1 4.7 1.5 2
6.3 2.3 4.4 1.3 2
5.6 3 4.1 1.3 2
5.5 2.5 4 1.3 2
5.5 2.6 4.4 1.2 2
6.1 3 4.6 1.4 2
5.8 2.6 4 1.2 2
5 2.3 3.3 1 2
5.6 2.7 4.2 1.3 2
5.7 3 4.2 1.2 2
5.7 2.9 4.2 1.3 2
6.2 2.9 4.3 1.3 2
5.1 2.5 3 1.1 2
5.7 2.8 4.1 1.3 2
6.3 3.3 6 2.5 3
5.8 2.7 5.1 1.9 3
7.1 3 5.9 2.1 3
6.3 2.9 5.6 1.8 3
6.5 3 5.8 2.2 3
7.6 3 6.6 2.1 3
4.9 2.5 4.5 1.7 3
7.3 2.9 6.3 1.8 3
6.7 2.5 5.8 1.8 3
7.2 3.6 6.1 2.5 3
6.5 3.2 5.1 2 3
6.4 2.7 5.3 1.9 3
6.8 3 5.5 2.1 3
5.7 2.5 5 2 3
5.8 2.8 5.1 2.4 3
6.4 3.2 5.3 2.3 3
6.5 3 5.5 1.8 3
7.7 3.8 6.7 2.2 3
7.7 2.6 6.9 2.3 3
6 2.2 5 1.5 3
6.9 3.2 5.7 2.3 3
5.6 2.8 4.9 2 3
7.7 2.8 6.7 2 3
6.3 2.7 4.9 1.8 3
6.7 3.3 5.7 2.1 3
7.2 3.2 6 1.8 3
6.2 2.8 4.8 1.8 3
6.1 3 4.9 1.8 3
6.4 2.8 5.6 2.1 3
7.2 3 5.8 1.6 3
7.4 2.8 6.1 1.9 3
7.9 3.8 6.4 2 3
6.4 2.8 5.6 2.2 3
6.3 2.8 5.1 1.5 3
6.1 2.6 5.6 1.4 3
7.7 3 6.1 2.3 3
6.3 3.4 5.6 2.4 3
6.4 3.1 5.5 1.8 3
6 3 4.8 1.8 3
6.9 3.1 5.4 2.1 3
6.7 3.1 5.6 2.4 3
6.9 3.1 5.1 2.3 3
5.8 2.7 5.1 1.9 3
6.8 3.2 5.9 2.3 3
6.7 3.3 5.7 2.5 3
6.7 3 5.2 2.3 3
6.3 2.5 5 1.9 3
6.5 3 5.2 2 3
6.2 3.4 5.4 2.3 3
5.9 3 5.1 1.8 3
二、代码:
import heapq
import numpy as np
import matplotlib.pyplot as plt
# PCA生成投影矩阵,输入数据,输出投影结果
def PCA(x_0, d):
x_sum = [] # 储存和
x_1 = [] # 中心化后的值
# 中心化
for i in range(len(x_0)): # 每个维度
x_1.append([]) # 增加维度
x_sum.append(sum(x_0[i]) / len(x_0[i])) # 均值
for j in range(len(x_0[0])): # 每个值
x_1[i].append(x_0[i][j] - x_sum[i]) # 中心化计算
x_1 = np.array(x_1) # 构造矩阵
x_XX = np.matmul(x_1, x_1.T) # 协方差矩阵(XX.T)
eigen, ev = np.linalg.eig(x_XX) # 求特征值,特征向量。
eigen = eigen[:d] # 取前d个特征值
ev = ev[:, :d] # 取前d个向量
print('特征值为:\n', eigen, '\n特征向量为:\n', ev) # 掏出来看一下获得的投影矩阵
x_1 = np.matmul(ev.T, x_0) # 计算投影结果
return x_1
# k近邻学习输出正确率
def K_(x_0, y_0, k):
c = 0 # 正确数
for i in range(len(x_0[0])): # 对于每个数据进行判断
m = {} # 储存k范围内出现的种类及数目
dis=[] # 储存距离
for j in range(len(x_0[0])): # 对于其他所有数据
if i is j: # 相同,跳过
continue
dis.append(((x_0[0][i] - x_0[0][j]) ** 2 + (x_0[1][i] - x_0[1][j]) ** 2) ** 0.5) # 计算距离(默认二维,可以改)
dis_min = heapq.nsmallest(k, dis) # 获取最小的k个值并排序
index_min = map(dis.index, dis_min) # 获取最小的k个值的下标
for j in index_min: # 对于最近的k个坐标
if y_0[j] in m: # 如果这个值在m中有
m[y_0[j]] = m[y_0[j]] + 1 # +1
else: # 没有
m[y_0[j]] = 1 # 创建
max_m=0
for j in m:
if m[j]>max_m:
max_m=m[j]
max_ = j
if max_ == y_0[i]: # 就是它
c = c + 1
return c / len(y_0)
# 主函数开始====================================================
f = open('Iris.txt', 'r') # 读文件
x = [[], [], [], []] # 花朵属性,(0,1,2,3),花朵种类
y = []
while 1:
yihang = f.readline() # 读一行
if len(yihang) <= 1: # 读到末尾结束
break
fenkai = yihang.split('\t') # 按\t分开
for i in range(4): # 分开的4个值
x[i].append(eval(fenkai[i])) # 化为数字加到x中
y.append(eval(fenkai[4]))
print('数据集===============================================')
print(len(x[0]))
x1 = PCA(x, 2) # PCA算法,获得投影结果
# 计算正确率===========================================
print('计算正确率===========================================')
print('k=5的k近邻学习正确率:', K_(x1, y, 5)*100, '%')
print('k=7的k近邻学习正确率:', K_(x1, y, 7)*100, '%')
print('k=9的k近邻学习正确率:', K_(x1, y, 9)*100, '%')
# 绘图 ===============================================
plt.figure(1) # 第一张画布
for i in range(len(y)): # 对数据集‘上色’
if y[i] == 1:
y[i] = 'r' # 数据集 1 红色
else:
if y[i] == 2:
y[i] = 'y' # 数据集 2 黄色
else:
y[i] = 'b' # 数据集 3 蓝色
plt.scatter(x1[0], x1[1], c=y, alpha=0.5) # 绘点数据集
plt.xlabel('x') # x轴标签
plt.ylabel('y') # y轴标签
plt.title('Projection') # 标题
plt.show() # 显示
结果示例: