跳至主要内容

5 篇文章 含有標籤「Data Mining」

檢視所有標籤

用 Python 自學資料科學與機器學習入門實戰:Scikit Learn 基礎入門

· 閱讀時間約 17 分鐘

 如何使用 Python 學習機器學習(Machine Learning)

本系列文章將透過 Python 及其資料科學與機器學習生態系(Numpy、Scipy、Pandas、scikit-learn、Statsmodels、Matplotlib、Scrapy、Keras、TensorFlow 等)來系統性介紹資料科學與機器學習相關的知識。在這個單元中我們將介紹 scikit-learn 這個機器學習和資料分析神兵利器和基本的機器學習工作流程。接下來我們的範例將會使用 Ananconda、Python3 和 Jupyter Notebook 開發環境進行,若還沒安裝環境的讀者記得先行安裝。首先我們先來認識一下基本機器學習工作流程,讓讀者對於機器學習工作流有基本而全面的認識。

基本機器學習工作流程(Machine Learning Workflow)

 如何使用 Python 學習機器學習(Machine Learning)

  1. 明確定義問題 (Problem Definition)
  2. 獲取資料與探索性資料分析 (Get Data & Exploratory Data Analysis)
  3. 資料預處理與特徵工程 (Data Clean/Preprocessing & Feature Engineering)
  4. 訓練模型與校調 (Model Training)
  5. 模型驗證 (Model Predict & Testing)
  6. 模型優化 (Model Optimization)
  7. 上線運行 (Deploy Model)

明確定義問題 (Problem Definition)

 如何使用 Python 學習機器學習(Machine Learning)

明確定義問題是進行機器學習工作流的第一步。由於機器學習和一般的 Web 網頁應用程式開發比較不一樣,其需要的運算資源和時間成本比較高,若能一開始就定義好問題並將問題抽象為數學問題將有助於我們要蒐集的資料集和節省工作流程的時間。

舉例來說,本篇文章範例希望預測 Iris 鳶尾花屬於哪一個類別(setosa 山鳶尾、versicolor 變色鳶尾、virginica 維吉尼亞鳶尾),這邊我們就可以決定是要進行有對應結果的監督式學習:二元分類問題(binary classification)、多類別分類問題(multi-classification)還是連續量的迴歸問題(regression),或是沒有標籤結果的非監督式學習(例如:clustering)等,我們這邊假設這是一個多類別分類問題:給定未知資料希望能預測花朵屬於哪一類。換句話說,就是說我們先定義好我們想要解決或是預測的問題,然後去蒐集對應的資料。

獲取資料與探索性資料分析 (Get Data & Exploratory Data Analysis)

 如何使用 Python 學習機器學習(Machine Learning)

基本上資料集的完整性某種程度決定了預測結果是否能發揮模型最大功效。由於我們是教學文章,這邊我們的範例使用 scikit-learn 內建的玩具資料集 Iris(鳶尾花)的花萼、花蕊長寬進行花朵類別判別(setosa 山鳶尾、versicolor 變色鳶尾、virginica 維吉尼亞鳶尾)。在這個資料集中已經幫我們標註好每筆資料對應的類別,所以我們可以視為多類別分類問題(multi-classification)。

 如何使用 Python 學習機器學習(Machine Learning)

引入模組

# 引入 numpy、pd 和 sklearn(scikit-learn) 模組
import numpy as np
import pandas as pd
from sklearn import datasets
# 引入 train_test_split 分割方法,注意在 sklearn v0.18 後 train_test_split 從 sklearn.cross_validation 子模組搬到 sklearn.model_selection 中
from sklearn.model_selection import train_test_split
# 引入 KNeighbors 模型
from sklearn.neighbors import KNeighborsClassifier
from sklearn.svm import LinearSVC

引入資料集並進行探索性資料分析

# 引入 iris 資料集
raw_iris = datasets.load_iris()
# 探索性分析 Exploratory data analysis,了解資料集內容
# 先印出 key 值,列出有哪些值:['data', 'target', 'target_names', 'DESCR', 'feature_names']
print(raw_iris.keys())

# 印出 feature 值
print(raw_iris['data'])
# 印出目標值,分別對應的是三種花的類別:['setosa 山鳶尾' 'versicolor 變色鳶尾' 'virginica 維吉尼亞鳶尾']
print(raw_iris['target'])
# 印出目標標籤,三種花的類別:['setosa' 'versicolor' 'virginica']
print(raw_iris['target_names'])
# 印出資料集內容描述
print(raw_iris['DESCR'])
# 印出屬性名稱,['sepal length 花萼長度 (cm)', 'sepal width 花萼寬度 (cm)', 'petal length 花蕊長度 (cm)', 'petal width 花蕊寬度 (cm)']
print(raw_iris['feature_names'])

# 類別種類
print(np.unique(raw_iris.target))

