PCA与梯度上升法

PAC

主成分分析(Principal Component Analysis)

  • 一个非监督的机器学习算法
  • 主要用于数据的降维
  • 通过降维,可以发现更便于人类理解的特征
  • 其他应用:可视化;去噪

image.png
image.png
如何找到这个让样本间间距最大的轴?
如何定义样本间间距?
image.png
找到一个轴,使得样本空间的所有点映射到这个轴后,方差最大
image.png
image.png
image.png
image.png
image.png
image.png
image.png

梯度上升法解决主成分分析问题

主成分分析
image.png
image.png
image.png
代码实现
生成测试用例

import numpy as np
import matplotlib.pyplot as plt
X = np.empty((100, 2))
X[:,0] = np.random.uniform(0., 100., size=100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)
plt.scatter(X[:,0], X[:,1])
plt.show()

无标题.png
demean

def demean(X):
    return X - np.mean(X, axis=0)
X_demean = demean(X)
plt.scatter(X_demean[:,0], X_demean[:,1])
plt.show()

无标题.png
梯度上升法

def f(w, X):
    return np.sum((X.dot(w)**2)) / len(X)

def df_math(w, X):
    return X.T.dot(X.dot(w)) * 2. / len(X)

def df_debug(w, X, epsilon=0.0001):
    res = np.empty(len(w))
    for i in range(len(w)):
        w_1 = w.copy()
        w_1[i] += epsilon
        w_2 = w.copy()
        w_2[i] -= epsilon
        res[i] = (f(w_1, X) - f(w_2, X)) / (2 * epsilon)
    return res

def direction(w):
    return w / np.linalg.norm(w)

def gradient_ascent(df, X, initial_w, eta, n_iters = 1e4, epsilon=1e-8):
    
    w = direction(initial_w) 
    cur_iter = 0

    while cur_iter < n_iters:
        gradient = df(w, X)
        last_w = w
        w = w + eta * gradient
        w = direction(w) # 注意1:每次求一个单位方向
        if(abs(f(w, X) - f(last_w, X)) < epsilon):
            break
            
        cur_iter += 1

    return w
initial_w = np.random.random(X.shape[1]) # 注意2:不能用0向量开始
eta = 0.001
# 注意3: 不能使用StandardScaler标准化数据
gradient_ascent(df_debug, X_demean, initial_w, eta)
gradient_ascent(df_math, X_demean, initial_w, eta)

image.png

w = gradient_ascent(df_math, X_demean, initial_w, eta)
plt.scatter(X_demean[:,0], X_demean[:,1])
plt.plot([0, w[0]*30], [0, w[1]*30], color='r')
plt.show()

无标题.png
使用极端数据集测试

X2 = np.empty((100, 2))
X2[:,0] = np.random.uniform(0., 100., size=100)
X2[:,1] = 0.75 * X2[:,0] + 3.
plt.scatter(X2[:,0], X2[:,1])
plt.show()

无标题.png

X2_demean = demean(X2)
w2 = gradient_ascent(df_math, X2_demean, initial_w, eta)
plt.scatter(X2_demean[:,0], X2_demean[:,1])
plt.plot([0, w2[0]*30], [0, w2[1]*30], color='r')
plt.show()

无标题.png

求数据的前n个主成分

求出第一主成分以后,如何求出下一个主成分?
数据进行改变,将数据在第一个主成分上的分量去掉
image.png
在新的数据上求第一主成分
代码
生成数据

import numpy as np
import matplotlib.pyplot as plt
X = np.empty((100, 2))
X[:,0] = np.random.uniform(0., 100., size=100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)
def demean(X):
    return X - np.mean(X, axis=0)
X = demean(X)
plt.scatter(X[:,0], X[:,1])
plt.show()

无标题.png
求出第一主成分

def f(w, X):
    return np.sum((X.dot(w)**2)) / len(X)

def df(w, X):
    return X.T.dot(X.dot(w)) * 2. / len(X)

def direction(w):
    return w / np.linalg.norm(w)

def first_component(X, initial_w, eta, n_iters = 1e4, epsilon=1e-8):
    
    w = direction(initial_w) 
    cur_iter = 0

    while cur_iter < n_iters:
        gradient = df(w, X)
        last_w = w
        w = w + eta * gradient
        w = direction(w) 
        if(abs(f(w, X) - f(last_w, X)) < epsilon):
            break
            
        cur_iter += 1

    return w
