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] += epsilonw_2 = w.copy()w_2[i] -= epsilonres[i] = (f(w_1, X) - f(w_2, X)) / (2 * epsilon)return resdef 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 = 0while cur_iter < n_iters:gradient = df(w, X)last_w = ww = w + eta * gradientw = direction(w) # 注意1:每次求一个单位方向if(abs(f(w, X) - f(last_w, X)) < epsilon):breakcur_iter += 1return 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 = 0while cur_iter < n_iters:gradient = df(w, X)last_w = ww = w + eta * gradientw = direction(w) if(abs(f(w, X) - f(last_w, X)) < epsilon):breakcur_iter += 1return 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) * wreturn res
first_n_components(2, X)

image.png

高维数据向低维数据映射

image.png
image.png
代码实现

import numpy as npclass PCA:def __init__(self, n_components):"""初始化PCA"""assert n_components >= 1, "n_components must be valid"self.n_components = n_componentsself.components_ = Nonedef 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 = 0while cur_iter < n_iters:gradient = df(w, X)last_w = ww = w + eta * gradientw = direction(w)if (abs(f(w, X) - f(last_w, X)) < epsilon):breakcur_iter += 1return wX_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,:] = wX_pca = X_pca - X_pca.dot(w).reshape(-1, 1) * wreturn selfdef 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 PCApca = 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_splitX_train, X_test, y_train, y_test = train_test_split(X, y, random_state=666)

训练

from sklearn.neighbors import KNeighborsClassifierknn_clf = KNeighborsClassifier()
knn_clf.fit(X_train, y_train)
knn_clf.score(X_test, y_test)

image.png
PCA降维

from sklearn.decomposition import PCApca = 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 PCApca = 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_openmlmnist = 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 KNeighborsClassifierknn_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 PCApca = 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 datasetsdigits = 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

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Java图形化界面编程——Container容器 笔记

2.3 Container容器 2.3.1 Container继承体系 Winow是可以独立存在的顶级窗口,默认使用BorderLayout管理其内部组件布局;Panel可以容纳其他组件&#xff0c;但不能独立存在&#xff0c;它必须内嵌其他容器中使用&#xff0c;默认使用FlowLayout管理其内部组件布局&#xff1b;S…

编曲入门软件哪个好 编曲入门教程 Studio One哪个版本好 Studio One6.5正版多少钱 FL Studio下载

新手编曲软件推荐&#xff1f;新手学编曲要先熟悉编曲逻辑&#xff0c;因此需要选择编曲逻辑简明易懂的宿主软件。编曲新手应该做哪些准备&#xff1f;准备好编曲设备、宿主软件、基础乐理学习资料。 一、编曲入门软件哪个好 新手入门阶段还没有形成系统的编曲思维&#xff0…

JSDoc 注释规范

JSDoc 注释 在 前端项目中&#xff0c;注释格式包含了一些特殊标记&#xff0c;如 param、returns 等&#xff0c;这种注释通常是用来标记函数或方法的参数和返回值的数据类型和描述。 这种注释格式通常被称为 JSDoc 注释。在实际开发中&#xff0c;这样的注释可以被一些工具解…

每日一题!如约而至!(图片整理,寻找数组的中心下标)

今天是腊月二十九&#xff0c;挂灯笼喽&#xff01; 图片整理_牛客题霸_牛客网 (nowcoder.com) #include <stdio.h> #include <string.h>int main() {char str[1001] {\0};while (scanf("%s", str) ! EOF) {//输入的是字符串int len strlen(str);for(…

今日arXiv最热NLP大模型论文:无需数据集,大模型可通过强化学习与实体环境高效对齐 | ICLR2024

引言&#xff1a;将大型语言模型与环境对齐的挑战 虽然大语言模型&#xff08;LLMs&#xff09;在自然语言生成、理解等多项任务中取得了显著成就&#xff0c;但是在面对看起来简单的决策任务时&#xff0c;却常常表现不佳。这个问题的主要原因是大语言模型内嵌的知识与实际环…

【力扣】查找总价格为目标值的两个商品,双指针法

查找总价格为目标值的两个商品原题地址 方法一&#xff1a;双指针 这道题和力扣第一题“两数之和”非常像&#xff0c;区别是这道题已经把数组排好序了&#xff0c;所以不考虑暴力枚举和哈希集合的方法&#xff0c;而是利用单调性&#xff0c;使用双指针求解。 考虑数组 pri…

Android 环境搭建

1、桥接工具安装 网站地址&#xff1a;AndroidDevTools - Android开发工具 Android SDK下载 Android Studio下载 Gradle下载 SDK Tools下载 使用安装包&#xff1a; adb 查看当前链接成功的设备&#xff1a;adb devices 使用adb shell指令来进入到手机的后台&#xff1a;

Redis篇之缓存击穿

一、什么是缓存击穿 1.缓存击穿的定义 缓存击穿&#xff1a;给某一个key设置了过期时间&#xff0c;当key过期的时候。恰好这时间点对这个key有大量的并发请求过来&#xff0c;这些并发的请求可能会瞬间把DB压垮。 2.图片理解 二、那么应该如何解决呢 1.方案一&#xff1a;…

C语言——移除元素(三种方法)

目录 前言 ​一.暴力遍历 二.临时数组 三.双指针法(推荐) 前言 https://leetcode.cn/problems/remove-element/ 这是力扣上的一道简单题&#xff0c;我们可以根据前面所讲的顺序表中的删除来实现&#xff0c;同时还有多种解法&#xff0c;下面将依次讲解 一.暴力遍历 这…

【高阶数据结构】位图布隆过滤器

文章目录 1. 位图1.1什么是位图1.2为什么会有位图1.3 实现位图1.4 位图的应用 2. 布隆过滤器2.1 什么是布隆过滤器2.2 为什么会有布隆过滤器2.3 布隆过滤器的插入2.4 布隆过滤器的查找2.5 布隆过滤器的模拟实现2.6 布隆过滤器的优点2.7 布隆过滤器缺陷 3. 海量数据面试题3.1 哈…

Android开发-之屏幕适配

Android开发-之屏幕适配 前言 Android 系统能发展到今天&#xff0c;离不开其开源性&#xff0c;但是随着越来越多的设备接入 Android 系统&#xff0c;并对 Android 系统进行各种各样的定制&#xff0c;导致长期以来出现了各种碎片化严重的问题。例如&#xff0c;Android 屏…

基于Chrome插件的Chatgpt对话无损导出markdown格式(Typora完美显示)

刚刚提交插件到Chrome插件商店正在审核&#xff0c;想尝试的可以先使用&#xff1a; https://github.com/thisisbaiy/ChatGPT-To-Markdown-google-plugin/tree/main 我将源代码上传至了GitHub&#xff0c;欢迎star, IssueGoogle插件名称为&#xff1a;ChatGPT to MarkDown plus…