dict_keys(['data', 'target', 'target_names', 'DESCR', 'feature_names']) [[ 5.1 3.5 1.4 0.2] [ 4.9 3. 1.4 0.2] [ 4.7 3.2 1.3 0.2] [ 4.6 3.1 1.5 0.2] [ 5. 3.6 1.4 0.2] [ 5.4 3.9 1.7 0.4] [ 4.6 3.4 1.4 0.3] [ 5. 3.4 1.5 0.2] [ 4.4 2.9 1.4 0.2] [ 4.9 3.1 1.5 0.1] [ 5.4 3.7 1.5 0.2] [ 4.8 3.4 1.6 0.2] [ 4.8 3. 1.4 0.1] [ 4.3 3. 1.1 0.1] [ 5.8 4. 1.2 0.2] [ 5.7 4.4 1.5 0.4] [ 5.4 3.9 1.3 0.4] [ 5.1 3.5 1.4 0.3] [ 5.7 3.8 1.7 0.3] [ 5.1 3.8 1.5 0.3] [ 5.4 3.4 1.7 0.2] [ 5.1 3.7 1.5 0.4] [ 4.6 3.6 1. 0.2] [ 5.1 3.3 1.7 0.5] [ 4.8 3.4 1.9 0.2] [ 5. 3. 1.6 0.2] [ 5. 3.4 1.6 0.4] [ 5.2 3.5 1.5 0.2] [ 5.2 3.4 1.4 0.2] [ 4.7 3.2 1.6 0.2] [ 4.8 3.1 1.6 0.2] [ 5.4 3.4 1.5 0.4] [ 5.2 4.1 1.5 0.1] [ 5.5 4.2 1.4 0.2] [ 4.9 3.1 1.5 0.1] [ 5. 3.2 1.2 0.2] [ 5.5 3.5 1.3 0.2] [ 4.9 3.1 1.5 0.1] [ 4.4 3. 1.3 0.2] [ 5.1 3.4 1.5 0.2] [ 5. 3.5 1.3 0.3] [ 4.5 2.3 1.3 0.3] [ 4.4 3.2 1.3 0.2] [ 5. 3.5 1.6 0.6] [ 5.1 3.8 1.9 0.4] [ 4.8 3. 1.4 0.3] [ 5.1 3.8 1.6 0.2] [ 4.6 3.2 1.4 0.2] [ 5.3 3.7 1.5 0.2] [ 5. 3.3 1.4 0.2] [ 7. 3.2 4.7 1.4] [ 6.4 3.2 4.5 1.5] [ 6.9 3.1 4.9 1.5] [ 5.5 2.3 4. 1.3] [ 6.5 2.8 4.6 1.5] [ 5.7 2.8 4.5 1.3] [ 6.3 3.3 4.7 1.6] [ 4.9 2.4 3.3 1. ] [ 6.6 2.9 4.6 1.3] [ 5.2 2.7 3.9 1.4] [ 5. 2. 3.5 1. ] [ 5.9 3. 4.2 1.5] [ 6. 2.2 4. 1. ] [ 6.1 2.9 4.7 1.4] [ 5.6 2.9 3.6 1.3] [ 6.7 3.1 4.4 1.4] [ 5.6 3. 4.5 1.5] [ 5.8 2.7 4.1 1. ] [ 6.2 2.2 4.5 1.5] [ 5.6 2.5 3.9 1.1] [ 5.9 3.2 4.8 1.8] [ 6.1 2.8 4. 1.3] [ 6.3 2.5 4.9 1.5] [ 6.1 2.8 4.7 1.2] [ 6.4 2.9 4.3 1.3] [ 6.6 3. 4.4 1.4] [ 6.8 2.8 4.8 1.4] [ 6.7 3. 5. 1.7] [ 6. 2.9 4.5 1.5] [ 5.7 2.6 3.5 1. ] [ 5.5 2.4 3.8 1.1] [ 5.5 2.4 3.7 1. ] [ 5.8 2.7 3.9 1.2] [ 6. 2.7 5.1 1.6] [ 5.4 3. 4.5 1.5] [ 6. 3.4 4.5 1.6] [ 6.7 3.1 4.7 1.5] [ 6.3 2.3 4.4 1.3] [ 5.6 3. 4.1 1.3] [ 5.5 2.5 4. 1.3] [ 5.5 2.6 4.4 1.2] [ 6.1 3. 4.6 1.4] [ 5.8 2.6 4. 1.2] [ 5. 2.3 3.3 1. ] [ 5.6 2.7 4.2 1.3] [ 5.7 3. 4.2 1.2] [ 5.7 2.9 4.2 1.3] [ 6.2 2.9 4.3 1.3] [ 5.1 2.5 3. 1.1] [ 5.7 2.8 4.1 1.3] [ 6.3 3.3 6. 2.5] [ 5.8 2.7 5.1 1.9] [ 7.1 3. 5.9 2.1] [ 6.3 2.9 5.6 1.8] [ 6.5 3. 5.8 2.2] [ 7.6 3. 6.6 2.1] [ 4.9 2.5 4.5 1.7] [ 7.3 2.9 6.3 1.8] [ 6.7 2.5 5.8 1.8] [ 7.2 3.6 6.1 2.5] [ 6.5 3.2 5.1 2. ] [ 6.4 2.7 5.3 1.9] [ 6.8 3. 5.5 2.1] [ 5.7 2.5 5. 2. ] [ 5.8 2.8 5.1 2.4] [ 6.4 3.2 5.3 2.3] [ 6.5 3. 5.5 1.8] [ 7.7 3.8 6.7 2.2] [ 7.7 2.6 6.9 2.3] [ 6. 2.2 5. 1.5] [ 6.9 3.2 5.7 2.3] [ 5.6 2.8 4.9 2. ] [ 7.7 2.8 6.7 2. ] [ 6.3 2.7 4.9 1.8] [ 6.7 3.3 5.7 2.1] [ 7.2 3.2 6. 1.8] [ 6.2 2.8 4.8 1.8] [ 6.1 3. 4.9 1.8] [ 6.4 2.8 5.6 2.1] [ 7.2 3. 5.8 1.6] [ 7.4 2.8 6.1 1.9] [ 7.9 3.8 6.4 2. ] [ 6.4 2.8 5.6 2.2] [ 6.3 2.8 5.1 1.5] [ 6.1 2.6 5.6 1.4] [ 7.7 3. 6.1 2.3] [ 6.3 3.4 5.6 2.4] [ 6.4 3.1 5.5 1.8] [ 6. 3. 4.8 1.8] [ 6.9 3.1 5.4 2.1] [ 6.7 3.1 5.6 2.4] [ 6.9 3.1 5.1 2.3] [ 5.8 2.7 5.1 1.9] [ 6.8 3.2 5.9 2.3] [ 6.7 3.3 5.7 2.5] [ 6.7 3. 5.2 2.3] [ 6.3 2.5 5. 1.9] [ 6.5 3. 5.2 2. ] [ 6.2 3.4 5.4 2.3] [ 5.9 3. 5.1 1.8]] [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2] ['setosa' 'versicolor' 'virginica'] Iris Plants Database

Notes

Data Set Characteristics: :Number of Instances: 150 (50 in each of three classes) :Number of Attributes: 4 numeric, predictive attributes and the class :Attribute Information:

  • sepal length in cm
  • sepal width in cm
  • petal length in cm
  • petal width in cm
  • class:
    • Iris-Setosa
    • Iris-Versicolour
    • Iris-Virginica :Summary Statistics:

============== ==== ==== ======= ===== ==================== Min Max Mean SD Class Correlation ============== ==== ==== ======= ===== ==================== sepal length: 4.3 7.9 5.84 0.83 0.7826 sepal width: 2.0 4.4 3.05 0.43 -0.4194 petal length: 1.0 6.9 3.76 1.76 0.9490 (high!) petal width: 0.1 2.5 1.20 0.76 0.9565 (high!) ============== ==== ==== ======= ===== ====================

:Missing Attribute Values: None :Class Distribution: 33.3% for each of 3 classes. :Creator: R.A. Fisher :Donor: Michael Marshall (MARSHALL%PLU@io.arc.nasa.gov) :Date: July, 1988

This is a copy of UCI ML iris datasets. http://archive.ics.uci.edu/ml/datasets/Iris

The famous Iris database, first used by Sir R.A Fisher

This is perhaps the best known database to be found in the pattern recognition literature. Fisher's paper is a classic in the field and is referenced frequently to this day. (See Duda & Hart, for example.) The data set contains 3 classes of 50 instances each, where each class refers to a type of iris plant. One class is linearly separable from the other 2; the latter are NOT linearly separable from each other.

References

  • Fisher,R.A. "The use of multiple measurements in taxonomic problems" Annual Eugenics, 7, Part II, 179-188 (1936); also in "Contributions to Mathematical Statistics" (John Wiley, NY, 1950).
  • Duda,R.O., & Hart,P.E. (1973) Pattern Classification and Scene Analysis. (Q327.D83) John Wiley & Sons. ISBN 0-471-22361-1. See page 218.
  • Dasarathy, B.V. (1980) "Nosing Around the Neighborhood: A New System Structure and Classification Rule for Recognition in Partially Exposed Environments". IEEE Transactions on Pattern Analysis and Machine Intelligence, Vol. PAMI-2, No. 1, 67-71.
  • Gates, G.W. (1972) "The Reduced Nearest Neighbor Rule". IEEE Transactions on Information Theory, May 1972, 431-433.
  • See also: 1988 MLC Proceedings, 54-64. Cheeseman et al"s AUTOCLASS II conceptual clustering system finds 3 classes in the data.
  • Many, many more ...