initial_w = np.random.random(X.shape[1])
eta = 0.01
w = first_component(X, initial_w, eta)

求第二主成分

X2 = np.empty(X.shape)
for i in range(len(X)):
    X2[i] = X[i] - X[i].dot(w) * w
plt.scatter(X2[:,0], X2[:,1])
plt.show()

无标题.png

X2 = X - X.dot(w).reshape(-1, 1) * w
plt.scatter(X2[:,0], X2[:,1])
plt.show()

无标题.png

w2 = first_component(X2, initial_w, eta)

image.png

w.dot(w2)

image.png


def first_n_components(n, X, eta=0.01, n_iters = 1e4, epsilon=1e-8):
    X_pca = X.copy()
    X_pca = demean(X_pca)
    res = []
    for i in range(n):
        initial_w = np.random.random(X_pca.shape[1])
        w = first_component(X_pca, initial_w, eta)
        res.append(w)
        
        X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w
        
    return res
first_n_components(2, X)

image.png

高维数据向低维数据映射

image.png
image.png
代码实现

import numpy as np


class PCA:

    def __init__(self, n_components):
        """初始化PCA"""
        assert n_components >= 1, "n_components must be valid"
        self.n_components = n_components
        self.components_ = None

    def fit(self, X, eta=0.01, n_iters=1e4):
        """获得数据集X的前n个主成分"""
        assert self.n_components <= X.shape[1], \
            "n_components must not be greater than the feature number of X"

        def demean(X):
            return X - np.mean(X, axis=0)

        def f(w, X):
            return np.sum((X.dot(w) ** 2)) / len(X)

        def df(w, X):
            return X.T.dot(X.dot(w)) * 2. / len(X)

        def direction(w):
            return w / np.linalg.norm(w)

        def first_component(X, initial_w, eta=0.01, n_iters=1e4, epsilon=1e-8):

            w = direction(initial_w)
            cur_iter = 0

            while cur_iter < n_iters:
                gradient = df(w, X)
                last_w = w
                w = w + eta * gradient
                w = direction(w)
                if (abs(f(w, X) - f(last_w, X)) < epsilon):
                    break

                cur_iter += 1

            return w

        X_pca = demean(X)
        self.components_ = np.empty(shape=(self.n_components, X.shape[1]))
        for i in range(self.n_components):
            initial_w = np.random.random(X_pca.shape[1])
            w = first_component(X_pca, initial_w, eta, n_iters)
            self.components_[i,:] = w

            X_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * w

        return self

    def transform(self, X):
        """将给定的X,映射到各个主成分分量中"""
        assert X.shape[1] == self.components_.shape[1]

        return X.dot(self.components_.T)

    def inverse_transform(self, X):
        """将给定的X,反向映射回原来的特征空间"""
        assert X.shape[1] == self.components_.shape[0]

        return X.dot(self.components_)

    def __repr__(self):
        return "PCA(n_components=%d)" % self.n_components


使用
生成数据

import numpy as np
import matplotlib.pyplot as plt
X = np.empty((100, 2))
X[:,0] = np.random.uniform(0., 100., size=100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 10., size=100)

使用

from playML.PCA import PCA

pca = PCA(n_components=2)
pca.fit(X)

image.png

pca = PCA(n_components=1)
pca.fit(X)

降维

X_reduction = pca.transform(X)
X_reduction.shape

image.png
恢复降维

X_restore = pca.inverse_transform(X_reduction)
X_restore.shape

image.png
可视化

plt.scatter(X[:,0], X[:,1], color='b', alpha=0.5)
plt.scatter(X_restore[:,0], X_restore[:,1], color='r', alpha=0.5)
plt.show()

无标题.png

scikit-learn中的PCA

from sklearn.decomposition import PCA
pca = PCA(n_components=1)
pca.fit(X)
pca.components_

image.png

X_reduction = pca.transform(X)
X_restore = pca.inverse_transform(X_reduction)
plt.scatter(X[:,0], X[:,1], color='b', alpha=0.5)
plt.scatter(X_restore[:,0], X_restore[:,1], color='r', alpha=0.5)
plt.show()

无标题.png

真实数据测试

import numpy as np
import matplotlib.pyplot as plt
from sklearn import datasets
digits = datasets.load_digits()
X = digits.data
y = digits.target

分数据集

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)

训练

from sklearn.neighbors import KNeighborsClassifier

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_train)
knn_clf.score(X_test, y_test)

