1. 程式人生 > >資料科學和人工智慧技術筆記 二、資料準備

資料科學和人工智慧技術筆記 二、資料準備

二、資料準備

作者:Chris Albon

譯者:飛龍

協議:CC BY-NC-SA 4.0

從字典載入特徵

from sklearn.feature_extraction import DictVectorizer

staff = [{'name': 'Steve Miller', 'age': 33.},
         {'name': 'Lyndon Jones', 'age': 12.},
         {'name': 'Baxter Morth', 'age': 18.}]

# 為我們的字典向量化器建立物件
vec = DictVectorizer(
) # 之後將 staff 字典轉換為向量,並輸出陣列 vec.fit_transform(staff).toarray() ''' array([[ 33., 0., 0., 1.], [ 12., 0., 1., 0.], [ 18., 1., 0., 0.]]) ''' # 獲取特徵名稱 vec.get_feature_names() # ['age', 'name=Baxter Morth', 'name=Lyndon Jones', 'name=Steve Miller']

載入 scikit-learn 的波士頓住房資料集

# 載入庫
from sklearn import datasets
import matplotlib.pyplot as plt 

載入波士頓住房資料集

波士頓住房資料集 是 20 世紀 70 年代的著名資料集。 它包含506個關於波士頓周邊房價的觀測。 它通常用於迴歸示例,包含 15 個特徵。

# 載入資料集
boston = datasets.load_boston()

# 建立特徵矩陣
X = boston.data

# 建立目標向量
y = boston.target

# 檢視第一個觀測的特徵值
X[0]

'''
array([  6.32000000e-03,   1.80000000e+01,   2.31000000e+00,
         0.00000000e+00,   5.38000000e-01,   6.57500000e+00,
         6.52000000e+01,   4.09000000e+00,   1.00000000e+00,
         2.96000000e+02,   1.53000000e+01,   3.96900000e+02,
         4.98000000e+00]) 
'''

如您所見,特徵未標準化。 如果我們將值顯示為小數,則更容易看到:

# 將第一個觀測的每個特徵值展示為浮點
['{:f}'.format(x) for x in X[0]]

'''
['0.006320',
 '18.000000',
 '2.310000',
 '0.000000',
 '0.538000',
 '6.575000',
 '65.200000',
 '4.090000',
 '1.000000',
 '296.000000',
 '15.300000',
 '396.900000',
 '4.980000'] 
'''

因此,標準化的特徵值通常是有益的和/或需要的。

載入 scikit-learn 的數字資料集

# 載入庫
from sklearn import datasets
import matplotlib.pyplot as plt 

數字是手寫數字的資料集。 每個特徵是 8×8 影象的一個畫素的強度。

# 載入數字資料集
digits = datasets.load_digits()

# 建立特徵矩陣
X = digits.data

# 建立目標向量
y = digits.target

# 檢視第一個觀測的特徵值
X[0]

'''
array([  0.,   0.,   5.,  13.,   9.,   1.,   0.,   0.,   0.,   0.,  13.,
        15.,  10.,  15.,   5.,   0.,   0.,   3.,  15.,   2.,   0.,  11.,
         8.,   0.,   0.,   4.,  12.,   0.,   0.,   8.,   8.,   0.,   0.,
         5.,   8.,   0.,   0.,   9.,   8.,   0.,   0.,   4.,  11.,   0.,
         1.,  12.,   7.,   0.,   0.,   2.,  14.,   5.,  10.,  12.,   0.,
         0.,   0.,   0.,   6.,  13.,  10.,   0.,   0.,   0.]) 
'''

觀測的特徵值展示為向量。 但是,通過使用images方法,我們可以將相同的特徵值載入為矩陣,然後視覺化實際的手寫字元:

# 將第一個觀測的特徵作為矩陣檢視
digits.images[0]

'''
array([[  0.,   0.,   5.,  13.,   9.,   1.,   0.,   0.],
       [  0.,   0.,  13.,  15.,  10.,  15.,   5.,   0.],
       [  0.,   3.,  15.,   2.,   0.,  11.,   8.,   0.],
       [  0.,   4.,  12.,   0.,   0.,   8.,   8.,   0.],
       [  0.,   5.,   8.,   0.,   0.,   9.,   8.,   0.],
       [  0.,   4.,  11.,   0.,   1.,  12.,   7.,   0.],
       [  0.,   2.,  14.,   5.,  10.,  12.,   0.,   0.],
       [  0.,   0.,   6.,  13.,  10.,   0.,   0.,   0.]]) 
'''

