文章目录
首先要了解一下下面的概念:
X的分布函数的形式已知,但它的一个或多个参数未知,借助于总体X的一个样本来估计总体未知参数的值的问题称为参数的点估计问题。主成分分析 (Principal Component Analysis, PCA) 是一种统计方法,通过正交变换将一组可能存在相关性的变量转换为一组线性不相关的变量,转换后的这组变量叫主成分。PCA 的主要应用有:降维、特征提取、去噪、故障检测。
1,2个轴正交的平面中方差最大的。依次类推,可以得到
n
n
n 个这样的坐标轴。通过这种方式获得的新的坐标轴,我们发现,大部分方差都包含在前面
k
k
k 个坐标轴中,后面的坐标轴所含的方差几乎为0。于是,我们可以忽略余下的坐标轴,只保留前面
k
k
k 个含有绝大部分方差的坐标轴。事实上,这相当于只保留包含绝大部分方差的维度特征,而忽略包含方差几乎为0的特征维度,实现对数据特征的降维处理。下面的实例中会用到 Matlab 中生成正态分布随机数的函数randn(),下面对其用法做简要的介绍。
randn(n):产生一个 n*n 的随机数方阵randn(m,n):产生一个 m*n 的随机数矩阵除此之外还有,Matlab 关于随机数的生成函数还有:
rand:产生均值为0.5、幅度在0~1之间的伪随机数。randperm(n):产生1到n的均匀分布随机序列。normrnd(a,b,c,d):产生均值为a、方差为b大小为c*d服从正态分布的随机矩阵。下面对randn做一个简单的验证:产生两列数据,分别画出它们的概率分布,看看图形是否符合正态分布。代码和绘制结果如下,可以看出结果符合预期。
%% 检验 randn 函数
function rTest()
data=randn(600,2);
figure
hold on
subplot(121)
t=2;
p=capaplot(data(:,1),[-t,t]);
subplot(122)
p=capaplot(data(:,2),[-t,t]);
end

function [coeff, score, latent, tsquared, explained, mu] = pca(x,varargin)
输入:x 是样本,N*P=N个样本量,P维
输出:
N×P数据矩阵X的主成分系数。X的行对应于观测值,列对应于变量。每列系数包含一个主成分的系数。各列按主成分方差(latent)降序排列。默认情况下,PCA将数据居中并使用奇异值分解算法。对于非默认选项,请使用名称/值对参数。X在主成分空间中的表示。score的行对应观察值,列对应主成分。中心数据可以用SCORE*COEFF重建。X的协方差矩阵的特征值,特征值从大到小进行排序。X中每个观测值的Hotelling T平方统计值。PCA使用所有主分量计算TSQUARED(在整个空间中计算),即使请求的组件较少(请参见下面的“NumComponents”选项)。对于缩小空间中的TSQUARED,使用MAHAL(SCORE,SCORE)。Centered设置为true时返回估计的平均值MU;设置为false时返回所有零。对于一维的情况,我们可以用置信区间来描述一个值落在某个区间(区域)的概率(置信水平),这个区间用几何表示是一个线段;对于二维的情况,几何意义上就从一条直线变成了一个平面,类似于置信区间,便有了置信椭圆(confidence ellipse)的概念。
下面是笔者的思考,一些自说自话罢了。
其实,写这篇博文的初衷是为了搞清楚『为什么两个随机变量不相关,其误差椭圆的长短轴平行于坐标轴』。还是看个例子,用数据说话吧。在看下面的内容之前首先要明确下面几点:
randn 函数来生成了两列均值为 0 方差为 1 的随机数;我们对这列随机数的理解为:每一列数据都表示对一个『待求量』的多次量测,显然我们已经假设我们的量测存在一个服从高斯分布的噪声,并且我们的『待求量』真值是0。我们也可以将每一列数据理解为对一个『随机变量』的多次抽样或观测。randn 函数虽然一次生成了两列数据,但是这两列数据是毫无关联的(当然也可以一次生成一列数据,分两次生成);换言之,这两列数据代表的两个『随机变量』是不相关的。首先用randn生成了两列均值为0、方差为1的随机数据,数据量是300*n;为了探究不同数据量的区别,因此画了6幅图如下,数据量分别是300*n,n=1,2,3,4,5,6。图中,len表示数据量的大小,a,b 分别表示椭圆长轴和短轴长度;红色和蓝色箭头(好吧,红色可能看不到箭头)分别表示长轴和短轴方向。可以看到,画出来的图形几近于圆,数据量越多,它越接近于圆。但是它的轴并不平行于坐标轴,可以这样解释:因为这两列数据的方差都是1,所以长短轴理论上应该相等,所以画出来的图形理论上应该是个圆(实际情况也是,数据量越多,它越接近于圆),所以其指向就无所谓了。

