官术网_书友最值得收藏!

在機器學習領域,Python語言可以大展身手,因為Python的設計哲學是“優雅、明確、簡單”。Python開發者的哲學是“用一種方法,最好是只有一種方法來做一件事”。在設計Python語言時,如果面臨多種選擇,Python開發者一般會拒絕花俏的語法,而選擇明確的沒有或者很少有歧義的語法。由于這種設計觀念的影響,Python源代碼具備更好的可讀性,并且能夠支撐大規模的軟件開發。幾乎在任何涉及軟件開發的領域都可以看到Python的身影,在機器學習領域它更是威名遠揚,大量的優秀機器學習庫都是基于Python開發或者提供Python接口的。所以本章重點介紹Python語言在機器學習領域的優勢和應用,包括幾個重點庫:NumPy、SciPy、NTLK、Scikit-Learn的簡介、環境依賴以及安裝,最后介紹TensorFlow的簡介及安裝。為后續的學習準備好工具箱。

2.1 Python在機器學習領域的優勢

Python在機器學習領域應用廣泛(如圖2-1所示),我認為主要原因有兩個:

● 語法簡單,功能強大;

● 生態完整,具備豐富的第三方庫,對應的機器學習庫非常豐富。

圖2-1 主流基于Python的機器學習庫

下面將重點介紹四個庫。

2.1.1 NumPy

NumPy是Python的一種開源的數值計算擴展。這種工具可用來存儲和處理大型矩陣,比Python自身的嵌套列表結構要高效的多。

NumPy包括:

● 一個強大的N維數組對象Array;

● 比較成熟的(廣播)函數庫;

● 用于整合C/C++和Fortran代碼的工具包;

● 實用的線性代數、傅里葉變換和隨機數生成函數。

NumPy提供了許多高級的數值編程工具,如:矩陣數據類型、矢量處理,以及精密的運算庫,專為進行嚴格的數字處理。

1.安裝方法

    pip install --user numpy

2.用法示例

首先需要創建數組才能對其進行其他操作。

可以通過給array函數傳遞Python的序列對象創建數組,如果傳遞的是多層嵌套的序列,將創建多維數組(下例中的變量c):

    >>> a = np.array([1, 2, 3, 4])
    >>> b = np.array((5, 6, 7, 8))
    >>> c = np.array([[1, 2, 3, 4], [4, 5, 6, 7], [7, 8, 9, 10]])
    >>> b
    array([5, 6, 7, 8])
    >>> c
    array([[1, 2, 3, 4],          [4, 5, 6, 7],          [7, 8, 9, 10]])
    >>> c.dtype
    dtype('int32')

數組的大小可以通過其shape屬性獲得:

    >>> a.shape
    (4, )
    >>> c.shape
    (3, 4)

數組元素的存取方法和Python的標準方法相同:

    >>> a = np.arange(10)
    >>> a[5]     # 用整數作為下標可以獲取數組中的某個元素
    5
    >>> a[3∶5]  # 用范圍作為下標獲取數組的一個切片,包括a[3]不包括a[5]
    array([3, 4])
    >>> a[∶5]   # 省略開始下標,表示從a[0]開始
    array([0, 1, 2, 3, 4])
    >>> a[∶-1]  # 下標可以使用負數,表示從數組后往前數
    array([0, 1, 2, 3, 4, 5, 6, 7, 8])
    >>> a[2∶4] = 100,101     # 下標還可以用來修改元素的值
    >>> a
    array([   0,    1, 100, 101,    4,    5,    6,    7,    8,    9])
    >>> a[1∶-1∶2]   # 范圍中的第三個參數表示步長,2表示隔一個元素取一個元素
    array([   1, 101,    5,    7])
    >>> a[∶∶-1] # 省略范圍的開始下標和結束下標,步長為-1,整個數組頭尾顛倒
    array([   9,    8,    7,    6,    5,    4, 101, 100,    1,    0])
    >>> a[5∶1∶-2] # 步長為負數時,開始下標必須大于結束下標
    array([   5, 101])

和Python的列表序列不同,通過下標范圍獲取的新的數組是原始數組的一個視圖。它與原始數組共享同一塊數據空間:

    >>> b = a[3∶7] # 通過下標范圍產生一個新的數組b, b和a共享同一塊數據空間
    >>> b
    array([101,    4,    5,    6])
    >>> b[2] = -10 # 將b的第2個元素修改為-10
    >>> b
    array([101,    4, -10,    6])
    >>> a # a的第5個元素也被修改為10
    array([   0,    1, 100, 101,    4, -10,    6,    7,    8,    9])

