Alink漫谈(二十) :卡方检验源码解析

Alink漫谈(二十) :卡方检验源码解析

0x00 摘要

Alink 是阿里巴巴基于实时计算引擎 Flink 研发的新一代机器学习算法平台,是业界首个同时支持批式算法、流式算法的机器学习平台。本文将带领大家来分析 Alink 中 卡方检验 的实现。

因为Alink的公开资料太少,所以以下均为自行揣测,肯定会有疏漏错误,希望大家指出,我会随时更新。

0x01 背景概念

问题:在南方的小明要去北京读书,小明的父母都担心起来,北方的生活能习惯吗?是不是只能吃面?他们的脑子里面提出了很多很多的假设,是不是都要验证一下呢。

1.1 假设检验

统计假设是指我们对总体的猜测或判断,比如中国广为流行的地域划分,北方人是不是都吃面食?江浙是不是都喜欢吃甜食?江南的妹子是不是脾气都很好?北方的男生是不是都大条?

为了证明,或者说绝对确定某个假设是正确或错误的,我们需要绝对知识,也就是说我们需要检查所有的样本,比如问问所有的北方人是不是都吃面食,或者说问问江浙一带的女生是不是都不吵架?

但是我们无法把所有样本都统计一遍

假设检验就是为了解决这个问题而诞生的,它使用随机的样本来判断假设是否有理

这来源于一个最基本的思路,那就是统计是从有限样本推断总体。既然我们不可能知道所有样本,换句话说我们不可能知道总体到底是什么统计性质,那么我们只能拿有限的样本做文章。

假设检验依据的原理是小概率事件原理。小概率事件是一个事件的发生概率,由于概率小,它在一次试验中是几乎不可能发生的。例如,拿我们生活的经验来说,只买一次彩票就中大奖的几率是很小的,所以还没看到过偶尔买彩票就中大奖的报道。

1.2 H0和H1是什么?

小明父母的种种假设到底对不对呢?对是一种结果,不对是另一种结果。在假设检验中,我们也有两部分,一部分叫做H0,一部分是H1。

H是英文单词hypothesis的第一个字母,H0代表了原假设(null hypothesis),H1是备择假设(alternative hypothesis)。换句话说,我们想在两个假设中选一个,尽管这个“选”不是通常意义下的“二选一”。

  • H0 原假设又叫零假设,一般来说,我们把认为想收集证据反对的假设称为0假设,比如太阳绕着地球转,鸟是不会飞的。小明这里的 H0 就是 “北方不吃米饭”,是小明父母不希望,想拒绝的。
  • H1又叫备选假设,一般来说,我们都希望备选假设,也就是H1为真,比如小明的父母希望北方也是吃饭的。

H0和H1并不是不能互换,但是选取的H0原则是H0必须是一个可以被拒绝的假设。对于一个假设检验问题,如果H1是一个不能被拒绝的假设,那么H0和H1不能互换。

什么样的H1是不能被拒绝的假设?比如下面这个问题:总体是一个班级的所有同学一次的考试成绩,原假设H0是全班同学的平均成绩为80分,H1是全班同学的平均成绩不是80分。在这个框架中,H0是一个可以被拒绝的假设,H1是一个不能被拒绝的假设。

为什么这么说?如果H0选做全班同学的平均成绩不是80分,那么哪怕你知道全班几乎所有人的成绩,不妨认为平均是80分,只要有一个人的成绩你不知道,那么知道其他人的成绩对于你拒绝H0没有任何帮助。只有在这个人恰好80分的情况下,原假设是不成立的,这个人是81或者79,原假设都成立。从另一个角度,也可以认为当H0是一个不能被拒绝的假设的时候,H0太过宽泛,和H1区分不了。

一般来说,假设检验的结果有下面两个:

  • H0错,H1对(用专业的话来说,就是接受H1,拒绝H0,因为有足够多的样本支持H1,比如说小明爸妈问了5,6个到北方读书的人,都说食堂面和饭都有。他们大可以说,北方也是吃饭的)。
  • H1错(用专业的话说,不拒绝H0,因为证据不够。小明爸妈问了5个到北方读书的人,1个说食堂面和饭都有,那食堂到底有没有呢?心里可是直打鼓了。)

