精华内容
下载资源
问答
  • 对目前企业统计工作存在的问题进行了分析,提出了企业统计工作创新的要点。
  • matlab统计分析

    万次阅读 2017-06-20 19:33:19
    由于对matlab当中的统计分析的工具箱不太熟悉,现在想测试一下 1、概率分布 随机变量的统计行为,就是他的概率分布。分别是 概率密度函数 pdf 表示的连续分布,每个点在这个范围的可能性。 累积分布函数...

    现在ros都可以与MATLAB进行通信了。
    https://github.com/talregev/ROS_Matlab
    看了大神的github
    真的太有收获了
    https://github.com/kintzhao?page=2&tab=repositories
    matlab安装教程:
    https://jingyan.baidu.com/article/456c463b22527e0a58314402.html

    顺便自己打算把一些好的作图的东西也粘的这个里面。
    如何批量导入dat信息。
    参考博客:
    http://blog.csdn.net/txlsddd/article/details/52601011?locationNum=1&fps=1
    在matlab当中,我们用ls来导入文件的名字,

    filename=ls('C:\Users\Administrator\Desktop\gene_info\*.dat');

    这里写图片描述
    然后我们这个里面的所有的文件进行循环
    这里写图片描述
    在matlab当中importdata和load的区别在于:load一般只针对于matlab特有的格式。例如.mat文件。importdata支持的格式一般是针对于文本文件。

    这条语句是用来进行导入文件的名字,将文件名做成一个字符串数组方便调用

    str=['C:\Users\Administrator\Desktop\gene_info\',filename(i,:)];

    然后将文件名str 进行importdata(str),随后给了data_cell这个一个元祖
    matlab当中的元胞数组是什么概念?
    这里写图片描述
    matlab当中的元胞数组http://blog.163.com/zmbetty7891@126/blog/static/162476718201092524859556/
    https://jingyan.baidu.com/article/20095761997932cb0721b485.html
    将所有的文件都放到一个元祖当中当中,就是上面的这个图。
    (将来不管是什么数据,首先要想到的就是把这些数据导入到一个元素当中)

    这个就是在第一行表示行数,就是给每个元祖进行了一下编号

    data=[1:length(data_cell)];    

    这里data是2是因为他们从第2个开始。

    for j=1:length(data_cell)
        data(2,j)=length(data_cell{1,j});
        for k=1:length(data_cell{1,j})
            numstr=regexprep(data_cell{1,j}(k,1),'rs','');
            data(k+2,j)=str2num(numstr{1,1});
        end
    end

    把字符转出相应的数字 将2翻译成two->to

    str2num

    把数字转出成相应的数据

    num2str 
    regexprep 用于对字符串进行查找并且替换

    相比于其他:regexpregexpiregexp用于对字符进行查找,大小写敏感。regexpi大小写不敏感。

    {}我们用这个括号来表示元祖
    ()用这个来对元素进行地进行定位
    data(k+2)

    这里+2因为在上面的得到的这些数组
    这里写图片描述
    第一行表示的序列
    第二行表示的长度
    从第三行后面的表示数组的长度,我觉得应该吧这个好的模板记住,以后有类型的事情,就用这个套路进行处理。

    filename=ls('C:\Users\Administrator\Desktop\gene_info\*.dat');
    for i=1:length(filename)
        str=['C:\Users\Administrator\Desktop\gene_info\',filename(i,:)];
        data_cell{1,i}=importdata(str);
    end
    data=[1:length(data_cell)];
    for j=1:length(data_cell)
        data(2,j)=length(data_cell{1,j});
        for k=1:length(data_cell{1,j})
            numstr=regexprep(data_cell{1,j}(k,1),'rs','');
            data(k+2,j)=str2num(numstr{1,1});
        end
    end

    matlab单步调试就是 F10
    matlab注释就是%,以及按ctrl+R

    如果是大量的数据就用importdata(‘文件的目录’)

        str2=['C:\Users\Administrator\Desktop\2016试题\B\B题附件\genotype.dat'];
        data_cell2=importdata(str2);
        numstr=regexprep(data_cell2(1,1),'rs','');

    这个后面的地方data_cell2(1,1)是提取出第一个细胞元组当中所有的数据
    这里写图片描述
    细胞数组是 matlab当中的一类特殊的数组
    http://www.fx114.net/qa-111-87603.aspx
    这里写图片描述
    cell生成细胞数组
    cellplot用图形方式显示细胞数组
    细胞数组的生成,先用cell函数预分配数组,然后再对每个元素赋值。
    B=cell(3,4) 创建一个3*4的细胞矩阵。

    MATLAB取消多行注释
    所以说用strcmp函数去比较两个字符是可取的,就是当检测到第一个字符不对,就走了
    导致的结果就是整个data里面有很多
    百度了一下还是用正则表达式去做。
    这里写图片描述
    这里写图片描述
    存储矩阵用()
    存储cell用{}
    这里写图片描述
    这里写图片描述


    在data_num当中产生200-1000个43个随机数

     for i=1:43
         data_num(i)=rand(1)*(1000-200)+200;
     end

    matlab当中关于点除的东西。其实 就不是矩阵的乘法运算。


    产生一列数据

     x_i(1,[1:43])=0;

    新建一个矩阵,这个矩阵是一列,然后我们分号进行分开。

     data=[x_i;data_ai;data_bi;data_num];

    然后通过提取第i个数组进行赋值

    x0=data(:,i);

    并且进行转置

     x0=x0';

    将最后的结果的数据进行存储

    result(i)=fval;

    采用模拟算法

    [x fval] = simulannealbnd(@fun1,x0,Aeq, beq);

    一些比较基础但是很有用函数
    floor函数是进行向下取整floor(1.5)=1
    ceil函数是进行向上取整ceil(1.5)=2
    round函数,是取最接近的整数 可以理解为四舍五入函数
    对于细胞数组cell使用的是{ }
    同样,也可以对一个cell进行转置。
    matlab如何进行读写操作。fopen()用来读入数据 fprintf()用来写入数据按照某种特定的格式。
    使用doc命令进行查找某个函数的功能,例如doc fopen
    利用fopen打开文件 也可以选择默认的按时,默认方式就是只读的方式进行打开。fileID=fopen('test.txt')等效于:fileID=fopen('test.txt','r');
    在matlab当中进行查找和替换的的strrep函数

    在 str1 中找到str2 ,替换成str3
    
    str1 = 'This is a good example.';
    str2 = 'good';
    str3 = 'great';
    str = strrep(str1, str2,str3)
    str =
    This is a great example.

    从论文算法的角度来看的话,感觉需要用的卡方检测,卡方检测就是统计样本实际的观测量与理论推断之间的偏离程度。实际观测与理论推断之间的偏离程度决定了卡方值的大小,卡方值越小,说明偏差越小,越符合。如果两个数值完全相等,卡方值位0,表明理论值与实际值完全符合。在这里说一个查专业资料,尽量去维基百科,英语查。哪里的资料要把百度更多一些。matlab当中的关于卡方检测的两个函数有crosstab和chi2gof函数。大神博客的链接:个人认为还是很详细的http://blog.sina.com.cn/s/blog_7054a1960102wizu.html

    由于对matlab当中的统计分析的工具箱不太熟悉,现在想测试一下
    1、概率分布
    随机变量的统计行为,就是他的概率分布。分别是
    概率密度函数 pdf 表示的连续分布,每个点在这个范围的可能性。
    累积分布函数(cdf)是概率密度函数的积分。
    逆累积分布函数 (icdf))
    随机数产生器
    均值和方差函数
    一般的概率密度函数

    x=[-1:0.1:1];
    f=normpdf(x,0,1);
    plot(x,f)

    这里写图片描述
    但是感觉不是太靠谱。这个为什么产生的一条直线。
    产生标准正态分布

    x=[-1:0.01:9];
    f=pdf('Normal',x,1,1);
    plot(x,f)

    这里写图片描述
    关于pdf(‘name’,x,a1,a2);
    当表示的一个二维的随机变量的时候。name表示分布的类型,例如normal.x表示取值的范围。a1表示的均值,a2表示的方差。a3如果有高纬的分布的话,反正就是以此表示他们的参数。例如

    x=[-1:0.1:1];
    f=pdf('Poisson',x,1);
    plot(x,f)

    这里写图片描述
    累积分布函数

    x=[-1:0.1:5];
    f=cdf('Normal',x,0,1);%f=icdf('Normal',x,0,1);
    plot(x,f);

    这是cdf函数
    这里写图片描述
    这是icdf函数
    这里写图片描述
    随机数产生器
    random函数

    y=random('Normal',0,1);

    输出的结果是是一个随机数。
    计算均值和方差

    [m,n]=normstat(0,0.3)

    返回的m,n分别是均值和方差 输入的两个参数 分别是 mu和 sigma

    举例说明:数学公式如何和matlab相互对应起来
    这里写图片描述
    计算某个值得概率密度用normcdf ,使用cdf函数能够快速的计算PDF。这就是累积概率分布的作用。

    normcdf(2,1,3)

    如果要求p(x>2)
    那么就是1减去上面这个数
    如果去要某个一个区间范围p(2<x<4)
    mcdf(4,1,3)-normcdf(2,1,3)
    描述下性统计
    中心位置度量,数据样本的中心度量的目的在于,对数据向本的数据分布线上的中心位置予以定位。
    均值是对位置的简单和通常的估计量。但是野值(就会出奇的大或者出奇的小)
    对于平均值进行定义
    这里写图片描述


    利用随机产生器,产生在0,1,然后100行5列的二维矩阵

    x=normrnd(0,1,1000,5);

    这里写图片描述

    xbar=mean(x);

    输出的是这里写图片描述,也即是mean函数只能在一个方向上进行求取平均数。
    几何平均数
    这里写图片描述
    如果X是一个向量,那么返回的是这个向量的几何平均,如果是一个矩阵,那么返回的是一个行向量,这个跟mean函数是一样的。

    exprnd(mu,m,n)产生 均值mu m*n的矩阵的 指数分布的的随机数。

    使用geomean(x)来求几何中心
    这里写图片描述

    中位数的野值的抗干扰性强
    使用median(x)


    对离散分布的度量
    离散分布的度量,就是样本的数据偏离其数值中心的程度,也叫作离差
    极差:最大的观测量与最小的观测量之间的差
    标准差和方差:常常用散布度量来衡量
    四分位数间距为随机变量的上四分位数和下四分位数之差。
    计算样本的内的四分位数间距使用的是iqr(x);
    计算极差range(x)
    计算样本的方差 var(x)
    计算标准差 std(x)
    计算协方差矩阵 cov(x)
    计算数据的平均绝对偏差 mad(x)

    中心矩
    是表示数学期望的矩
    这里写图片描述
    样本矩即是平均数;中心距就是 所有的x-x的平均数,然后平方,然后在求和。原点矩,就是x^2再求和。
    这个的r表示的r阶的中心距。
    moment(x,order);使用order来表示阶数
    相关系数
    相关系数表示的是两个随机变量之间线性相依的程度
    可以使用corrcoef函数来计算
    R=corrcoef(x)在这个x当中,x的行元素表示的观测值,列元素表示变量。
    统计作图
    box plots(box图)
    distribution plots(概率图)
    scatter plots(散点图)

    x=[normrnd(4,1,1,100) normrnd(6,0.5,1,200)];
    boxplot(x)

    这里写图片描述
    矩形框中红色的表示的是中位数,中位数正好在数据正中间,说明数据有一半大于这个中位数,目前明显是不是。红色的格子上下两边称为上下四分数点,:他的意思是,数据中有四分之一的数据大于上四分位数。
    盒子上下有一条纵向的线,表示的触须线。上面的截止横线表示的变量值本体的最大值。下横线表示的变量值本体最小的值。异常的点用*来表示。
    (如果将来要用到这种图的,还是要会分析这种图的)

    分布图
    卡方分布

    x=0:0.1:15;
    y=chi2pdf(x,8);%第一个参数表示自变量,第二个参数表示的是自由度V
    plot(x,y)

    自由度v,和自变量x,以及因变量Y之间的关系式
    这里写图片描述
    这里写图片描述

    f分布

    V1和V2的自由度

    y=fpdf(x,5,3);

    这里写图片描述
    这里写图片描述

    这里写图片描述

    t分布
    也是用tpdf();就可以了
    这里写图片描述

    假设检测
    假设检验,利用得到的少量的信息,来判断整体是否达到某个标准。
    他们的步骤:
    1、假设H 0假设
    2、得到一组观测值
    3、给定显著型水平
    4、应用子样的某些统计量特征

    使用ranklsum函数

    [p,h]=ranksum(x,y,alpha)
    p返回的x,y的一致性水平水平,h为假设检验的返回值
    x,y为两组观测值,alpha为显著性水平

    这里写图片描述

    x=[-1:0.1:1];
    y1=tpdf(x,3);
    y2=fpdf(x,1,2);
    plot(x,y1,'+',x,y2,'*')
    [p,h]=ranksum(y1,y2,0.05);

    h为0表示,y1和y2显著相关 h为1表示不相关,p为表示他们的相关的水平。
    说明改假设成立
    这里写图片描述
    如果我再这个改了这个alpha的数值,那么
    这里写图片描述
    这个h的方就变成了1


    t检验

    [h,sig,ci]=ttest(x,m,alpha);

    h为假设检测返回值,sig与这里写图片描述,m为假设的样本的均值。
    利用matlab生成world文档
    %创建一个Microsoft word的服务器
    try
    word=actxGetRunningServer(‘Word.Application’);
    catch
    word=actxserver(‘Word.Application’);
    end

    %设置服务器可见
    set(word,’Visible’,1);
    %可以通过word.get查看对象的所有属性
    %通过invoke可以看见所有的可能的命令,其实我们常用的就是几个
    %word.Documents.invoke;
    %利用add方法建立一个空白的文档
    document=word.document.Add;
    利用matlab读取excel文档
    遇到的问题:

     xlsread('D:\matlab\R2015matlab\bin\daoru.xls')
    错误使用 xlsread (line 251)

    问题的原因:excel 里面有com的插件
    解决方法:
    https://zhidao.baidu.com/question/536815299.html
    勾选掉:
    这里写图片描述
    然后就好了
    这里写图片描述
    xlsread 的参数说明

    num = xlsread(filename)
    num = xlsread(filename,sheet)
    num = xlsread(filename,xlRange) reads from the specified range of the first worksheet in the workbook. Use Excel range syntax, such as 'A1:C3'.
    num = xlsread(filename,sheet,xlRange) reads from the specified worksheet and range.

    第二个参数就是 excel 里面的sheet


    使用matlab 写入excel数据
    这里写图片描述
    从这个图说明,也可以用cell进行读写,那就是偶很好用
    如果是数据量很大的话,就像是数学建模的B题,数据量太大的,是没有办法用excel进行存储的。

    xlswrite('C:\Users\Administrator.WIN7-20161129QO\Desktop\daoru.xls',A);

    用法也一样的

    xlswrite(filename,A) writes matrix A to the first worksheet in the Microsoft® Excel® spreadsheet workbook filename starting at cell A1.
    xlswrite(filename,A,sheet) writes to the specified worksheet.
    xlswrite(filename,A,xlRange) writes to the rectangular region specified by xlRange in the first worksheet of the workbook. Use Excel range syntax, such as 'A1:C3'.

    但是你也可以选择读取一部分
    这里写图片描述
    其实我感觉数学建模朝着大数据量的方向发展。
    我尝试了 一下,将原来的矩阵转置之后 excel的行数是可以承受9445这个数,但是列是没有办法承受1000这个数字的
    仔细看了一下报错,是因为我的是xls 如果换成xlsx就可以存储啦,哈哈,原来这么easy
    目前有了excel我觉得就可以用spss进行分析了。
    其实本质上就没那么多的事,虚惊一场,哈哈

    txt导入matlab
    使用load命令

    load('C:\Users\Administrator.WIN7-20161129QO\Desktop\test.txt')

    或者你有的时候直接将这个txt拖入到matlab的工作空间中就可以了

    maltab导入txt
    我感觉 用的几率不是很大
    http://jingyan.baidu.com/article/e6c8503c609ea8e54f1a189d.html

    matlab用于训练机器学习的模型的函数主要分成三类
    1、有监督的学习(有label)
    2、无监督的学习(没有label)—聚类
    3、集成学习

    当你需要训练模型对进行预测(例如股市将会涨还是落)或者分类()

    当要选择采用何种算法的时候
    这里写图片描述

    分类就选择用 判别分析,支持向量机、朴素贝叶斯、最近邻
    回归:线性回归GLM SVR GPR 集成方法,决策树 神经网路
    聚类:K-means 高斯混合 神经网络 HMM

    一般的解决问题的思路:
    1、加载数据
    2、对数据进行预处理
    3、预处理后的数据提取特征
    4、根据特征训练模型
    5、通过迭代抓住最佳的训练模型

    通常我们把数据分成两组,一组从来进行测试,另外一种进行训练,这种方法叫作保留法,是一种有用的交叉验证技术。
    matlab的混淆矩阵:
    在人工智能中,混淆矩阵(confusion matrix)是可视化工具,特别用于监督学习,在无监督学习一般叫做匹配矩阵。
    这里写图片描述

    KNN(K-近邻算法)将新点和训练数据进行比较,然后返回最近的k个多数类别。

    简化方法
    减少特征的技术:
    相关矩阵:可显示变量之间的关系,因此可以删除非高度相关的变量或特征
    主成分分析(PCA)-可消除冗余
    序列特征减少-采用迭代的方式减少模型的特征,直到无法改进模型的性能为止。

    无监督学习
    在聚类分析中,根据某些相似性度量吧数据划分成组。采用聚类的组正形式,同一类(或者同一簇)中的对象非常相似,不同类中的对象决然不同。
    聚类算法分成两大类:
    1、硬聚类:其中每个数据点只属于一类
    2、软聚类:其中每个数据点可属于多类

    k-均值
    工作原理:
    将数据分割成k个相互排斥的类,一个点在多个程度上适合划入哪一个类,由该点到类中心的距离决定。
    这里写图片描述

    k-中心点
    要求:与数据契合的的聚类中心。
    这里写图片描述

    层次聚类:
    工作原理:
    通过分析点之间的想相似度,将对象分组成一二进制的层次结构树,产生聚类嵌套集
    这里写图片描述
    自组织映射
    工作原理是:
    基于神经网络的聚类,将数据集变成保留拓扑结构的2D图
    这里写图片描述
    软聚类算法
    模糊 C-均值
    工作原理:
    当数据点可能属于多个类进行基于分割的聚类
    这里写图片描述
    高斯混合模型
    工作原理:
    数据点具有一定概率的不同的多元正态分布。
    这里写图片描述
    常见的降维度方法
    主成分分析:
    这里写图片描述
    因子分析
    识别数据集当中个变量之间潜在相关性
    这里写图片描述
    非负矩阵分解
    当模型只能非负数的时候
    这里写图片描述

    监督式学习
    如果你想预测先有数据的输出,应该使用监督式学习。监督学习就是已知输入数据集,和一直对数据集合的输出,然后训练一个模型,为新的输入数据和相应作出合理的预测。
    监督式学习分成,分类和回归两种形式
    分类:预测离散相应
    回归:预测连续相应
    在处理分类问题的时候,一开始就是确定你这个问题是二分类,还是多分类。对于二分类,有病,没病就是一个二分类。某些算法(例如逻辑回归)专门为二分类问题设计的。
    逻辑回归
    这里写图片描述
    K最近邻
    KNN,假定相互靠近的对象都是相似的,因此有很多距离来查找最近邻

    这里写图片描述
    支持向量机
    通过搜索能将全部数据点分割开的判别便捷,对数据尽心分类。
    这里写图片描述

    神经网络
    这里写图片描述
    朴素贝叶斯
    假设勒种的某一具体的特征的存在于其他任何特征的存在都是不相关的。
    这里写图片描述
    判别分析
    这里写图片描述
    决策树
    这里写图片描述


    总结
    这里写图片描述
    将一个很大额数据量通过监督学习,成为较低维度,然后进行特征选取,和监督学习。

    这里写图片描述
    这里写图片描述
    这里写图片描述

    使用HOG特征对数字进行分类
    方向梯度直方图(Histogram of Oriented Gradient, HOG)特征是一种在计算机视觉和图像处理中用来进行物体检测的特征描述子。HOG特征通过计算和统计图像局部区域的梯度方向直方图来构成特征。


    这个地方更新的是谢中华的matlab统计分析的与应用40个案例分析的笔记

    第一个例子的输出
    clc
    clear all
    data=[15.14,14.81,15.11,15.26,15.08,15.17,15.12,14.95,15.06,14.87];
    [muhat,sigmahat,muci,sigmaci] = normfit(data,0.1)
    90%的置信区间:
    [14.9760 15.1380]
    正态总体参数的检验

    总体的标准差未知,单个正态分布的 利用均值的t检验—–ttest()
    总体的标准差未知,两个正态分布的 利用均值比较t检验——— ttest2()
    总体的均值未知,单个正态总体 利用卡方检测—-vartest()—-方差检测
    总体的均值未知,两个正态利用方差 F检验—-vartest2()

    在某些统计推断中,通常假定总体服从一定的分布,例如正态分布,然后再这个分布的基础上,构造相应的统计量,通过统计量的分布做出一些统计判断
    在描述统计量上面,我们有:均值,方差,标准差,最大最小值,极差,中位数,众数,变异系数,峰度,偏度。

    变异系数是衡量数据资料中观测值变异程度的一个统计量。
    当进行两个或者多个变量的比较的之后,均值相同,我们使用标准差进行比较,如果均值不同,就不能使用标准差进行比较了。需要采用标准差和均值的比值,也就是变异系数来进行比较。
    data=xlsread(‘D:\a.xls’);
    data_mean=mean(data(:,6));
    data_std=std(data(:,6));
    data_score=data_std/data_mean;

    箱线图
    箱子图当中™

    data=xlsread(‘D:\a.xls’);
    boxlabel={课程A’,’课程B’,‘课程C’};
    boxplot(data(:,6)’,boxlabel,’notch’,’on’,’orientation’,’horizontal’)
    boxplot(data(:,3:5))

    这里写图片描述
    左边的这个线,或者是下面的这个线,表示的样本1/4分数线的位置,+的位置表示的出现异常的点
    右侧,或者上侧的线表示样本0.75的分数线的位置。在样本的中位数上画一条线,也就是盒子的中间,这个箱子包含了50%的样本数据,1/4的位置是样本的最小值,3/4的位置,表示的是样本的最大值。箱线图可以十分直观的反应样本数据的分散程度以及总体的对称分布。虚线的长度近似,那么表示总体是对称分布嘚

    画出频率直方图

    在matlab当中就是利用ecdf函数和ecdfhist函数,进行绘制

    data=xlsread(‘D:\a.xls’);
    [f,xc]=ecdf(data(:,6));
    ecdfhist(f,xc,8)
    hold on
    %下面是用来做对比曲线的
    x=1:0.1:1000;
    y=normpdf(x,mean(data(:,6)),std(data(:,6)));
    plot(x,y)

    这里写图片描述

    经验分布函数
    经验分布函数使用的cdfplot 和ecdf函数
    [h.state]=cdfplot(data(:,6));
    这里写图片描述
    分布检验
    chi2gof函数用来做卡方拟合优度检测,检验样本是否服从指定分布。卡方检测的原理:利用若干个小区间吧样本观测观测数据进行分组,是的理论上每组包含5个以上的观测,如果不满足这个要求,那么久通过合并相邻组来达到这个要求。根据分组结果计算X2检验统计量
    h=chi2gof(data);
    如果h为0d的话,则表示在显著水平0.05下接受该原则
    通过控制一些参数,来是改变
    ‘nbin’控制分组数量
    通过ctrs 指定各个区间的的中点数
    Jbtest函数用来做Jarque-Bera检验,检验样本是否服从正态分布,调用这个函数不许需要指定分布的方差和均值,由于正态分布的偏度为0,峰度为3 基于Jarque-Bera检验,利用样本的偏度和峰度构造检验统计量
    [h,p]=jbtest(data(:,6))

    返回的是检验的p值
    K-test函数
    用作单个样本Kolmogorov-Smirnov函数,它可以作双侧检验,判断样本是否服从指定的分布。也可以作单侧检验,验证样本的分布函数是否在指定的分布函数之上。kstest函数根据样本的经验分布函数 和指定的分布函数 构造检验统计量

    默认的是正态分布
    [h,p]=kstest(data(:,6))
    如果你想用的cdf定义的连续分布的话
    data=xlsread(‘D:\a.xls’);
    cdf=[data(:,6),normcdf(data(:,6),315,80)];
    [h,p]=kstest(data(:,6),cdf)

    使用kstest2函数,检验样本x1和x2是否具有相同的分布。
    h=kstest2(data(:,5),data(:,4))
    当H=1 则说明拒绝这一个假设
    cdfplot(data(:,5))
    hold on
    cdfplot(data(:,4))
    利用hold on能够将这个图在同一个图当中显示
    lillietest函数
    当总体的均值和方差未知的时候,Lilliefor(1967)提出了样本均值 和标准差s代替总体的样本均值 和标准差 ,然后 使用Kolmogorov-Smirnov函数检验,这就是所谓的Lilliefors检验 lillietest函数用于Lillietest检验,检验样本是否服从指定分布,lillietest函数可用于正态分布,指数分布,极值分布。他们都属于位置和尺度分布族(分布中包含位置和尺度参数)lilltest函数不能用于非位置尺度分布族分布的检验。
    Lilliefors检验是双侧拟合优度检验,它根据样本经验分布函数和指定分布的分布函数构造检验统计量 , 是样本经验分布函数, 是指定分布的分布函数
    默认是正态分布
    h=lillietest(data(:,5))
    后面跟的参数可以说明到底是何种分布。
    h=lillietest(data(:,5),0.05,’ev’)
    最终的结果
    我们利多重方法,来说明这个数据的分布确实是属于正态分布。

    在统计的过程中,我们需要用(部分样本)估计总体的概率密度,通常的估计方法:参数法和非参数法。参数法假定总体是服从某种已知的分布,只是通过样本来估计这种分布的参数。
    非参数,则不用。
    首先介绍经验密度函数
    1、假设 是取自 的样本, 表示的样本观测值,那么我们定义经验密度函数
    叫作样本的经验密度函数,它看可以做为总体密度函数的非参数估计, 当中 表示每个区间的长度, 叫作窗宽或者带宽。他决定的经验密度函数的性状。如果 取得值比较大,那么 的图像相对光滑,如果 取得相对小,那么 相对不光滑。
    后面我们他讨论 对 的影响。
    我们先引入核密度函数
    首先引入Parzen窗密度函数
    在是最简单的核密度估计,其中 就是窗宽
    然后我们给出核密度函数的一般定义:,假设 是取自一元连续总体的样本,在任意点 处的样本总体密度函数估计定义为

    其中 称为核函数, 称为窗宽。为了保证 作为密度函数的合理性,要求 满足 。
    

    常用的核函数:uniform、Triangle、Quartic、Triweight、Gaussian、Cosinus
    核函数的选择一般对核密度函数影响并不是很大,一般窗宽才是影响最大的。选择合适的窗宽十分重要,因此需要一种最佳窗宽的方法

    其中 为总体真实分布密度。 是关于窗宽 的函数,求这个值的最小值,可以得出最佳窗框的估计。

    核密度估计使用ksdensity
    data=xlsread(‘D:\a.xls’);
    [f,xi]=ksdensity(data(:,6));

    ksdensity(data(:,6));
    直接绘制核密度函数图


    2016年数学建模B题

    第一问
    matlab快速取消注释:Ctrl+T 快速进行注释ctrl+R

    data2=[1:1000];%产生的是1到1000的

    然后将目录设置成一个str2的string字符串
    使用importdata导入数据
    然后使用正则表达式将里面的rs全部替换掉。正则表示式可以对大段的文字进行查找和替换。
    matlab里面提供三个正则表达式1、regexp 对大小写敏感 2、regexpi 对大小写不敏感 3、regexprep 对字符进行查找并且替换。一个regexp函数可以输出很多内容。可以通过这种方式将所有的输出的内容进行输出,当然

    [start end extents match tokens names] = regexpi('str', 'expr')

    进行数据的导入和存储,这次事情让我第一次明白cell的强大的地方,其实原来,我压根都没有办法用矩阵进行存储,只能用cell. 因此两个字母在矩阵当中是不能进行存储的。我在这个坑里面走了好久才走出来。
    以后就用这个模板。
    matlab当中读取各种数据的参考文档
    http://blog.csdn.net/zhuxiaoyang2000/article/details/7330783

    %导入数据data_cell
    str2=['E:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\genotype.dat'];
    data_cell=importdata(str2);
    %通过正则表达式将rs除去
    data_cell_01=regexprep(data_cell(1,1),'rs','');%通过正则表示进行替换
    %将对应位置上的数据进行替换
    data_cell_01=regexp(data_cell_01(1,1), '\s+', 'split');%这里的S1表示通过空格进行分割
    data_num=cell(1,9445);
    for i=1:9445
    data_num{1,i}=data_cell_01{1,1}{1,i};
    end
    %接下来字母部分,从2到最后1001.然后通过空格进行分割
    data_str=zeros(1000,9445);%进行初始化str
    for i=2:1001
    data_cell_02{1,i-1}=regexp(data_cell(i,1), '\s+', 'split');%这里的S1表示通过空格进行分割
    end
    %既然都是一个char类型,为什么不知直接进行赋值呢 1000*9445
     data_str=cell(1000,9445);%进行初始化num
    for i=1:1000 
           for j=1:9445
             a=data_cell_02{1,i}{1,1}{1,j};
             data_str{i,j}=char(a);
           end
    end
    data=cat(1,data_num,data_str);使用cat将最后的结果的函数进行存储。
    
    

    然后我现在定的方案是将其转化成四位二进制

    %然后遍历整个data进行提取数据 然后用16进行来表示,用10进制来表示
    %现在制定的方案是采用16进制,通过10进制转成16进制
    for i=2:1001
       for j=1:9445
            data_judge=data{i,j};
            if regexp('AA',data_judge)
                    data_num(i,j)=0;
            end
            if regexp('AT',data_judge)
                    data_num(i,j)=1;  
            end
            if regexp('AC',data_judge)
                    data_num(i,j)=2;
            end
                if regexp('TA',data_judge)
                    data_num(i,j)=3;
                end
                if regexp('TA',data_judge)
                    data_num(i,j)=4;   
                end
                if regexp('TT',data_judge)
                    data_num(i,j)=5;
                end
                if regexp('TC',data_judge)
                    data_num(i,j)=6;   
                end
                if regexp('TG',data_judge)
                    data_num(i,j)=7;
                end
                if regexp('CA',data_judge)
                    data_num(i,j)=8;
                end
                if regexp('CT',data_judge)
                    data_num(i,j)=9; 
                end
                if regexp('CC',data_judge)
                    data_num(i,j)=10;
                end
                if regexp('CG',data_judge)
                    data_num(i,j)=11;   
                end
                if regexp('GA',data_judge)
                    data_num(i,j)=12;
                end
                if regexp('GT',data_judge)
                    data_num(i,j)=13;
                end
                if regexp('GC',data_judge)
                    data_num(i,j)=14;   
                end
                if regexp('GG',data_judge)
                    data_num(i,j)=15; 
                end
       end
    end
    data_num_cell_42=cell(1000,9445);
    for i=2:1001
        for j=1:9445
            data_num_42=dec2bin(data_num(i,j),4);
            data_num_cell_42{i-1,j}=data_num_42;
        end
    end

    感触:在遍历的时候千万不要用if else,如果用的话,会有很多不好的情况发生。例如会出现很多0,那么你直接用if end if end 这样一步的遍历整个程序,就可以了。

    目前采用卡方检测的方法
    matlab当中关于卡方检测的函数 crosstab 和 chi2gof
    double和cell是不能直接拼接起来的,
    首先用num2cell转化的成cell之后,然后就可以利用[]拼接起来

     data_cell=[A_ill_cell data_num_cell_42];
     A_ill_cell=mat2cell(A_ill);

    查找某个值得位置
    这里写图片描述
    但是find函数必须是标量整数
    原来matlab可以修改数据,造假小能手,哈哈
    这里写图片描述

    可以在这个里面修改matlab的数据
    这里写图片描述
    这里可以使用它做用不同类型,进行表示
    甚至可以修改线条的颜色
    这里写图片描述
    这里写图片描述
    这里也可以加入图例
    这里写图片描述
    到这里基本上该会的都会了,就是点击和添加箭头
    这里写图片描述
    补充一些数学当中的常见的距离
    所有的这些距离,看着高大上在matlab中其实就一个函数pdist和pdist2函数
    pdist函数是一维的 pdist2函数是二维的

    D = pdist(X,distance);

    distance 为’euclidean’表示欧式距离
    ‘seuclidean’表示标准欧式距离
    ‘chebychev’表示切比雪夫距离
    ‘cosine’余弦距离
    ‘jaccard’ 杰卡德相似性系数
    ‘hamming’汉明距离
    ‘mahalanobis’马氏距离
    ‘minkowski’ 闵可夫斯基距离


    这个数据处理方方式,真的很牛逼,通过赋值5,6,7,8强AA TT CC GG区分开,然后再排序,有了顺序之后,然后进行赋值。厉害。

    for i=2:1001
       for j=1:9445
            data_judge=data{i,j};
            if regexp('AA',data_judge)
                    data_num(i-1,j)=5;
            end
            if regexp('AT',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('AC',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('AG',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('TA',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('TT',data_judge)
                    data_num(i-1,j)=6;  
            end
            if regexp('TC',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('TG',data_judge)
                    data_num(i-1,j)=1;  
            end
             if regexp('CA',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('CT',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('CC',data_judge)
                    data_num(i-1,j)=7;  
            end
            if regexp('CG',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('GA',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('GT',data_judge)
                    data_num(i-1,j)=1;  
            end
            if regexp('GC',data_judge)
                    data_num(i-1,j)=1;
            end
            if regexp('GG',data_judge)
                    data_num(i-1,j)=8;  
            end
       end
    end

    现在使用的编码方式:
    强原来的方式转换成5,6,7,8,然后再进行转化
    这里写图片描述
    logical作为函数,取出下标为1的元素 举个例子
    我想取出一个矩阵对角矩阵的额元素,可以使用
    参考博客
    http://blog.sina.com.cn/s/blog_65edcfe60102uzhs.html

    test=[1,2,3;4,5,6;7,8,9];
    for i=1:3
        for j=1:3
            local(i,j)=(test(i,j)==9);
        end
    end
    test(local)=0;

    这种方式,就是可以将是1的时候的等于1,然后再传到矩阵里面,就可以进行替换。真的很牛逼这种方式。不得不佩服。
    这里写图片描述

    就是这段代码

    for i=1:9445
        m=unique(data_num(:,i));%中间不重复的数字就3个 1 6 7
        n=setdiff(m,[1]);
        loc1=(data_num(:,i)==n(1));%这里返回的是逻辑值
        data_num(loc1,i)=0;
        %然后将这个逻辑值乘以
        loc2=(data_num(:,i)==n(2));%这里返回的是逻辑值
        data_num(loc2,i)=2;
    end

    接下来就可以做第二问了
    就两个向量之间的欧式距离(也就是求二范数)
    这里写图片描述
    然后就对没两组这样的数据,进行求他们之间的欧式距离,就可以了,我来用matlab实现一下。
    上面这个地方写错了,应该是S=norm(p1-p2)这样才是求的欧式距离
    代码如下:

    for i=1:500
        A_norm(i,:)=data_num(i,:);
        A_ill(i,:)=data_num(i+500,:);
    end
    for i=1:9445
        cout_norm_0(:,i)=sum(A_norm(:,i)==0);
        cout_norm_1(:,i)=sum(A_norm(:,i)==1);
        cout_norm_2(:,i)=sum(A_norm(:,i)==2);
        cout_ill_0(:,i)=sum(A_ill(:,i)==0);
        cout_ill_1(:,i)=sum(A_ill(:,i)==1);
        cout_ill_2(:,i)=sum(A_ill(:,i)==2);
    end
    cout_norm=[cout_norm_0;cout_norm_1;cout_norm_2]/500;
    cout_ill=[cout_ill_0;cout_ill_1;cout_ill_2]/500;
    for i=1:9445
        P_norm=cout_norm(:,i);
        P_ill=cout_ill(:,i);
        S(:,i)=norm(P_norm-P_ill);
    end
    plot(S);
    [B,in]=sort(S);

    这里写图片描述
    使用sort函数可以对原来数据进行排序,B就是对其进行大小的排序,然后in 就是再位置
    默认是从小到大
    差别对大’2273298’,7368252,7543405最高的位点对应的数值分别为:0.207980768341691 ;0.161294761229248 ; 0.160274764077193
    sort函数进行降序排列(“descend”)

    sort(S,"descend")

    在计算x 乘以x的转置的时候,一定要看清那个是n*1那个是1*n,不然计算会出错。
    remap函数的使用

    >>B=repmat( [1 2;3 4],2,3)
    B = 
    
    1      2      1     2    1    2
    
    3      4      3     4    3    4
    
    1     2     1     2     1     2
    
    3     4     3     4     3     4

    到这里第二问就不在计较了


    开始第三问
    这里一定要数据的后缀名添加上。

    filename=ls('D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\*.dat');

    首先导入300组数据

    filename=ls('D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\*.dat');
    for i=1:300
        string_name{i,:}=filename(i,:);
    end
    
    for i=1:300
        file_string=char(string_name{i,:});
        %data_str=strcat(1,'D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\',file_string);
        data_str=['D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\',file_string];
        data_300{i,:}=importdata(data_str);
    end

    matlab 替换某个字符

    >> ch='anCDHUe123'
    ch =
    anCDHUe123
    >> k=find(ch>='A'&ch<='Z')
    k =
         3     4     5     6
    >> ch(k)=[]
    ch =
    ane123
    %将所有的data导入 上面我们分析的都是在一个基因的情况下,现在我们要分析300个基因的情况下 对应的位点
    filename=ls('D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\*.dat');
    for i=1:300
        string_name{i,:}=filename(i,:);
    end
    
    for i=1:300
        file_string=char(string_name{i,:});
        %data_str=strcat(1,'D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\',file_string);
        data_str=['D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\gene_info\',file_string];
        data_300{i,:}=importdata(data_str);
    
    end
    for i=1:300
        for j=1:length(data_300{i,:})
            data_300{i,1}{j,1}=strrep(data_300{i,1}{j,1},'rs','');
        end 
    end

    发现strrep真是一个很神奇的函数,尽然能够在数字和字母混杂的情况下,也能够将要替换的字母提取出来,要比正则表达式的效率快很多。
    现在我已经把位点 和碱基的对照表做好了。

    for i=1:300
        for j=1:length(data_300{i,:})
            data_300{i,1}{j,1}=strrep(data_300{i,1}{j,1},'rs','');
        end 
    end
    for i=1:9445
    data_list{1,i}=str2num(data{1,i});
    end
    data_list_mat=zeros(1,9445);
    data_list_mat=cell2mat(data_list);
    data_num_S=[data_list_mat;data_num];

    要找数据的相关性,遗传疾病和基因的关联性可以由基因包含的几个基因和或者一个基因做出来。

     for i=1:300
        for j=1:length(data_300{i,:})       
            str_data_300(i,j)=strcmpi(data_300{i,1}{j,1},'2273298');
            if str_data_300(i,j)==1
                i    
            end
        end 
    end
    

    返回i值 我这里返回的5 然后我查看表格,最后对应出来就是gene_102是患病基因。
    接下来处理第四问

    clear;
    load('C:\Users\Administrator.WIN7-20161129QO\Desktop\最后的012.mat');
    multi=load('D:\工作项目\2017-06-16-数学建模整理-2017-09-20\2016试题\B\B题附件\multi_phenos.txt');
    %也就是给了你1000个这个数据,然后,其实这个点就是分类有点复杂之外,其他都是一样,
    %0表示没有这种性状,1表示有这种性状
    %将有这种性状的分成一类,将没有这种性状的分成一类
    %然后后面都是一样的
    %这个代码有点问题 我的目标是将0和1 的位置进行提付,如果是0就归为 正常,如果是1就认识是有病组,然后进行分组。
    % for i=1:10
    %     data_m=multi(:,i);%首先将所有分类
    %         for j=1:1000
    %             [a,b]=find(data_m==1);
    %             data_list(i,b)=b;
    %         end
    % end
    
    %%%首先我先提取出第一列%这个低昂有问题
    multi01=multi(:,10);
    for j=1:1000
        if find(multi01(j,1)==0)
            data_multi_0(1,j)=j;
        end
        if find(multi01(j,1)==1)
            data_multi_1(1,j)=j;
        end
    end
    
    %然后遍历整个零矩阵和1矩阵
    %  @患病组A_ill 不患病组的A_norm
    %得到患病组的矩阵 01 矩阵 得到正常组的 01 矩阵
    %然后再统计个数和差异 但是这样不就打乱了位点了吗,不打乱,我只要要的行数 最后列数仍然是9445,只是表示的第二个人 这里是有1000个人
    %证明这种方案的可行性
    
    
    %这样就就对数据进行完了处理,对于第一组数据的第一个性状而言,现在是有500组 这段主要的功能就是将里面的0个除去
    data_multi_0=num2str(data_multi_0);
    data_multi_0=strrep(data_multi_0,'0','');
    data_multi_0=str2num(data_multi_0);
    data_multi_1=num2str(data_multi_1);
    data_multi_1=strrep(data_multi_1,'0','');
    data_multi_1=str2num(data_multi_1);
    %将参数作为传递参数的值
    
    %%%然后现在根据这里面的参数,进行分组
    for i=1:500
        %患病组1
        k=data_multi_1(1,i);
        A_ill(i,:)=data_num(k,:);
        %正常组
        g=data_multi_0(1,i);
        A_norm(i,:)=data_num(g,:);
    end
    
    for i=1:9445
        cout_norm_0(:,i)=sum(A_norm(:,i)==0);
        cout_norm_1(:,i)=sum(A_norm(:,i)==1);
        cout_norm_2(:,i)=sum(A_norm(:,i)==2);
        cout_ill_0(:,i)=sum(A_ill(:,i)==0);
        cout_ill_1(:,i)=sum(A_ill(:,i)==1);
        cout_ill_2(:,i)=sum(A_ill(:,i)==2);
    end
    cout_norm=[cout_norm_0;cout_norm_1;cout_norm_2]/length(cout_norm_0);
    cout_ill=[cout_ill_0;cout_ill_1;cout_ill_2]/length(cout_ill_0);
    
    for i=1:9445
        P_norm=cout_norm(:,i);
        P_ill=cout_ill(:,i);
        S(:,i)=norm(P_norm-P_ill);
    end
    
    [result,in]=sort(S,'descend');
    plot(S)

    我觉得上面的循环,就 这个地方处理的比较好,就是将所有的数据转化成char类型,然后将0进行剔除。

    data_multi_0=num2str(data_multi_0);
    data_multi_0=strrep(data_multi_0,'0','');
    data_multi_0=str2num(data_multi_0);
    data_multi_1=num2str(data_multi_1);
    data_multi_1=strrep(data_multi_1,'0','');
    data_multi_1=str2num(data_multi_1);

    然后还是你这个地方

    multi01=multi(:,10);
    for j=1:1000
        if find(multi01(j,1)==0)
            data_multi_0(1,j)=j;
        end
        if find(multi01(j,1)==1)
            data_multi_1(1,j)=j;
        end
    end

    将处理的地方转化成行,然后判断。其实如果能够好好利用find函数,能够将这个过程简化不少
    然后我把我做的答案贴出来。

    1->1167
    2->1907
    3->8956
    4->2982
    5->2982
    6->1486
    7->4662
    8->8759
    9->2982
    10->7181

    然后再用其他方法做做。查查find函数的用法。

    下面我打算用一赢这个 classificaiton learner app这个工具箱,使用这个工具箱,你可以使用支持向量机 决策树,以及K值最近邻。
    这里写图片描述
    感觉图到是很漂亮,我用的matlab官网提供的mat
    到时候现学现卖吧啊,准备用另外一种方法验证自己的想法。重头开始做。我现在打算第二问用卡方检测做一遍。
    卡方检测主要的就是chi2gof函数,如果返回的数值为0,那么则不能够说明他们相关。
    但是那么他们得返


    **随机森林**random tree
    随机森林是通过集成学习的思想,将多棵树集成的一种算法,他的基本单元是决策树,他本质上属于机器学习当中的一大分支-集成学习方法。每棵决策树都是一个分类器,那么对于一个输入样本N个树就会有N个分类结果。而随机森林集成了所有分类的投票结果,将投票次数最多的类别指定为最终的输出。
    Decision Tree 决策树是在已知各种情况发生的概率的基础上,通过构成的决策树来求取净现值期望值大于等于零的概率,评价项目分先,判断决策能的方法。决策树是一个预测模型。决策树是一种树形结构,其中每个内部的节点表示一个属性上的测试,每个分支表示一个测试的输出,每个节点表示一种类别。决策树是一种常见的分类方法。每个决策树可以都表示一种树型结构,它由它的分支来对该类型的对象依靠属性进行分类,每个决策树都依靠对数据源的分割进行数据测试。这个过程可以递归式的进行修剪,直到不能进行分割为止。将多棵决策树组合在一起,构成随机森林用来提高分类的正确率。
    ID3算法是分类的一部分,决策树由两个部分构成:分类和预测。ID3算法主要是针对于属性的选择问题,他采用贪心算法,自顶向下进行构造,随着树的不断构建,将训练集划分为更小的子集。ID3算法需要选择进行分类的准则,通常有3个量度,信息增益,增益率和Gini指标。

    2015年数学建模的习题

    我就不解释了,都写了注释和模板

    %2015年题目第一问
    %第一问的结果需要作出一个excel的表格,输出样本的类别的标签 每行20个
    %当子空间独立的时候,也就是
    clc
    clear all
    load 1
    data_zscore=zscore(data);
    %这里采用分布聚类
    dataT=data_zscore';
    data_y=pdist(dataT);
    %利用平均值法创建系统的聚类树
    data_z=linkage(data_y,'average');
    %dataopti_order=optimalleaforder(data_z,data_y)
    [data_h,data_T,perm]=dendrogram(data_z,2);
    %这个地方的套路就是,你要找属于哪一类的元素
    data_A=find(data_T==1);
    %将分类的结果画出。这个呢么多怎么可能画出来呢
    data_B=find(data_T==2);
    %这个将列向量转化成一矩阵,当然,你也可以20*5之后再转置,都可以
    data_A_m=reshape(data_A,5,20);
    data_B_m=reshape(data_B,5,20);
    %这边输入的之后,最后直接转换成一个矩阵
    xlswrite('C:\Users\Administrator.WIN7-20161129QO\Desktop\Q1.xlsx',data_A_m,'Sheet1','A1:T5');
    xlswrite('C:\Users\Administrator.WIN7-20161129QO\Desktop\Q1.xlsx',data_B_m,'Sheet2','A1:T5');

    这是第二问,采用的系统聚类

    clc
    clear all
    load 2b
    data_zscore=zscore(data);
    figure(1)
    plot3(data(1,:),data(2,:),data(3,:),'*');
    % %这里采用分布聚类
    dataT=data_zscore';
    data_y=pdist(dataT);
    % %利用平均值法创建系统的聚类树
    data_z=linkage(data_y,'average');
    % %dataopti_order=optimalleaforder(data_z,data_y)
    figure(2)
    [data_h,data_T,perm]=dendrogram(data_z,3);
    data_A=find(data_T==1);
    data_B=find(data_T==2);
    data_C=find(data_T==3);
    for i=1:length(data_A)
        data_A_p(:,i)=data(:,data_A(i,1));
    end
    for i=1:length(data_B)
        data_B_p(:,i)=data(:,data_B(i,1));
    end
    for i=1:length(data_C)
        data_C_p(:,i)=data(:,data_C(i,1));
    end
    figure(3)
    plot3(data_A_p(1,:),data_A_p(2,:),data_A_p(3,:),'*');
    figure(4)
    plot3(data_B_p(1,:),data_B_p(2,:),data_B_p(3,:),'*');
    figure(5)
    plot3(data_C_p(1,:),data_C_p(2,:),data_C_p(3,:),'*');

    其实不管怎么样,都是需要先把题目看清楚,这个问题,一定要好好反省。
    到了数学建模那天中午,一定要找个打印店,然后把这个题目打印出来。

    这种方法的效果也不是很理想。

    clear all
    load 2d
    dataSet=data';
    dataSet=dataSet/max(max(abs(dataSet)));
    num_clusters=2;
    sigma=0.1;
    Z=pdist(dataSet);
    W=squareform(Z);
    C = spectral(W,sigma, num_clusters);
    plot(dataSet(C==1,1),dataSet(C==1,2),'r*', dataSet(C==2,1),dataSet(C==2,2),'b*');
    function C = spectral(W,sigma, num_clusters)
    % 谱聚类算法
    % 使用Normalized相似变换
    % 输入  : W              : N-by-N 矩阵, 即连接矩阵
    %        sigma          : 高斯核函数,sigma值不能为0
    %        num_clusters   : 分类数
    %
    % 输出  : C : N-by-1矩阵 聚类结果,标签值
    %
        format long
        m = size(W, 1);
        %计算相似度矩阵  相似度矩阵由权值矩阵得到,实践中一般用高斯核函数
        W = W.*W;   %平方
        W = -W/(2*sigma*sigma);
        S = full(spfun(@exp, W)); % 在这里S即为相似度矩阵,也就是这不在以邻接矩阵计算,而是采用相似度矩阵
    
        %获得度矩阵D
        D = full(sparse(1:m, 1:m, sum(S))); %所以此处D为相似度矩阵S中一列元素加起来放到对角线上,得到度矩阵D
    
        % 获得拉普拉斯矩阵 Do laplacian, L = D^(-1/2) * S * D^(-1/2)
        L = eye(m)-(D^(-1/2) * S * D^(-1/2)); %拉普拉斯矩阵
    
        % 求特征向量 V
        %  eigs 'SM';绝对值最小特征值
        [V, ~] = eigs(L, num_clusters, 'SM');
        % 对特征向量求k-means
        C=kmeans(V,num_clusters);
    end

    这里写图片描述
    这个效果还是不好

    展开全文
  • 随着环境保护和节能减排工作的深入开展,环境统计在企业环境管理中的作用和地位也愈加重要。在现代企业环境管理中,环境统计是其重要支撑,离开了环境统计,环境管理就成为无源之水、空中楼阁,也就...环境统计分析是手段。
  • PHP做数据统计分析

    千次阅读 2019-03-25 14:45:31
    前段时间的主要工作是开发统计系统, 统计公司产品的安装量和回访量,统计数据则由客户端调用C接口写入mysql数据库,即我们只需要分析客户端写入的原始数据即可。下面是对这个项目的一个总结: 系统评估 1、预估...

    前段时间的主要工作是开发统计系统, 统计公司产品的安装量和回访量,统计数据则由客户端调用C接口写入mysql数据库,即我们只需要分析客户端写入的原始数据即可。下面是对这个项目的一个总结:

    系统评估

    • 1、预估当前每天的回访量有大几百万,随着其它产品的不断推广, 要统计的数据可能越来越多。
    • 2、统计的数据有比较强的约束关系。对于一条安装数据,必须判断之前唯一安装表中是否存在该记录, 若存在则再根据版本判断升级或重装,否则为新装数据,回访数据类似逻辑。所以,如果要出按小时统计数据,则必须把前一个小时数据处理完之后才可以处理后面的数据;前一天的数据处理完之后才可以处理后一天的数据。
    • 3、团队中都擅长的是PHP。hadoop或其他大数据处理方式经验薄弱,面临学习成本和一些未知因素。

    所以最终还是选择用PHP+Mysql来统计,前期应该可以撑一撑。

    整体思路

    接下来对每个步骤进行梳理:

    • 1、C接口直接写数据到安装表和回访表,原始数据的表采用按年分表,按天分区。原始数据量比较大,也不适合PHP写入。
    • 2、转移数据。原始表记录数比较多,为了尽可能的减少与原始表的耦合,这里做了一个转移的动作,将原始表的最新安装、回访数据转移到近期安装、回访表中。近期表只保留3天的数据,即近期回访表的数据会维持在2000w左右。这个动作是否可以用触发器来完成?这里没有采用触发器,个人始终认为触发器和业务依赖太紧,当原始数据需要调整时触发器也要相应调整,觉得不是很方便,因为修改触发器势必会影响写入操作。
    • 3、数据更新。因为需要一条一条判断数据为新装、重装或者新用户、老用户,区域等,所以有这个更新的过程,更新每一条记录的状态。这里将可能是系统瓶颈所在。
    • 4、小时报表。 数据更新完之后即可根据该数据出报表,因为统计的字段8个左右,所以累计到一定时间之后,这个表的数据也将会很多,前台不适合直接从这里取报表数据。
    • 5、其他报表。 可根据小时报表出天的报表,或者出特定字段的报表等等,这是很方便的,同时数据量也将成倍的减少。

    系统实现

    项目使用CI开发,实现的步骤就没太多说的,查询的时候注意下索引的先后顺序就行了,系统到目前还没出现因不中索引而引起的问题。不过程序上的一些调整可以记录下:

    • 1、 报表采用highchart实现,但最开始是直接在控制器获取到报表数据后传到视图,当一个页面有多个报表的时候需要把这些数据一次性读取出来之后页面才会显示。运行了一段时间发现打开慢,也不方便扩展,所以把报表统一改成了ajax调用。
    • 2、 菜单的调整。最开始未意识到后面有更多的产品移植过来,所以对菜单也进行过一次调整。
    • 3、 crontab的调整。最开始所有的crontab脚本都放置在一个控制器中,随着不断的增加发现越来越难控了,难以按产品区分,有些也不用了。为了理清这些脚本以及执行频率,对这里- 进行了一次调整。
    • 4、主从调整。运行一段时间后增加了个从库(32G),所有查询的操作从从库拿,调整之后前台报表表现明显。
    • 5、模型的调整。 这个还未深入调整^_^,因为有新老系统的原因, 模型太多,以及很多业务逻辑写在模型中,模型很重。

    上面的每一个调整并不需要多少时间, 但对不段增长的系统是很有好处的,每当它要倾斜时,我们就把它扶正,希望它能坚持更久一点。

    系统新增功能和调整

    调整用户唯一ID。

    IOS产品原先用uuid来判断唯一性,但7.0之后发现uuid不唯一了,所以统计系统部分产品要将唯一值由uuid替换为序列号,但一直以来都是uuid为唯一ID,统计这边也直接以uuid为唯一键了。这意味着唯一键要调整,大部分表结构都需要调整了。

    原始表有的有序列号,有的没有,所以首先是原始表统一增加序列号字段,因为转移的数据只将特定的字段值写进去,所以原始表的调整对统计不会有影响。同时原始表已有2.5亿数据,直接调整表结构基本不可能。所以采取新建一张调整后的表,rename一下即可,rename的过程是很快的,rename之前的几千条未转移的数据再手动转移一下。

    统计这边将在近期表新增一个唯一字段, 唯一字段不依赖固定值。因为即便调整了, 有一些产品还是以uuid为准,唯一值在转移的过程中判断即可。 统计系统调整时先停下所有的脚本,近期表直接删除重建即可,唯一表因为需要处理,边转移边处理一下即可,报表数据保留原有。所以整个过程下来调整并不算大,只是因为数据量比较大,处理觉得麻烦一点而已。

    增加一个产品

    系统中已经增加了好几个产品了, 这里增加产品的接口是用php实现的。即客户端调用php页面,php写数据库,回访数据大概每天100w左右。运行几天后发现php接口机器挂了, nignx进程数太多。原因就是统计系统比较忙时,数据库压力比较大,php一条一条写入很慢, 很多进程都在等待,于是爆了。。。

    针对这个问题的处理方法是,php接口直接写数据到文本,然后脚本定时load数据到数据库。

    历史数据处理

    有个产品需要对历史数据进行重新统计,历史数据有1亿多。因为历史数据和新数据之间的字段、值等需要进行一次处理,所以采用 SELECT INTO OUTFILE的方式导出,1.6亿数据中导出1.2亿大概5分钟左右。导出之后的的文件有9G左右,直接一次LOAD mysql会超出binlog的限制。所以设置了binglog为3G,然后对原数据按每1000w行进行切割,在一个个导入。

    如果导入的表已经建好索引,开始导入1000w要半个多小时,导入了4000w数据后发现奇慢无比。后来重新导,导入的表未建立索引,1000w数据大概需要9分钟左右。不过后来增加索引花了大概2个半小时。

    对原始数据的处理也是一个问题,为了提升效率,比较大的数据采用多进程跑,比如开10多个进程同时跑一个小时的数据,二三十万数据3分钟就搞定。但当系统中的这些进程碰到一起时,系统就开始慢了, 所以只能用程序去控制下。

    系统总结

    1、 到目前位置系统运行还算正常,但随着新功能的不断增加,这也是个挑战。如果只是针对单个产品,一般的业务,用php来处理,日2000w数据问题应该不是很大。

    2、系统监控。到目前位置做个几个统计系统了,前面一个是最完善的,有很多监控,可以很快发现问题。当前这个系统数据量是比较大的,但监控还比较薄弱,或者已经有很多潜在的问题被忽略,所以做好监控是有必要的。

    3、 使用php运行crontab要防止脚本重复执行,限制起来也很简单,可以用php的exec函数去查看一下当前脚本是否正在执行(需要服务器未限制exec函数),如果正在执行就直接退出,给个简单的判断方法:

    function get_process_num($process_name) { return exec('ps -ef | grep "'.$process_name.'" | grep -v "grep" | wc -l'); }

     

    展开全文
  • 分析了目前输油管道能源消耗统计与分析现状。指出能源统计与分析要结合输油管道的特点,采用能源工艺分析法,可以提高分析的可靠性、准确性,指导输油生产,降低输油...并对做好能源统计分析工作提出了合理化建议。
  • 面对学生成绩,做好成绩数据统计分析,可以帮助教学行政做好评定教学质量和比较各种教学策略的成效,及时调整教学方向;可以帮助科组长及时发现本学科教学中存在的问题及薄弱环节,及时调整本科教学内容;可以帮助班...

    前 言

      考试作为衡量教师教学效果和检查学生掌握知识程度的测量工具,在学校的日常教学工作占有重要地位。面对学生成绩,做好成绩数据统计分析,可以帮助教学行政做好评定教学质量和比较各种教学策略的成效,及时调整教学方向;可以帮助科组长及时发现本学科教学中存在的问题及薄弱环节,及时调整本科教学内容;可以帮助班主任更深入了解本班各学科的优劣,及时协调科任老师的教学时间安排和引导学生的学习方向,做好培优扶困工作;可以帮助科任老师清楚了解学生是否达到预期的学习目标,自己的教学计划是否需调整,做好查漏补缺工作;可以帮助学生了解自己学习的不足及优势,及时调整自己的学习方法,提高自己的学习效率。
      笔者一直以来负责区域片区的成绩统计工作,苦于一直没有找到一本专门关于应用EXCEL进行学生成绩统计分析的参考书,随着广大中小学校对教育数据分析越来越迫切的需求,下面笔者基于EXCEL2010版本,以初三期中考试成绩数据为例,通过一个个实例操作,逐一介绍做好一次成绩统计分析,一般需涉及到哪些统计学知识和统计指标,各种统计功能在EXCEL电子表格下的实现过程,并说明这样做的意义。
    本实例的阅读对象是广大中小学教育工作者和成绩数据管理员,适合具有一定EXCEL操作基础的人群,也适合需了解或提高统计学在中小学教育统计中的应用的广大读者。
      本实例部分公式或统计学思想来自互联网和各种教育文献,在本实例中均做了明确的标注,如有不妥之处,欢迎关注笔考的微信公众号( iSTEAM)或发邮件到笔者的电子邮箱(59144885@QQ.COM),你的建议将是笔者工作的动力,共同推进中小学教育数据统计的发展。
    编者
    2019年11月7日星期四

    【目 录】

    • 【前 言 】
    • 第1章 考试成绩表总体分析
      • 1.1异常数据排查
      • 1.2利用“描述统计”对成绩进行总体分析
        • 实例1-2
    • 第2章 统计分数段人数
      • 2.1 利用数据透视数据表统计分数段
        • 实例2-1
      • 2.2利用countifs函数统计各分数段人数
        • 实例2-2
      • 2.3用其它函数统计分数段人数
      • 2.4 正态分布图
        • 实例2-4
    • 第3章 一分三率和离均率
      • 3.1计算一分三率
      • 3.2计算离均率
        • 实例3-2
    • 第4章 相关分析的应用
      • 4.1利用“相关系数”工具进行相关分析
        • 实例4-1
      • 4.2绘制散点图和回归方程
        • 实例4-2
    • 第5章 排名
      • 5.1使用rank函数排名
        • 5.1.1 RANK 函数的语法和用法
        • 5.1.2 RANK函数的应用
      • 5.2 利用“排位与百分比排位”分析工具实现排名
        • 实例5-2
      • 5.3标准分数的计算与排名
    • 第6章 成绩分析报告的编写
      • 6.1 分析报告流程
      • 6.2总体概况
      • 6.3成绩分析
      • 6.4成绩横向比较
      • 6.5 制作历次考试离均率变化图表
      • 6.6历次考试一分三率情况
      • 6.7培优扶困情况
    • 【 结 语 】
    • 【参考文献】

    【参考文献】

    • [1]平均数:《教育统计与测量评价新编教程》第19页.主编:黄光扬.2019年版.华东师范大学出版社.
    • [2]中位数:《统计学》108页,张晓庆.王玉良.王景涛 编著.清华大学出版社.2012年版.
    • [3]众数:《统计学》106页,张晓庆.王玉良.王景涛 编著.清华大学出版社.2012年版.
    • [4] 标准差:《教育统计与测量评价新编教程》第22页.主编:黄光扬.2019年版.华东师范大学出版社.
    • [5]峰度:《统计学》122页.张晓庆.王玉良.王景涛 编著.清华大学出版社.2012年版.
    • [6]偏度:《统计学》122页.张晓庆.王玉良.王景涛 编著.清华大学出版社.2012年版.
    • [7]差异系数:《教育统计与测量评价新编教程》第25页.主编:黄光扬.2019年版.华东师范大学出版社.
    • [8]《统计学》110页.张晓庆.王玉良.王景涛 编著,清华大学出版社,2012年版.
    • [9]区分度:《教育统计与测量评价新编教程》第82页.主编:黄光扬.2019年版.华东师范大学出版社.
    • [10]区分度计算:百度文库:https://wenku.baidu.com/view/b16e1f8fa0116c175f0e48b3.html
    • [11] EXCEL中正态曲线图如何绘制方法详解,百度文库:https://wenku.baidu.com/view/0d9358fc866fb84ae55c8dd7.html
    • [12] NORMDIST 函数的使用,来源百度百科:https://baike.baidu.com/item/NORMDIST/7257202?fr=aladdin
    • [13] 用EXCEL统计各分数段人数https://wenku.baidu.com/view/316a144327d3240c8447ef43.html
    • [14]《基于SPSS的数据分析(第四版)》201页.薛薇编著.中国人民大学出版社.2017年7月第四版
    • [15] 黄光扬.《教育统计与测量评价新编教程》第37页.2019年版.华东师范大学出版社.
    • [16] 龚笛,姜荣.学生成绩的统计分析.《统计学与应用》2014.3.1-6.
    • [17] 黄光扬.《教育统计与测量评价新编教程》第30页,2019年版,华东师范大学出版社.
    • [18] RANK函数,https://support.office.com/zh-cn/article/rank-%E5%87%BD%E6%95%B0-6a2fc49d-1831-4a03-9d8c-c279cf99f723
    • [19] PERCENTRANK函数,https://support.office.com/zh-cn/article/percentrank-%E5%87%BD%E6%95%B0-f1b5836c-9619-4847-9fc9-080ec9024442
    • [20] 宋宣.华东师范大学.中学应该使用标准分.《考试论谈》,2009.10.011.
    展开全文
  • Druid (大数据实时统计分析数据存储)

    万次阅读 2016-12-18 09:48:14
    原文见此 : Druid White PaperDruid 是一个为在大数据集之上做实时统计分析而设计的开源数据存储。这个系统集合了一个面向列存储的层,一个分布式、shared-nothing的架构,和一个高级的索引结构,来达成在秒级...

    原文见此 : Druid White Paper

    Druid 是一个为在大数据集之上做实时统计分析而设计的开源数据存储。这个系统集合了一个面向列存储的层,一个分布式、shared-nothing的架构,和一个高级的索引结构,来达成在秒级以内对十亿行级别的表进行任意的探索分析。在这篇论文里面,我们会描述Druid的架构,和怎样支持快速聚合、灵活的过滤、和低延迟数据导入的一些细节。

    1. 介绍

    在最近几年,互联网技术的快速增长已经产生了大量由机器产生的数据。单独来看,这些数据包含很少的有用信息,价值都是很低的。从这些巨大的数据里面分析出有用的信息需要大量的时间和资源,很多公司都选择了放弃这些数据。虽然已有基础设施来处理这些居于事件的数据(例如IBM的Netezza,惠普的Vertica,EMC的Green-plum),但它们大多以高价售卖,那些负担得起的公司才是他们的目标客户。

    几年前,Google推出了MapReduce,他们利用普通硬件来索引互联网和分析日志的机制。在原始的MapReduce论文公布之后,Hadoop很快就被大量的跟随和作为参考。Hadoop现在被很多组织机构部署来用于存储和分析大规模的日志数据。Hadoop很大的贡献在于帮助企业将他们那些低价值的事件流数据转化为高价值的聚合数据,这适用于各种应用,例如商业智能和AB测试。

    和许多伟大的系统一样,Hadoop开阔了我们处理问题的视野。然而,Hadoop擅长的是存储和获取大规模数据,但是它并不提供任何性能上的保证它能多快获取到数据。此外,虽然Hadoop是一个高可用的系统,但是在高并发负载下性能会下降。最后,Hadoop对于存储数据可以工作得很好,但是并没有对数据导入进行优化,使导入的数据立即可读。

    早在Metamarkets的产品开发过程中,我们遇上了所有这些问题,并意识到Hadoop是一个很好的后端、批量处理和数据仓库系统。然而,作为一个需要在高并发环境下(1000+用户)保证查询性能和数据可用性的公司,并需要提供产品级别的保证,Hadoop并不能满足我们的需求。我们在宇宙中探索了不同的解决方案,在尝试了关系型数据库管理系统和NoSQL架构后,我们得出了一个结论,就是在开源的世界里,并没有可以充分满足我们需求的系统。最后我们创建了Druid,一个开源的、分布式、列存储、实时分析的数据存储。在许多方面,Druid和其他OLAP系统有很多相似之处,交互式查询系统,内存数据库(MMDB),众所周知的分布式数据存储。其中的分布式和查询模型都参考了当前的一些搜索引擎的基础架构。

    本文介绍了Druid的架构,探讨了建立一个用于生产环境并保持永远在线的托管服务所做的各种设计决策,并试图帮助任何一位面临类似问题的人提供一个可能的解决方案。Druid已经在好几个技术公司的生产环境中进行了部署。本文的结构如下:我们首先在第2节描述面临的问题,接着我们在第3节详细介绍系统的架构,说明数据在系统里面是怎样流通的,然后会在第4节讨论数据为什么和怎么样转换为二进制格式,第5节会简要介绍下查询接口,第6节会介绍下现有的一些性能结果,最后,我们在第7节说明怎样将Druid运行于生产环境,第8节介绍下一些相关的工作。

    2. 问题定义

    Druid的最初目的是设计来解决导入和分析大规模交易事件(日志数据)。这种时间序列形式的数据通常在OALP类工作流中比较常见,且数据的本质是非常重的追加写。

    表1: 在Wikipedia由编辑产生的Druid示例数据

    TimestampPageUsernameGenderCityCharacters AddedCharacters Removed
    2011-01-01T01:00:00ZJustin BieberBoxerMaleSan Francisco180025
    2011-01-01T01:00:00ZJustin BieberReachMaleWaterloo291242
    2011-01-01T02:00:00ZKe$haHelzMaleCalgary195317
    2011-01-01T02:00:00ZKe$haXenoMaleTaiyuan3194170

    例如,考虑下表1包含的数据,表1包含了在Wikipedia编辑而产生的数据。每当用户编辑一个Wikipedia的页面的时候,就会产生一条关于编辑的包含了元数据的事件数据,这个元数据包含了3个不同的部分。首先,有一个timestamp列指示编辑的时间。然后,还有一组维度列(dimension)表明关于编辑的各种属性,例如被编辑的页面、由谁编辑的、编辑用户的位置。最后,还有一组包含值的(通常是数字)、可以被聚合计算的指标列(metric),例如在编辑中添加或删除的字符个数。

    我们的目标是在这个数据之上做快速的钻取(drill-downs)和聚合计算,我们希望回答之如“编辑贾斯汀·比伯这个页面的编辑者中有多少是来自于旧金山的男性?” 和 “最近一个月中由来自于Calgary的人添加的平均字符数是多少?”。我们也希望可以以任意组合维度来查询并在秒级以内返回数据。

    之所以需要Druid,是因为现实情况是现有的开源关系型数据库(RDBMS)和NoSQL key/value 数据库没办法为一些交互式应用提供低延迟的数据导入和查询。在Metamarkets的早期,我们的重点是建立一个托管的仪表板,允许用户以可视化的方式任意地去浏览事件流数据。支撑这个仪表板的数据存储需要以足够快的速度返回查询结果,在这之上的数据可视化才可以给用户提供良好的用户体验。

    除了查询响应时间的要求外,该系统还必须是多租户和高可用的。Metamarkets的产品是用于高并发的环境中,停机成本是昂贵的,而且许多企业都没法承受系统不可用时的等待,即便是软件升级或者是网络故障。停机时间于创业公司来说,特别是那些缺乏适当的内部运维管理的,是可以决定一个公司的成败的。

    最后,另外一个Metamarkets成立之初面临的一个挑战是允许用户和报警系统可以“实时”地做商业决策。从一个事件数据被创建,到这个事件数据可以被查询的时间,决定了利益相关方能够在他们的系统出现潜在灾难性情况时多快做出反应。流行的开源数据仓库系统,例如Hadoop,并不能达到我们所需要的秒级的数据导入和查询的要求。

    数据导入、分析和可用性这些问题存在于多个行业中,自从Druid在2012年10月开源以来,它被作为视频、网络监控,运营监控和广告分析平台部署到多家公司。

    3. 架构

    一个Druid集群包含不同类型的节点,而每种节点都被设计来做好某组事情。我们相信这样的设计可以隔离关注并简化整个系统的复杂度。不同节点的运转几乎都是独立的并且和其他的节点有着最小化的交互,因此集群内的通信故障对于数据可用性的影响微乎其微。

    为了解决复杂的数据分析问题,把不同类型的节点组合在一起,就形成了一个完整的系统。Druid这个名字来自于Druid类的角色扮演游戏。Druid集群的构成和数据流向如图1所示。

    图1. Druid集群概览和内部数据流向

    3.1 实时节点

    实时节点封装了导入和查询事件数据的功能,经由这些节点导入的事件数据可以立刻被查询。实时节点只关心一小段时间内的事件数据,并定期把这段时间内收集的这批不可变事件数据导入到Druid集群里面另外一个专门负责处理不可变的批量数据的节点中去。实时节点通过Zookeeper的协调和Druid集群的其他节点协调工作。实时节点通过Zookeeper来宣布他们的在线状态和他们提供的数据。

    实时节点为所有传入的事件数据维持一个内存中的索引缓存。随着事件数据的传入,这些索引会逐步递增,并且这些索引是可以立即查询的。查询这些缓存于JVM的基于堆的缓存中的事件数据,Druid就表现得和行存储一样。为了避免堆溢出问题,实时节点会定期地、或者在达到设定的最大行限制的时候,把内存中的索引持久化到磁盘去。这个持久化进程会把保存于内存缓存中的数据转换为基于列存储的格式,这个行存储相关的会在第4节介绍。所有持久化的索引都是不可变的,并且实时节点会加载这些索引到off-heap内存中使得它们可以继续被查询。这个过程会在【33】引用文献中详细说明并且如图2所示。

    图2. 实时节点缓存事件数据到内存中的索引上,然后有规律的持久化到磁盘上。在转移之前,持久化的索引会周期性地合并在一起。查询会同时命中内存中的和已持久化的索引。

    所有的实时节点都会周期性的启动后台的计划任务搜索本地的持久化索引,后台计划任务将这些持久化的索引合并到一起并生成一块不可变的数据,这些数据块包含了一段时间内的所有已经由实时节点导入的事件数据,我们称这些数据块为"Segment"。在传送阶段,实时节点将这些segment上传到一个永久持久化的备份存储中,通常是一个分布式文件系统,例如S3或者HDFS,Druid称之为"Deep Storage"。导入、持久化、合并和传送这些阶段都是流动的,并且在这些处理阶段中不会有任何数据的丢失。

    图3. 节点开始、导入数据、持久化与定期传送数据。这些处理进程无限循环。不同的实时节点处理流程间的时间是可配置的。

    图3说明了实时节点的各个处理流程。节点启动于 13:47 ,并且只会接受当前小时和下一小时的事件数据。当事件数据开始导入后,节点会宣布它为 13:00 到 14:00这个时间段的Segment数据提供服务。每10分钟(这个时间间隔是可配置的),节点会将内存中的缓存数据刷到磁盘中进行持久化,在当前小时快结束的时候,节点会准备接收 14:00 到 15:00 的事件数据,一旦这个情况发生了,节点会准备好为下一个小时提供服务,并且会建立一个新的内存中的索引。随后,节点宣布它也为 14:00 到 15:00 这个时段提供一个segment服务。节点并不是马上就合并 13:00 到 14:00 这个时段的持久化索引,而是会等待一个可配置的窗口时间,直到所有的 13:00 到 14:00 这个时间段的一些延迟数据的到来。这个窗口期的时间将事件数据因延迟而导致的数据丢失减低到最小。在窗口期结束时,节点会合并 13:00 到 14:00 这个时段的所有持久化的索引合并到一个独立的不可变的segment中,并将这个segment传送走,一旦这个segment在Druid集群中的其他地方加载了并可以查询了,实时节点会刷新它收集的 13:00 到 14:00 这个时段的数据的信息,并且宣布取消为这些数据提供服务。

    3.1.1 可用性与可扩展性

    实时节点是一个数据的消费者,需要有相应的生产商为其提供数据流。通常,为了数据耐久性的目的,会在生产商与实时节点间放置一个类似于Kafka这样的消息总线来进行连接,如图4所示。实时节点通过从消息总线上读取事件数据来进行数据的导入。从事件数据的创建到事件数据被消费掉通常是在几百毫秒这个级别。

    图4. 多个实时节点可以从同一个消息总线进行读取。每个节点维护自身的偏移量

    图4中消息总线的作用有两个。首先,消息总线作为传入数据的缓冲区。类似于Kafka这样的消息总线会维持一个指示当前消费者(实时节点)从事件数据流中已经读取数据的位置偏移量,消费者可以通过编程的方式更新偏移量。实时节点每次持久化内存中的缓存到磁盘的时候,都会更新这个偏移量。在节点挂掉和恢复的情况下,如果节点没有丢失磁盘数据,节点可以重新加载磁盘中所有持久化的索引数据,并从最后一次提交的偏移位置开始继续读取事件数据。从最近提交的偏移位置恢复数据大大减少了数据的恢复时间,在实践中,我们可以看到节点从故障中恢复仅用了几秒钟时间。

    消息总线的另外一个目的就是可以让多个实时节点可以从同一个单一的端点读取数据。多个实时节点可以从数据总线导入同一组数据,为数据创建一个副本。这样当一个节点完全挂掉并且磁盘上的数据也丢失了,副本可以确保不会丢失任何数据。统一的单一的数据导入端点也允许对数据进行分片,这样多个实时节点时每个节点就可以只导入一部分的数据,这允许无缝地进行实时节点的添加。在实践中,这个模型已经让一个生产环境中最大的Druid集群消费原始数据的速度大约达到500MB/S(150,000条/秒 或者 2TB/小时)。

    3.2 历史节点

    历史节点封装了加载和处理由实时节点创建的不可变数据块(segment)的功能。在很多现实世界的工作流程中,大部分导入到Druid集群中的数据都是不可变的,因此,历史节点通常是Druid集群中的主要工作组件。历史节点遵循 shared-nothing 的架构,因此节点间没有单点问题。节点间是相互独立的并且提供的服务也是简单的,它们只需要知道如果加载、删除和处理不可变的segment。

    类似于实时节点,历史节点在Zookeeper中通告它们的在线状态和为哪些数据提供服务。加载和删除segment的指令会通过Zookeeper来进行发布,指令会包含segment保存在deep storage的什么地方和怎么解压、处理这些segment的相关信息。在历史节点从deep storage下载某一segment之前,它会先检查本地缓存信息中看segment是否已经存在于节点中,如果segment还不存在缓存中,历史节点会从deep storage中下载segment到本地。这个处理过程如图5所示,一旦处理完成,这个segment就会在Zookeeper中进行通告。此时,这个segment就可以被查询了。历史节点的本地缓存也支持历史节点的快速更新和重启,在启动的时候,该节点会检查它的缓存,并为任何它找到的数据立刻进行服务的提供。

    图5. 历史节点从deep storage下载不可变的segment。segment在可以被查询之前必须要先加载到内存中

    历史节点可以支持读一致性,因为它们只处理不可变的数据。不可变的数据块同时支持一个简单的并行模型:历史节点可以以非阻塞的方式并发地去扫描和聚合不可变的数据块。

    3.2.1 Tiers

    历史节点可以分组到不同的tier中,哪些节点会被分到一个tier中是可配置的。可以为不同的tier配置不同的性能和容错参数。Tier的目的是可以根据segment的重要程度来分配高或低的优先级来进行数据的分布。例如,可以使用一批很多个核的CPU和大容量内存的节点来组成一个“热点数据”的tier,这个“热点数据”集群可以配置来用于下载更多经常被查询的数据。一个类似的"冷数据"集群可以使用一些性能要差一些的硬件来创建,“冷数据”集群可以只包含一些不是经常访问的segment。

    3.2.2 可用性

    历史节点依赖于Zookeeper来管理segment的加载和卸载。如果Zookeeper变得不可用的时候,历史节点就不再可以为新的数据提供服务和卸载过期的数据,因为是通过HTTP来为查询提供服务的,对于那些查询它当前已经在提供服务的数据,历史节点仍然可以进行响应。这意味着Zookeeper运行故障时不会影响那些已经存在于历史节点的数据的可用性。

    3.3 Broker节点

    Broker节点扮演着历史节点和实时节点的查询路由的角色。Broker节点知道发布于Zookeeper中的关于哪些segment是可查询的和这些segment是保存在哪里的,Broker节点就可以将到来的查询请求路由到正确的历史节点或者是实时节点,Broker节点也会将历史节点和实时节点的局部结果进行合并,然后返回最终的合并后的结果给调用者。

    3.3.1 缓存

    Broker节点包含一个支持 LRU 失效策略的缓存。这个缓存可以使用本地堆内存或者是一个外部的分布式 key/value 存储,例如 Memcached 。每次Broker节点接收到查询请求时,都会先将查询映射到一组segment中去。这一组确定的segment的结果可能已经存在于缓存中,而不需要重新计算。对于那些不存在于缓存的结果,Broker节点会将查询转发到正确的历史节点和实时节点中去,一旦历史节点返回结果,Broker节点会将这些结果缓存起来以供以后使用,这个过程如图6所示。实时数据永远不会被缓存,因此查询实时节点的数据的查询请求总是会被转发到实时节点上去。实时数据是不断变化的,因此缓存实时数据是不可靠的。

    图6. 结果会为每一个segment缓存。查询会合并缓存结果与历史节点和实时节点的计算结果

    缓存也可作为数据可用性的附加级别。在所有历史节点都出现故障的情况下,对于那些命中已经在缓存中缓存了结果的查询,仍然是可以返回查询结果的。

    3.3.2 可用性

    在所有的Zookeeper都中断的情况下,数据仍然是可以查询的。如果Broker节点不可以和Zookeeper进行通信了,它会使用它最后一次得到的整个集群的视图来继续将查询请求转发到历史节点和实时节点,Broker节点假定集群的结构和Zookeeper中断前是一致的。在实践中,在我们诊断Zookeeper的故障的时候,这种可用性模型使得Druid集群可以继续提供查询服务,为我们争取了更多的时间。

    3.4 协调节点

    Druid的协调节点主要负责数据的管理和在历史节点上的分布。协调节点告诉历史节点加载新数据、卸载过期数据、复制数据、和为了负载均衡移动数据。Druid为了维持稳定的视图,使用一个多版本的并发控制交换协议来管理不可变的segment。如果任何不可变的segment包含的数据已经被新的segment完全淘汰了,则过期的segment会从集群中卸载掉。协调节点会经历一个leader选举的过程,来决定由一个独立的节点来执行协调功能,其余的协调节点则作为冗余备份节点。

    协调节点会周期性的执行,以确定集群的当前状态。它通过在运行的时候对比集群的预期状态和集群的实际状态来做决定。和所有的Druid节点一样,协调节点维持一个和Zookeeper的连接来获取当前集群的信息。同时协调节点也维持一个与MySQL数据库的连接,MySQL包含有更多的操作参数和配置信息。其中一个存在于MySQL的关键信息就是历史节点可以提供服务的所有segment的一个清单,这个表可以由任何可以创建segment的服务进行更新,例如实时节点。MySQL数据库中还包含一个Rule表来控制集群中segment的是如何创建、销毁和复制。

    3.4.1 Rules

    Rules管理历史segment是如何在集群中加载和卸载的。Rules指示segment应该如何分配到不同的历史节点tier中,每一个tier中应该保存多少份segment的副本。Rules还可能指示segment何时应该从集群中完全地卸载。Rules通常设定为一段时间,例如,一个用户可能使用Rules来将最近一个月的有价值的segment载入到一个“热点数据”的集群中,最近一年的有价值的数据载入到一个“冷数据”的集群中,而将更早时间前的数据都卸载掉。

    协调节点从MySQL数据库中的rule表加载一组rules。Rules可能被指定到一个特定的数据源,或者配置一组默认的rules。协调节点会循环所有可用segment并会匹配第一条适用于它的rule。

    3.4.2 负载均衡

    在典型的生产环境中,查询通常命中数打甚至上百个segment,由于每个历史节点的资源是有限的,segment必须被分布到整个集群中,以确保集群的负载不会过于不平衡。要确定最佳的负载分布,需要对查询模式和速度有一定的了解。通常,查询会覆盖一个独立数据源中最近的一段邻近时间的一批segment。平均来说,查询更小的segment则更快。

    这些查询模式提出以更高的比率对历史segment进行复制,把大的segment以时间相近的形式分散到多个不同的历史节点中,并且使存在于不同数据源的segment集中在一起。为了使集群中segment达到最佳的分布和均衡,我们根据segment的数据源、新旧程度、和大小,开发了一个基于成本的优化程序。该算法的具体细节超出了本文的范畴,我们可能会在将来的文献中进行讨论。

    3.4.3 副本/复制(Replication)

    协调节点可能会告诉不同的历史节点加载同一个segment的副本。每一个历史节点tier中副本的数量是完全可配置。设置一个高级别容错性的集群可以设置一个比较高数量的副本数。segment的副本被视为和原始segment一样的,并使用相同的负载均衡算法。通过复制segment,单一历史节点故障对于整个Druid集群来说是透明的,不会有任何影响。我们使用这个特性来进行软件升级。我们可以无缝地将一个历史节点下线,更新它,再启动回来,然后将这个过程在集群中所有历史节点上重复。在过去的两年中,我们的Druid集群从来没有因为软件升级而出现过停机。

    3.4.4 可用性

    Druid的协调节点有Zookeeper和MySQL这两个额外的依赖,协调节点依赖Zookeeper来确定集群中有哪些历史节点。如果Zookeeper变为不可用,协调节点将不可以再进行segment的分配、均衡和卸载指令的发送。不过,这些都不会影响数据的可用性。

    对于MySQL和Zookeeper响应失效的设计原则是一致的:如果协调节点一个额外的依赖响应失败了,集群会维持现状。Druid使用MySQL来存储操作管理信息和关于segment如何存在于集群中的segment元数据。如果MySQL下线了,这些信息就在协调节点中变得不可用,不过这不代表数据不可用。如果协调节点不可以和MySQL进行通信,他们会停止分配新的segment和卸载过期的segment。在MySQL故障期间Broker节点、历史节点、实时节点都是仍然可以查询的。

    4. 存储格式

    Druid中的数据表(称为数据源)是一个时间序列事件数据的集合,并分割到一组segment中,而每一个segment通常是0.5-1千万行。在形式上,我们定义一个segment为跨越一段时间的数据行的集合。Segment是Druid里面的基本存储单元,复制和分布都是在segment基础之上进行的。

    Druid总是需要一个时间戳的列来作为简化数据分布策略、数据保持策略、与第一级查询剪支(first-level query pruning)的方法。Druid分隔它的数据源到明确定义的时间间隔中,通常是一个小时或者一天,或者进一步的根据其他列的值来进行分隔,以达到期望的segment大小。segment分隔的时间粒度是一个数据大小和时间范围的函数。一个超过一年的数据集最好按天分隔,而一个超过一天的数据集则最好按小时分隔。

    Segment是由一个数据源标识符、数据的时间范围、和一个新segment创建时自增的版本字符串来组合起来作为唯一标识符。版本字符串表明了segment的新旧程度,高版本号的segment的数据比低版本号的segment的数据要新。这些segment的元数据用于系统的并发控制,读操作总是读取特定时间范围内有最新版本标识符的那些segment。

    Druid的segment存储在一个面向列的存储中。由于Druid是适用于聚合计算事件数据流(所有的数据进入到Druid中都必须有一个时间戳),使用列式来存储聚合信息比使用行存储更好这个是 有据可查 的。列式存储可以有更好的CPU利用率,只需加载和扫描那些它真正需要的数据。而基于行的存储,在一个聚合计算中相关行中所有列都必须被扫描,这些附加的扫描时间会引起性能恶化。

    Druid有多种列类型来表示不同的数据格式。根据列的类型,会使用不同的压缩算法来降低一个列存储在内存和磁盘的成本。在表1提供的示例中,page, user, gender, 和 city 列都只包含字符串,直接存储字符串的成本很高而且没有必要,可以使用字典编码(Dictionary encoding)来代替。字典编码是一个常用的数据压缩算法,也已经用在类似 PowerDrill 这样的数据存储上。在表1的示例中,我们可以将每一个page映射到一个唯一的整数标识符上。

    Justin Bieber -> 0
    Ke$ha -> 1
    

    这个映射关系允许我们使用一个整数数组来表示page列,这个数组索引了原始数据集的相应的行。对于page列,我们可以用以下的方式来表示:

    [0, 0, 1, 1]
    

    这个整数数组结果使得它可以很好的应用压缩算法。在编码的基础上使用常用的压缩算法在列式存储中很常见。Druid使用的 LZF 压缩算法。类似的压缩算法也可以应用于数字列,例如,表1中增加的字符数和删除的字符数这两列也可以使用独立的数组来表示:

    Characters Added   -> [1800, 2912, 1953, 3194]
    Characters Removed -> [25, 42, 17, 170]
    

    在这种情况下,我们以和它们字典描述相反的方式来压缩这些原始值。

    4.1 索引过滤数据

    In many real world OLAP workflows, queries are issued for the aggregated results of some set of metrics where some set of di- mension specifications are met. An example query is: “How many Wikipedia edits were done by users in San Francisco who are also male?” This query is filtering the Wikipedia data set in Table 1 based on a Boolean expression of dimension values. In many real world data sets, dimension columns contain strings and metric columns contain numeric values. Druid creates additional lookup indices for string columns such that only those rows that pertain to a particular query filter are ever scanned. Let us consider the page column in Table 1. For each unique page in Table 1, we can form some representation indicating in which table rows a particular page is seen. We can store this information in a binary array where the array indices represent our rows. If a particular page is seen in a certain row, that array index is marked as 1. For example:

    Justin Bieber -> rows [0, 1] -> [1][1][0][0]
    Ke$ha         -> rows [2, 3] -> [0][0][1][1]
    

    Justin Bieber is seen in rows 0 and 1. This mapping of col- umn values to row indices forms an inverted index [39]. To know whichrowscontainJustin BieberorKe$ha,wecanORtogether the two arrays.

    [0][1][0][1] OR [1][0][1][0] = [1][1][1][1]
    

    This approach of performing Boolean operations on large bitmap sets is commonly used in search engines. Bitmap indices for OLAP workloads is described in detail in [32]. Bitmap compression al- gorithms are a well-defined area of research [2, 44, 42] and often utilize run-length encoding. Druid opted to use the Concise algo- rithm [10]. Figure 7 illustrates the number of bytes using Concise compression versus using an integer array. The results were gen- erated on a cc2.8xlarge system with a single thread, 2G heap, 512m young gen, and a forced GC between each run. The data set is a single day’s worth of data collected from the Twitter garden hose [41] data stream. The data set contains 2,272,295 rows and 12 dimensions of varying cardinality. As an additional comparison, we also resorted the data set rows to maximize compression.

    图7. Integer array size versus Concise set size.

    In the unsorted case, the total Concise size was 53,451,144 bytes and the total integer array size was 127,248,520 bytes. Overall, Concise compressed sets are about 42% smaller than integer ar- rays. In the sorted case, the total Concise compressed size was 43,832,884 bytes and the total integer array size was 127,248,520 bytes. What is interesting to note is that after sorting, global com- pression only increased minimally.

    4.2 Storage Engine

    Druid的持久化组件允许不同的存储引擎以插件的方式接入,类似于 Dynamo 。这些存储引擎可以将数据存储在一个完全的in-memory结构的引擎中,例如JVM heap,或者是存储于 memory-mapped 结构的存储中。Druid中存储引擎可配置更换的这个能力依赖于一个特定的应用规范。一个in-memory的存储引擎要比memory-mapped存储引擎的成本昂贵得多,但是如果对于性能特别敏感的话,in-memory存储引擎则是更好的选择。默认情况下使用的是memory-mapped存储引擎。

    当使用一个memory-mapped存储引擎的时候,Druid依赖于操作系统来对segment在内存中进行换入和换出操作。因为只有当segment加载到内存中了才可以被查询,所以memory-mapped存储引擎允许将最近的segment保留在内存中,而那些不会再被查询的segment则被换出。使用memory-mapped的主要缺点是当一个查询需要更多的segment并且已经超出了节点的内存容量时,在这种情况下,查询性能将会因为不断的在在内存中进行segment的换入和换出而下降。


    展开全文
  • 国外数据平台统计分析sdk

    千次阅读 2020-02-04 22:01:04
    1.Appsee 2.Mixpanel 3.Google Mobile Analytics 4.Countly 5.Flurry 6.Localytics 7.Yandex.Metrica 8.Distimo 9.AppFigures ...国外的统计有: Flurry(https://developer.yahoo.com) ...
  • 运用文献研究、逻辑分析等方法对当前关于中国青少年健康相关行为的研究文献进行梳理,对青少年健康行为调查指标的选择及特点进行分析,多视角探讨大中小学生健康行为特点,为进一步做好青少年健康促进工作提供理论...
  • 出门在外,被问得最多的问题就是“应用开发者为啥要用TalkingData的统计分析,自己做不行吗,看起来很简单啊”。每当这时,我就觉得万般辛酸,内牛满面,在做统计分析平台的过程中遇到的无数坑,骑着羊驼在脑海呼啸...
  • 出门在外,被问得最多的问题就是“应用开发者为啥要用TalkingData的统计分析,自己做不行吗,看起来很简单啊”。每当这时,我就觉得万般辛酸,内牛满面,在做统计分析平台的过程中遇到的无数坑,骑着羊驼在脑海呼啸...
  • 摘要:使用R搭建统计分析服务器,Java通过TCP/IP协议来与R服务器交互,输入分析数据及参数,获得统计分析结果。 步骤: 1. 搭建Rserve服务器,从而可以监听统计分析请求 参考文章:R与JAVA的整合 ...
  • 高校科技统计工作是科研管理制度化、科学化、规范化的基础,科技统计的目的在于应用,是了解过去,掌控现状,规划未来。...因此,做好高校科技统计工作对提高高校科研管理水平和可持续发展具有重要作用。
  • 一般来说,是需要制定市场研究的计划、明确数据的来源、明确抽样方案、明确数据采集方法、做好数据处理分析工作这四项工作。 1.制定市场调研的计划 在进行数据分析之前,数据采集工作是一项最重要的工作,数据采集的...
  • 基于Python的科研统计系统设计*郭丽蓉【摘要】本文从学院实际需求为出发点,设计了基于Python的科研论文统计分析系统。从数据采集、数据统计分析、数据可视化等功能模块做了详细的流程描述及图文分析。通过系统使用...
  • 数据统计埋点工作框架及细节规范

    千次阅读 2019-08-09 21:56:15
    明确定位与工作重心 数据产品经理是让数据产生价值(决策、增长、收入)的设计者、实现者和推行者。如何理解这样的定位呢? 首先,最基础的是要熟悉数据工具平台与产品业务,其次,要学会逐步建立产品完整的数据...
  •  二、做好门诊工作统计分析,每日在巡视门诊各科室中,发现问题及时通知领导、医务科、科主任,共同商榷,及时解决。各门诊按 时开门,不得迟到、早退、脱岗、串岗,不让病人找医生,每日查岗 记录登记清楚,月底...
  • 如何做好数据分析

    千次阅读 2019-04-30 12:02:18
    专业一点讲:数据分析就是适当的统计分析方法对收集来的大量数据进行分析,将他们加以汇总、理解和消化,以求最大化的开发数据的功能,发挥数据的作用。 那么,我们做数据 分析的目的是什么呢? 事实上,数据分析...
  • 高校科技统计工作是科研管理制度化、科学化、规范化的基础,科技统计的目的在于应用,是了解过去,掌控现状,规划未来。...因此,做好高校科技统计工作对提高高校科研管理水平和可持续发展具有重要作用。
  • 还在担心没工作岗位么,爬取271W条数据,开发了一个大数据分析平台,为你做精准分析
  • EXCEL在水质监测分析工作中的应用

    千次阅读 2009-08-13 09:54:00
    摘 要:Excel在水质计算方面的应用广泛,包括监测数据的计算、成果的评价和水环境监测质量控制工作的计算措施,有效地保证了监测数据在分析中的及时性和可靠性,从而使日常工作规范化,达到水质监测表格的通用性和...
  • 数据分析是面向大量数据,运用相应的统计分析方法,从中提取有用信息从而形成结论的一个过程。数据分析的作用很大,它可以科学地帮助人们制定恰当的策略。 对于正在从事数据分析工作的人们来说,却也是苦乐交加。...
  • 自从BDP个人版能够对接百度统计之后,小莉就能实时轻松获取网站的流量数据。而且在BDP中,小莉只需轻松点击鼠标就可以将多个平台的数据进行关联分析,不仅能够自动获取最新数据,还能够深度分析网站数据~
  • 年终将至,不少人都在赶自己的年终报告吧? 身边有这样一位财务的朋友向我吐槽: ...工作量大,基础工作得有人做,重复工作多,尾大不掉,根本没有时间做分析。自己尝试做过费用、生产利用率分析,但因...
  • 经营分析工作总结(转贴)

    千次阅读 2008-10-24 07:48:00
    有次我们做经营分析系统的操作培训完后,酒席上一位地市分公司的负责人说了一句“你们经营分析系统搞了这么久,不就是一个复杂的报表系统么 ? ”。 的确,他说的是实话,一个复杂的报表系统的确是数据仓库应用的...
  •  我们先来看搜索引擎的主要工作:页面收录、页面分析、页面排序及关键字查询。搜索引擎的工作流程是:页面收录——页面分析——页面排序——关键字查询。  一、搜索引擎工作原理——页面收录  第一
  • 4个关键,如何清晰的做好数据分析

    千次阅读 2017-07-10 09:45:43
    数据分析就近几年看来,越来越有一种像通用技能发展的趋势,从生产、研发、市场、销售到运营,多多少会存在数据分析的需求。关于数据分析,网络上有不少分析报告案例,但细细读来,好多都缺少辨证,逻辑不严谨,又...
  • 输出结果美观漂亮,它使用Windows的窗口方式展示各种管理和分析数据方法的功能,使用对话框展示出各种功能选择项,只要掌握一定的Windows操作技能,粗通统计分析原理,就可以使用该软件为特定的科研工作服务。...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 44,159
精华内容 17,663
关键字:

如何做好统计分析工作