大數據須要掌握的基本算法

大數據須要會的基本算法

前言

數學就像一條章魚,它有觸手能夠觸及到幾乎每一個學科上面。雖然大部分人在上學的時候有系統的學習,但都沒有進行深刻的研究和運用,只是拿來拓展本身的思惟邏輯。可是若是你想從事數學相關的研究或者崗位,你將不得不努力學習數學。若是你已經完成了數學學位或一些技能學位,你可能會知道你所學的是否都是必要的。html

你可能想知道:作大數據須要掌握多少數學知識?在這篇文章中,咱們將簡單瞭解大數據須要掌握的基本算法。python

機器學習算法,有數百種算法。覆蓋每種類型算法的深度不屬於本文的範圍,本文將討論您須要知道的如下經常使用算法的數學算法:git

  • Naive Bayes(樸素貝葉斯)
  • Linear Regression(線性迴歸)
  • Logistic Regression(邏輯迴歸)
  • K-Means clustering(k均值聚類算法)
  • Decision Trees(決策樹)

Naïve Bayes’ Classifiers(樸素貝葉斯分類算法)

樸素貝葉斯分類器是分類算法集合中基於貝葉斯理論的一種算法。github

貝葉斯理論

貝葉斯理論指的是,根據一個已發生事件的機率,計算另外一個事件的發生機率。貝葉斯理論從數學上的表示能夠寫成這樣:算法

【注意】: AB都是事件,P(B)不爲0編程

上面的公式看着有點複雜,咱們能夠對它進行分解。 基本上,只要咱們給出了事件B爲真,那麼就能算出事件A發生的機率,事件B也被稱爲證據。數組

  • P(A|B)是條件機率。- 在B爲真的狀況下發生事件A的可能性。
  • P(B|A)也是條件機率。- 給定A的事件B發生的可能性爲真。
  • P(A)是事件A的先驗(先驗機率,例如,在證據以前發生的機率),證據是一個未知事件的一個屬性值(在這裏就是事件B)。簡單來講就是P(A)P(B)是彼此獨立觀察AB的機率。

接下來咱們會經過例子來加深理解。bash

案例

人們在生活中也常常會無心識的用到貝葉斯定理,好比下面這個例子網絡

推算一下爲何大多數人會認爲東北人酒量大?

條件已知:機器學習

  • P(A)=碰見酒量大的人的機率。
  • P(B) = 碰見東北人的機率。
  • P(B|A) = 碰見酒量大的人是東北人的機率

推算出東北人的酒量大的機率:P(A|B) = P(A)*P(B|A)/P(B)=碰見酒量大的人的機率*碰見酒量大的人是東北人的機率/碰見東北人的機率。

從上面的公式咱們還能夠學到如何下降對東北人酒量大的偏見:

  • 減小碰見酒量大的人的機率,碰見酒量大的人是東北人的機率(碰到酒量大的人和哪裏人難以控制)。
  • 增長碰見東北人的機率。(這點咱們能夠選擇去東北人多的地方)

上面咱們講的是在生活中的應用,那麼用在大數據處理和機器學習有哪些應用呢,請繼續看下面這個例子:

垃圾郵件的分類

假設咱們有十萬郵件,每一個郵件都已經標記好是不是垃圾郵件。經過這些數據咱們能夠算出:

  • P(A)=垃圾郵件的機率,垃圾郵件/全部的郵件。
  • P(B) = 郵件中出現詞M的機率,出現詞M的郵件/全部的郵件。
  • P(B|A) = 垃圾郵件中出現詞M機率,垃圾郵件中含有詞M的郵件數量/全部的垃圾郵件。

能夠獲得: 出現詞M的郵件是垃圾郵件的機率P(A|B) = P(A)*P(B|A)/P(B) =郵件中出現詞M的機率X垃圾郵件中出現詞M機率/是垃圾郵件的機率。

對垃圾郵件學習的過程就是計算P(A|B)的過程。通常會有多個詞或多個詞的組合嘗試,直到找到機率大於預期機率(好比,0.7,0.88,0.93等)的詞 M一、M2 等。而後就能夠用獲得的詞計算,判斷新的郵件是不是垃圾郵件。

Linear Regression(線性迴歸)

線性迴歸,就是可以用一根直線較爲精確地描述數據之間的關係。這樣當出現新的數據的時候,就可以預測出一個簡單的值。