有一点要注意,无法拒绝H0并不是说H0为真,而是说我们的证据不足,无法证明H1。我们经常在法庭上听到,证据不足,无罪释放,但是,这个人到底有没有罪,还是要打个问号的。

1.3 P值 (P-value)

P值,也就是常见到的 P-value。P 值是一种概率,指的是在 H0 假设为真的前提下,样本结果出现的概率。即 p值是在原假设成立的基础上计算的

如果 P-value 很小,则说明在原假设为真的前提下,样本结果出现的概率很小,甚至很极端,这就反过来说明了原假设很大概率是错误的

另外一个角度想,p值也是弃真错误的概率。也就是这个假设成立的情况下,出现这个糟糕结果的概率,也当然就是如果此时把h0拒绝,出现错误的概率。只要p值足够小,我们就认为此时拒绝h0,出错的概率很小,那就干脆把h0拒绝好了。

通常,会设置一个显著性水平(significance level) alpha 与 P-value 进行比较,如果 P-value < alpha ,则说明在显著性水平 alpha 下拒绝原假设,alpha 通常情况下设置为0.05。

假如我们比较某地区男、女性的饮食口味是否存在差异,则 H0 是 "男女的饮食口味相同,不存在差异"。

最后得出 P=0.283 > 0.05,在α=0.05水平上不拒绝零假设,即不能认为该地区男女的饮食口味不同。

1.4 交叉表

在统计学中,交叉表是矩阵格式的一种表格,显示变量的(多变量)频率分布。

“交叉表”对象是一个网格,用来根据指定的条件返回值。数据显示在压缩行和列中。这种格式易于比较数据并辨别其趋势。它由三个元素组成:行 / 列 / 摘要字段。

让我们举例说明:

马军头领 步兵头领
二龙山 1 6
少华山 3 0
  • “交叉表”中的行沿水平方向延伸(从一侧到另一侧)。在上面的示例中,”二龙山” 是一行。
  • “交叉表”中的列沿垂直方向延伸(上下)。在上面的示例中,“马军头领” 是一列。
  • 汇总字段位于行和列的交叉处。每个交叉处的值代表对既满足行条件又满足列条件的记录的汇总(求和、计数等)。在上面的示例中,“二龙山”和“马军头领”交叉处的值是1,这是在二龙山上马军头领的数目。

上文中交叉表是按两个变量交叉分类的,该列联表称为两维列联表,若按3个变量交叉分类,所得的列联表称为3维列联表,依次类推。3维及以上的列联表通常称为“多维列联表”或“高维列联表”,而一维列联表就是频数分布表。

1.5 卡方

交叉分类所得的表格称为“列联表”,统计推断(检验)则要使用列联表分析的方法------卡方检验。

卡方检验,主要用于检验统计样本的实际观测值与理论推断值之间的偏离程度,或者是检验一批数据是否与某种理论分布相符合

Alink 文档中给出的是:卡方独立性检验是检验两个因素(各有两项或以上的分类)之间是否相互影响的问题,其零假设是两因素之间相互独立

1.5.1 公式

卡方值是卡方检验时用到的检验统计量,卡方值越大,说明观测值与理论值之间的偏离就越大;反之,二者偏差越小。实际应用时,可以根据卡方值计算 P-value,从而选择拒绝或者接受原假设。

公式如下:

\[X^2 = \sum\frac{(observed - expected)^2}{expected} \]

1.5.2 基本思想

卡方检验最基本的思想就是通过观察实际值与理论值的偏差来确定理论的正确与否。