除了使用下標范圍存取元素之外,NumPy還提供了兩種存取元素的高級方法。

NumPy和MatLab不一樣,對于多維數組的運算,缺省情況下并不使用矩陣運算,如果你希望對數組進行矩陣運算的話,可以調用相應的函數。

NumPy庫提供了matrix類,使用matrix類創建的是矩陣對象,它們的加減乘除運算缺省采用矩陣方式計算,因此用法和MatLab十分類似。但是由于NumPy中同時存在ndarray和matrix對象,用戶很容易將兩者弄混。這有違Python的“顯式優于隱式”的原則,因此并不推薦在較復雜的程序中使用matrix。下面是使用matrix的一個例子:

    >>> a = np.matrix([[1,2,3], [5,5,6], [7,9,9]])
    >>> a*a**-1
    matrix([[   1.00000000e+00,    1.66533454e-16,   -8.32667268e-17],
[ -2.77555756e-16,    1.00000000e+00,   -2.77555756e-17],
[   1.66533454e-16,    5.55111512e-17,    1.00000000e+00]])

因為a是用matrix創建的矩陣對象,因此乘法和冪運算符都變成了矩陣運算,于是上面計算的是矩陣a和其逆矩陣的乘積,結果是一個單位矩陣。

矩陣的乘積可以使用dot函數進行計算。對于二維數組,它計算的是矩陣乘積,對于一維數組,它計算的是點積。當需要將一維數組當作列矢量或者行矢量進行矩陣運算時,推薦先使用reshape函數將一維數組轉換為二維數組:

    >>> a = array([1, 2, 3])
    >>> a.reshape((-1,1))
    array([[1],          [2],          [3]])
    >>> a.reshape((1, -1))
    array([[1, 2, 3]])

除了dot計算乘積之外,NumPy還提供了inner和outer等多種計算乘積的函數。這些函數計算乘積的方式不同,尤其是當處理多維數組的時候,更容易搞混。下面分別介紹這幾個函數。

● dot:對于兩個一維的數組,計算的是這兩個數組對應下標元素的乘積和(數學上稱之為“內積”);對于二維數組,計算的是兩個數組的矩陣乘積;對于多維數組,它的通用計算公式如下,即結果數組中的每個元素都是——數組a的最后一維上的所有元素與數組b的倒數第二位上的所有元素的乘積和。

    dot(a, b)[i, j, k, m] = sum(a[i, j, ∶] * b[k, ∶, m])

下面以兩個三維數組的乘積演示一下dot乘積的計算結果。

首先創建兩個三維數組,這兩個數組的最后兩維滿足矩陣乘積的條件:

    >>> a = np.arange(12).reshape(2,3,2)
    >>> b = np.arange(12,24).reshape(2,2,3)
    >>> c = np.dot(a, b)

dot乘積的結果c可以看作是數組a, b的多個子矩陣的乘積:

    >>> np.alltrue( c[0, ∶,0, ∶] == np.dot(a[0], b[0]) )
    True
    >>> np.alltrue( c[1, ∶,0, ∶] == np.dot(a[1], b[0]) )
    True
    >>> np.alltrue( c[0, ∶,1, ∶] == np.dot(a[0], b[1]) )
    True
    >>> np.alltrue( c[1, ∶,1, ∶] == np.dot(a[1], b[1]) )
    True

● inner:和dot乘積一樣,對于兩個一維數組,計算的是這兩個數組對應下標元素的乘積和;對于多維數組,它計算的結果數組中的每個元素都是——數組a和b的最后一維的內積,因此數組a和b的最后一維的長度必須相同。

    inner(a, b)[i, j, k, m] = sum(a[i, j, ∶]*b[k, m, ∶])

下面是inner乘積的演示:

    >>> a = np.arange(12).reshape(2,3,2)
    >>> b = np.arange(12,24).reshape(2,3,2)
    >>> c = np.inner(a, b)
    >>> c.shape (2, 3, 2, 3)
    >>> c[0,0,0,0] == np.inner(a[0,0], b[0,0])
    True
    >>> c[0,1,1,0] == np.inner(a[0,1], b[1,0])
    True
    >>> c[1,2,1,2] == np.inner(a[1,2], b[1,2])
    True