線性迴歸模型

在機器學習中,數學函數被稱爲模型。在線性迴歸的狀況下,模型能夠表示爲:

其中a1,a2,...,an表示特定於數據集的參數值,x1,x2,...,xn表示咱們選擇在模型中使用的要素列,y表示目標列。線性迴歸的目標是找到最佳描述特徵列和目標列之間關係的最佳參數值。換句話說:找到最適合數據的線,以即可之外推趨勢線以預測將來結果。爲了找到線性迴歸模型的最佳參數,咱們但願最小化模型的殘差平方和。

搭建迴歸模型的基本步驟

  • 根據預測目標,肯定自變量和因變量
  • 繪製散點圖,肯定迴歸模型類型
  • 估計模型參數,創建迴歸模型
  • 對迴歸模型進行檢驗
  • 利用迴歸模型進行預測

接下來的案例是關於一個簡單的線性迴歸模型。

簡單線性迴歸 - 一個一元一次迴歸方程。

y=a+bx+e

  • y:因變量
  • x:自變量
  • a:常數項(迴歸直線在y軸上的截距)
  • b:迴歸係數(迴歸直線的斜率)
  • e:隨機偏差(隨機因素對因變量所產生的影響)

案例-身高體重

以下所示數據,咱們隨機獲取一些男生的身高和體重

編號 身高(cm) 體重(kg)
1 165 60
2 170 64
3 172 66
4 177 68
5 180 70
6 157 55
... ... ...

求根據一名男生的身高預報他的體重的迴歸方程,並預報一名身高爲173cm的男生的體重,散列點以下

解:1.選取身高爲自變量X,體重爲因變量Y,做散點圖:

  • 由散點圖知道身高和體重有比較好的線性相關關係,所以能夠用線性迴歸方程刻畫它們之間的關係。

  • 迴歸方程:y = 0.603x - 38.623
  • 帶入求出173cm的體重

python 源碼以下:

import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
from sklearn.linear_model import LinearRegression

if __name__ == "__main__":
    data = pd.read_csv('./linear.csv')  # TV、Radio、Newspaper、Sales
    print(data)
    x = data[['height', 'weight']]
    # 畫出散點圖,求x和y的相關係數
    plt.scatter(data.height, data.weight)
    data.corr()
    print(data.corr())
    # 估計模型參數,創建迴歸模型
    # 首先導入簡單線性迴歸的求解類LinearRegression
    # 而後使用該類進行建模,獲得lrModel的模型變量
    lrModel = LinearRegression()
    # 把自變量和因變量選擇出來
    x = data[['height']]
    y = data[['weight']]
    plt.xlabel('X')
    # 設置Y軸標籤
    plt.ylabel('Y')
    # 調用模型的fit方法,對模型進行訓練
    # 這個訓練過程就是參數求解的過程
    # 並對模型進行擬合
    lrModel.fit(x, y)
    # 對迴歸模型進行檢驗
    lrModel.score(x, y)
    print(lrModel.score(x, y))
    # 利用迴歸模型進行預測
    lrModel.predict([[160], [170]])
    print(lrModel.predict([[160], [170]]))
    # 查看截距
    alpha = lrModel.intercept_[0]
    # 查看參數
    beta = lrModel.coef_[0][0]

    test = alpha + beta * np.array([167, 170])
    print(alpha, beta, test)
    y_test = beta * x + alpha

    # plt.plot(x, y, 'g-', linewidth=6, label='真實數據')
    plt.plot(x, y_test, 'r-', linewidth=2, label='預測數據')
    plt.show()
複製代碼

總結

建模特色
  • 建模速度快,不須要很複雜的計算,在數據量大的狀況下依然運行速度很快。
  • 能夠根據係數給出每一個變量的理解和解釋。
  • 對異常值很敏感。
建模步驟 - sklearn建模流程
  • 創建模型 lrModel = sklearn.linear_model.LinearRegression()
  • 訓練模型 lrModel.fit(x,y)
  • 模型評估 lrModel.score(x,y)
  • 模型預測 lrModel.predict(x)

Logistic Regression(邏輯迴歸)