['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] [0 1 2]

資料預處理與特徵工程 (Data Clean/Preprocessing & Feature Engineering)

 如何使用 Python 學習機器學習(Machine Learning)

良好的資料輸入取決於資料預處理與特徵工程,而好的輸入將大大影響到模型是否可以發揮其理論正常水準。以下把資料轉成 DataFrame 格式方便進行操作。由於這邊的資料集已經是相當完整的資料集,所以我們這邊就不用特別進行資料預處理和特徵工程的部份,然而在真實世界中,真正在進行機器學習工作流程的時候資料預處理往往是最花時間的部份。同時為了方便模型的校調,我們這邊把資料集分為 70% 訓練資料,30% 驗證資料。

# 將資料轉為 pandas DataFrame
# data 為觀察目標變數
df_X = pd.DataFrame(raw_iris.data)
# target 為預測變數
df_y = pd.DataFrame(raw_iris.target)

# 將資料切分為 training data 和 testing data,其中 random_state 若設為 0 或不設則即便實例不同但因種子相同產生同樣隨機編號,若設為 1 則每次隨機產生不同編號
# test_size 為切分 training data 和 testing data 的比例
X_train, X_test, y_train, y_test = train_test_split(df_X, df_y, test_size=0.3)
# 印出所有資料集筆數
print(len(df_y))

150

# 印出切分 y_train 的數量為所有資料集的 70%,共 105 筆
print(y_train)
print(len(y_train))

0 39 0 106 2 99 1 0 0 16 0 118 2 80 1 29 0 11 0 104 2 100 2 72 1 108 2 42 0 20 0 31 0 115 2 111 2 89 1 83 1 130 2 41 0 66 1 120 2 113 2 6 0 126 2 62 1 23 0 97 1 .. .. 10 0 76 1 129 2 144 2 137 2 12 0 79 1 123 2 127 2 36 0 74 1 37 0 131 2 110 2 22 0 32 0 147 2 134 2 102 2 75 1 88 1 148 2 33 0 56 1 28 0 90 1 82 1 25 0 121 2 13 0

[105 rows x 1 columns] 105

# 印出切分的 y_test 資料為所有資料集的 30%,共 45 筆
print(y_test)
print(len(y_test))

0 102 2 53 1 143 2 70 1 61 1 67 1 24 0 124 2 36 0 92 1 114 2 31 0 120 2 87 1 74 1 47 0 69 1 56 1 93 1 16 0 144 2 133 2 29 0 57 1 116 2 50 1 86 1 44 0 3 0 21 0 82 1 99 1 134 2 111 2 135 2 4 0 2 0 91 1 85 1 122 2 127 2 11 0 27 0 79 1 51 1 45

訓練模型與校調 (Model Training)

 如何使用 Python 學習機器學習(Machine Learning)

上面是 scikit-learn 提供的演算法 cheat-sheet,當你面對琳琅滿目的模型一開始不知道要選擇什麼的話可以按圖索驥參考,另外這邊提供大圖支援連結

這邊我們參考上圖來選擇適合模型:

  1. 樣本資料是否大於 50 筆:範例資料集總共有 150 筆資料,大於 50
  2. 是否為分類問題:Iris 花朵類別預測是多類別分類問題
  3. 是否有標籤好的資料:已經有 label 資料
  4. 樣本資料是否小於 100K:資料小於 100K
  5. 選擇 Linear SVC 模型(第一個選擇的模型)
  6. 是否是文字資料:不是
  7. 選擇 KNeighborsClassifier 模型(第二個選擇的模型)
  8. 後續優化 / SVC / Ensemble
# 初始化 LinearSVC 實例
lin_clf = LinearSVC()
# 使用 fit 來建置模型,其參數接收 training data matrix, testing data array,所以進行 y_train.values.ravel() Data Frame 轉換
lin_clf.fit(X_train, y_train.values.ravel())

LinearSVC(C=1.0, class_weight=None, dual=True, fit_intercept=True, intercept_scaling=1, loss='squared_hinge', max_iter=1000, multi_class='ovr', penalty='l2', random_state=None, tol=0.0001, verbose=0)

# 初始化 KNeighborsClassifier 實例
knn = KNeighborsClassifier()

# 使用 fit 來建置模型,其參數接收 training data matrix, testing data array,所以進行 y_train.values.ravel() 轉換
knn.fit(X_train, y_train.values.ravel())

KNeighborsClassifier(algorithm='auto', leaf_size=30, metric='minkowski', metric_params=None, n_jobs=1, n_neighbors=5, p=2, weights='uniform')

模型驗證 (Model Predict & Testing)

 如何使用 Python 學習機器學習(Machine Learning)

監督式學習的分類問題通常會分為訓練模型和驗證模型,這邊我們使用 predict 去產生對應的目標值,此時和正確答案(已經標籤好的目標值)比較可以知道模型預測的正確率。我們可以看到 KNeighborsClassifier 在正確率(accuracy)表現上相對比較好一點(0.98 比 0.93)。

# 使用 X_test 來預測結果
print(lin_clf.predict(X_test))

[1 1 0 2 1 2 0 1 1 2 2 1 0 2 0 0 2 1 2 0 0 1 2 0 2 1 2 0 0 0 1 0 2 1 1 0 0 0 1 0 1 2 2 1 1]

# 印出預測準確率
print(lin_clf.score(X_test, y_test))

0.933333333333

# 使用 X_test 來預測結果
print(knn.predict(X_test))

[1 1 0 1 1 2 0 1 1 2 2 1 0 2 0 0 2 1 2 0 0 1 2 0 2 1 2 0 0 0 1 0 1 1 1 0 0 0 1 0 1 2 2 1 1]

# 印出 testing data 預測標籤機率
print(knn.predict_proba(X_test))

[[ 0. 1. 0. ] [ 0. 1. 0. ] [ 1. 0. 0. ] [ 0. 0.8 0.2] [ 0. 1. 0. ] [ 0. 0. 1. ] [ 1. 0. 0. ] [ 0. 1. 0. ] [ 0. 1. 0. ] [ 0. 0. 1. ] [ 0. 0. 1. ] [ 0. 1. 0. ] [ 1. 0. 0. ] [ 0. 0. 1. ] [ 1. 0. 0. ] [ 1. 0. 0. ] [ 0. 0. 1. ] [ 0. 1. 0. ] [ 0. 0. 1. ] [ 1. 0. 0. ] [ 1. 0. 0. ] [ 0. 1. 0. ] [ 0. 0. 1. ] [ 1. 0. 0. ] [ 0. 0.2 0.8] [ 0. 1. 0. ] [ 0. 0. 1. ] [ 1. 0. 0. ] [ 1. 0. 0. ] [ 1. 0. 0. ] [ 0. 1. 0. ] [ 1. 0. 0. ] [ 0. 1. 0. ] [ 0. 1. 0. ] [ 0. 1. 0. ] [ 1. 0. 0. ] [ 1. 0. 0. ] [ 1. 0. 0. ] [ 0. 0.6 0.4] [ 1. 0. 0. ] [ 0. 1. 0. ] [ 0. 0. 1. ] [ 0. 0. 1. ] [ 0. 1. 0. ] [ 0. 1. 0. ]]

# 印出預測準確率
print(knn.score(X_test, y_test))

0.977777777778

模型優化 (Model Optimization)

由於本文是簡易範例,這邊就沒有示範如何進行模型優化(這邊可以嘗試使用 SVC 和 Ensemble 方法)。不過一般來說在分類模型優化上,讓模型預測表現的更好的方法大約有幾種:

  1. 特徵工程:選擇更適合特徵值或是更好的資料清理,某種程度上很需要專業知識的協助(domain konwledge)去發現和整合出更好的 feature
  2. 調整模型參數:調整模型的參數
  3. 模型融合:結合幾個弱分類器結果來變成強的分類器

上線運行 (Deploy Model)

當模型優化完畢就可以進行上線運行,其中 Python 比 R 更具優勢的地方,那就是 Python 很容易跟現有的系統進行整合,Python 也有許多好用的 Web 框架可以使用,也因為 Python 是膠水語言,若要進行效能優化也可以很容易呼叫 C/C++ 進行操作,提昇執行效能。

總結

以上用一個簡單的範例介紹了 Python 機器學習套件 Scikit Learn 的基本功能和機器學習整個基本 Workflow。由於是基礎範例所以省略一些比較繁瑣的資料處理部分,事實上,真實世界資料大多是非結構化資料的髒資料,而資料分析的過程往往需要花上許多時間進行資料預處理和資料清理上。接下來我們將介紹其他 Python 資料科學和機器學習生態系和相關工具。

延伸閱讀

  1. 机器学习实战 之 kNN 分类
  2. Machine Learning Workflow
  3. Kaggle机器学习之模型融合(stacking)心得
  4. Python 資料視覺化
  5. Train & Predict workflow
  6. Sample Classification Pipeline workflow
  7. 【机器学习】模型融合方法概述

(image via mediummaprsilvrbackcamoscipymirlabconcreteinteractivesndimg

用 Python 自學資料科學與機器學習入門實戰:Matplotlib 基礎入門

· 閱讀時間約 8 分鐘

 從零開始學資料科學:Numpy 基礎入門

本系列文章將透過系統介紹資料科學(Data Science)相關的知識,透過 Python 帶領讀者從零開始進入資料科學的世界。這邊我們將介紹 Matplotlib 這個 Python 資料視覺化的核心工具。

什麼是 Matplotlib?

Python 的視覺化套件有靜態的 MatplotlibSeabornggplot(借鏡於 Rggplot2)套件以及動態的 Bokeh 套件(類似於 D3.js)。其中 Matplotlib 是 Python 的一個重要模組(Python 是一個高階語言也是一種膠水語言,可以透過整合其他低階語言同時擁有效能和高效率的開發),主要用於資料視覺化上。一般來說使用 Matplotlib 有兩種主要方式:直接和 Matplotlib 的全域 pyplot 模組互動操作,第二種則是物件導向形式的操作方式。若是只有一張圖的話使用全域 pyplot 很方便,若是有多張圖的話用物件導向操作。一般來說 Matplotlib 預設值並不理想,但它的優點在於很容易在上面外包一層提供更好的預設值或是自己修改預設值。

第一張 Matplotlib 圖片

# 引入模組
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
x = pd.period_range(pd.datetime.now(), periods=200, freq='d')
x = x.to_timestamp().to_pydatetime()
# 產生三組,每組 200 個隨機常態分布元素
y = np.random.randn(200, 3).cumsum(0)
plt.plot(x, y)
plt.show()

 從零開始學資料科學:Matplotlib 基礎入門

常用屬性和參數調整

# Matplotlib 使用點 point 而非 pixel 為圖的尺寸測量單位,適合用於印刷出版。1 point = 1 / 72 英吋,但可以調整

import matplotlib as mpl
mpl.rcParams['lines.linewidth'] = 5
mpl.rcParams['lines.color'] = 'r'
mpl.rcParams['figure.figsize'] = (10, 10)
plt.gcf().set_size_inches(10, 10)

x = pd.period_range(pd.datetime.now(), periods=200, freq='d')
x = x.to_timestamp().to_pydatetime()
# 產生三組,每組 200 個隨機常態分布元素
y = np.random.randn(200, 3).cumsum(0)
plt.plot(x, y)
plt.show()

物件導向式 Matplotlib

 從零開始學資料科學:Matplotlib 基礎入門

# 設定標籤
plots = plt.plot(x, y)
plt.legend(plots, ('Apple', 'Facebook', 'Google'), loc='best', framealpha=0.5, prop={'size': 'large', 'family': 'monospace'})
plt.show()

 從零開始學資料科學:Matplotlib 基礎入門

# 標題與軸標籤
plt.title('Random Trends')
plt.xlabel('Date')
plt.ylabel('Cum. Sum')
plt.figtext(0.995, 0.01, 'CopyRight', ha='right', va='bottom')
# 避免被圖表元素被蓋住
plt.tight_layout()
plt.plot(x, y)
plt.show()

 從零開始學資料科學:Matplotlib 基礎入門

# 儲存圖表
plt.savefig('plt.svg')
# 使用物件導向方式控制圖表,透過控制 figure 和 axes 來操作。其中 figure 和全域 pyplot 部分屬性相同。例如: fig.text() 對應到 plt.fig_text()
fig = plt.figure(figsize=(8, 4), dpi=200, tight_layout=True, linewidth=1, edgecolor='r')
# 軸與子圖表
fig = plt.figure(figsize=(8, 4))

# 插入主要軸,可以透過 add_axes 控制軸在圖裡的位置。例如:[bottom*0.1, left*0.1, top*0.5, right*0.5],fig.add_axes([0.1, 0.1, 0.5, 0.5])
ax = fig.add_axes([0.1, 0.1, 0.8, 0.8])
ax.set_title('Main Axes with Insert Child Axes')
ax.plot(x, y[:, 0])
ax.set_xlabel('Date')
ax.set_ylabel('Cum. sum')

# 插入軸
ax = fig.add_axes([0.15, 0.15, 0.3, 0.3])
ax.plot(x, y[:, 1], color='g')
ax.set_xticks([])

 從零開始學資料科學:Matplotlib 基礎入門

# 單一圖與軸繪製(subplots 不帶參數回傳擁有一軸 figure 物件,幾乎等同於 matplotlib 全域物件)
# matplotlib 內建版面編排系統相對好用。圖表大小不一可以使用 gridspec 模組
figure, ax = plt.subplots()
plots = ax.plot(x, y, label='')
figure.set_size_inches(8, 4)
ax.legend(plots, ('Apple', 'Faceook', 'Google'), loc='best', framealpha=0.25, prop={'size': 'small', 'family': 'monospace'})

ax.set_title('Random trends')
ax.set_xlabel('Date')
ax.set_ylabel('Cum. sum')

ax.grid(True) # 使用格子
figure.text(0.995, 0.01, 'ACM 2015', ha='right', va='bottom')
figure.tight_layout()

 從零開始學資料科學:Matplotlib 基礎入門

# 使用子圖表
figure, ax = plt.subplots()
plots = ax.plot(x, y, label='')
figure.set_size_inches(8, 4)
ax.legend(plots, ('Apple', 'Faceook', 'Google'), loc='best', framealpha=0.25, prop={'size': 'small', 'family': 'monospace'})
ax.set_title('Random trends')
ax.set_xlabel('Date')
ax.set_ylabel('Cum. sum')
ax.grid(True)

figure.text(0.995, 0.01, 'Acm', ha='right', va='bottom')
figure.tight_layout()

 從零開始學資料科學:Matplotlib 基礎入門

# 使用子圖表產生多個圖表
fig, axes = plt.subplots(nrows=3, ncols=1, sharex=True, sharey=True, figsize=(8, 8))
labelled_data = zip(y.transpose(), ('Apple', 'Faceook', 'Google'), ('b', 'g', 'r'))
fig.suptitle('Three Random Trends', fontsize=16)

for i, ld in enumerate(labelled_data):
ax = axes[i]
ax.plot(x, ld[0], label=ld[1], color=ld[2])
ax.set_ylabel('Cum. sum')
ax.legend(loc='upper left', framealpha=0.5, prop={'size': 'small'})
axes[-1].set_xlabel('Date')

 從零開始學資料科學:Matplotlib 基礎入門

常見圖表

  1. 直方圖(Histogram)

    # 直方圖
    normal_samples = np.random.normal(size=100) # 生成 100 組標準常態分配(平均值為 0,標準差為 1 的常態分配)隨機變數
    plt.hist(normal_samples, width=0.1)
    plt.show()

     從零開始學資料科學:Matplotlib 基礎入門

  2. 散佈圖(Scatter plot)

    # 散佈圖
    num_points = 100
    gradient = 0.5
    x = np.array(range(num_points))
    y = np.random.randn(num_points) * 10 + x * gradient
    fig, ax = plt.subplots(figsize=(8, 4))
    ax.scatter(x, y)

    fig.suptitle('A Simple Scatter Plot')
    plt.show()

     從零開始學資料科學:Matplotlib 基礎入門

    # 散佈圖 + 迴歸
    num_points = 100
    gradient = 0.5
    x = np.array(range(num_points))
    y = np.random.randn(num_points) * 10 + x * gradient

    fig, ax = plt.subplots(figsize=(8, 4))

    ax.scatter(x, y)

    m, c = np.polyfit(x, y, 1) # 使用 Numpy 的 polyfit,參數 1 代表一維,算出 fit 直線斜率
    ax.plot(x, m * x + c) # 使用 y = m * x + c 斜率和常數匯出直線
    fig.suptitle('Scatter with regression')
    plt.show()
  3. 線圖(Line plot)

     從零開始學資料科學:Matplotlib 基礎入門

    # 線圖
    age = [4, 4, 17, 17, 18]
    points = [2, 20, 22, 24, 20]

    plt.plot(age, points)
    plt.show()
  4. 長條圖(Bar plot)

     從零開始學資料科學:Matplotlib 基礎入門

    # 長條圖
    labels = ['Physics', 'Chemistry', 'Literature', 'Peace']
    foo_data = [3, 6, 10, 4]
    bar_width = 0.5
    xlocations = np.array(range(len(foo_data))) + bar_width

    plt.bar(xlocations, foo_data, width=bar_width)

    plt.title('Stock Price')
    plt.show()

     從零開始學資料科學:Matplotlib 基礎入門

  5. 盒鬚圖(Box plot)

    # 盒鬚圖
    normal_examples = np.random.normal(size = 100) # 生成 100 組標準常態分配(平均值為 0,標準差為 1 的常態分配)隨機變數

    plt.boxplot(normal_examples)
    plt.show()

     從零開始學資料科學:Matplotlib 基礎入門

  6. 圓餅圖(Pie plot)

    # 圓餅圖
    data = np.random.randint(1, 11, 5) # 生成
    x = np.arange(len(data))

    plt.pie(data)

    plt.show()

 從零開始學資料科學:Matplotlib 基礎入門

Python 其他資料視覺化套件

  1. Seaborn

    # Seaborn
    import numpy as np
    import seaborn as sns
    import matplotlib.pyplot as plt
    sns.set(style="white", context="talk")
    rs = np.random.RandomState(7)


    # 準備 matplotlib 圖表
    f, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 6), sharex=True)

    # 產生連續資料
    x = np.array(list("ABCDEFGHI"))
    y1 = np.arange(1, 10)
    sns.barplot(x, y1, palette="BuGn_d", ax=ax1)
    ax1.set_ylabel("Sequential")

    # 調整成 diverging 資料
    y2 = y1 - 5
    sns.barplot(x, y2, palette="RdBu_r", ax=ax2)
    ax2.set_ylabel("Diverging")

    # 隨機資料
    y3 = rs.choice(y1, 9, replace=False)
    sns.barplot(x, y3, palette="Set3", ax=ax3)
    ax3.set_ylabel("Qualitative")

    # 秀出圖片
    sns.despine(bottom=True)
    plt.setp(f.axes, yticks=[])
    plt.tight_layout(h_pad=3)

     從零開始學資料科學:Matplotlib 基礎入門

  2. Bokeh

    # Bokeh
    from bokeh.plotting import figure, output_file, show

    # 準備資料
    x = [1, 2, 3, 4, 5]
    y = [6, 7, 2, 4, 5]

    # 輸出成靜態 HTML
    output_file("lines.html")

    # 創建新的標題和軸圖表
    p = figure(title="simple line example", x_axis_label='x', y_axis_label='y')

    # 繪製直線圖
    p.line(x, y, legend="Temp.", line_width=2)

    # 呈現結果
    show(p)