为了让两列数据的方差不同,我们将第一列数据乘上了2,不同数据量的绘图结果如下。可以看到,它确实是长短轴平行于坐标轴的椭圆!!

涉及的绘图代码如下:
%% 两个不相关变量的特性
function Test1(wid,hei,a,b)
figure
pmag=50; %the size of margin pix
marx(1:b+1,1)=3;marx(1)=8;
mary(1:a+1,1)=3;mary(1)=8;
sumx=sum(marx);sumy=sum(mary);
marx=marx./sumx;mary=mary./sumy;
lefy=pmag/hei/mary(1);
lefx=pmag/wid/marx(1);
marx=marx.*lefx;
mary=mary.*lefy;
wid1=(1-lefx)/b;
hei1=(1-lefy)/a;
xt=-4:2:4;xtl1=sprintfc('%g',xt);xtl2=kcell(size(xtl1));xl=[-5 5];
yt1=-4:2:4;ytl1=sprintfc('%g',yt1);ytl2=kcell(size(ytl1));yl=[-5 5];
set(gcf,'position',[0 0 wid hei])
for i=1:a
magy=(a-i)*hei1+sum(mary(1:end-i));
for j=1:b
magx=(j-1)*wid1+sum(marx(1:j));
n=(i-1)*b+j;
subplot(a,b,n);
set(gca,'position',[magx magy wid1 hei1],'box','on');
% plot here!
len=300;
data=randn(n*len, 2); % get the data
PCA(data);
set(gca,'XLim',xl,'XTick',xt,'XTicklabel',xtl2);
set(gca,'YLim',yl,'YTick',yt1,'YTicklabel',ytl2);
if j==1
ylabel('Ylab');
set(gca,'YTick',yt1,'YTicklabel',ytl1);
end
if i==a
xlabel('Xlab');
set(gca,'XTick',xt,'XTicklabel',xtl1);
end
end
end
end
% get a null cell which is a*b dims
function data=kcell(m)
a=m(1);b=m(2);
data=cell(a,b);
for i=1:a
for j=1:b
data(i,j)=cellstr(num2str(data{i,j}));
end
end
end
%% PCA
function PCA(data)
len=size(data,1);
data(:,1)=2*data(:,1);
center = mean(data);
[coeff, ~, latent, ~, ~] = pca(data);
% r1 r2 为自定义的向量大小参数(模)
r1 = 6;
r2 = 3;
% p1 p2 为第一主轴和第二主轴上的点
p1 = r1*coeff(:, 1)'+center;
p2 = r2*coeff(:, 2)'+center;
% 主轴方向与X轴之间的夹角
angle = cart2pol(coeff(1, :), coeff(2, :))*180/pi;
beta = angle(1, 1);
% 置信椭圆坐标(以 95% 为例)
semimajor = sqrt(latent(1, 1)); % 长轴长度(一半)
semiminor = sqrt(latent(2, 1)); % 短轴长度(一半)
alpha = linspace(0, 360, 2000)';
% 卡方分布表
% https://people.richland.edu/james/lecture/m170/tbl-chi.html
% level = 4.605; % 90%
level = 5.991; % 95%
% level = 9.210; % 99%
% 椭圆坐标点
ellipse_X = center(1, 1)+sqrt(level)*(semimajor*cosd(alpha)*cosd(beta)-...
semiminor*sind(alpha)*sind(beta));
ellipse_Y = center(1, 2)+sqrt(level)*(semimajor*cosd(alpha)*sind(beta)+...
semiminor*sind(alpha)*cosd(beta));
%% 可视化
% figure
hold on
box on
grid on
% 原始数据
scatter(data(:, 1), data(:, 2), 15, 'LineWidth', 1.2,...
'MarkerEdgeColor', [151, 138, 189]/255,...
'MarkerFaceColor', [151, 138, 189]/255);
xlim([-5, 5]);
ylim([-5, 5]);
set(gca, 'linewidth', 1.5)
% 置信椭圆
plot(ellipse_X, ellipse_Y, 'Color', [0, 102, 255]/255,...
'LineStyle', '-', 'LineWidth', 3),
% 第一主轴方向
arrow_1 = annotation('arrow', 'Color', [162, 20, 47]/255,...
'HeadStyle', 'cback2', 'LineWidth', 3, 'HeadWidth', 20, 'HeadLength', 20);
arrow_1.Parent = gca;
arrow_1.X = [center(1, 1), p1(1, 1)];
arrow_1.Y = [center(1, 2), p1(1, 2)];
% 第二主轴方向
arrow_2 = annotation('arrow', 'Color', [0, 114, 189]/255,...
'HeadStyle', 'cback2', 'LineWidth', 3, 'HeadWidth', 20, 'HeadLength', 20);
arrow_2.Parent = gca;
arrow_2.X = [center(1, 1), p2(1, 1)];
arrow_2.Y = [center(1, 2), p2(1, 2)];
% 中心点
plot(center(1, 1), center(1, 2),...
'Marker', 'o',...
'MarkerSize', 8,...
'MarkerEdgeColor', [162, 20, 47]/255,...
'MarkerFaceColor', [162, 20, 47]/255);
% title('主轴方向和置信椭圆', 'FontSize', 16, 'FontWeight', 'bold')
str=sprintf('len=%d\na=%.2f\nb=%.2f',len,semimajor,semiminor);
text(2, -3, str, 'FontSize', 16, 'FontWeight', 'bold')
axis equal
end
为了让两个随机变量相关,我们记randn生成的两列数据为
X
=
[
a
,
b
]
X=[a,b]
X=[a,b](其中
a
a
a 的均值为 0,方差为 2;
b
b
b 的均值为 0,方差为 1),将其乘上一个矩阵得到新的数据
Y
Y
Y:
Y
=
[
a
′
,
b
′
]
=
[
a
,
b
]
⋅
[
1
1
−
1
2
]
=
X
⋅
Z
Y=[a',b']=[a,b]\cdot \left[ \begin{array}{ccc} 1 & 1 \\ -1 & 2 \\ \end{array} \right]=X\cdot Z
Y=[a′,b′]=[a,b]⋅[1−112]=X⋅Z
也就是说,
a
′
=
a
−
b
,
b
′
=
a
+
2
b
a'=a-b,\ b'=a+2b
a′=a−b, b′=a+2b,然后我们绘制其置信椭圆如下图所示:

