1. 程式人生 > >【程式設計師眼中的統計學(12)】相關與迴歸:我的線條如何?

【程式設計師眼中的統計學(12)】相關與迴歸:我的線條如何?

作者 白寧超
2015年10月25日22:16:07

摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越來越重要。本系列統計學的學習基於《深入淺出統計學》一書(偏向程式碼實現,需要讀者有一定基礎,可以參見後面PPT學習)。正如(吳軍)先生在《數學之美》一書中闡述的,基於統計和數學模型對機器智慧發揮重大的作用。諸如:語音識別、詞性分析、機器翻譯等世界級的難題也是從統計中找到開啟成功之門鑰匙的。尤其是在自然語言處理方面更顯得重要,因此,對統計和數學建模的學習是尤為重要的。最後感謝團隊所有人的參與。(

)

 目錄

【程式設計師眼中的統計學(3)】概率計算:把握機會

【程式設計師眼中的統計學(11)】卡方分佈的應用

1 演算法的基本描述

1.1 演算法描述

為了瞭解兩個變數(自變數和因變數)之間的相關關係,利用線性迴歸法對二變數資料進行分析,得出最佳擬合線和相關係數,從而通過一個變數的值,估計推測另一個變數的值。

1.2 定義

假如有一個二變數資料分佈如下:

X

x1

x2

x3

x4

……

xn-2

xn-1

xn

Y

y1

y2

y3

y4

……

yn-2

yn-1

yn

變數XY的取值一一對應且呈現線性相關的關係。

1.3 符號解釋

X:表示自變數
Y
:表示因變數
xi
:表示自變數的取值

yi:表示因變數的取值

1.4 計算方法

1、假設最佳擬合線的方程為:y=ax+b

2、計算自變數X和因變數Y的均值:

3、利用最小二乘法迴歸法求最佳擬合線的斜率:

4、計算最佳擬合線的切距:

5、由求得的斜率和切距得出最佳擬合線的方程:

6、計算自變數X和因變數Y的標準差:

7、計算相關係數

8、通過相關係數判斷所求最佳擬合線與資料的擬合度,規則如下:

1)如果相關係數的絕對值越接近1,則所求最佳擬合線的擬合度越高,可用於資料預測。

2)如果相關係數的絕對值越接近0,則所求最佳擬合線的擬合度越低,不推薦用於進行預測(預測的結果可能不準確)。

2 演算法的應用場景。

2.1 該場景下演算法描述

案例描述:有一個不同場次的預計天晴時數和音樂會聽眾人數的關係資料樣本,利用這些資料,如何基於音樂會當天預計天晴時數(小時)來估計出票情況。

2.2 該場景下演算法定義

案例定義:有一個二變數資料同時給出預計天晴時數和音樂會聽眾人數,如下所示:

天晴時數(小時)

1.9

2.5

3.2

3.8

4.7

5.5

5.9

7.2

音樂會聽眾人數(百人)

22

33

30

42

38

39

42

55

如果音樂會當天預計天晴時數可能為4.3小時,請問音樂會聽眾人數可能會有多少人?

2.3 該場景下演算法中符號解釋

天晴時數:表示自變數

聽眾人數:表示因變數

2.4 該場景下演算法計算方法

1、假設最佳擬合線的方程為:y=ax+b

2、計算天晴時數和聽眾人數的均值:

 

3、利用最小二乘法迴歸法求最佳擬合線的斜率:

4、計算最佳擬合線的切距:

5、由求得的斜率和切距得出最佳擬合線的方程: 

6、計算天晴時數和聽眾人數的標準差:

 

7、計算相關係數:

 

8、通過相關係數判斷所求最佳擬合線與資料的擬合度並得出預測結果:

由於r接近1,說明音樂會聽眾人數和預計天晴時數之間有很強的正相關。換句話說,根據已有的資料,利用最佳擬合線根據預計天晴時數給出了期望音樂會聽總人數的合理的良好估計。

當音樂會當天預計天晴時數可能為4.3小時,利用最佳擬合線方程,那麼就可估計當天音樂會聽眾人數大約會是3868人。

3演算法的優點和缺點

3.1 本演算法優點

優點:發掘變數資料間的線性相關模式,並能為預測提出意見和結果。

3.2 本演算法缺點

缺點:只適用於對已有的資料資訊進行估計,不一定適用於資料限制以外的範圍。以音樂會為例,當音樂會當天預計天晴時數可能為8小時,就不一定能良好估計聽眾人數可能會有多少人。

3.3 本演算法適應場景