總結

以上介紹了 Matplotlib 的基礎知識和 api,同時也介紹了 Python 其他資料視覺化套件。一般來說 Matplotlib 預設值並不理想,但它的優點在於很容易在上面外包一層提供更好的預設值或是自己修改預設值。一般來說我們在進行資料科學和機器學習分析的過程中我們會先使用資訊視覺化工具來了解整個資料集的特色並針對資料進行後續的處理和特徵選取,所以說資料視覺化不僅能呈現資料分析的結果,對於資料分析的過程也十分重要。

延伸閱讀

  1. [python] numpy axis概念整理筆記
  2. [第 18 天] 資料視覺化 matplotlib
  3. 数据可视化(三)- Seaborn简易入门

(image via matplotlib

用 Python 自學資料科學與機器學習入門實戰:Pandas 基礎入門

· 閱讀時間約 12 分鐘
Python 資料科學系列教學

本文是 Python 資料科學與機器學習系列 的第三篇文章:

  1. Python 資料科學入門介紹
  2. NumPy 基礎教學
  3. Pandas 基礎入門 (本文)
  4. Matplotlib 資料視覺化
  5. Scikit-learn 機器學習

📚 查看完整系列

 如何使用 Python 學習機器學習(Machine Learning)

本系列文章將透過 Python 及其資料科學生態系(Numpy、Scipy、Pandas、Scikit-learn、Statsmodels、Matplotlib、Scrapy、Keras、TensorFlow 等)來系統性介紹資料科學和相關的知識,透過 Python 帶領讀者進入資料科學的世界和機器學習的世界。在這個單元中我們將介紹 Pandas 這個基於 Numpy 的資料處理和分析神兵利器。

事實上,真實世界並非如此美好,大部分資料分析的工作時間有很大一部分都是在處理髒資料,希望讓資料可以符合模型輸入的需求,而 Pandas 正是扮演這個資料預處理和資料清洗的核心角色,是 Python 在和 R 爭奪資料科學第一程式語言霸主時的生力軍,接下來我們將介紹 Pandas 核心功能和資料的操作方式。

 如何使用 Python 學習機器學習(Machine Learning)

Pandas 核心功能介紹

創建資料結構

在 Pandas 中主要有兩大資料結構:Series、DataFrame,與 Numpy 中的 ndarray 比較不同的是 Pandas DataFrame 可以存異質資料(不同資料型別)。

Series 類似於 Python 本身的 list 資料結構,不同的是每個元素有自己的 index(可以自己命名):

%matplotlib inline
# 引入 numpy 和 pandas 模組
import numpy as np
import pandas as pd
s1 = pd.Series([1, 3, 5, np.nan, 6, 8]) # 使用 Python lits 產生 Series,其中包含一個值為 NaN

print(s1)

0 1.0 1 3.0 2 5.0 3 NaN 4 6.0 5 8.0 dtype: float64

s2 = pd.Series(np.random.randint(2, size=[3])) # 使用 np.random.randint 產生 3 個 0-2(不含 2)的數組

print(s2)

0 1 1 1 2 1 dtype: int64

DataFrame 可以使用 np.random.randn 產生值來創建,也可以使用 Python dict 進行創建:

# 產生 20170101-20170106 的值,DatetimeIndex(['2017-01-01', '2017-01-02', '2017-01-03', '2017-01-04', '2017-01-05', '2017-01-06'], dtype='datetime64[ns]', freq='D')
dates = pd.date_range('20170101', periods=6)

# 產生 row6,column4 個 standard normal distribution 隨機值,使用 ABCD 當 columns,使用 dates 當 index
df0 = pd.DataFrame(np.random.randn(6,4), index=dates, columns=list('ABCD'))
print(df0)

A B C D 2017-01-01 1.112542 -0.142577 0.832830 -2.755133 2017-01-02 -0.218838 -0.304488 1.437599 -0.402454 2017-01-03 0.295245 -0.786898 -1.231896 -0.224959 2017-01-04 -0.346745 -1.582944 -0.464175 -0.410576 2017-01-05 0.163782 0.948795 -0.420505 -0.641032 2017-01-06 0.515806 -0.935421 -0.701349 -0.820109

# 使用 dict 來創建 DataFrame
teams = ['Web', 'Mobile', 'Data']
nums = [12, 14, 34]
rd_team_dict = {
'teams': teams,
'nums': nums
}
rd_team_df = pd.DataFrame(rd_team_dict)

print(rd_team_df)

nums teams 0 12 Web 1 14 Mobile 2 34 Data

觀察資料

# 觀察資料型態、結構、內容值
df = pd.DataFrame({ 'A' : 1.,
'B' : pd.Timestamp('20170102'),
'C' : pd.Series(1,index=list(range(4)),dtype='float32'),
'D' : np.array([3] * 4,dtype='int32'),
'E' : pd.Categorical(["test","train","test","train"]),
'F' : 'foo' })

# 印出內容值資料型別
print(df.dtypes)

A float64 B datetime64[ns] C float32 D int32 E category F object dtype: object

# 印出資料維度
print(df.shape)

(4, 6)

# 印出每行資料長度
print(len(df))

4

# 印出 DataFrame 資料概況
print(df.info())

<class 'pandas.core.frame.DataFrame'> Int64Index: 4 entries, 0 to 3 Data columns (total 6 columns): A 4 non-null float64 B 4 non-null datetime64[ns] C 4 non-null float32 D 4 non-null int32 E 4 non-null category F 4 non-null object dtypes: category(1), datetime64ns, float32(1), float64(1), int32(1), object(1) memory usage: 180.0+ bytes None

# 印出基本敘述統計數據
print(df.describe())

A C D count 4.0 4.0 4.0 mean 1.0 1.0 3.0 std 0.0 0.0 0.0 min 1.0 1.0 3.0 25% 1.0 1.0 3.0 50% 1.0 1.0 3.0 75% 1.0 1.0 3.0 max 1.0 1.0 3.0

# 印出首 i 個數據
print(df.head(2))

A B C D E F 0 1.0 2017-01-02 1.0 3 test foo 1 1.0 2017-01-02 1.0 3 train foo

# 印出尾 i 個數據
print(df.tail(2))

A B C D E F 2 1.0 2017-01-02 1.0 3 test foo 3 1.0 2017-01-02 1.0 3 train foo

# 印出 index 值
print(df.index)

Int64Index([0, 1, 2, 3], dtype='int64')

# 印出 columns 值
print(df.columns)

Index(['A', 'B', 'C', 'D', 'E', 'F'], dtype='object')

# 印出 values 值
print(df.values)

[[1.0 Timestamp('2017-01-02 00:00:00') 1.0 3 'test' 'foo'] [1.0 Timestamp('2017-01-02 00:00:00') 1.0 3 'train' 'foo'] [1.0 Timestamp('2017-01-02 00:00:00') 1.0 3 'test' 'foo'] [1.0 Timestamp('2017-01-02 00:00:00') 1.0 3 'train' 'foo']]

# 印出轉置 DataFrame
print(df.T)

0 1 2
A 1 1 1
B 2017-01-02 00:00:00 2017-01-02 00:00:00 2017-01-02 00:00:00
C 1 1 1
D 3 3 3
E test train test
F foo foo foo

3
A 1
B 2017-01-02 00:00:00
C 1
D 3
E train
F foo

# sort by the index labels。axis=0 使用 index 進行 sort,axis=1 使用 columns 進行 sort。ascending 決定是否由小到大
print(df.sort_index(axis=0, ascending=False))

A B C D E F 3 1.0 2017-01-02 1.0 3 train foo 2 1.0 2017-01-02 1.0 3 test foo 1 1.0 2017-01-02 1.0 3 train foo 0 1.0 2017-01-02 1.0 3 test foo

# sort by the values of columns
print(df.sort_values(by='E'))

A B C D E F 0 1.0 2017-01-02 1.0 3 test foo 2 1.0 2017-01-02 1.0 3 test foo 1 1.0 2017-01-02 1.0 3 train foo 3 1.0 2017-01-02 1.0 3 train foo

選取資料

# 選取值的方式一般建議使用 1. loc, 2. iloc, 3. ix
# label-location based 行列標籤值取值,以下取出 index=1 那一欄,[列, 行]
print(df.loc[0])

A 1 B 2017-01-02 00:00:00 C 1 D 3 E test F foo Name: 0, dtype: object

# iloc 則通過行列數字索引取值,[列,行]
print(df.iloc[0:3, 1:2])

B 0 2017-01-02 1 2017-01-02 2 2017-01-02

# 兼容 loc 和 iloc
print(df.ix[0, 'B'])

2017-01-02 00:00:00

# 兼容 loc 和 iloc
print(df.ix[1, 3])

3

# 布林取值,取出 A 行大於 0 的資料
print(df[df.A > 0])

A B C D E F 0 1.0 2017-01-02 1.0 3 test foo 1 1.0 2017-01-02 1.0 3 train foo 2 1.0 2017-01-02 1.0 3 test foo 3 1.0 2017-01-02 1.0 3 train foo

# 產生 Series 值
s1 = pd.Series([1,2,3,4,5,6], index=pd.date_range('20170102', periods=6))
print(s1)

2017-01-02 1 2017-01-03 2 2017-01-04 3 2017-01-05 4 2017-01-06 5 2017-01-07 6 Freq: D, dtype: int64

# 更新值
df.loc[:,'D'] = np.array([5] * len(df))
print(df)

A B C D E F 0 1.0 2017-01-02 1.0 5 test foo 1 1.0 2017-01-02 1.0 5 train foo 2 1.0 2017-01-02 1.0 5 test foo 3 1.0 2017-01-02 1.0 5 train foo

處理遺失資料

# 查缺補漏
df2 = pd.DataFrame(index=dates[0:4], columns=list(df.columns) + ['E'])

df2.loc[dates[0]:dates[1], :] = 1

# drop 掉 NaN 值
print(df2.dropna(how='any'))
# 補充 NaN 為 3
print(df2.fillna(value=3))
print(df2)

# 回傳 NaN 布林值
print(pd.isnull(df2))

# inplace 為 True 為直接操作資料,不是操作 copy 副本
df2.dropna(how='any', inplace=True)

A B C D E F E 2017-01-01 1 1 1 1 1 1 1 2017-01-02 1 1 1 1 1 1 1 A B C D E F E 2017-01-01 1 1 1 1 1 1 1 2017-01-02 1 1 1 1 1 1 1 2017-01-03 3 3 3 3 3 3 3 2017-01-04 3 3 3 3 3 3 3 A B C D E F E 2017-01-01 1 1 1 1 1 1 1 2017-01-02 1 1 1 1 1 1 1 2017-01-03 NaN NaN NaN NaN NaN NaN NaN 2017-01-04 NaN NaN NaN NaN NaN NaN NaN A B C D E F E 2017-01-01 False False False False False False False 2017-01-02 False False False False False False False 2017-01-03 True True True True True True True 2017-01-04 True True True True True True True

資料操作

# 針對每一個值進行操作
df.apply(lambda x: x.max() - x.min())

A 2.696944 B 5.285329 C 1.948946 D 2.615037 dtype: float64

串接資料

# 串接資料

df = pd.DataFrame(np.random.randn(10, 4))
print(df)
pieces = [df[:3], df[3:7], df[7:]]
print(pieces)
print(pd.concat(pieces))

0 1 2 3 0 -0.171208 2.200967 0.385574 -0.481588 1 1.447335 1.756239 0.083053 0.255434 2 -0.508576 0.818774 -0.438210 -0.819860 3 1.704828 -0.329642 -1.059202 -0.820319 4 -1.792491 -0.761873 -1.090574 -0.484552 5 0.166621 1.704577 -1.613185 -0.391985 6 0.806292 0.699608 -1.768223 -1.081318 7 -1.168532 0.768302 0.831701 0.422367 8 0.065940 -0.038649 -0.060712 -0.500365 9 0.623535 0.558461 -0.956861 1.229675 [ 0 1 2 3 0 -0.171208 2.200967 0.385574 -0.481588 1 1.447335 1.756239 0.083053 0.255434 2 -0.508576 0.818774 -0.438210 -0.819860, 0 1 2 3 3 1.704828 -0.329642 -1.059202 -0.820319 4 -1.792491 -0.761873 -1.090574 -0.484552 5 0.166621 1.704577 -1.613185 -0.391985 6 0.806292 0.699608 -1.768223 -1.081318, 0 1 2 3 7 -1.168532 0.768302 0.831701 0.422367 8 0.065940 -0.038649 -0.060712 -0.500365 9 0.623535 0.558461 -0.956861 1.229675] 0 1 2 3 0 -0.171208 2.200967 0.385574 -0.481588 1 1.447335 1.756239 0.083053 0.255434 2 -0.508576 0.818774 -0.438210 -0.819860 3 1.704828 -0.329642 -1.059202 -0.820319 4 -1.792491 -0.761873 -1.090574 -0.484552 5 0.166621 1.704577 -1.613185 -0.391985 6 0.806292 0.699608 -1.768223 -1.081318 7 -1.168532 0.768302 0.831701 0.422367 8 0.065940 -0.038649 -0.060712 -0.500365 9 0.623535 0.558461 -0.956861 1.229675

合併資料

# 合併資料
left = pd.DataFrame({'key': ['foo', 'foo'], 'lval': [1, 2]})
right = pd.DataFrame({'key': ['foo', 'foo'], 'rval': [4, 5]})

print(pd.merge(left, right, on='key'))

key lval rval 0 foo 1 4 1 foo 1 5 2 foo 2 4 3 foo 2 5

新增資料

# 新增資料於最後
df = pd.DataFrame(np.random.randn(8, 4), columns=['A','B','C','D'])
print(df)
s = df.iloc[3]
print(df.append(s, ignore_index=True))

A B C D 0 1.780499 1.207626 0.631475 -1.747506 1 -0.603999 -2.364099 1.153066 0.504784 2 0.721924 0.199784 -0.158318 -0.882946 3 -0.378070 -0.379311 0.478997 0.271056 4 0.620888 -0.366262 -0.738695 -0.380854 5 -0.587604 -1.728096 0.279645 -0.927843 6 -0.916445 2.921231 -0.795880 0.867531 7 -0.373190 1.526771 0.136712 0.015765 A B C D 0 1.780499 1.207626 0.631475 -1.747506 1 -0.603999 -2.364099 1.153066 0.504784 2 0.721924 0.199784 -0.158318 -0.882946 3 -0.378070 -0.379311 0.478997 0.271056 4 0.620888 -0.366262 -0.738695 -0.380854 5 -0.587604 -1.728096 0.279645 -0.927843 6 -0.916445 2.921231 -0.795880 0.867531 7 -0.373190 1.526771 0.136712 0.015765 8 -0.378070 -0.379311 0.478997 0.271056

群組操作

# 群組操作
print(df.groupby(['A','B']).sum())

C D A B
-1.232691 0.489020 0.436602 -1.439868 -0.259460 -0.269874 1.655001 0.530137 -0.256261 -0.743254 0.128837 1.050430 0.015723 0.596866 -0.232503 1.247810 0.049633 -0.093130 0.895723 1.049938 0.458667 0.348883 -0.681931 -0.517437 1.446492 0.007736 0.208870 0.211517 2.357912 -0.187805 -0.376578 -0.459085

繪圖

# 印出圖表
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000))
ts = ts.cumsum()
ts.plot()