# 將第一個觀測的特徵作為影象視覺化
plt.gray() 
plt.matshow(digits.images[0]) 
plt.show()

# <matplotlib.figure.Figure at 0x1068494a8> 

png

載入 scikit-learn 的鳶尾花資料集

# 載入庫
from sklearn import datasets
import matplotlib.pyplot as plt 

The Iris flower dataset is one of the most famous databases for classification. It contains three classes (i.e. three species of flowers) with 50 observations per class.

# 載入數字資料集
iris = datasets.load_iris()

# 建立特徵矩陣
X = iris.data

# 建立目標向量
y = iris.target

# 檢視第一個觀測的特徵值
X[0]

# array([ 5.1,  3.5,  1.4,  0.2]) 

為分類製作模擬資料

from sklearn.datasets import make_classification
import pandas as pd

# 建立模擬的特徵矩陣和輸出向量,帶有 100 個樣本,
features, output = make_classification(n_samples = 100,
                                       # 十個特徵
                                       n_features = 10,
                                       # 五個實際預測輸出分類的特徵,
                                       n_informative = 5,
                                       # 五個隨機特徵,和輸出分類無關,
                                       n_redundant = 5,
                                       # 三個輸出分類
                                       n_classes = 3,
                                       # 第一類有 20% 的觀測,第二類有 30%,
                                       # 第三類有 50%,'None' 表示均衡分類。
                                       weights = [.2, .3, .8])

# 檢視前五個管澤志和它們的 10 個特徵
pd.DataFrame(features).head()
0 1 2 3 4 5 6 7 8 9
0 -1.338796 2.218025 3.333541 2.586772 -2.050240 -5.289060 4.364050 3.010074 3.073564 0.827317
1 1.535519 1.964163 -0.053789 0.610150 -4.256450 -6.044707 7.617702 4.654903 0.632368 3.234648
2 0.249576 -4.051890 -4.578764 -1.629710 2.188123 1.488968 -1.977744 -2.888737 -4.957220 3.599833
3 3.778789 -4.797895 -1.187821 0.724315 1.083952 0.165924 -0.352818 0.615942 -4.392519 1.683278
4 0.856266 0.568888 -0.520666 -1.970701 0.597743 2.224923 0.065515 0.250906 -1.512495 -0.859869
# 檢視前五個觀測的分類
pd.DataFrame(output).head()
0
0 2
1 2
2 1
3 2
4 2

為矩陣生成模擬資料

from sklearn.datasets import make_blobs
import matplotlib.pyplot as plt

# 生成特徵(X)和輸出(Y),帶有 200 個樣本,
X, y = make_blobs(n_samples = 200,
                  # 兩個特徵,
                  n_features = 2,
                  # 三個簇,
                  centers = 3,
                  # .5 的簇內標準差,
                  cluster_std = 0.5,
                  # 並打亂。
                  shuffle = True)

# 建立前兩個特徵的散點圖
plt.scatter(X[:,0],
            X[:,1])

# 展示散點圖
plt.show()

png

為迴歸製作模擬資料

import pandas as pd
from sklearn.datasets import make_regression

# 生成特徵,輸出和真實的相關度,樣本為 100,
features, output, coef = make_regression(n_samples = 100,
                                         # 三個特徵,
                                         n_features = 3,
                                         # 只有兩個特徵是有用的,
                                         n_informative = 2,
                                         # 每個觀測有一個目標值,
                                         n_targets = 1,
                                         # 高斯噪聲的標準差為 0.0,
                                         noise = 0.0,
                                         # 展示用於生成資料的真實相關度。
                                         coef = True)

# 檢視前五行的特徵
pd.DataFrame(features, columns=['Store 1', 'Store 2', 'Store 3']).head()
Store 1 Store 2 Store 3
0 -0.166697 -0.177142 -2.329568
1 -0.093566 -0.544292 0.685165
2 0.625958 -0.193049 1.168012
3 -0.843925 -0.567444 -0.193631
4 -1.079227 -0.819236 1.609171
# 檢視前五行的輸出
pd.DataFrame(output, columns=['Sales']).head()
Sales
0 -149.387162
1 -4.164344
2 52.166904
3 -56.996180
4 27.246575
# 檢視用於生成資料的真實相關度
pd.DataFrame(coef, columns=['True Coefficient Values'])
True Coefficient Values
0 0.000000
1 80.654346
2 57.993548

