用Python实现PCA和MDA降维和聚类
降维和聚类算是无监督学习的重要领域,还是那句话,不论是PCA、MDA还是K-means聚类,网上大牛总结的杠杠的,给几个参考链接:
http://www.cnblogs.com/jerrylead/archive/2011/04/18/2020209.html http://bbezxcy.iteye.com/blog/2090591 http://www.tuicool.com/articles/7nIvum http://www.cnblogs.com/python27/p/MachineLearningWeek08.html http://blog.pluskid.org/?p=407 http://www.cnblogs.com/Key-Ky/archive/2013/11/24/3440684.html http://www.cnblogs.com/coser/archive/2013/04/10/3013044.html
PCA和MDA的推导过程都是手推,本来想拍照发上来,但前几次‘作’过之后实在提不起兴趣,还好有小伙伴(妹子)总结的很好:
http://blog.csdn.net/totodum/article/details/51049165 http://blog.csdn.net/totodum/article/details/51097329
来看我们这次课的任务:
•数据Cat4D3Groups是4维观察数据, •请先采用MDS方法降维到3D,形成Cat3D3Groups数据,显示并观察。 •对Cat3D3Groups数据采用线性PCA方法降维到2D,形成Cat2D3Groups数据,显示并观察。
•对Cat2D3Groups数据采用K-Mean方法对数据进行分类并最终确定K,显示分类结果。 •对Cat2D3Groups数据采用Hierarchical分类法对数据进行分类,并显示分类结果。
理论一旦推导完成,代码写起来就很轻松:
Part 1:降维处理 MDA:
# -*- coding:gb2312 -*-from pylab import *import numpy as npfrom mpl_toolkits.mplot3d import Axes3Ddef print_D(data):
N = np.shape(data)[0]
d = np.zeros((N, N)) for i in range(N):
c = data[i, :] for j in range(N):
e = data[j, :]
d[i, j] = np.sqrt(np.sum(np.power(c - e, 2))) return ddef MDS(D, K):
N = np.shape(D)[0]
D2 = D ** 2
H = np.eye(N) - 1.0/N
T = -0.5 * np.dot(np.dot(H, D2), H)
eigVal, eigVec = np.linalg.eig(T)
indices = np.argsort(eigVal) # 返回从小到大的索引值
indices = indices[::-1] # 反转
eigVal = eigVal[indices] # 特征值从大到小排列
eigVec = eigVec[:, indices] # 排列对应特征向量
m = eigVec[:, :K]
n = np.diag(np.sqrt(eigVal[:K]))
X = np.dot(m, n) return X# test'''
data = genfromtxt("CAT4D3GROUPS.txt")
D = print_D(data)
# print D
# 4D 转 3D
CAT3D3GROUPS = MDS(D, 3)
# print CAT3D3GROUPS
# D_3D = print_D(CAT3D3GROUPS)
# print D_3D
figure(1)
ax = subplot(111,projection='3d')
ax.scatter(CAT3D3GROUPS[:, 0], CAT3D3GROUPS[:, 1], CAT3D3GROUPS[:, 2], c = 'b')
ax.set_zlabel('Z') #坐标轴
ax.set_ylabel('Y')
ax.set_xlabel('X')
title('MDS_4to3')
# 4D 转 2D
CAT2D3GROUPS = MDS(D, 2)
# print CAT2D3GROUPS
# D_2D = print_D(CAT2D3GROUPS)
# print D_2D
figure(2)
plot(CAT2D3GROUPS[:, 0], CAT2D3GROUPS[:, 1], 'b.')
xlabel('x')
ylabel('y')
title('MDS_4to2')
'''
PDA:
代码里的注释啰啰嗦嗦应该解释的很清楚,这里不再赘述,看结果:
1、用MDS方法降维到3D,形成Cat3D3Groups数据: 共两个函数,辅助函数用来生成欧氏距离矩阵,MDS函数用于降维。
通过输出的距离矩阵可以看出,降维前后欧氏距离误差小于10^-4,证明算法有效。同时旋转3D图像也可以明显找出2D平面图的视角
2、用PCA方法降维到2D,形成Cat2D3Groups数据:
用PCA直接对4D数据降维后的结果与MDS等价,证明算法有效。同时旋转3D图像也可以明显找出2D平面图的视角。
3、总结分析: 先用MDS算法将4D数据降到3D,再用PCA降到2D。
与MDS降维生成的2D图像及数据对比,误差忽略不计,证明算法有效,同时证明MDS和PCA算法在进行小批量数据降维处理上效果类似。
Part 2:聚类分析: 数据用前面降维之后的二维数据。K-means聚类分析的程序主要参考《Machine Learning in Action》- Peter Harrington这本书第十章,我自己添加了选择最优K值的功能:
其中三个辅助函数用于求欧氏距离,返回矩阵索引值和画图,k-mean函数用于聚类,当所有样本点到其所属聚类中心距离不变时,输出聚类结果,并返回cost function的值。
Cost function计算方法:对每个簇,求所有点到所属聚类中心的欧氏距离,平方后取均值E。聚类结束后,所有簇E值求和取平均得到cost function的值。
不同K值下的分类结果如下(标明聚类中心):
主观判断,k = 4时聚类结果最优。用Elbow方法选择K值结果如下:
发现在K = 2时cost function值下降最为明显,与之前判断的结果不符。思考后发现,K=1时聚类没有意义,所以上图并不能有效选择K值,调整后结果如下:
明显看出,k = 4时cost function下降极为明显。与主观判断结果相符。
Hierarchical分类,参考网上代码,出处不记得了:
当一个类集合中包含多个样本点时,类与类之间的距离取Group Average:把两个集合中的点两两的欧氏距离全部放在一起求平均值,分类结果如下:
重复运行后分类结果并未有太大变化。主观判断,从分成3类及4类的结果看,Hierarchical分类方法效果不如K-mean聚类效果好。
- 如何调用finecms指定栏目的描述关键词
- finecms栏目文章页seo设置
- Logistic回归实战篇之预测病马死亡率(一)
- DedeCMS后台500错误一种原因是不支持PHP5.3、5.4及以上版本
- finecms指定从第几篇文章开始调用5条记录,并调用文章所在栏目
- finecms如何调用多个栏目的子栏目
- 从傅立叶变换到Gabor滤波器
- 三个小时学会wordpress模板制作
- The each() function is deprecated报错的解决方法
- 书接上文:薛定谔的猫是如何诞生的?
- docker源码分析(3)---镜像(1)
- k8s源码分析-----kubelet(8)pod管理
- 大会 | DiracNets:无需跳层连接的ResNet
- golang时间戳格式化与解析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- O、Θ、Ω、o、ω,别再傻傻分不清了!
- SpringBoot一1(初次使用)+HelloWord
- 到底什么才是真正的空间复杂度?
- RabbitMQ都写了,RocketMQ怎么能落下?
- dotnet ConcurrentDictionary 的 GetOrAdd 性能比 TryGetValue 加 TryAdd 低
- CentOS7下升级GLIBC2.31
- 网络扫描利器Fing之Linux版本使用教程
- dotnet 通过依赖注入的 Scoped 给工作流注入相同的上下文信息
- 微信文章爬虫
- vue 随记(6):构建的艺术
- Centos7发布SpringBoot项目并后台运行
- k8s部署zookeeper集群
- dotnet 使用 SemaphoreSlim 可能的内存泄露
- WPF 绑定继承的样式提示 只能根据带有基类型 IFrameworkInputElement 的目标类型的 Style 样式
- 29.opengl高级光照-视差贴图