image.png
PCA降维

from sklearn.decomposition import PCA

pca = PCA(n_components=2)
pca.fit(X_train)
X_train_reduction = pca.transform(X_train)
X_test_reduction = pca.transform(X_test)
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
knn_clf.score(X_test_reduction, y_test)

image.png
速度提高了 精度降低了

主成分所解释的方差

pca.explained_variance_ratio_

image.png

from sklearn.decomposition import PCA

pca = PCA(n_components=X_train.shape[1])
pca.fit(X_train)
pca.explained_variance_ratio_

image.png
可视化

plt.plot([i for i in range(X_train.shape[1])], 
         [np.sum(pca.explained_variance_ratio_[:i+1]) for i in range(X_train.shape[1])])
plt.show()

无标题.png
主成分个数可解释95%+的方差

pca = PCA(0.95)
pca.fit(X_train)
pca.n_components_

image.png
说明需要28维

X_train_reduction = pca.transform(X_train)
X_test_reduction = pca.transform(X_test)
knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
knn_clf.score(X_test_reduction, y_test)

image.png

使用PCA对数据进行降维可视化

pca = PCA(n_components=2)
pca.fit(X)
X_reduction = pca.transform(X)
for i in range(10):
    plt.scatter(X_reduction[y==i,0], X_reduction[y==i,1], alpha=0.8)
plt.show()

无标题.png

MNIST手写数据集 训练

import numpy as np 

from sklearn.datasets import fetch_openml
 
mnist = fetch_openml('mnist_784')

X, y = mnist['data'], mnist['target']
X_train = np.array(X[:60000], dtype=float)
y_train = np.array(y[:60000], dtype=float)
X_test = np.array(X[60000:], dtype=float)
y_test = np.array(y[60000:], dtype=float)

image.png
使用KNN

from sklearn.neighbors import KNeighborsClassifier

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_train)
%time knn_clf.score(X_test, y_test)

image.png
PCA进行降维

from sklearn.decomposition import PCA 
pca = PCA(0.90)
pca.fit(X_train)
X_train_reduction = pca.transform(X_train)
X_test_reduction = pca.transform(X_test)
X_train_reduction.shape

image.png

knn_clf = KNeighborsClassifier()
knn_clf.fit(X_train_reduction, y_train)
%time knn_clf.score(X_test_reduction, y_test)

image.png

使用PCA降噪

例子

import numpy as np
import matplotlib.pyplot as plt
X = np.empty((100, 2))
X[:,0] = np.random.uniform(0., 100., size=100)
X[:,1] = 0.75 * X[:,0] + 3. + np.random.normal(0, 5, size=100)
plt.scatter(X[:,0], X[:,1])
plt.show()

无标题.png

from sklearn.decomposition import PCA

pca = PCA(n_components=1)
pca.fit(X)
X_reduction = pca.transform(X)
X_restore = pca.inverse_transform(X_reduction)
plt.scatter(X_restore[:,0], X_restore[:,1])
plt.show()

无标题.png

手写识别例子

from sklearn import datasets

digits = datasets.load_digits()
X = digits.data
y = digits.target

制造噪音

noisy_digits = X + np.random.normal(0, 4, size=X.shape)

取100个

example_digits = noisy_digits[y==0,:][:10]
for num in range(1,10):
    example_digits = np.vstack([example_digits, noisy_digits[y==num,:][:10]])

绘制

def plot_digits(data):
    fig, axes = plt.subplots(10, 10, figsize=(10, 10),
                             subplot_kw={'xticks':[], 'yticks':[]},
    gridspec_kw=dict(hspace=0.1, wspace=0.1)) 
    for i, ax in enumerate(axes.flat):
        ax.imshow(data[i].reshape(8, 8),
                  cmap='binary', interpolation='nearest',
                  clim=(0, 16))

    plt.show()
    
plot_digits(example_digits)

无标题.png
降噪

pca = PCA(0.5).fit(noisy_digits)
pca.n_components_

image.png

components = pca.transform(example_digits)
filtered_digits = pca.inverse_transform(components)
plot_digits(filtered_digits)

无标题.png

特征脸

加载数据

import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import fetch_lfw_people
faces = fetch_lfw_people()

查看属性

faces.keys()
faces.data.shape
faces.target_names
faces.images.shape

image.png
获取36个数据

random_indexes = np.random.permutation(len(faces.data))
X = faces.data[random_indexes]
example_faces = X[:36,:]
example_faces.shape