其代码如下:
%% 两个相关变量的特征
function Test2()
len=300;
data=randn(5*len, 2); % get the data
data(:,1)=2*data(:,1); % 第一列方差变为2
data1=zeros(size(data));
Z=[1 1;-1 2];
data1=data*Z;
% data1(:,1)=data(:,1)-data(:,2);
% data1(:,2)=data(:,1)+2*data(:,2);
PCA(data1);
end
我们能让两个不相关的随机变量通过乘以一个矩阵变成相关的;同样的我们也可以通过乘一个矩阵使它们『解相关』。对于这组数据,我们已经知道了使它们两个变成相关的矩阵 Z Z Z,那么再乘 Z − 1 Z^{-1} Z−1 显然可以解相关;但是对于一个我们不知道变换矩阵(对应此例也就是上文的 Z − 1 Z^{-1} Z−1 ) 的数据,我们一般用下面的方法来求『变换阵』。
PS:之前的我还以为用 LU 分解来求变换阵,并且认为求解变换阵的方法是『高斯变换』,变换阵被称为『高斯变换阵』。但是并不是,是通过特征值和特征向量来求的。
现在的问题是:已知两个随机变量的许多量测(两列数据),而且这两个随机变量是相关的;怎么找到一个矩阵,使得这两列数据乘上这个矩阵之后,这两列数据就不相关了。笔者觉得有两种方法,一种是几何意义上的:将置信椭圆旋转一下,使得其长短轴平行于坐标轴;另一种是纯代数方法:通过矩阵变换找到这样的旋转矩阵(旋转在代数意义上就是乘以一个矩阵)。
实际上,上述问题用主成分分析找主元、降相关就可以解决。
基于特征值分解协方差矩阵实现 PCA 算法的步骤
下面对此种方法求『解相关矩阵』进行一个简单的证明。
基于上述步骤,对于相关变量得到了其变换阵 X 1 X1 X1,绘图结果如下,左上是原始数据,左下和右上对应中可行的转换矩阵,右下啥也不是。我们发现得到的变换阵 X 1 X1 X1 并不是 Z − 1 Z^{-1} Z−1 ( D a t a Y = D a t a X ⋅ Z Data_Y=Data_X\cdot Z DataY=DataX⋅Z),这说明变换阵不唯一?