具体做的时候常常先假设两个变量确实是独立的(行话就叫做“原假设”),然后观察实际值(也可以叫做观察值)与理论值(这个理论值是指“如果两者确实独立”的情况下应该有的值)的偏差程度。

  • 如果偏差足够小,我们就认为误差是很自然的样本误差,是测量手段不够精确导致或者偶然发生的,两者确确实实是独立的,此时就接受原假设。
  • 如果偏差大到一定程度,使得这样的误差不太可能是偶然产生或者测量不精确所致,我们就认为两者实际上是相关的,即否定原假设,而接受备择假设。

1.5.3 实现过程

卡方分析的方法:

  • 假设两个变量是相互独立,互不关联的。这在统计上称为原假设;
  • 对于调查中得到的两个变量的数据,用一个表格的形式来表示它们的分布(频数和百分数),这里的频数叫观测频数,这种表格叫列联表;
  • 如果原假设成立,在这个前提下,可以计算出上面列联表中每个格子里的频数应该是多少,这叫期望频数;
  • 比较观测频数与期望频数的差,如果两者的差越大,表明实际情况与原假设相去甚远;差越小,表明实际情况与原假设越相近。这种差值用一个卡方统计量来表示;
  • 对卡方值进行检验,如果卡方检验的结果不显著,则不能拒绝原假设,即两变量是相互独立、互不关联的,如果卡方检验的结果显著,则拒绝原假设,即两变量间存在某种关联,至于是如何关联的,这要看列联表中数据的分布形态。

具体实现过程:

  1. 按照假设检验的步骤,首先我们需要确定原假设 H0(null hypothesis):原假设是变量独立的,实际观测频率和理论频率一致。
  2. 其次我们根据实际观测的联连表,去求理论的联连表;卡方统计值:X2,记为Statistic;
  3. 然后选取适合的置信度(一般为95%)同自由度一起确定临界值Critical Value,比较卡方统计值和临界值大小:
    1. If Statistic >= Critical Value: 认为变量对结果有影响,则拒绝原假设,变量不独立
    2. If Statistic < Critical Value: 认为变量对结果没有影响,接受原假设,变量独立

1.6 自由度

自由度:取值不受限制的变量的个数。

如何理解这句简单的话呢?给定一组数据,我们来计算不同的统计量,看看自由度的变化。这些数据分别为 1 2 4 6 8. 5个数。

先来求平均值,这几个数据都可以任意变化成其它数据,而我们仍然可以对它们求平均值,它们的平均值也跟着变化。这时自由度为5,也就是说有几个数据自由度就是几。

卡方检验的自由度:

1)如果是独立性检验,那么自由度就等于(a-1)*(b-1),a b表示这两个检验条件的对应的分类数。

2)适合性检验,类别数减去1。此处相当于约束条件只有一个。

卡方检验只有在用笔算查表时使用自由度,软件计算不用担心这个问题,但是最好明白自由度代表着总的变量数目减去约束条件的数目。

0x02 示例代码

本文示例代码如下,这里需要注意的是:

  • "col1","col2"是所选择的列;
  • "col4"是Label;
public class ChiSquareTestBatchOpExample {
    public static void main(String[] args) throws Exception {
        Row[] testArray =
                new Row[]{
                        Row.of("a",1.1,1.2,1),Row.of("b",0.9,1.0,-2),Row.of("c",-0.01,100),Row.of("d",100.9,0.1,-99),Row.of("a",0.2,0.3,-99)
                };

        String[] colNames = new String[]{"col1","col2","col3","col4"};

        MemSourceBatchOp source = new MemSourceBatchOp(Arrays.asList(testArray),colNames);

        ChiSquareTestBatchOp test = new ChiSquareTestBatchOp()
                .setSelectedCols("col1","col2")
                .setLabelCol("col4");

        test.linkFrom(source).print();
    }
}

输出如下:

col|chisquare_test
---|--------------
col1|{"comment":"chi-square test","df":9.0,"p":0.004301310843500827,"value":24.0}
col2|{"comment":"chi-square test","value":24.0}

转换为图表更好理解:

col chisquare_test
col1 {"comment":"chi-square test","value":24.0}
col2 {"comment":"chi-square test","value":24.0}