绘制

def plot_faces(faces):
    
    fig, axes = plt.subplots(6, 6, figsize=(10, 10),
                         subplot_kw={'xticks':[], 'yticks':[]},
    gridspec_kw=dict(hspace=0.1, wspace=0.1)) 
    for i, ax in enumerate(axes.flat):
        ax.imshow(faces[i].reshape(62, 47), cmap='bone')
    plt.show()
    
plot_faces(example_faces)

无标题.png
特征脸

%%time
from sklearn.decomposition import PCA 
pca = PCA(svd_solver='randomized')# 随机方式
pca.fit(X)
pca.components_.shape

image.png
绘制

plot_faces(pca.components_[:36,:])

无标题.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/378596.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

【我与Java的成长记】之String类详解

系列文章目录 能看懂文字就能明白系列 C语言笔记传送门 Java笔记传送门 &#x1f31f; 个人主页&#xff1a;古德猫宁- &#x1f308; 信念如阳光&#xff0c;照亮前行的每一步 文章目录 系列文章目录&#x1f308; *信念如阳光&#xff0c;照亮前行的每一步* 前言一、字符串构…

zabbix配置主动监控

1.准备一台新的主机&#xff0c;安装相关软件包。 [rootsishi ~]# rpm -Uvh https://repo.zabbix.com/zabbix/5.0/rhel/7/x86_64/zabbix-release-5.0-1.el7.noarch.rpm [rootsishi ~]# yum -y install zabbix-agent2.修改zabbix-agent端的配置文件 [rootsishi ~]# vim /etc/z…

图像处理入门:OpenCV的基础用法解析

图像处理入门&#xff1a;OpenCV的基础用法解析 引言OpenCV的初步了解深入理解OpenCV&#xff1a;计算机视觉的开源解决方案什么是OpenCV&#xff1f;OpenCV的主要功能1. 图像处理2. 图像分析3. 结构分析和形状描述4. 动态分析5. 三维重建6. 机器学习7. 目标检测 OpenCV的应用场…

SegmentAnything官网demo使用vue+python实现

一、效果&准备工作 1.效果 没啥好说的&#xff0c;低质量复刻SAM官网 https://segment-anything.com/ 需要提一点&#xff1a;所有生成embedding和mask的操作都是python后端做的&#xff0c;计算mask不是onnxruntime-web实现的&#xff0c;前端只负责了把rle编码的mask解…

【MacOS】装 mac-win10 双系统(2017年的老mac,Intel芯片)

Navigator 一、前情二、完整过程2.1 Mac系统迁移2.2 分区合并2.3 下载win10镜像2.4 安装win102.5 安装驱动等2.6 设置默认启动系统 一、前情 昨天给学妹的mac装软件。发现之前她找维修店装了双系统&#xff0c;但是win10根本不能用&#xff0c;搞得乱七八糟的&#xff0c;于是…

产品经理学习-产品运营《海报制作》

如何策划一款优秀的海报 海报是什么&#xff1f; 是一种将文字和图片结合的信息传递形式&#xff1b;其作用和目的是把想传递给用户的信息高效的传递出去&#xff0c;让用户在极短的时间内产生兴趣&#xff0c;进而产生收藏、分享等行为。 海报的类型&#xff1a; 类型 特点 …

qt/c++实现表情选择框

&#x1f482; 个人主页:pp不会算法^ v ^ &#x1f91f; 版权: 本文由【pp不会算法v】原创、在CSDN首发、需要转载请联系博主 &#x1f4ac; 如果文章对你有帮助、欢迎关注、点赞、收藏(一键三连)和订阅专栏哦 实现功能 。编解码的设计 。映射关系设计 。匹配机制设计 演示效…

上海泗博HART转ModbusTCP网关HME-635应用案例之组态王和超声波液位计通信

如今工业现场的应用也逐渐把现场的不同应用协议转换成以太网&#xff0c;以此来提升现场的通信速度和质量。Modbus TCP是工业以太网协议的一种&#xff0c;也是现场应用中最常使用的。本应用案例是基于Modbus TCP的组态王和基于HART的超声波液位计之间数据通讯的具体应用。 应用…

小白都能看懂的力扣算法详解——链表(一)

&#xff01;&#xff01;本篇所选题目及解题思路均来自代码随想录 (programmercarl.com) 一 203.移除链表元素 题目要求&#xff1a;给你一个链表的头节点 head 和一个整数 val &#xff0c;请你删除链表中所有满足 Node.val val 的节点&#xff0c;并返回新的头节点。 203.…