代码如下:
%% PCA 求 变换矩阵 并绘图
function Test3()
len=300;
data=randn(5*len, 2); % get the data
data(:,1)=2*data(:,1); % 第一列方差变为2
Z=[1 1;-1 3];
data1=data*Z;
A=data1'*data1/(5*len);
[X,D]=eig(A); % 求特征值 D 和特征向量 X; X 各列是相应的特征向量
% A*X(:,1)-D(1,1)*X(:,1)
data2=data1*X;
X1=[X(:,2),X(:,1)]; % 因为第一个特征值比较大,所以优先将第一个特征向量放在前面
data3=data1*X1;
data4=data1*X1';
% Plot
subplot(2,2,1);
PCA(data1); % 原始数据
subplot(2,2,2);
PCA(data2); % 去相关之后的 y 轴长
subplot(2,2,3);
PCA(data3); % 去相关之后的 x 轴长
subplot(2,2,4);
PCA(data4); % 啥也不是
end
PS:实际上,笔者使用的 PCA 函数中已经做了主成分分析(求出了样本的方差-协方差矩阵),里面用的是 Matlab 自带的 pca 函数,为了更详细地了解 PCA 的过程,笔者又做了点额外工作,PCA 函数在本博文中仅仅发挥一个画图的功能。
.m文件,戳我下载。一、什么是MQTT协议MessageQueuingTelemetryTransport:消息队列遥测传输协议。是一种基于客户端-服务端的发布/订阅模式。与HTTP一样,基于TCP/IP协议之上的通讯协议,提供有序、无损、双向连接,由IBM(蓝色巨人)发布。原理:(1)MQTT协议身份和消息格式有三种身份:发布者(Publish)、代理(Broker)(服务器)、订阅者(Subscribe)。其中,消息的发布者和订阅者都是客户端,消息代理是服务器,消息发布者可以同时是订阅者。MQTT传输的消息分为:主题(Topic)和负载(payload)两部分Topic,可以理解为消息的类型,订阅者订阅(Su
TCL脚本语言简介•TCL(ToolCommandLanguage)是一种解释执行的脚本语言(ScriptingLanguage),它提供了通用的编程能力:支持变量、过程和控制结构;同时TCL还拥有一个功能强大的固有的核心命令集。TCL经常被用于快速原型开发,脚本编程,GUI和测试等方面。•实际上包含了两个部分:一个语言和一个库。首先,Tcl是一种简单的脚本语言,主要使用于发布命令给一些互交程序如文本编辑器、调试器和shell。由于TCL的解释器是用C\C++语言的过程库实现的,因此在某种意义上我们又可以把TCL看作C库,这个库中有丰富的用于扩展TCL命令的C\C++过程和函数,所以,Tcl是
开门见山|拉取镜像dockerpullelasticsearch:7.16.1|配置存放的目录#存放配置文件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/config#存放数据的文件夹mkdir-p/opt/docker/elasticsearch/node-1/data#存放运行日志的文件夹mkdir-p/opt/docker/elasticsearch/node-1/log#存放IK分词插件的文件夹mkdir-p/opt/docker/elasticsearch/node-1/plugins若你使用了moba,直接右键新建即可如上图所示依次类推创建
文章目录概念索引相关操作创建索引更新副本查看索引删除索引索引的打开与关闭收缩索引索引别名查询索引别名文档相关操作新建文档查询文档更新文档删除文档映射相关操作查询文档映射创建静态映射创建索引并添加映射概念es中有三个概念要清楚,分别为索引、映射和文档(不用死记硬背,大概有个印象就可以)索引可理解为MySQL数据库;映射可理解为MySQL的表结构;文档可理解为MySQL表中的每行数据静态映射和动态映射上面已经介绍了,映射可理解为MySQL的表结构,在MySQL中,向表中插入数据是需要先创建表结构的;但在es中不必这样,可以直接插入文档,es可以根据插入的文档(数据),动态的创建映射(表结构),这就
HTTP缓存是指浏览器或者代理服务器将已经请求过的资源保存到本地,以便下次请求时能够直接从缓存中获取资源,从而减少网络请求次数,提高网页的加载速度和用户体验。缓存分为强缓存和协商缓存两种模式。一.强缓存强缓存是指浏览器直接从本地缓存中获取资源,而不需要向web服务器发出网络请求。这是因为浏览器在第一次请求资源时,服务器会在响应头中添加相关缓存的响应头,以表明该资源的缓存策略。常见的强缓存响应头如下所述:Cache-ControlCache-Control响应头是用于控制强制缓存和协商缓存的缓存策略。该响应头中的指令如下:max-age:指定该资源在本地缓存的最长有效时间,以秒为单位。例如:Ca
如何用IDEA2022创建并初始化一个SpringBoot项目?目录如何用IDEA2022创建并初始化一个SpringBoot项目?0. 环境说明1. 创建SpringBoot项目 2.编写初始化代码0. 环境说明IDEA2022.3.1JDK1.8SpringBoot1. 创建SpringBoot项目 打开IDEA,选择NewProject创建项目。 填写项目名称、项目构建方式、jdk版本,按需要修改项目文件路径等信息。 选择springboot版本以及需要的包,此处只选择了springweb。 此处需特别注意,若你使用的是jdk1
前言上一篇我们简要讲述了粒子系统是什么,如何添加,以及基本模块的介绍,以及对于曲线和颜色编辑器的讲解。从本篇开始,我们将按照模块结构讲解下去,本篇主要讲粒子系统的主模块,该模块主要是控制粒子的初始状态和全局属性的,以下是关于该模块的介绍,请大家指正。目录前言本系列提要一、粒子系统主模块1.阅读前注意事项2.参考图3.参数讲解DurationLoopingPrewarmStartDelayStartLifetimeStartSpeed3DStartSizeStartSize3DStartRotationStartRotationFlipRotationStartColorGravityModif
VMware虚拟机与本地主机进行磁盘共享前提虚拟机版本为Windows10(专业版,不是可能有问题)本地主机为家庭版或学生版(此版本会有问题,但有替代方式)最好是专业版VMware操作1.关闭防火墙,全部关闭。2.打开电脑属性3.点击共享-》高级共享-》权限4.如果没有everyone,就添加权限选择完全控制,然后应用确定。5.打开cmd输入lusrmgr.msc(只有专业版可以打开)如果不是专业版,可以跳过这一步。点击用户-》administrator密码要复杂密码,否则不行。推荐admaiN@1234类型的密码。设置完密码,点击属性,将禁用解开。6.如果虚拟机的windows不是专业版,可
我正在尝试编写Ruby代码来检查我发现的特定消息上的椭圆曲线数字签名算法(ECDSA)签名here.问题是我不知道如何将公钥的八位字节字符串转换为OpenSSL::PKey::EC::Point目的。如果我用C写这个,我会把八位字节字符串传递给OpenSSL的o2i_ECPublicKey,它做的事情接近我想要的,实际上被referenceimplementation使用.但是,我搜索了sourcecodeofRuby(MRI)而且它不包含对o2i_ECPublicKey的调用,所以我不知道如何在不编写C扩展的情况下使用Ruby中的该函数。这是十六进制的八位字节字符串。它只是一个0x0
IK分词器本文分为简介、安装、使用三个角度进行讲解。简介倒排索引众所周知,ES是一个及其强大的搜索引擎,那么它为什么搜索效率极高呢,当然和他的存储方式脱离不了关系,ES采取的是倒排索引,就是反向索引;常见索引结构几乎都是通过key找value,例如Map;倒排索引的优势就是有效利用Value,将多个含有相同Value的值存储至同一位置。分词器为了配合倒排索引,分词器也就诞生了,只有合理的利用Value,才会让倒排索引更加高效,如果一整个Value不进行任何操作直接进行存储,那么Value和key毫无区别。分词器Analyzer通常会对Value进行操作:一、字符过滤,过滤掉html标签;二、分