df是自由度,p就是p-value, value就是我们前面说的卡方值,即

\[卡方值 = \sum\frac{(observed - expected)^2}{expected} \]

0x03 总体逻辑

训练总体逻辑如下:

  • 使用 flatMap 做 flatting data to triple。遍历输入Row,然后把Row给flat了,得到三元组<idx in row,value in row,y-label>。比如 对应输入 Row.of("b",-2),则row = {Row@9419} "b,9,-2",因为col1,col2是特征,col4是 label,则发送两个三元组是 <0,b,-2>,<1,-2>;
  • 使用 toTable 把前面处理的dataSet再进行转换,生成一张表 data。{"col","feature","label"} 就对应着我们之前的三元组;
  • 对 data 进行 计算交叉表 和 卡方校验;
    • groupBy("col,feature,label") 进行分类排序;
    • select("col,label,count(1) as count2")) 得出 feature 的个数作为count2;
    • groupBy("col").reduceGroup 再根据col排序,归并;
      • 得到 <feature,y-label> : "count of feature" 这个map;
      • Crosstab.convert(map) 利用map来做交叉表;
    • map(new ChiSquareTestFromCrossTable()) 利用交叉表来构建卡方检验;
      • test(crossTabWithId) 这里进行计算,其中会调用 org.apache.commons.math3.distribution.GammaDistribution.cumulativeProbability 进行Gamma计算;

0x04 训练

还是老套路,直奔ChiSquareTestBatchOp的linkFrom函数。

代码是缩减版,但原本就非常简单,获取“选择的列”和“Y列”,然后用输入数据进行训练检验。

深入看下去却很有难度。

public ChiSquareTestBatchOp linkFrom(BatchOperator<?>... inputs) {
    BatchOperator<?> in = checkAndGetFirst(inputs);
    String[] selectedColNames = getSelectedCols();
    String labelColName = getLabelCol();

    this.setOutputTable(ChiSquareTestUtil.buildResult(
        ChiSquareTestUtil.test(in,selectedColNames,labelColName),getMLEnvironmentId()));

    return this;
}

最后会辗转进入到 ChiSquareTest.test,这里才是真章。

public static DataSet<Row> test(BatchOperator in,String[] selectedColNames,String labelColName) {
    in = in.select(ArrayUtils.add(selectedColNames,labelColName));
    return ChiSquareTest.test(in.getDataSet(),in.getMLEnvironmentId());
}

4.1 ChiSquareTest

其test函数的输入输出是:

  • 输入:in 的最后一列是label,其余列是所选择的特征列;
  • 输出:有三列,分别是 1th is colId,2th is pValue,3th is chi-square value;

这里的总体逻辑是:

  • 使用 flatMap 做 flatting data to triple。遍历输入Row,然后把Row给flat了,得到三元组<idx in row,y-label>;
  • 使用 toTable 把前面处理的dataSet再进行转换,生成一张表 data。{"col","label"} 就对应着我们之前的三元组;
  • 对 data 进行 计算交叉表 和 卡方校验;

具体代码如下:

