博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Bobo老师机器学习笔记第七课-如何求得前N个主成分
阅读量:4171 次
发布时间:2019-05-26

本文共 2371 字,大约阅读时间需要 7 分钟。

在上一篇博客中B oBo老师介绍了主成分分析法的原理,以及用代码实现了如何求得一个主成分。那这篇文章中我们主要讲述如何求得前N个主成分,以及如何用代码实现。 

1、如何求取前N个主成分?

   主要方法是 数据进行改变,将数据在第一个主成分上的分量给去掉,然后在新的数据上求取第一主成分, 而在新数据的第一主成分其实就是原来数据的第二主成分,那么如何求取新数据呢,如下图。 

上图中X‘就是原来数据减去在第一主成分上分量获取的新数据, w是第一主成分,X‘(project)是数据X在w方向的分量。 

代码实现:

'''封装自己的PCA算法,用来求取前N个主成分'''import numpy as npimport matplotlib.pyplot as pltclass PCA(object):    def __init__(self, n_components):        self.n_components = n_components  # 求前几个主成分的个数        self.components_ = None    def fit(self, x_train, eta=0.01, n_iters=1e4, eplosion=1e-18):        def demean(X):            """            Mekes the mean of X is zero.            :param X:  Martrix            :return:  matrix which mean of X is zero            """            return X - np.mean(X, axis=0)        def f(X, w):            return np.sum((X.dot(w)) ** 2) / len(X)        def direction(w):            return w / np.linalg.norm(w)        def df(X, w):            return (X.T.dot(X.dot(w))) * 2. / len(X)        def first_component(X, eta, initial_w, n_iters, eplosion):            # 在此处混淆了一个概念,就是当适用随机梯度下降法的时候,不用n_iter来控制,梯度上升发还是需要,因为它依然是按照梯度方法也就是增大最大的方向进行            w = direction(initial_w)            cur_index = 0            while cur_index < n_iters:                last_w = w                w = w + eta * df(X, w)                w = direction(w)                if abs(f(X, w) - f(X, last_w)) < eplosion:                    break                cur_index += 1            return w        X = demean(x_train)        self.components_= np.empty((self.n_components, X.shape[1]))        for i in range(self.n_components):            # 每次都要进行初始化            initial_w = np.random.random(X.shape[1])            w = first_component(X, eta, initial_w, n_iters, eplosion)            self.components_[i, :] = w            X = X - X.dot(w.reshape(-1, 1)) * w        return self.components_    def __repr__(self):        return "PCA(n_components=%d)" % self.n_componentsif __name__ == '__main__':    x = np.random.randint(1, 100, size=100)    X = np.empty((100, 2))    X[:, 0] = x    X[:, 1] = 0.75 * x + 3. + np.random.normal(1,10., size=len(x))    pca = PCA(n_components=2)    pca.fit(X)    print (pca.components_)

运行结果:

[[ 0.75221024  0.65892318]

 [ 0.65892319 -0.75221023]]

这是数据X在2个方向的主成分,可以通过点乘会发现这两个主成分结果为0,这是因为它们是垂直的。我在本地计算出来是

2.053357484044227e-12 

总结:

1、在这个里面要理解清楚分量的求法

2、相互点乘时候要注意维度 

 

要是你在西安,感兴趣一起学习AIOPS,欢迎加入QQ群 860794445

转载地址:http://ohkai.baihongyu.com/

你可能感兴趣的文章
嵌入式100题(017):malloc的底层实现
查看>>
嵌入式100题(018):在1G内存的计算机中能否malloc(1.2G)?为什么?
查看>>
嵌入式100题(019):指针与引用的相同和区别;如何相互转换?
查看>>
嵌入式100题(040):什么是三次握手
查看>>
嵌入式100题(037):Http1.1和Http1.0的区别
查看>>
嵌入式100题(038):HTTPS与HTTP的一些区别
查看>>
嵌入式100题(042):为什么服务端易受到SYN攻击?
查看>>
嵌入式100题(043):什么是四次挥手
查看>>
嵌入式100题(044):为什么客户端最后还要等待2MSL?
查看>>
嵌入式100题(045):为什么建立连接是三次握手,关闭连接确是四次挥手呢?...
查看>>
嵌入式100题(028):static的用法(定义和用途)
查看>>
嵌入式100题(027):char和int之间的转换
查看>>
嵌入式100题(029):const常量和#define的区别(编译阶段、安全性、内存占用等)...
查看>>
嵌入式100题(030):volatile作用和用法
查看>>
嵌入式100题(033):TCP、UDP的优缺点
查看>>
嵌入式100题(035):TCP为什么是可靠连接
查看>>
嵌入式100题(034):TCP UDP适用场景
查看>>
嵌入式100题(70):一个程序从开始运行到结束的完整过程(四个过程)
查看>>
嵌入式100题(71):什么是堆,栈,内存泄漏和内存溢出?
查看>>
嵌入式100题(73):死锁的原因、条件 创建一个死锁,以及如何预防
查看>>