● outer:只按照一維數組進行計算,如果傳入參數是多維數組,則先將此數組展平為一維數組,之后再進行運算。outer乘積計算的列向量和行向量的矩陣乘積:

    >>> np.outer([1,2,3], [4,5,6,7])
    array([[ 4,   5,   6,   7],          [ 8, 10, 12, 14],          [12, 15, 18, 21]])

矩陣中更高級的一些運算可以在NumPy的線性代數子庫linalg中找到。例如inv函數計算逆矩陣,solve函數可以求解多元一次方程組。下面是solve函數的一個例子:

    >>> a = np.random.rand(10,10)
    >>> b = np.random.rand(10)
    >>> x = np.linalg.solve(a, b)
    >>> np.sum(np.abs(np.dot(a, x) - b))
    3.1433189384699745e-15

solve函數有兩個參數a和b。a是一個N×N的二維數組,而b是一個長度為N的一維數組,solve函數找到一個長度為N的一維數組x,使得a和x的矩陣乘積正好等于b,數組x就是多元一次方程組的解。

2.1.2 SciPy

SciPy是一款方便、易于使用、專為科學和工程設計的Python工具包,如圖2-2所示。它包括統計、優化、整合、線性代數模塊、傅里葉變換、信號和圖像處理、常微分方程求解器等等。

圖2-2 SciPy主頁

安裝方法:

    pip install --user numpy scipy matplotlib iPython jupyter pandas sympy nose

2.1.3 NLTK

NLTK在NLP領域中是最常使用的一個Python庫,包括圖形演示和示例數據,其提供的教程解釋了工具包支持的語言處理任務背后的基本概念。

安裝程序如下:

    pip install -U nltk

加載數據如下:

    >>> import nltk
    >>> nltk.download()

用法示例如下。

分詞與標識:

    >>> import nltk
    >>> sentence = """At eight o'clock on Thursday morning
    ... Arthur didn't feel very good."""
    >>> tokens = nltk.word_tokenize(sentence)
    >>> tokens
    ['At',  'eight',  "o'clock",  'on',  'Thursday',  'morning',  'Arthur',  'did',  "n't",
'feel', 'very', 'good', '.']
    >>> tagged = nltk.pos_tag(tokens)
    >>> tagged[0∶6]
    [('At',  'IN'),  ('eight',  'CD'),  ("o'clock",  'JJ'),  ('on',  'IN'),  ('Thursday',
'NNP'), ('morning', 'NN')]

標識名詞實體:

    >>> entities = nltk.chunk.ne_chunk(tagged)
    >>> entities
    Tree('S', [('At', 'IN'), ('eight', 'CD'), ("o'clock", 'JJ'),                  ('on',
'IN'), ('Thursday', 'NNP'), ('morning', 'NN'),
        Tree('PERSON', [('Arthur', 'NNP')]),
            ('did', 'VBD'), ("n't", 'RB'), ('feel', 'VB'),
            ('very', 'RB'), ('good', 'JJ'), ('.', '.')])

展現語法樹(如圖2-3):

圖2-3 展現語法樹

    >>> from nltk.corpus import treebank
    >>> t = treebank.parsed_sents('wsj_0001.mrg')[0]
    >>> t.draw()

2.1.4 Scikit-Learn

Scikit-Learn是基于Python的機器學習模塊,基于BSD開源許可證。這個項目最早于2007年發起,目前也是由社區自愿者進行維護的。Scikit-Learn官方網站上可以找到相關的Scikit-Learn的資源、模塊下載、文檔、例程等等。Scikit-Learn的基本功能主要分為6個部分:分類,回歸,聚類,數據降維,模型選擇,數據預處理。具體可以參考官方網站上的文檔,見圖2-4。

圖2-4 Scikit-Learn主頁

依賴的環境:

● Python (>= 2.6 or >= 3.3)

● NumPy (>= 1.6.1)

● SciPy (>= 0.9)

安裝方法:

    pip install -U scikit-learn
主站蜘蛛池模板: 威信县| 漳平市| 三江| 望都县| 紫金县| 湘潭市| 东安县| 丰都县| 马尔康县| 乌兰浩特市| 三台县| 南澳县| 华蓥市| 沈丘县| 宁化县| 星座| 平凉市| 沂源县| 周口市| 长岛县| 平湖市| 泾阳县| 茂名市| 银川市| 鱼台县| 旬邑县| 叙永县| 临高县| 安阳市| 翁源县| 雷州市| 周宁县| 四子王旗| 福建省| 广德县| 呼和浩特市| 嘉荫县| 抚顺市| 清徐县| 荣成市| 子长县|