protected static DataSet<Row> test(DataSet<Row> in,Long sessionId) {
    //flatting data to triple.
    //这里就是遍历输入Row,然后把Row给flat了,得到三元组<idx in row,y-label>
    //比如 对应输入 Row.of("b",-2>
    DataSet<Row> dataSet = in
        .flatMap(new FlatMapFunction<Row,Row>() {
            @Override
            public void flatMap(Row row,Collector<Row> result) {
                int n = row.getArity() - 1;
                String nStr = String.valueOf(row.getField(n));
                for (int i = 0; i < n; i++) {
                    Row out = new Row(3);
                    out.setField(0,i);
                    out.setField(1,String.valueOf(row.getField(i)));
                    out.setField(2,nStr);
                    result.collect(out);
                }
            }
        });

  	// 把前面处理的dataSet再进行转换,生成一张表。{"col","label"} 就对应着我们之前的三元组
    Table data = DataSetConversionUtil.toTable(
        sessionId,dataSet,new String[]{"col","label"},new TypeInformation[]{Types.INT,Types.STRING,Types.STRING});


    // 对 data 进行 计算交叉表 和 卡方校验
    //calculate cross table  and chiSquare test.
    return DataSetConversionUtil.fromTable(sessionId,data
        .groupBy("col,label") //分类排序
        .select("col,count(1) as count2")) // 为了得出 feature 的个数作为count2
        .groupBy("col").reduceGroup( // 再根据col排序
            new GroupReduceFunction<Row,Tuple2<Integer,Crosstab>>() {
                @Override
                public void reduce(Iterable<Row> iterable,Collector<Tuple2<Integer,Crosstab>> collector) {
                    Map<Tuple2<String,String>,Long> map = new HashMap<>();
                    int colIdx = -1;
                    for (Row row : iterable) {
            
// 假如有如下,row = {Row@9684} "0,a,1,2",他对应了两个 Row.of("a",就是 <col,count(1)>,就是 <'a'是第0列,'a',对应 y-label是 1, 'a' 有两个>
                      
                        map.put(Tuple2.of(row.getField(1).toString(),row.getField(2).toString()),(long) row.getField(3));
                        colIdx = (Integer) row.getField(0);
                    }
                  
// 得到 <feature,y-label> : "count of feature" 这个map
map = {HashMap@9676}  size = 4
 {Tuple2@9688} "(a,1)" -> {Long@9689} 2
 {Tuple2@9690} "(b,-2)" -> {Long@9689} 2
 {Tuple2@9691} "(d,-99)" -> {Long@9689} 2
 {Tuple2@9692} "(c,100)" -> {Long@9689} 2                   
                  
                    // 利用map来做交叉表
                    collector.collect(new Tuple2<>(colIdx,Crosstab.convert(map)));
                }
            })
        .map(new ChiSquareTestFromCrossTable()); // 构建卡方检验
}

4.2 Crosstab

上面代码中,使用 collector.collect(new Tuple2<>(colIdx,Crosstab.convert(map))); 来构建交叉表。

Crosstab 就是 Cross Tabulations reflects the relationship between two variables。即以map key为横轴,纵轴,value作为数值,就是feature和label之间的交叉。

public static Crosstab convert(Map<Tuple2<String,Long> maps) {
 
    Crosstab crosstab = new Crosstab();

    //get row tags and col tags
    Set<Tuple2<String,String>> sets = maps.keySet();

    Set<String> rowTags = new HashSet<>(); // 拿到行,列
    Set<String> colTags = new HashSet<>();
    for (Tuple2<String,String> tuple2 : sets) {
        rowTags.add(tuple2.f0);
        colTags.add(tuple2.f1);
    }

    crosstab.rowTags = new ArrayList<>(rowTags);
    crosstab.colTags = new ArrayList<>(colTags);

    int rowLen = crosstab.rowTags.size();
    int colLen = crosstab.colTags.size();

    //compute value
    crosstab.data = new long[rowLen][colLen];
    for (Map.Entry<Tuple2<String,Long> entry : maps.entrySet()) {
        int rowIdx = crosstab.rowTags.indexOf(entry.getKey().f0);
        int colIdx = crosstab.colTags.indexOf(entry.getKey().f1);
        crosstab.data[rowIdx][colIdx] = entry.getValue();
    }
    return crosstab;
}

这里输入输出如下

// 输入如下
maps = {HashMap@9676}  size = 4
 {Tuple2@9688} "(a,100)" -> {Long@9689} 2  

// 交叉表如下
crosstab = {Crosstab@9703} 
 colTags = {ArrayList@9720}  size = 4
  0 = "1"  1 = "100"  2 = "-2"  3 = "-99"
 rowTags = {ArrayList@9721}  size = 4
  0 = "a"  1 = "b"  2 = "c"  3 = "d"