【Java数据结构】ArrayList和LinkedList的遍历

一&#xff1a;ArrayList的遍历 import java.util.ArrayList; import java.util.Iterator; import java.util.List;/*** ArrayList的遍历*/ public class Test {public static void main(String[] args) {List<Integer> list new ArrayList<>();list.add(5);list…

探索C语言中的联合体与枚举:数据多面手的完美组合!

​ ✨✨ 欢迎大家来到贝蒂大讲堂✨✨ &#x1f388;&#x1f388;养成好习惯&#xff0c;先赞后看哦~&#x1f388;&#x1f388; 所属专栏&#xff1a;C语言学习 贝蒂的主页&#xff1a;Betty‘s blog 1. 联合体的定义 联合体又叫共用体&#xff0c;它是一种特殊的数据类型&…

【网页设计期末】茶文化网站

本文资源&#xff1a;https://download.csdn.net/download/weixin_47040861/88818886 1.题目要求 设计要求&#xff1a; &#xff08;1&#xff09;网站页面数量不少于4个&#xff0c;文件命名规范&#xff0c;网站结构要求层次清楚&#xff0c;目录结构清晰&#xff0c;代码…

TCP的连接和断开详解

目录 1.TCP基础知识 1.1.TCP 头格式 1.2.TCP协议介绍 1.3.UDP协议介绍 1.4.TCP 和 UDP 区别 1.5.TCP 和 UDP 应用场景 1.6.计算机网络相关术语&#xff08;缩写&#xff09; 2.TCP 连接建立&#xff1a;三次握手 2.1.TCP 三次握手过程 2.2.三次握手原理 2.3.异常分析…

浏览器F12调试

系列文章目录 提示&#xff1a;这里可以添加系列文章的所有文章的目录&#xff0c;目录需要自己手动添加 例如&#xff1a;第一章 Python 机器学习入门之pandas的使用 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目…

java实现栈功能

1.使用数组方式 public static void main(String[] args) throws Exception {BufferedReader br new BufferedReader(new InputStreamReader(System.in));int operateNum Integer.parseInt(br.readLine());//操作次数String inputInfo;//输入信息StringBuilder outputSb new…

湿度计算方法

湿度计算方法 &#xff08;1&#xff09;绝对湿度&#xff1a; 绝对湿度是指一定体积的空气中含有的水蒸气的质量&#xff0c;一般其单位是克/立方米。 其中的符号分别是&#xff1a; e–蒸汽压&#xff0c;单位是帕斯卡&#xff08;Pa) Rw–水的气体常数461.52J/&#xff…

1899_野火FreeRTOS教程阅读笔记_任务创建

1899_野火FreeRTOS教程阅读笔记_任务创建 全部学习汇总&#xff1a; g_FreeRTOS: FreeRTOS学习笔记 (gitee.com) 关于这部分&#xff0c;从一般前后台程序到RTOS的任务描述了很多。但是我觉得这本书的这部分描述没有描述到关键的信息点。其实&#xff0c;RTOS存在的一个主要的目…

UML 2.5图形库

UML 2.5图形库 drawio是一款强大的图表绘制软件&#xff0c;支持在线云端版本以及windows, macOS, linux安装版。 如果想在线直接使用&#xff0c;则直接输入网址drawon.cn或者使用drawon(桌案), drawon.cn内部完整的集成了drawio的所有功能&#xff0c;并实现了云端存储&#…

一文读懂:MybatisPlus从入门到进阶

快速入门 简介 在项目开发中&#xff0c;Mybatis已经为我们简化了代码编写。 但是我们仍需要编写很多单表CURD语句&#xff0c;MybatisPlus可以进一步简化Mybatis。 MybatisPlus官方文档&#xff1a;https://www.baomidou.com/&#xff0c;感谢苞米豆和黑马程序员。 Mybat…

Spring Boot的打包方式:JAR vs. WAR 打包方式

Spring Boot的打包方式&#xff1a;JAR vs. WAR 打包方式 Spring Boot是一个流行的Java开发框架&#xff0c;提供了快速、便捷的应用程序开发和部署方式。本文将介绍Spring Boot的两种常见打包方式&#xff1a;JAR和WAR。我们将深入探讨它们的特点、适用场景和部署方式&#xf…