呈因果關係的變數之間,由原因因素值估計預測結果因素值。如光照時長與水稻產量。

3.4 本演算法不適應場景

無因果關係的變數之間,例如,人的體重與身高。

3.5 本演算法適用的資料型別

本演算法適用於double資料型別,預設保留三位小數,可以自行設定保留位數。

4 演算法的輸入資料、中間結果以及輸出結果

4.1 本演算法輸入資料

* @param twoVarData double[][[],表示樣本資料

* @param testiVar double,因變數測試值

* @param fraDigits int,結果保留幾位小數

4.2 本演算法中間結果

* @param iVarAvg double,表示自變數的均值

* @param dVarAvg double,表示因變數的均值

* @param slope double,表示最佳擬合線的斜率

* @param tangentDistance double,表示切距

* @param Sx double,表示自變數的標準差

* @param Sy double,表示因變數的標準差

4.3 本演算法輸出結果

* @return result String[4],包含{斜率,切距,最佳擬合線方程,相關係數}結果字元型數值

* @return estValue double,因變數估計值

5 演算法的程式碼參考

5.1 類和方法基本描述

類原始碼:見源程式:Statistics.src.CorrelationAndRegression

利用相關與迴歸原理計算二變數[自變數和因變數]資料的最佳擬合線,並通過最佳擬合線[y=a+bx]來挖掘二變數[自變數和因變數]資料之間的線性關係,從而通過自變數的值預測估計因變數的值。

5.2 類和方法呼叫介面

見源程式:Statistics.src.CorrelationAndRegression

CorrelationAndRegression.java 下包含如下方法:

calculateAvgValue(double[] varData,int fraDigits)//計算變數的均值

calculateSlope(double[][] twoVarData,int fraDigits) //計算最佳擬合線的斜率

calculateTangentDistance(double slope,double iVarAvg,double dVarAvg,int fraDigits) //計算最佳擬合線的切距

calculateStandardDeviation(double[] varData,int fraDigits)//計算變數的標準差

calculateCorrelationCoefficient(double slope,double Sx,double Sy,int fraDigits) //計算相關係數

calculateEstimatedValue(double slope,double tangentDistance,double testiVar,int fraDigits) //計算因變數的估計值

analyze(double[][] twoVarData,int fraDigits) //迴歸分析並得出結果

呼叫封裝方法:Statistics.src.utils.ScoreUtil

ScoreUtil.java中的方法:

getFractionDigits(double, int) //對數值保留幾位小數

5.3 原始碼

import utils.ScoreUtil;

/**
 * 相關與迴歸
 * @description 利用相關與迴歸原理計算二變數[自變數和因變數]資料的最佳擬合線,
 *     並通過最佳擬合線[y=a+bx]來挖掘二變數[自變數和因變數]資料之間的關係,從而通過自變數的值預測估計因變數的值。
 *     應用場景:例如,通過天氣狀態預測演唱會到場的人數;或者通過光照時長來估計植物的生長情況。
 *     侷限性:只能根據已有的資料資訊進行估計,不一定適用於資料限制意外的範圍。
 *        例如,現有2000年到2010年的資料資訊,就不能預測估計2010年以後的資料。
 * @author candymoon
 * @2015-8-13下午4:19:57
 */
public class CorrelationAndRegression {
    /**
     * 求變數值的平均值(公式:平均值=總和/總數)
     * @param varData 變數資料值
     * @param fraDigits 結果保留位數
     * @return 平均值
     */
    public static double calculateAvgValue(double[] varData,int fraDigits){
        double avgValue = 0;
        int  len = varData.length;//陣列長度
        for (int i = 0; i < varData.length; i++) {
            avgValue += varData[i];
        }
        //計算均值
        avgValue = avgValue/len;
        //並將結果保留3位小數(四捨五入)
        String avgValue_String = ScoreUtil.getFractionDigits(avgValue, fraDigits);
        avgValue = Double.valueOf(avgValue_String);
        return avgValue;
    } 
    /**
     * 計算最佳擬合線(y=a+bx)的斜率b
     * @description 最佳擬合線(y=a+bx)的斜率b的計算公式為:b=∑((x-xAvg)(y-yAvg))/∑(x-xAvg)²
     * ,其中x為自變數,xAvg為自變數均值,y為因變數,yAvg為因變數均值。
     * @param twoVarData 二變數資料
     * @param fraDigits 結果保留位數
     * @return 斜率
     */
    public static double calculateSlope(double[][] twoVarData,int fraDigits){
        double slope = 0;//斜率
        double iVarAvg = 0;//自變數均值
        double dVarAvg = 0;//因變數均值
        //計算自變數均值和因變數均值
        iVarAvg = calculateAvgValue(twoVarData[0],fraDigits);
        dVarAvg = calculateAvgValue(twoVarData[1],fraDigits);
        int iVarLen = twoVarData[0].length;
        double numerator = 0;//分子 
        double denominator = 0;//分母
        //計算公式的分子和分母
        for (int i = 0; i < iVarLen; i++) {
            double x = twoVarData[0][i];
            double y = twoVarData[1][i];
            numerator += (x-iVarAvg)*(y-dVarAvg);
            denominator += (x-iVarAvg)*(x-iVarAvg);
        }
        //計算斜率
        slope = numerator/denominator;
        //並將結果保留幾位小數(四捨五入)
        String slope_String = ScoreUtil.getFractionDigits(slope, fraDigits);
        slope = Double.valueOf(slope_String);
        return slope;
    }
    /**
     * 計算最佳擬合線(y=a+bx)的切距a
     * @description 因為最佳擬合線要經過點(自變數均值,因變數均值),所以其計算公式為:
     *              a=dVarAvg-b*iVarAvg
     * @param slope 斜率
     * @param iVarAvg 自變數
     * @param dVarAvg 因變數
     * @param fraDigits 結果保留位數
     * @return 切距
     */
    public static double calculateTangentDistance(double slope,double iVarAvg,double dVarAvg,int fraDigits){
        double tanDis = 0;//切距
        //計算切距
        tanDis = dVarAvg-(slope*iVarAvg);
        //並將結果保留3位小數(四捨五入)
        String tanDis_String = ScoreUtil.getFractionDigits(tanDis, fraDigits);
        tanDis = Double.valueOf(tanDis_String);
        return tanDis;
    }
    /**
     * 計算變數資料的標準差
     * @description 標準差計算公式為:標準差 =((var-varAvg)²/(n-1))^2
     * @param varData 變數資料
     * @param fraDigits 結果保留位數
     * @return 標準差
     */
    public static double calculateStandardDeviation(double[] varData,int fraDigits){
        double standardDev = 0;//標準差
        double varAvg = 0;//變數均值
        double denominator = 0;//分母
        //計算變數均值
        varAvg = calculateAvgValue(varData,fraDigits);
        int varDataLen = varData.length;
        for (int i = 0; i < varDataLen; i++) {
            double var = varData[i];
            denominator += (var-varAvg)*(var-varAvg);
        }
        //計算標準差
        standardDev = Math.pow(denominator/(varDataLen-1),0.5);
        //並將結果保留3位小數(四捨五入)
        String standardDev_String = ScoreUtil.getFractionDigits(standardDev, fraDigits);
        standardDev = Double.valueOf(standardDev_String);
        return standardDev;
    }
    /**
     * 計算相關係數
     * @description 相關係數表示最佳擬合線與二變數資料的擬合程度,相關係數計算公式為:r = (b*Sx)/Sy;
     *  r的取值範圍為[-1,1],當|r|越接近1,則表示擬合程度越高;當|r|越接近0,則表示擬合程度越低
     *  (1)當r=-1時,表示完全負相關;(2)當r=1時,表示完全正相關;(3)當r=0時,表示不相關。
     * @param slope 斜率
     * @param Sx 自變數的標準差
     * @param Sy 因變數的標準差
     * @param fraDigits 結果保留位數
     * @return 相關係數
     */
    public static double calculateCorrelationCoefficient(double slope,double Sx,double Sy,int fraDigits){
        double r = 0;//相關係數
        r = (slope*Sx)/Sy;
        //並將結果保留3位小數(四捨五入)
        String r_String = ScoreUtil.getFractionDigits(r, fraDigits);
        r = Double.valueOf(r_String);
        return r;
    }
    /**
     * 計算因變數的估計值
     * @description 利用最佳擬合線方程y=a+bx求解
     * @param slope 最佳擬合線的斜率
     * @param tangentDistance 最佳擬合線的切距
     * @param testiVar 測試自變數值
     * @param fraDigits 結果保留幾位小數
     * @return 因變數的估計值
     */
    public static double calculateEstimatedValue(double slope,double tangentDistance,double testiVar,int fraDigits){
        double estValue = 0;//估計值
        //利用最佳擬合線方程y=a+bx求解
        estValue = tangentDistance+(slope*testiVar);
        //並將結果保留3位小數(四捨五入)
        String estValue_String = ScoreUtil.getFractionDigits(estValue, fraDigits);
        estValue = Double.valueOf(estValue_String);
        return estValue;
    }
    /**
     * 求斜率、切距、最佳擬合線、相關係數
     * @param twoVarData 二變數資料
     * @param testiVar 測試值
     * @param fraDigits 結果保留幾位小數
     * @return 字串結果陣列{斜率、切距、最佳擬合線、相關係數}
     */
    public static String[] analyze(double[][] twoVarData,int fraDigits){
        String[] result = new String[4];//字串結果陣列
        String bestFittingLine = "";
        double iVarAvg = 0;//自變數均值
        double dVarAvg = 0;//因變數均值
        double b = 0;//斜率
        double a = 0;//切距
        double r = 0;//相關係數
        double Sx = 0;//自變數的標準差
        double Sy = 0;//因變數的標準差
        //計算自變數和因變數的均值
        iVarAvg = calculateAvgValue(twoVarData[0],fraDigits);
        dVarAvg = calculateAvgValue(twoVarData[1],fraDigits);
        //計算斜率
        b = calculateSlope(twoVarData,fraDigits);
        //計算切距
        a = calculateTangentDistance(b,iVarAvg,dVarAvg,fraDigits);
        //計算自變數和因變數的標準差
        Sx = calculateStandardDeviation(twoVarData[0],fraDigits);
        Sy = calculateStandardDeviation(twoVarData[1],fraDigits);
        //計算相關係數
        r = calculateCorrelationCoefficient(b,Sx,Sy,fraDigits);
        //組合最佳擬合線方程
        bestFittingLine = "y="+a+"+"+b+"x";
        //將結果加入到結果陣列
        result[0]= b+"";
        result[1]= a+"";
        result[2]= bestFittingLine+"";
        result[3]= r+"";
        return result;
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        /*
         * iVar是independent variable(自變數)的縮寫
         * dVar是dependent variable(因變數)的縮寫
         */
         double[] iVar = {1.9,2.5,3.2,3.8,4.7,5.5,5.9,7.2};//自變數值
         double[] dVar = {22,33,30,42,38,49,42,55};//因變數值
         double[][] twoVarData = new double[][]{iVar,dVar};//二變數資料
         int fraDigits = 3;//結果保留幾位小數數 
         double testiVar = 4.3;//測試自變數值
         String[] result = analyze(twoVarData,fraDigits);
         double estValue = 0;//估計值
         System.out.println("-------------輸出結果---------------");
         System.out.println(" 斜率:"+result[0]+" 切距:"+result[1]);
         System.out.println(" 最佳擬合線:"+result[2]);
         System.out.println(" 相關係數:"+result[3]);
         estValue = calculateEstimatedValue(Double.valueOf(result[0]),Double.valueOf(result[1]),testiVar,fraDigits);
         System.out.println(" 測試自變數值:"+testiVar);
         System.out.println(" 因變數估計值:"+estValue);
         System.out.println("----------------------------------");
    }

}

6 共享

相關推薦

程式設計師眼中統計學12相關迴歸線條如何?

作者 白寧超 2015年10月25日22:16:07 摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越來

程式設計師眼中統計學2集中趨勢度量分散性、變異性、強大的距

// 用於統計輸入了多少資料 static int n = 0; static String a1[]; static int b1[]; /** * @Title: set * @Description: 資料賦值 *

程式設計師眼中統計學1資訊圖形化第一印象

package pictuer; import java.awt.Dimension; import java.awt.Font; import java.io.PrintStream; import java.text.DecimalFormat; import java.text.Simpl

程式設計師眼中統計學7正態分佈的運用正態之美

作者 白寧超 2015年10月15日18:30:07 摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越來

程式設計師眼中統計學8統計抽樣的運用抽取樣本

作者 白寧超 2015年10月15日18:30:07 摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越來

程式設計師眼中統計學6幾何分佈、二項分佈及泊松分佈堅持離散

/** * 在n次伯努利試驗中,試驗r次才得到第一次成功的機率 P(X=r)=pq^{r-1} * @param p double型保留一位小數,表示成功的概率 * @param q double型保留一位小數,表示失敗的概率即1-p * @param r 整型,實驗次數 *

程式設計師眼中統計學6.1原創實現幾何分佈演算法以及應用

作者 白寧超 2015年8月14日16:07:23 摘要:本文繼統計學幾何分佈、二項分佈、泊松分佈研究的深入,基於各種分佈基礎概念和核心知識介紹之後。就各種分佈的實現和真實環境下應用方是目的。本文就演算法文件規範和程式碼註釋進行梳理,利用其基本核心演算法,實現我們要達到的目的。大家通用的一些統計

程式設計師眼中統計學6.2原創實現二項分佈演算法以及應用

package DistTools; /** * * @(#)GeoDist.java * @Description:描述:本演算法中在n次伯努利試驗中:試驗n次得到r次成功的概率、二項分佈的期望、二項分佈方差的具體實現。 * @Definitions:定義:在相互獨立事件中

程式設計師眼中統計學5排列組合排序、排位、排

/** * 獲取無重線排列總數目 * 描述:從n個元數中選取m個元數進行全排列,得出一共有多少種排法 * 公式:A(m,n)=m!/(n-m)! * 優缺點:輸入資料必須互不相同。求階乘時,使用了for迴圈,避免了遞迴方法導致記憶體溢位的風險。

程式設計師眼中統計學11卡方分佈的應用

作者 白寧超 2015年8月9日22:33:00 摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越

程式設計師眼中統計學9總體和樣本的估計進行預測

作者 白寧超 2015年10月15日18:30:07 摘要:程式設計師眼中的統計學系列是作者和團隊共同學習筆記的整理。首先提到統計學,很多人認為是經濟學或者數學的專利,與計算機並沒有交集。誠然在傳統學科中,其在以上學科發揮作用很大。然而隨著科學技術的發展和機器智慧的普及,統計學在機器智慧中的作用越來

程式設計師眼中統計學4離散概率分佈的運用善用期望

/** * @ClassName ScoreUtil * @Description 分數處理工具類 * @author candymoon * @Date 2014-4-25 */ public class ScoreUtil { /** * 使用jav

程式設計師眼中統計學3概率計算把握機會

/** * 計算條件概率 * * @param pOfA 概率P(A) * @param pOfAB 概率P(AB) * @return 概率P(B|A) */ public static float Cond

python 歷險記——一個 Java 程式設計師的告白

引言 想學爬蟲還是 python 專業啊,之前一直在用 java, 現在決定嚐嚐鮮,使用 python及爬蟲框架來完成網路資料採集。 程式語言之間都是相通的,比如都需要模組化,引入其他檔案來實現功能,使用列表等容器來處理資料,都要使用 json 或 xml 來解析和傳輸資料。 你會發現通過 類比 的方式,帶

程式設計師之路開篇

高中的時候,有次學校開了一個計算機語言培訓班,學費也不貴,學的是BASIC,第一次去試聽,老師講了a,b的值互換問題和進位制之間轉換問題,我聽得頭都大了,想不到還有這樣一種高中生都難以理解的東西,直到高考結束,成績還不錯,報考的是哈工大威海校區的軟體工程專業。 我不知道等待我的是什麼樣的難題

java常見面試題Java程式設計師面試題

不知不覺中,已經將面試題更新到第六篇了,龐大的java面試題庫,想要刷完似乎不大可能,需要一點一點的積累。 1、java 中會存在記憶體洩漏嗎,請簡單描述。   答:會;存在無用但可達的物件,這些物件不能被GC 回收,導致耗費記憶體資源。 2、靜態變數和例項變數的區別?

關於Google神牛Jeff Dean的笑話,非程式設計師勿入

During his own Google interview, Jeff Dean was asked the implications if P=NP were true. He said, “P = 0 or N = 1.” Then, before the interviewer had ev

python 歷險記之面向物件——一個 Java 程式設計師的告白

前言 在上篇文章 中,我使用了與 java類比 以及 程式碼例項 的方式涉及了 python 3 中 string, 資料結構(Dict, List, 元組)等重要的主題。 今天我會繼續探險,去征服 python 3 中的面向物件, let's go 讓我們出發吧! 類和物件 剛接觸 python 中的類和物

java常見面試題Java程式設計師面試題

本期的java面試題是偏向資料庫方面的,對相關技術知識匱乏的,或者對這方面不大自信的同學,面試之前可以參考一下這套題,這只是節選,試運營一下,如果不能滿足你們的需求,可以直接評論留言! 1、檢視的優缺點 答:優點: 1)對資料庫的訪問,因為檢視可以有選擇性的選取資料庫

java常見面試題Java程式設計師面試題

上一次更新的java面試題,很多小夥伴反應很簡單,其實上一期更新的就是更偏基礎的面試題,但這並不意味著,面試就這麼簡單,在java的學習中,有從Java基礎、框架、設計模式等等都是重點學習的點。在本文的面試題分享中,我們循序漸進,儘量挑一些重點的內容來分享! 1、當一個物件