邏輯迴歸算法(Logistic Regression)雖然是線性迴歸算法,可是其它線性迴歸有所不一樣,邏輯迴歸的預測結果只有兩種,即true(1)和false(0)。所以,Logistic regression ( 邏輯迴歸 ) ,儘管它的名字是迴歸,是一個用於分類的線性模型而不是用於迴歸。因此,邏輯迴歸算法每每適用於數據的分類。

那麼要想數據將數據的擬合結果映射到1和0上,就須要構造一個函數,使得該函數的結果只有0、1。事實上,邏輯迴歸算法的擬合函數稱爲sigmond函數,該函數的輸出值只有0、1,並且是一個平滑的函數。咱們又稱該函數爲邏輯函數。該函數的表達式以下:

  • Y爲決策值
  • x爲特徵值
  • e爲天然對數。

那麼爲何sigmoid函數老是返回0到1之間的值?請記住,從代數中將任何數字提升到負指數與將該數字的倒數提升到相應的正指數相同。

咱們能夠用 Python 把它的函數圖像畫出來

從圖上可知,Y的值域爲(0,1),那麼就能夠將決策函數值大於等於 0.5 的具備對應x屬性的對象歸爲正樣本,決策函數值小於 0.5 的具備對應x屬性的對象歸爲負樣本。這樣就能夠對樣本 數據進行二分類。

上圖的代碼以下:

import matplotlib.pyplot as plt
import numpy as np

def sigmoid(x):
    # 直接返回sigmoid函數
    return 1 / (1 + np.exp(-x))

if __name__ == '__main__':
    # param:起點,終點,間距
    x = np.arange(-10, 10, 0.2)
    y = sigmoid(x)
    plt.plot(x, y, 'r-', linewidth=2)
    plt.show()
複製代碼

Logistic Regression的目的是尋找一個非線性函數 Sigmoid的最佳擬合參數,在求解過程當中用最優化算法完成。該算法的優勢是容易理解與實現,計算代價不高

案例1 - 鳶尾花數據收集

鳶尾花數據集或許是最有名的模式識別測試數據

該數據集包括3個鳶尾花類別,每一個類別有50個樣 本。其中一個類別是與另外兩類線性可分的,而另 外兩類不能線性可分。

該數據集共150行,每行1個樣本。 每一個樣本有5個字段,分別是

  • 花萼長度
  • 花萼寬度
  • 花瓣長度
  • 花瓣寬度
  • 類別(共3類)
    • Iris setosa山鳶尾
    • Iris versicolor雜色鳶尾
    • Iris Virginica維吉尼亞鳶尾

咱們看看代碼的實現效果圖

從圖中咱們能夠看到,預測的分類結果與訓練數據的真實結果結果基本一致,部分鳶尾花出現交叉。 項目源碼以下

import numpy as np
import pandas as pd
from sklearn import preprocessing
from sklearn.linear_model import LogisticRegression
from sklearn.preprocessing import StandardScaler, PolynomialFeatures
from sklearn.pipeline import Pipeline
import matplotlib as mpl
import matplotlib.pyplot as plt
import matplotlib.patches as mpatches