png

輸入/輸出

# 讀取檔案/輸出檔案,支援 csv, h5, xlsx 檔案格式
df.to_csv('foo.csv')
pd.read_csv('foo.csv')
df.to_excel('foo.xlsx', sheet_name='Sheet1')
print(pd.read_excel('foo.xlsx', 'Sheet1', index_col=None, na_values=['NA']))

A B C D 0 1.446492 0.007736 0.208870 0.211517 1 0.049633 -0.093130 0.895723 1.049938 2 -1.232691 0.489020 0.436602 -1.439868 3 -0.259460 -0.269874 1.655001 0.530137 4 0.015723 0.596866 -0.232503 1.247810 5 0.458667 0.348883 -0.681931 -0.517437 6 2.357912 -0.187805 -0.376578 -0.459085 7 -0.256261 -0.743254 0.128837 1.050430

總結

以上整理了一些 Pandas 核心功能和如何操作資料,接下來我們將介紹其他 Python 資料科學和機器學習生態系和相關工具。

延伸閱讀

  1. 10 Minutes to pandas
  2. Pandas 使用教學 - 第一部分
  3. Python Pandas - Understanding inplace=True
  4. pandas学习笔记
  5. 【Python实战】Pandas:让你像写SQL一样做数据分析(一)

(image via pydatanbcnews

用 Python 自學資料科學與機器學習入門實戰:Numpy 基礎入門

· 閱讀時間約 4 分鐘

 從零開始學資料科學:Numpy 基礎入門

本系列文章將透過系統介紹資料科學(Data Science)相關的知識,透過 Python 帶領讀者從零開始進入資料科學的世界。這邊我們將介紹 Numpy 這個強大的 Python 函式庫。

什麼是 Numpy?

Numpy 是 Python 的一個重要模組(Python 是一個高階語言也是一種膠水語言,可以透過整合其他低階語言同時擁有效能和高效率的開發),主要用於資料處理上。Numpy 底層以 C 和 Fortran 語言實作,所以能快速操作多重維度的陣列。當 Python 處理龐大資料時,其原生 list 效能表現並不理想(但可以動態存異質資料),而 Numpy 具備平行處理的能力,可以將操作動作一次套用在大型陣列上。此外 Python 其餘重量級的資料科學相關套件(例如:Pandas、SciPy、Scikit-learn 等)都幾乎是奠基在 Numpy 的基礎上。因此學會 Numpy 對於往後學習其他資料科學相關套件打好堅實的基礎。

Numpy 基礎操作

 從零開始學資料科學:Numpy 基礎入門

  1. Numpy 陣列 Numpy 的重點在於陣列的操作,其所有功能特色都建築在同質且多重維度的 ndarray(N-dimensional array)上。ndarray 的關鍵屬性是維度(ndim)、形狀(shape)和數值類型(dtype)。 一般我們稱一維陣列為 vector 而二維陣列為 matrix。一開始我們會引入 numpy 模組,透過傳入 listnumpy.array() 創建陣列。

    # 引入 numpy 模組
    import numpy as np
    np1 = np.array([1, 2, 3])
    np2 = np.array([3, 4, 5])

    # 陣列相加
    print(np1 + np2) # [4 6 8]

    # 顯示相關資訊
    print(np1.ndim, np1.shape, np1.dtype) # 1 (3,) int64 => 一維陣列, 三個元素, 資料型別

    np3 = np.array([1, 2, 3, 4, 5, 6])

    從檔案取資料:

    npd = np.genfromtxt('data.csv', delimiter=',')

    改變陣列維度:

    np3 = np3.reshape([2, 3])
    print(np3.ndim, np3.shape, np3.dtype) # 2 (2, 3) int64

    改變陣列型別(bool、int、float、string):

    bool 可以包含 True、False,int 可以包含 int16、int32、int64。其中數字是指 bitsfloat 可以包含 16、32、64 表示小數點後幾位。string 可以是 string、unicode。nan 則表示遺失值。

    np3 = np3.astype('int64')
    np3.dtype
    # dtype('int64')
  2. 建立陣列 建立填滿 0 或 1 的陣列:

    np1 = np.zeros([2, 3]) # array([[ 0.,  0.,  0.], [ 0.,  0.,  0.]])
    np2 = np.ones([2, 3]) # array([[ 1., 1., 1.], [ 1., 1., 1.]])

 從零開始學資料科學:Numpy 基礎入門

  1. 陣列索引與切片 一維陣列操作和 Python 原生 list 類似:

    np3 = np.array([1, 2, 3, 4, 5, 6])
    print(np3[2]) # 3

    二維陣列:

    np3 = np3.reshape([2, 3])

    print(np3[1, 0]) # 4

 從零開始學資料科學:Numpy 基礎入門

  1. 基本操作 使用布林遮罩來取值:

    np3 = np.array([1, 2, 3, 4, 5, 6])
    print(np3 > 3) # [False False False True True True]
    print(np3[np3 > 3]) # [4 5 6]

    加總:

    np3 = np3.reshape([2, 3])
    print(np3.sum(axis=1)) # 將 axis=1 橫向加總 [6 15]

總結

以上介紹了 Numpy 的基礎知識,建立了基本的 array 和 ndarray 的觀念。相信在熟悉 Numpy 之後 Pandas 的學習將會比較容易 (Pandas 的資料容器 DataFrame、Series 事實上是奠基在 Numpy 的陣列上)

延伸閱讀

  1. 7 Steps to Mastering Machine Learning With Python
  2. [python] numpy axis概念整理筆記
  3. Python科学计算:numpy

(image via berkeleycodingeekcornellscipy-lectures

用 Python 自學資料科學與機器學習入門實戰:入門導論

· 閱讀時間約 9 分鐘
Python 資料科學系列教學

本文是 Python 資料科學與機器學習系列 的第一篇文章:

  1. Python 資料科學入門介紹 (本文)
  2. NumPy 基礎教學
  3. Pandas 基礎入門
  4. Matplotlib 資料視覺化
  5. Scikit-learn 機器學習

📚 查看完整系列

 如何使用 Python 學習機器學習(Machine Learning)

隨著資料科學(Data Science)技術的興起,人工智慧(Artificial Intelligence)機器學習(Machine Learning) 成為近幾年來電腦科學界十分熱門的研究領域,如今在實體和線上的學習機器學習的資源有很多,本文整理了一些好用學習資源希望幫助初學者能更容易使用 Python 入門機器學習的領域中,從零開始學習機器學習。若是對於資料科學不熟悉的讀者可以先參考適用於初學者的資料科學影片 ,讓自己對於資料科學有初步的認識。

 如何使用 Python 學習機器學習(Machine Learning)

「人工智慧」(Artificial Intelligence)這專有名稱正式出現在西元 1956 年,在美國達特茅斯學院 (Dartmouth College)召開的第一次人工智慧會議。根據維基百科的定義,人工智慧係指由機器所展現的智慧,一般而言人工智慧又分為「強人工智慧」(Strong AI)和「弱人工智慧」(Weak AI) 兩種不同的主張。所謂的強人工智慧指的是有自我意識、有知覺可以自己推理和解決問題的機器智慧,而「弱人工智慧」只能模擬人類的思維與行為表現,但缺乏真正的推理與解決問題的能力,也不具有自主意識。人工智慧在歷史上經歷了幾次熱潮和寒冬,從最早的邏輯推理到後來的專家系統,再到目前的機器學習/深度學習,機器學習可以視為人工智慧的一個實現方式或是發展的一個歷程。

事實上,人工智慧或是機器學習都是一門跨領域的學門,牽涉了電腦科學、數學、神經學、心理學、經濟學、統計學等層面,也有許多相關的學門:

 如何使用 Python 學習機器學習(Machine Learning)

隨著運算資源(雲端運算、GPU 等)、海量資料(目前還有許多資料還沒被創造,等待我們去發掘呢)以及機器學習/深度學習的發展,生活上許多產品已經可以看到人工智慧的應用。但人工智慧最美好的境界莫過於人機之間的互動以及相輔相成,以 AlphaGO 為例,雖然人類在圍棋領域輸給人機器,但也從機器的思考方式去重新思考了圍棋的真諦和有別於人類的思考方式。

「就因為某樣東西思考的方式跟你不一樣,就代表它沒在思考嗎?」 "Just because something thinks differently from you, does it mean it’s not thinking?" ---《模仿遊戲》《Imitation Game》(2015)

 如何使用 Python 學習機器學習(Machine Learning)

什麼是機器學習(Machine Learning)?

機器學習是一種資料科學的技術也是一種實現人工智慧的一種方式,協助電腦從現有的資料學習,以便預測未來的行為、結果和趨勢。根據學習的方式又可以分為需要解答的監督式學習(Supervised learning)非監督式學習(Unsupervised learning)增強學習(Reinforcement learning)等(還有一種混合式的半監督式學習)等子類別。機器學習技術可以應用的範圍十分廣泛,總的來說機器學習可以解決以下幾種問題:

  1. 分類問題:這是 A 類 或 B 類嗎?

  2. 異常值判斷:這很奇怪嗎?

  3. 預測性分析:有多少?

  4. 分群問題:這是如何組織的?

  5. 增強學習協助決策:我接下來該怎麼辦?

當我們蒐集到相關、精確、連貫、足夠資料就可以挑選合適的演算法進行模型的的建置。

為什麼選擇 Python?

在資料科學和機器學習領域最重要的兩大程式語言就是 Python 和 R,Python 簡潔易學、應用範圍廣(不限於數據分析)且學習曲線平緩,適合作為第一個入門的程式語言,透過 pandas、SciPy/NumPy、sckikit-learn、matplotlib 和 statsmodels 可以進行數據分析的工作,適合工程任務和需要和網路應用程式整合的專案。至於 R 由於是統計學家開發的程式語言,則是擅長於統計分析、圖表繪製,常用於學術研究領域,建議也要有一定程度的掌握。一般情況下 Python 和 R 並非互斥,而是互補,許多資料工程師、科學家往往是在 Python 和 R 兩個語言中轉換,小量模型驗證、統計分析和圖表繪製使用 R,當要撰寫演算法和資料庫、網路服務互動等情況時在移轉到 Python。為了降低學習成本。

此外 Python 本身是一種通用語言,除了資料科學外也可以廣泛使用在網路開發、網站建置、遊戲開發、網路爬蟲等領域,當你需要整合系統產品服務時,可以擔任一站式的開發語言,更重要的是 Python 也可以當成膠水語言非常輕易和 C/C++ 等效能較佳的語言整合。簡而言之,Python 是一種簡潔易學但功能強大,值得投資的程式語言,所以我們這邊先使用 Python 進行介紹。

若對於 Python 和 R 比較,這邊有兩篇文章可以參考 数据科学界华山论剑:R与Python巅峰对决Which is better for data analysis: R or Python?

如何開始入門機器學習?

事實上,資料科學是個跨領域學門,在學習如何使用 Python 進行機器學習過程中通常必須掌握以下知識:

  • 機器學習演算法
  • Python 程式語言和資料分析函式庫
  • 線性代數/統計學等相關學門
  • 專業領域的領域知識(Domain Knowledge)

為了掌握以上三大領域知識(我們先把焦點放在機器學習核心技法,暫時忽略資料科學中對於領域知識的掌握),具體來說我們可以有以下步驟可以參考:

  1. 掌握基礎 Python 程式語言知識

    線上學習資源:

  1. 了解基礎數學/統計學和機器學習基礎知識
  1. 知道如何使用 Python 科學計算函式庫和套件

    推薦安裝 Anaconda,支援跨平台多種版本 Python,預設將數據分析、科學計算的套件裝好,自帶 spyder 編輯器、Jupyter Notebook(IPython Notebook),可以提供一個網頁版介面,讓使用者可以透過瀏覽器進行 Julia、Python 或 R 程式的開發與維護。

  1. 使用 scikit-learn 學習 Python 機器學習應用
  1. 運用 Python 實作機器學習演算法
  • 感知器
  • 決策樹
  • 線性迴歸
  • k-means 分群
  1. 實作進階機器學習演算法
  • SVM
  • KNN
  • Random Forests
  • 降低維度
  • 驗證模型
  1. 了解深度學習(Deep Learning)在 Python 的實作和應用

總結

以上整理了一些機器學習網路學習資源,若你累積一些小小經驗後,不妨挑戰一下 Kaggle 或是 KDD 測試一下自己的實力並累積更多數據分析的經驗。

延伸閱讀

  1. 7 Steps to Mastering Machine Learning With Python
  2. 人人都可成為資料科學大師!一整年的網路自學清單就在這了
  3. Analytics Vidhya
  4. 台灣資料科學年會
  5. 「2016 台灣資料科學愛好者年會」精彩資料總整理(持續更新中)
  6. 大數據會消失,資料科學不會!你該知道的資料科學第一堂課
  7. 如何選擇 Microsoft Azure Machine Learning 的演算法
  8. Microsoft Azure Machine Learning 機器學習服務文件
  9. Kdnuggets
  10. Bigdatafinance
  11. Using Python and R together: 3 main approaches
  12. 机器学习最佳入门学习资源
  13. 机器学习(Machine Learning)&深度学习(Deep Learning)资料(Chapter 1)
  14. SIRAJ RAVAL'S DEEP LEARNING

(image via respondr