data = {long[4][]@9713} 
 0 = {long[4]@9722}   0 = 2  1 = 0  2 = 0  3 = 0
 1 = {long[4]@9723}   0 = 0  1 = 0  2 = 2  3 = 0
 2 = {long[4]@9724}   0 = 0  1 = 2  2 = 0  3 = 0
 3 = {long[4]@9725}   0 = 0  1 = 0  2 = 0  3 = 2

构造出来交叉表如下:

1 100 -2 -99
a 2
b 2
c 2
d 2

4.3 构建卡方检验

4.1中,有 .map(new ChiSquareTestFromCrossTable()); ,这里就是根据collector.collect(new Tuple2<>(colIdx,Crosstab.convert(map)));交叉表构建卡方检验。

/**
 * calculate chi-square test value from cross table.
 */
public static class ChiSquareTestFromCrossTable implements MapFunction<Tuple2<Integer,Crosstab>,Row> {

    @Override
    public Row map(Tuple2<Integer,Crosstab> crossTabWithId) throws Exception {
        Tuple4 tuple4 = test(crossTabWithId);

      	// f0 is id of cross table,f1 is pValue,f2 is chi-square Value,f3 is df
        Row row = new Row(4);
        row.setField(0,tuple4.f0);
        row.setField(1,tuple4.f1);
        row.setField(2,tuple4.f2);
        row.setField(3,tuple4.f3);

        return row;
    }
}

test(crossTabWithId)是关键点,其中 distribution.cumulativeProbability 最后调用到 org.apache.commons.math3.distribution.GammaDistribution.cumulativeProbability。

这里能够看到

  • df 的定义就是 (double)(rowLen - 1) * (colLen - 1),即(行 - 1)*(列 - 1)
  • 卡方值就是严格按照定义来构建的。
  • p-value是 调用到 org.apache.commons.math3.distribution.GammaDistribution.cumulativeProbability。
/**
 * @param crossTabWithId: f0 is id,f1 is cross table
 * @return tuple4: f0 is id which is id of cross table,f3 is df
 */
protected static Tuple4<Integer,Double,Double> test(Tuple2<Integer,Crosstab> crossTabWithId) {
    int colIdx = crossTabWithId.f0;
    Crosstab crosstab = crossTabWithId.f1;

    int rowLen = crosstab.rowTags.size();
    int colLen = crosstab.colTags.size();

    //compute row sum and col sum 计算出列的数值和,行的数值和
    double[] rowSum = crosstab.rowSum(); 
    double[] colSum = crosstab.colSum();
    double n = crosstab.sum();


    //compute statistic value 计算统计值
    double chiSq = 0;
    for (int i = 0; i < rowLen; i++) {
        for (int j = 0; j < colLen; j++) {
            double nij = rowSum[i] * colSum[j] / n;
            double temp = crosstab.data[i][j] - nij;
            chiSq += temp * temp / nij; // 就是按照定义来构建卡方值
        }
    }

    //set result
    double p;
    if (rowLen <= 1 || colLen <= 1) {
        p = 1;
    } else {
        ChiSquaredDistribution distribution =
            new ChiSquaredDistribution(null,(rowLen - 1) * (colLen - 1));
        p = 1.0 - distribution.cumulativeProbability(Math.abs(chiSq));
    }

    // return tuple4: f0 is id which is id of cross table,f3 is df
    return Tuple4.of(colIdx,p,chiSq,(double)(rowLen - 1) * (colLen - 1));
}

// runtime是
tuple4 = {Tuple4@9842} "(0,0.004301310843500827,24.0,9.0)"
 f0 = {Integer@9843} 0
 f1 = {Double@9844} 0.004301310843500827
 f2 = {Double@9847} 24.0
 f3 = {Double@9848} 9.0

0xFF 参考

卡方检验(Chi_square_test): 原理及python实现

T检验、卡方检验以及p-value

卡方检验的自由度

交叉表和卡方检验

卡方检验值转换为P值

相似度计算和p-value

怎么来理解伽玛(gamma)分布?

Spark MLlib基本算法【相关性分析、卡方检验、总结器】