if __name__ == "__main__":
    path = './iris.data'  # 數據文件路徑
    data = pd.read_csv(path, header=None)
    data[4] = pd.Categorical(data[4]).codes
    x, y = np.split(data.values, (4,), axis=1)
    # print 'x = \n', x
    # print 'y = \n', y
    # 僅使用前兩列特徵
    x = x[:, :2]
   
    # y.ravel()是獲取矩陣
    lr = LogisticRegression(C=1e5)
    # pipeline 優化邏輯迴歸準確度 參數集在新數據集(好比測試集)上的重複使用
    # 管道機制更像是編程技巧的創新,而非算法的創新。
    # 可放在Pipeline中的步驟可能有 (1)特徵標準化是須要的,可做爲第一個環節
    # (2)既然是分類器,classifier也是少不了的,天然是最後一個環節
    # 標準化數據 - PolynomialFeatures類能夠進行特徵的構造
    # lr = Pipeline([('sc', StandardScaler()),
    # ('poly', PolynomialFeatures(degree=1)),
    # ('clf', LogisticRegression())])
    lr.fit(x, y.ravel())
    y_hat = lr.predict(x)
    y_hat_prob = lr.predict_proba(x)
    np.set_printoptions(suppress=True)
    print('y_hat = \n', y_hat)
    print('y_hat_prob = \n', y_hat_prob)
    print('準確度:%.2f%%' % (100*np.mean(y_hat == y.ravel())))
    # 畫圖
    N, M = 200, 200     # 橫縱各採樣多少個值
    x1_min, x1_max = x[:, 0].min(), x[:, 0].max()   # 第0列的範圍
    x2_min, x2_max = x[:, 1].min(), x[:, 1].max()   # 第1列的範圍
    t1 = np.linspace(x1_min, x1_max, N)
    t2 = np.linspace(x2_min, x2_max, M)
    x1, x2 = np.meshgrid(t1, t2)                    # 生成網格採樣點
    print(x1, x2)
    x_test = np.stack((x1.flat, x2.flat), axis=1)   # 測試點


    # mpl.rcParams['font.sans-serif'] = ['simHei']
    # mpl.rcParams['axes.unicode_minus'] = False
    cm_light = mpl.colors.ListedColormap(['#77E0A0', '#FF8080', '#A0A0FF'])
    cm_dark = mpl.colors.ListedColormap(['g', 'r', 'b'])
    y_hat = lr.predict(x_test)                  # 預測值
    y_hat = y_hat.reshape(x1.shape)                 # 使之與輸入的形狀相同
    print("y_hat", y_hat)
    plt.figure(facecolor='w')
    #這個函數講x1,x2的兩個網絡矩陣和對應的預測值y_hat繪製在圖片上,能夠發現輸出爲三個顏色區塊,分佈表示分類的區域
    plt.pcolormesh(x1, x2, y_hat, cmap=cm_light)     # 預測值的顯示
     # 樣本的散列點
    plt.scatter(x[:, 0], x[:, 1], c=y.flat, edgecolors='k', s=50, cmap=cm_dark)
    plt.xlabel(u'Iris height', fontsize=14)
    plt.ylabel(u'Iris width', fontsize=14)
    print(x1_min, x1_max, x2_min, x2_max)
    plt.xlim(x1_min, x1_max)
    plt.ylim(x2_min, x2_max)
    plt.grid()
    patchs = [mpatches.Patch(color='#77E0A0', label='Iris-setosa'),
              mpatches.Patch(color='#FF8080', label='Iris-versicolor'),
              mpatches.Patch(color='#A0A0FF', label='Iris-virginica')]
    plt.legend(handles=patchs, fancybox=True, framealpha=0.8)
    # plt.title(u'鳶尾花Logistic迴歸分類效果 - 標準化', fontsize=17)
    plt.show()

複製代碼
部分代碼解析
  • 繪製數據散列點
#第一種方法
#獲取第一列的數據
X = [x[0] for x in DD]  
#獲取第二列的數據
Y = [x[1] for x in DD]  
plt.scatter(X[:50], Y[:50], color='red', marker='o', label='setosa') #前50個樣本
plt.scatter(X[50:100], Y[50:100], color='blue', marker='x', label='versicolor') #中間50個
plt.scatter(X[100:], Y[100:],color='green', marker='+', label='Virginica') #後50個樣本