Scikit 中的感知機

感知機學習器是最早的機器學習技術之一,並且仍然是許多現代神經網路的基礎。 在本教程中,我們使用感知器學習器來分類經典的鳶尾花資料集。這個教程受 Sebastian Raschka 的 Python 機器學習的啟發。

# 載入所需的庫
from sklearn import datasets
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import Perceptron
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score
import numpy as np

# 載入鳶尾花資料集
iris = datasets.load_iris()

# 建立 X 和 y 資料
X = iris.data
y = iris.target

# 檢視 y 資料的前五個觀測
y[:5]

# array([0, 0, 0, 0, 0]) 

# 檢視 x 資料的前五個觀測
# 注意有四個獨立變數(特徵)
X[:5]

'''
array([[ 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]]) 
'''

# 將資料分割為 70% 訓練集和 30% 測試集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3)

# 訓練縮放器,將所有特徵標準化為均值為 0 和標準差為 1。
sc = StandardScaler()
sc.fit(X_train)

# StandardScaler(copy=True, with_mean=True, with_std=True) 

# 對 X 訓練資料引用縮放器
X_train_std = sc.transform(X_train)

# 對 X 測試資料應用相同的縮放器
X_test_std = sc.transform(X_test)

# 建立感知機物件,引數為,40 個迭代,0.1 的學習率
ppn = Perceptron(n_iter=40, eta0=0.1, random_state=0)

# 訓練感知機
ppn.fit(X_train_std, y_train)

'''
Perceptron(alpha=0.0001, class_weight=None, eta0=0.1, fit_intercept=True,
      n_iter=40, n_jobs=1, penalty=None, random_state=0, shuffle=True,
      verbose=0, warm_start=False) 
'''

# 在 X 資料上應用已訓練的感知機,來對 y 測試資料做預測
y_pred = ppn.predict(X_test_std)

# 檢視預測的 y 測試資料
y_pred

'''
array([0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 1, 1, 0, 2, 2, 2, 0, 0, 0, 0, 0, 2,
       2, 1, 0, 0, 2, 1, 0, 0, 0, 0, 2, 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1]) 
'''

# 檢視真實的 y 測試資料
y_test

'''
array([0, 0, 0, 1, 0, 0, 2, 2, 0, 0, 1, 1, 1, 0, 2, 2, 2, 1, 0, 0, 0, 0, 2,
       2, 1, 1, 0, 2, 1, 1, 1, 0, 0, 2, 1, 0, 2, 0, 2, 0, 2, 0, 2, 0, 1]) 
'''

# 檢視模型準確率,它是:1 -(預測錯的觀測 / 總觀測)
print('Accuracy: %.2f' % accuracy_score(y_test, y_pred))

# Accuracy: 0.87 

儲存機器學習模型

在 scikit 中,有兩種方式來儲存模型以便將來使用:pickle 字串和作為檔案的 pickled 模型。

from sklearn.linear_model import LogisticRegression
from sklearn import datasets
import pickle
from sklearn.externals import joblib

# 載入鳶尾花資料
iris = datasets.load_iris()

# 建立特徵矩陣 X,和向量 y
X, y = iris.data, iris.target

# 訓練原始的 logistic 迴歸模型
clf = LogisticRegression(random_state=0)
clf.fit(X, y) 

'''
LogisticRegression(C=1.0, class_weight=None, dual=False, fit_intercept=True,
          intercept_scaling=1, max_iter=100, multi_class='ovr', n_jobs=1,
          penalty='l2', random_state=0, solver='liblinear', tol=0.0001,
          verbose=0, warm_start=False) 
'''

# 將已訓練的模型儲存為 pickle 字串
saved_model = pickle.dumps(clf)

# 檢視 pickled 模型
saved_model