spark(1.1) mllib 源码分析(一)-卡方检验

交叉表和卡方检验

统计学中的H0和H1假设(1)

统计学中的H0,H1假设是怎么来的?为什么H0不是H1,H1不是H0呢?

统计学假设检验中 p 值的含义具体是什么?

卡方检验用于特征选择

卡方检验基础

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


文章浏览阅读5.3k次,点赞10次,收藏39次。本章详细写了mysql的安装,环境的搭建以及安装时常见的问题和解决办法。_mysql安装及配置超详细教程
文章浏览阅读1.8k次,点赞50次,收藏31次。本篇文章讲解Spark编程基础这门课程的期末大作业,主要围绕Hadoop基本操作、RDD编程、SparkSQL和SparkStreaming编程展开。_直接将第4题的计算结果保存到/user/root/lisi目录中lisipi文件里。
文章浏览阅读7.8k次,点赞9次,收藏34次。ES查询常用语法目录1. ElasticSearch之查询返回结果各字段含义2. match 查询3. term查询4. terms 查询5. range 范围6. 布尔查询6.1 filter加快查询效率的原因7. boosting query(提高查询)8. dis_max(最佳匹配查询)9. 分页10. 聚合查询【内含实际的demo】_es查询语法
文章浏览阅读928次,点赞27次,收藏18次。
文章浏览阅读1.1k次,点赞24次,收藏24次。作用描述分布式协调和一致性协调多个节点的活动,确保一致性和顺序。实现一致性、领导选举、集群管理等功能,确保系统的稳定和可靠性。高可用性和容错性Zookeeper是高可用的分布式系统,通过多个节点提供服务,容忍节点故障并自动进行主从切换。作为其他分布式系统的高可用组件,提供稳定的分布式协调和管理服务,保证系统的连续可用性。配置管理和动态更新作为配置中心,集中管理和分发配置信息。通过订阅机制,实现对配置的动态更新,以适应系统的变化和需求的变化。分布式锁和并发控制。
文章浏览阅读1.5k次,点赞26次,收藏29次。为贯彻执行集团数字化转型的需要,该知识库将公示集团组织内各产研团队不同角色成员的职务“职级”岗位的评定标准;
文章浏览阅读1.2k次,点赞26次,收藏28次。在安装Hadoop之前,需要进行以下准备工作:确认操作系统:Hadoop可以运行在多种操作系统上,包括Linux、Windows和Mac OS等。选择适合你的操作系统,并确保操作系统版本符合Hadoop的要求。安装Java环境:Hadoop是基于Java开发的,因此需要先安装和配置Java环境。确保已经安装了符合Hadoop版本要求的Java Development Kit (JDK),并设置好JAVA_HOME环境变量。确认硬件要求:Hadoop是一个分布式系统,因此需要多台计算机组成集群。
文章浏览阅读974次,点赞19次,收藏24次。# 基于大数据的K-means广告效果分析毕业设计 基于大数据的K-means广告效果分析。
文章浏览阅读1.7k次,点赞6次,收藏10次。Hadoop入门理论
文章浏览阅读1.3w次,点赞28次,收藏232次。通过博客和文献调研整理的一些农业病虫害数据集与算法。_病虫害数据集
文章浏览阅读699次,点赞22次,收藏7次。ZooKeeper使用的是Zab(ZooKeeper Atomic Broadcast)协议,其选举过程基于一种名为Fast Leader Election(FLE)的算法进行。:每个参与选举的ZooKeeper服务器称为一个“Follower”或“Candidate”,它们都有一个唯一的标识ID(通常是一个整数),并且都知道集群中其他服务器的ID。总之,ZooKeeper的选举机制确保了在任何时刻集群中只有一个Leader存在,并通过过半原则保证了即使部分服务器宕机也能维持高可用性和一致性。
文章浏览阅读10w+次,点赞62次,收藏73次。informatica 9.x是一款好用且功能强大的数据集成平台,主要进行各类数据库的管理操作,是使用相当广泛的一款ETL工具(注: ETL就是用来描述将数据从源端经过抽取(extract)、转换(transform)、加载(load)到目的端的过程)。本文主要为大家图文详细介绍Windows10下informatica powercenter 9.6.1安装与配置步骤。文章到这里就结束了,本人是在虚拟机中装了一套win10然后在此基础上测试安装的这些软件,因为工作学习要分开嘛哈哈哈。!!!!!_informatica客户端安装教程
文章浏览阅读7.8w次,点赞245次,收藏2.9k次。111个Python数据分析实战项目,代码已跑通,数据可下载_python数据分析项目案例
文章浏览阅读1.9k次,点赞61次,收藏64次。TDH企业级一站式大数据基础平台致力于帮助企业更全面、更便捷、更智能、更安全的加速数字化转型。通过数年时间的打磨创新,已帮助数千家行业客户利用大数据平台构建核心商业系统,加速商业创新。为了让大数据技术得到更广泛的使用与应用从而创造更高的价值,依托于TDH强大的技术底座,星环科技推出TDH社区版(Transwarp Data Hub Community Edition)版本,致力于为企业用户、高校师生、科研机构以及其他专业开发人员提供更轻量、更简单、更易用的数据分析开发环境,轻松应对各类人员数据分析需求。_星环tdh没有hive
文章浏览阅读836次,点赞21次,收藏19次。
文章浏览阅读1k次,点赞21次,收藏15次。主要介绍ETL相关工作的一些概念和需求点
文章浏览阅读1.4k次。本文以Android、java为开发技术,实现了一个基于Android的博物馆线上导览系统 app。基于Android的博物馆线上导览系统 app的主要使用者分为管理员和用户,app端:首页、菜谱信息、甜品信息、交流论坛、我的,管理员:首页、个人中心、用户管理、菜谱信息管理、菜谱分类管理、甜品信息管理、甜品分类管理、宣传广告管理、交流论坛、系统管理等功能。通过这些功能模块的设计,基本上实现了整个博物馆线上导览的过程。
文章浏览阅读897次,点赞19次,收藏26次。1.背景介绍在当今的数字时代,数据已经成为企业和组织中最宝贵的资源之一。随着互联网、移动互联网和物联网等技术的发展,数据的产生和收集速度也急剧增加。这些数据包括结构化数据(如数据库、 spreadsheet 等)和非结构化数据(如文本、图像、音频、视频等)。这些数据为企业和组织提供了更多的信息和见解,从而帮助他们做出更明智的决策。业务智能(Business Intelligence,BI)...
文章浏览阅读932次,点赞22次,收藏16次。也就是说,一个类应该对自己需要耦合或调用的类知道的最少,类与类之间的关系越密切,耦合度越大,那么类的变化对其耦合的类的影响也会越大,这也是我们面向对象设计的核心原则:低耦合,高内聚。优秀的架构和产品都是一步一步迭代出来的,用户量的不断增大,业务的扩展进行不断地迭代升级,最终演化成优秀的架构。其根本思想是强调了类的松耦合,类之间的耦合越弱,越有利于复用,一个处在弱耦合的类被修改,不会波及有关系的类。缓存,从操作系统到浏览器,从数据库到消息队列,从应用软件到操作系统,从操作系统到CPU,无处不在。
文章浏览阅读937次,点赞22次,收藏23次。大数据可视化是关于数据视觉表现形式的科学技术研究[9],将数据转换为图形或图像在屏幕上显示出来,并进行各种交互处理的理论、方法和技术。将数据直观地展现出来,以帮助人们理解数据,同时找出包含在海量数据中的规律或者信息,更多的为态势监控和综合决策服务。数据可视化是大数据生态链的最后一公里,也是用户最直接感知数据的环节。数据可视化系统并不是为了展示用户的已知的数据之间的规律,而是为了帮助用户通过认知数据,有新的发现,发现这些数据所反映的实质。大数据可视化的实施是一系列数据的转换过程。