# 巨匠Python - 機器學習 ###### tags: `資料分析` # 第一章、機器學習主要概念 ![](https://i.imgur.com/SIzbCFA.png) [Scikit Learn - 機器學習概念地圖](https://scikit-learn.org/stable/tutorial/machine_learning_map/index.html) ## (一) 常用資料型態轉換工具 ``` import pandas as pd import numpy as np # 【建立二維】 ndarray => ndarray numpy_2d = np.arange(15).reshape(3,5) # 【建立二維】 ndarray => DataFrame df = pd.DataFrame( numpy_2d, index=['name1','name2','name3'], columns=['y','m','d','earn','cost']) # 【取出一維資料】 DataFrame => Series # 取column print(df.earn) print(df['earn']) # 取row print(df.loc['name1',:]) # 以label取值 print(df.iloc[0,:]) # 以index取值 # 【建立二維】 Series => DataFrame df2 = pd.DataFrame({'earn':df.earn,'cost':df.cost}) # 【取出一維資料】 ndarray => ndarray numpy_1d = numpy_2d[:,3] ``` ## (二)機器學習 Q&A **Q1. 資料適合哪一種機器學習方式?** * 樣本數大於50才進行機器學習 * 預測類別 * 已貼標籤 => 監督式學習:分類 * 未貼標籤 => 非監督式學習:分群 * 預測數量 * 監督式學習:迴歸 **Q2. 機器學習的三種類型與各自目標** * 監督式學習(迴歸/分類): 標記資料、直接回饋、預測未來 * 非監督式學習(分群):沒有標記沒有回饋、找到隱藏的結構 * 強化式學習:決策過程、獎勵系統、學習一系列的行動 **Q3. 迴歸與分類差異** * 迴歸: 預測連續輸出的結果,預估數值 * 分類: 預測離散輸出的結果,預估分類結果 ## (三) joblib 迴歸模型儲存與讀取 `!pip install joblib` ``` # 01. 儲存模型 import joblib joblib.dump(model,'drink_sales.pkl') # 會儲存在暫存資料夾中 # 02. 連結google drive from google.colab import drive drive.mount('/content/drive',force_remount=True) # 03. 載入模型 import joblib model=joblib.load('/content/drive/MyDrive/%path%') ``` # 第一章、資料預處理 Data Processing :::danger **安裝 [Scikit-learn 機器學習工具包](https://scikit-learn.org/stable/)** `!pip install scikit-learn` ::: :::warning * **[訓練組、受試組拆分模型](https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.train_test_split.html)** `from sklearn.model_selection import train_test_split` ::: ``` # ----- 定義變量 (接受二維資料)----- # # Explanatory Variable(s) or Feature(s) (自變量/獨立變數/特徵) X = pd.DataFrame(new_films, columns=['USD_Production_Budget']) # Response Variable or Target (應變量/控制變數/目標) y = pd.DataFrame(new_films, columns=['USD_Worldwide_Gross']) # ----- 拆解訓練組、受試組 ----- # features = data.iloc[:, :-1] target = data.PRICE X_train, X_test, y_train, y_test = train_test_split( features, # 自變數 target, # 應變數 test_size=0.2, # test數組的大小 random_state=10) # 隨機因子 ``` # 第二章、迴歸 Regression ## 一、簡單線性迴歸 Simple Linear Regression :::warning * **[線性回歸模型](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LinearRegression.html)** `from sklearn.linear_model import LinearRegression` * **誤差值分析** ``` from sklearn.metrics import r2_score from sklearn.metrics import mean_absolute_error from sklearn.metrics import median_absolute_error from sklearn.metrics import mean_squared_error ``` ::: **線性回歸** ![](https://i.imgur.com/nN51sTq.png) ``` # ----- 00. 建立模型 ----- # regression = LinearRegression() # ----- 01. 模型訓練 ----- # # Find the best-fit line (需使用二維資料) regression.fit(X, y) # 截距 Θ(0) intercept print(regression.intercept_) # 斜率 Θ(1) coefficient print(regression.coef_) # ----- 02. 模型預測 ----- # predicted_values = regression.predict(X_train) ``` **模型效度判斷** ``` # ----- Method1: R平方 (R-Squared) ----- # # 又稱為判定係數(coefficient of determination) # 衡量回歸模型的表現 (可以解釋的變數比例) # 若 R-Squared > 0.5 即表示回歸模型具參考價值 regression.score(X, y) # ----- Method2: 誤差值分析 ----- # predicted_values = regression.predict(X_train) residuals = (y_train - predicted_values) # 求誤差值平均、偏態係數,越趨近於0,效度越高 resid_mean = round(residuals.mean(), 2) resid_skew = round(residuals.skew(), 2) sns.displot(residuals, aspect=2, kde=True, color='#00796b') plt.title(f'Residuals Skew ({resid_skew}) Mean ({resid_mean})') plt.show() # ----- Method3:其他誤差值計算 ----- # from sklearn.metrics import r2_score from sklearn.metrics import mean_absolute_error from sklearn.metrics import median_absolute_error from sklearn.metrics import mean_squared_error # 測試組 y_test vs. 預測組 y_pred mean_squared_error(y_test,y_pred) # 平均平方誤差/均方誤差 MSE np.sqrt(mean_squared_error(y_test,y_pred)) # 根號平均平方誤差/均方根誤差 RMSE mean_absolute_error(y_test,y_pred) # 平均絕對值誤差 MAE median_absolute_error(y_test,y_pred) # 中位絕對值誤差 r2_score(y_test,y_pred) # r2_score ``` ![](https://i.imgur.com/M45BJqV.png) :::spoiler **Q&A:sklearn vs. numpy.polyfit()之差異** * 相同部分 sklearn經訓練之後會產生模型,這個模型可以拿來進行預測。 numpy部分亦可以將數值資料帶入方程式中,可以產生結果。 * 不同部分 sklearn經訓練之後的模型,可以儲存模型,以供之後使用。 numpy只能儲存數值,不能儲存方程式。 sklearn經訓練之後的模型,可以進行驗證,評估模型好壞。 numpy只有方程式,若要驗證得自己手動方式寫語法處理。 ::: # 第三章、分類 Classification :::warning * **sklearn 內建資料集** `from sklearn import datasets` * **[感知器學習 Perceptron Learning Algorithm(PLA)](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.Perceptron.html)** `from sklearn.linear_model import Perceptron` * 模型函數: * n_iter:訓練次數,整數 * eta:學習率,為浮點數,介於0到1之間 * 模型範例:`model = Perceptron(max_iter=40, eta0=0.1)` * **[羅吉斯迴歸 Logistic Regression](https://scikit-learn.org/stable/modules/generated/sklearn.linear_model.LogisticRegression.html)** `from sklearn.linear_model import LogisticRegression` * 模型函數: * solver:Algorithm to use in the optimization problem. * `liblinear`:線性-線性分類 * `newton-cg`:平面/二階-牛頓方法,最嚴謹,但速度慢 * `lbfgs`:平面/二階-線性分類,有更動才會載入,速度較牛頓快 * `sag`:平面/一階-梯度下降(依前個數值) * `saga`:平面/一階-梯度下降的擴展,加入L1正規化,避免過度擬合 * 模型範例:`model = LogisticRegression(solver='liblinear')` * **[最近鄰分類 K-Nearest Neighbors(K-NN)](https://scikit-learn.org/stable/modules/generated/sklearn.neighbors.KNeighborsClassifier.html)** `from sklearn.neighbors import KNeighborsClassifier` * 模型函數: * n_neighbors:最近鄰數量,預設為5 * 模型範例:`model = KNeighborsClassifier(n_neighbors=3) * **[支援向量機 Support Vector Machine (SVM)](https://scikit-learn.org/stable/modules/generated/sklearn.svm.SVC.html)** `from sklearn.svm import SVC` * 模型函數: * kernel:Specifies the kernel type to be used in the algorithm. * `linear`:線性 * `poly`:非線性,另可加入degree參數增加模型複雜度,規劃n次方的計算 * `rdf`:非線性,代表高斯轉換 * C:控制分類錯誤的懲罰,控制模型複雜度 * gamma:投射範圍/作用範圍的倒數 * **評估:準確值/分類報告/混淆矩陣** ``` from sklearn.metrics import accuracy_score from sklearn.metrics import classification_report from sklearn.metrics import confusion_matrix ``` ::: ## 一、線性-感知器學習 Perceptron Learning Algorithm(PLA) ![](https://i.imgur.com/qDPkcXW.png) 1. 最早的神經網路模型,由突觸接收(input),若加權(w)後大於閥值(threshold),則判斷為(A),否則為(B) 2. 只能判斷資料為A/B 3. 成立前提為:資料具線性可分性(Linear separability),否則演算法不會停止 4. 因條件嚴苛,故改良為:pocket-PLA * 選出誤差最低的分類線即停止 * 因額外需儲存與比較,運作速度較慢 **Sklearn - Iris資料集** ``` # ----- 00. 載入鳶嘴花資料集 ----- # import pandas as pd from sklearn import datasets iris = datasets.load_iris() # ----- 01. 資料探索 ----- # # 資料集屬性 print(iris.keys()) # 資料集詳細描述 print(iris.DESCR) # 資料型態 print(iris.__class__) # 資料筆數 (共150筆樣本) print(len(iris.data)) # 特徵名稱 (花萼長度、寬度;花瓣長度、寬度) print(iris.feature_names) # 目標名稱 (3個品種) print(iris.target_names) # 分類的目標 print(iris.target) ''' 資料型態 <class 'sklearn.utils.Bunch'> 資料特徵名稱 ['sepal length (cm)', 'sepal width (cm)', 'petal length (cm)', 'petal width (cm)'] 資料目標名稱 iris.target_names ['setosa' 'versicolor' 'virginica'] 資料目標 iris.target [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] ''' # ----- 02. 以DataFrame方式呈現 ----- # # 比對轉換,表示iris.target的意義 species = [iris.target_names[x] for x in iris.target] # 將資料轉換為DataFrame data = pd.DataFrame(iris.data,columns=['sepal length', 'sepal width', 'petal length', 'petal width']) data['species'] = species data['level'] = iris.target # ----- 03. 拆解訓練組與測試組 ----- # from sklearn.model_selection import train_test_split features = data.iloc[:, 1:5] target = data.iloc[:, -1] X_train, X_test, y_train, y_test = train_test_split( features, # 自變數 target, # 應變數 test_size=0.3, # test數組的大小 # random_state=10 # 隨機因子 ) ``` **感知器分類** * 注意若train的資料過多,可能導致過度擬合 ``` from sklearn.linear_model import Perceptron # ----- 00. 訓練分類模型 ----- # # n_iter:訓練次數,整數 # eta :學習率,為浮點數,介於0到1之間 model = Perceptron(max_iter=40, eta0=0.1) model.fit(X_train, y_train) # ----- 01. 進行預測 ----- # predict = model.predict(X_test) print("預測結果: ", predict) print("實際結果: ", np.array(y_test)) # ----- 02. 模型分數評估 ----- # from sklearn.metrics import accuracy_score from sklearn.metrics import classification_report from sklearn.metrics import confusion_matrix print("===== 準確率 accuracy score =====") print(accuracy_score(y_test,predict)) '''分數 > 0.75 極為表現良好''' print("\n===== 混淆矩陣 confussion matrix =====") print("縱軸: 真實數量, 橫軸: 猜測數量\n") print(confusion_matrix(y_test,predict)) print("\n===== 分類報告 classification report =====") print("3種品項的精確率(預測為真), 召回率(事實為真), 兩者平均值, 實際出現次數\n") print("精確度: 從預測正確的角度(橫軸)計算(O, O(猜12=>精確12), X(猜8=>其實7))\n") print("召回率: 從真實正確的角度(橫軸)計算(O, X(正確13=>猜12), O(正確7=>召回7))\n") print(classification_report(y_test,predict)) ``` ![](https://i.imgur.com/b1FpR9a.png) ## 二、線性-羅吉斯迴歸 Logistic Regression ![](https://i.imgur.com/VaZtYFc.png) ![](https://i.imgur.com/h7xoZwC.png) 1. 由PLA延伸,判斷資料可能是A/B的機率 **羅吉斯迴歸** ``` from sklearn.linear_model import LogisticRegression # ----- 00. 訓練分類模型 ----- # model = LogisticRegression(solver='liblinear') model.fit(X_train, y_train) # ----- 01. 進行預測 ----- # predict = model.predict(X_test) print("預測結果: ", predict) print("實際結果: ", np.array(y_test)) # ===== Logistic Regression 額外可針對機率做計算 ===== pd.options.display.float_format = '{:,.2f}'.format predict_probability = model.predict_proba(X_test) print("\n===== Logistic Regression可預測機率 =====\n") print(predict_probability) ''' ===== Logistic Regression可預測機率 ===== [[2.00841669e-02 6.43838219e-01 3.36077614e-01] [2.61997627e-03 3.40084040e-01 6.57295984e-01] [1.58477364e-02 7.44523453e-01 2.39628811e-01] [1.27083409e-03 3.46926469e-01 6.51802697e-01] ''' # ----- 02. 模型分數評估 ----- # print("===== 準確率 accuracy score =====") print(accuracy_score(y_test,predict)) '''分數 > 0.75 極為表現良好''' print("\n===== 混淆矩陣 confussion matrix =====") print("縱軸: 真實數量, 橫軸: 猜測數量\n") print(confusion_matrix(y_test,predict)) print("\n===== 分類報告 classification report =====") print("3種品項的精確率(預測為真), 召回率(事實為真), 兩者平均值, 實際出現次數\n") print("精確度: 從預測正確的角度(橫軸)計算(O, O(猜12=>精確12), X(猜8=>其實7))\n") print("召回率: 從真實正確的角度(橫軸)計算(O, X(正確13=>猜12), O(正確7=>召回7))\n") print(classification_report(y_test,predict)) ``` ## 三、線性-最近鄰分類 K-Nearest Neighbors(K-NN) ``` from sklearn.neighbors import KNeighborsClassifier import numpy as np # ----- 00. 訓練分類模型 ----- # model = KNeighborsClassifier(n_neighbors=3) model.fit(X_train, y_train) # ----- 01. 進行預測 ----- # predict = model.predict(X_test) print("預測結果: ", predict) print("實際結果: ", np.array(y_test)) # ----- 02. 模型分數評估 ----- # print("===== 準確率 accuracy score =====") print(accuracy_score(y_test,predict)) '''分數 > 0.75 極為表現良好''' print("\n===== 混淆矩陣 confussion matrix =====") print("縱軸: 真實數量, 橫軸: 猜測數量\n") print(confusion_matrix(y_test,predict)) print("\n===== 分類報告 classification report =====") print("3種品項的精確率(預測為真), 召回率(事實為真), 兩者平均值, 實際出現次數\n") print("精確度: 從預測正確的角度(橫軸)計算(O, O(猜12=>精確12), X(猜8=>其實7))\n") print("召回率: 從真實正確的角度(橫軸)計算(O, X(正確13=>猜12), O(正確7=>召回7))\n") print(classification_report(y_test,predict)) ``` ![](https://i.imgur.com/bHaV1B9.png) ## 四、平面-支援向量機 Support Vector Machine(SVM) [資料來源](https://medium.com/jameslearningnote/%E8%B3%87%E6%96%99%E5%88%86%E6%9E%90-%E6%A9%9F%E5%99%A8%E5%AD%B8%E7%BF%92-%E7%AC%AC3-4%E8%AC%9B-%E6%94%AF%E6%8F%B4%E5%90%91%E9%87%8F%E6%A9%9F-support-vector-machine-%E4%BB%8B%E7%B4%B9-9c6c6925856b) 1. 適用非線性、高維度資料(特徵欄位>3)