#第二種
plt.scatter(x[:, 0], x[:, 1], c=y.flat, edgecolors='k', s=50, cmap=cm_dark)   
複製代碼
  • lr = LogisticRegression(C=1e5) lr.fit(x, y.ravel())
    初始化邏輯迴歸模型並進行訓練,C=1e5表示目標函數,正則項係數的倒數具體能夠查看官網
  • x1_min, x1_max = x[:, 0].min(), x[:, 0].max()
    x2_min, x2_max = x[:, 1].min(), x[:, 1].max()
    獲取的鳶尾花兩列數據,對應爲花萼長度和花萼寬度,每一個點的座標就是(x,y)。 先取X二維數組的第一列(長度)的最小值、最大值 生成數組,再取X二維數組的第二列(寬度)的最小值、最大值生成數組, 最後用meshgrid函數生成兩個網格矩陣x1和x2,以下所示:
    [[4.3        4.31809045 4.3361809  ... 7.8638191  7.88190955 7.9       ]
    複製代碼

[4.3 4.31809045 4.3361809 ... 7.8638191 7.88190955 7.9 ] [4.3 4.31809045 4.3361809 ... 7.8638191 7.88190955 7.9 ] ... [4.3 4.31809045 4.3361809 ... 7.8638191 7.88190955 7.9 ] [4.3 4.31809045 4.3361809 ... 7.8638191 7.88190955 7.9 ] [4.3 4.31809045 4.3361809 ... 7.8638191 7.88190955 7.9 ]] [[2. 2. 2. ... 2. 2. 2. ] [2.0120603 2.0120603 2.0120603 ... 2.0120603 2.0120603 2.0120603] [2.0241206 2.0241206 2.0241206 ... 2.0241206 2.0241206 2.0241206] ... [4.3758794 4.3758794 4.3758794 ... 4.3758794 4.3758794 4.3758794] [4.3879397 4.3879397 4.3879397 ... 4.3879397 4.3879397 4.3879397] [4.4 4.4 4.4 ... 4.4 4.4 4.4 ]] ```

  • x.ravel() 調用ravel()函數將xx和yy的兩個矩陣轉變成一維數組

  • y_hat = y_hat.reshape(x1.shape)
    用reshape()函數修改形狀,將其y_hat轉換爲兩個特徵(長度和寬度)。輸出以下

    [[1. 1. 1. ... 2. 2. 2.]
     [1. 1. 1. ... 2. 2. 2.]
     [1. 1. 1. ... 2. 2. 2.]
     ...
     [0. 0. 0. ... 2. 2. 2.]
     [0. 0. 0. ... 2. 2. 2.]
     [0. 0. 0. ... 2. 2. 2.]]
    複製代碼
  • lr.predict(x_test)
    對數據進行預測函數

  • plt.pcolormesh(x1, x2, y_hat, cmap=cm_light)

    這個函數講x1,x2的兩個網絡矩陣和對應的預測值y_hat繪製在圖片上,能夠發現輸出爲三個顏色區塊,分佈表示分類的區域

更多知識點但願讀者下來後進行拓展,也推薦大學從Sklearn開源知識官網學習最新的實例。

案例2

邏輯迴歸實例

若是你想深刻了解概念,我建議學習機率論以及離散數學或實際分析。

K-Means clustering(k均值聚類算法)

k-means聚類算法是一種無監督機器學習算法,用於對未標記的數據(即未定義類別或組的數據)進行分類。該算法經過在數據中查找組來工做,組的數量由變量k表示。而後,它遍歷數據,根據提供的特徵將每一個數據點分配給k個組中的一個。k-means聚類依賴於整個算法中距離的概念來「分配」數據點給一個聚類。若是你不熟悉距離的概念,它指的是兩個給定項目之間的空間量。在數學中,任何描述集合中任意兩個元素之間距離的函數稱爲距離函數或度量。

定義

聚是一個將數據集中在某些方面類似的數據成員進行分類組織的過程,聚類就是一種發現這種內在結構的技術,聚類技術常常被稱爲無監督學習。

k均值聚類是最著名的劃分聚類算法,因爲簡潔和效率使得他成爲全部聚類算法中最普遍使用的。給定一個數據點集合和須要的聚類數目k,k由用戶指定,k均值算法根據某個距離函數反覆把數據分入k個聚類中。

度量有兩種類型:歐幾里德度量和出租車度量。
歐幾里德度量定義

歐幾里德度量定義以下:

其中 (x1, y1)(x2, y2)是笛卡爾平面上的座標點。雖然 歐幾里德度量是足夠的,但在某些狀況下它不起做用。假設你在一個大城市裏散步,若是有一座巨大的建築物擋住了你的去路,那麼說「我離目的地只有6.5個單位」是沒有意義的。爲了解決這個問題,咱們可使用出租車指標

出租車度量

出租車指標以下:

這一個沒那麼複雜;實際上你只須要知道加減法,瞭解代數的基本知識,就能夠掌握距離公式。可是爲了對這些度量中的每一種幾何的基本類型有一個明確的理解,我推薦一個同時包含歐幾里德幾何非歐幾里德幾何的幾何類。爲了深刻了解度量和度量空間的含義,須要閱讀數學分析並學習一門真正的分析課程。

算法

步驟以下

  • 先隨機取 k 個對象做爲初始的聚類中心。
  • 計算每一個對象與各個種子聚類中心之間的距離,把每一個對象分配給距離它最近的聚類中心。
  • 聚類中心以及分配給它們的對象就表明一個聚類。
  • 一旦所有對象都被分配了,每一個聚類的聚類中心會根據聚類中現有的對象被從新計算。
  • 重複上面的步驟直到知足某個終止條件,終止條件能夠是下面:
    • 沒有(或最小數目)對象被從新分配給不一樣的聚類。
    • 沒有(或最小數目)聚類中心再發生變化。
    • 偏差平方和局部最小。

Decision Trees(決策樹)

上面的圖就是我在網上找的一張決策樹圖,最終的結果是心儀或者不心儀。

基本概念

決策樹是相似流程圖的樹結構,它使用分支方法來講明決策的每一個可能結果。樹中的每一個節點表明對特定變量的測試 - 每一個分支都是該測試的結果。

組成

  • 決策點,是對幾種可能方案的選擇,即最後選擇的最佳方案。若是決策屬於多級決策,則決策樹的中間能夠有多個決策點,以決策樹根部的決策點爲最終決策方案。
  • 狀態節點,表明備選方案的經濟效果(指望值),經過各狀態節點的經濟效果的對比,按照必定的決策標準就能夠選出最佳方案。由狀態節點引出的分支稱爲機率枝,機率數目表示可能出現的天然狀態數目每一個分枝上要註明該狀態出現的機率。
  • 結果節點,將每一個方案在各類天然狀態下取得的損益值標註於結果節點的右端。

決策樹依賴於一種稱爲信息理論的理論來肯定它們是如何構建的。在信息理論中,人們對某個主題的瞭解越多,人們能夠知道的新信息就越少。信息理論的關鍵措施之一被稱爲熵。

關於熵

熵的概念源於物理學,用於度量一個熱力學系統的無序程度。

信息熵:不得不提香農這個大寫的人啦!信息論裏面的知識。在信息論裏面,信息熵衡量信息量的大小,也就是對隨機變量不肯定度的一個衡量。熵越大,不肯定性越大。

熵能夠這樣寫:

推薦看這個鏈接,裏面講解的很詳細,而且附有demo 決策樹講解

  • P(x) 是數據集中發生特徵的機率。 從定義中可知:0≤Entropy(X)≤log(n) 當隨機變量只取兩個值時,即 X的分佈爲 P(X=1)=p,X(X=0)=1−p,0≤p≤1則熵爲:Entropy(X)=−plog2(p)−(1−p)log2(1−p)。

熵值越高,則數據混合的種類越高,其蘊含的含義是一個變量可能的變化越多(反而跟變量具體的取值沒有任何關係,只和值的種類多少以及發生機率有關),它攜帶的信息量就越大。熵在信息論中是一個很是重要的概念,不少機器學習的算法都會利用到這個概念。 應該注意,任何基數b均可以用於對數;可是咱們經常使用的是2,e和10 。你可能注意到一個像S的一個符號。這是求和符號,它意味着儘量屢次地連續添加求和以外的任何函數。加多少次取決於求和的下限和上限。在計算了熵以後,咱們能夠利用信息增益來構造決策樹,從而判斷哪個分裂將最大程度地下降熵。信息增益公式以下:

信息增益衡量一我的能得到多少「比特」信息。在決策樹的狀況下,咱們能夠計算數據集中每一個列的信息增益,以便找到哪一個列將爲咱們提供最大的信息增益,而後對該列進行拆分。

  • 1)通常而言,信息增益越大,則意味着用屬性 A 進行劃分所得到的"純度提高"越大,所以,咱們可用信息增益來進行決策樹的劃分屬性選擇。

  • 2)著名的ID3 決策樹學習算就是以信息增益爲準則來選擇劃分屬性。

案例dem

基本的代數和機率是你真正須要刮掉決策樹的表面。若是你想要對機率和對數進行深刻的概念性理解,我會推薦機率論和代數課程

總結

數學在數據科學中無處不在。雖然有些數據科學算法有時會感受像魔術,但咱們能夠理解許多算法的細節而不須要代數和基本機率和統計數據。 若是你不想學習任何數學?從技術上講,你 能夠依靠機器學習庫,如scikit-learn爲你作全部這些。可是,對於數據科學家來講,對這些算法背後的數學和統計學有充分的瞭解很是有幫助,這樣他們就能夠爲他們的問題和數據集選擇最佳算法,從而作出更準確的預測。因此擁抱痛苦,深刻數學!它並不像你想象的那麼難,並且咱們甚至已經開設了一些關於這些主題的課程來幫助你入門:

參考連接

相關文章
相關標籤/搜索