# b'\x80\x03csklearn.linear_model.logistic\nLogisticRegression\nq\x00)\x81q\x01}q\x02(X\x07\x00\x00\x00penaltyq\x03X\x02\x00\x00\x00l2q\x04X\x0b\x00\x00\x00multi_classq\x05X\x03\x00\x00\x00ovrq\x06X\x08\x00\x00\x00max_iterq\x07KdX\x08\x00\x00\x00classes_q\x08cnumpy.core.multiarray\n_reconstruct\nq\tcnumpy\nndarray\nq\nK\x00\x85q\x0bC\x01bq\x0c\x87q\rRq\x0e(K\x01K\x03\x85q\x0fcnumpy\ndtype\nq\x10X\x02\x00\x00\x00i8q\x11K\x00K\x01\x87q\x12Rq\x13(K\x03X\x01\x00\x00\x00<q\x14NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq\x15b\x89C\x18\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x02\x00\x00\x00\x00\x00\x00\x00q\x16tq\x17bX\x07\x00\x00\x00n_iter_q\x18h\th\nK\x00\x85q\x19h\x0c\x87q\x1aRq\x1b(K\x01K\x01\x85q\x1ch\x10X\x02\x00\x00\x00i4q\x1dK\x00K\x01\x87q\x1eRq\x1f(K\x03h\x14NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq b\x89C\x04\x07\x00\x00\x00q!tq"bX\x06\x00\x00\x00n_jobsq#K\x01X\x11\x00\x00\x00intercept_scalingq$K\x01X\x03\x00\x00\x00tolq%G?\x1a6\xe2\xeb\x1cC-X\x07\x00\x00\x00verboseq&K\x00X\x04\x00\x00\x00dualq\'\x89X\x0c\x00\x00\x00random_stateq(K\x00X\x05\x00\x00\x00coef_q)h\th\nK\x00\x85q*h\x0c\x87q+Rq,(K\x01K\x03K\x04\x86q-h\x10X\x02\x00\x00\x00f8q.K\x00K\x01\x87q/Rq0(K\x03h\x14NNNJ\xff\xff\xff\xffJ\xff\xff\xff\xffK\x00tq1b\x88C`\x9a\x1c\x904+\x8f\xda?v5\xf6\x7f9\xaa\xda?FVL\xe5\x05R\xfb\xbf\xf6\xad\xd9^ya\xf7?\x89\x86\x10B\x03\x9d\xf9\xbf\x7f\xa7x\xf5\\\x8c\xf8\xbf\x8b$8y\xdd\x18\x02\xc0\xac\x8f\xee\xd9+|\xe2?\\\x10\xf2\xcc\x8c\xc4\[[email protected]](/cdn-cgi/l/email-protection)\xda\xb0;l,w\xf0\xbf8_\xe7W*+\xf6\xbf\xefT`-lq\[[email protected]](/cdn-cgi/l/email-protection)\n\x00\x00\x00intercept_q4h\th\nK\x00\x85q5h\x0c\x87q6Rq7(K\x01K\x03\x85q8h0\x89C\x18\xd4\x86D\x03\xb1\xff\xd0?\xa2\xcc=I\xe5]\xf1?\x84\'\xad\x8dxo\xf3\xbfq9tq:bX\n\x00\x00\x00warm_startq;\x89X\x01\x00\x00\x00Cq<G?\xf0\x00\x00\x00\x00\x00\x00X\r\x00\x00\x00fit_interceptq=\x88X\x06\x00\x00\x00solverq>X\t\x00\x00\x00liblinearq?X\x0c\x00\x00\[[email protected]](/cdn-cgi/l/email-protection)' 

# 載入 pickled 模型
clf_from_pickle = pickle.loads(saved_model)

# 使用載入的 pickled 模型來做預測
clf_from_pickle.predict(X)

'''
array([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, 2, 1, 1,
       1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 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, 1, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) 
'''

# 將模型作為 pickle 儲存到檔案
joblib.dump(clf, 'filename.pkl') 

'''
['filename.pkl',
 'filename.pkl_01.npy',
 'filename.pkl_02.npy',
 'filename.pkl_03.npy',
 'filename.pkl_04.npy'] 
'''

# 從檔案載入模型
clf_from_joblib = joblib.load('filename.pkl') 

# 使用載入的模型做預測
clf_from_joblib.predict(X)

'''
array([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, 2, 1, 1,
       1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 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, 1, 2, 2, 2, 2, 2, 2, 2, 2,
       2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2]) 
'''