如何評價演算法的好壞?
- 2019 年 11 月 27 日
- 筆記
來源:林驥
序言
評價一個演算法的好壞,我認為關鍵是看能不能解決問題。如果演算法能很好地解決實際的問題,那麼我認為就是好演算法。比如預測的演算法,關鍵是看預測的準確率,即預測值與實際值之間的接近程度,而不是看演算法本身的評分高低。
在《如何用人工智慧預測雙 11 的交易額》這篇文章中,利用線性回歸演算法,我預測 2019 年雙 11 交易額為 2471 億元,而阿里官方公布的實際交易額是 2684 億元,預測值比實際值少 7.9%,對這個結果,我覺得準確率不夠高。反思預測的過程,我認為可以從以下幾個方面來進行改進。
1. 樣本
為了簡化演算法模型,我捨棄掉了前幾年相對較小的數據,只保留了最近 5 年的數據。
在數據量本身就比較少的情況下,我仍然遵循簡單原則,這無形中就加大了演算法不穩定的風險,出現了欠擬合的問題。
儘管演算法的評分很高,但是評分高並不代表演算法就好。所以,樣本的選擇非常重要,不能單純地追求演算法的評分高,而忽略樣本的品質。
2. 演算法
如果保留所有樣本,那麼顯然數據呈現的規律並不是線性的,用多項式回歸演算法應該是個更好的選擇。
假如用三次多項式回歸演算法進行預測,那麼演算法程式碼如下:
# 導入所需的庫 import numpy as np import pandas as pd import matplotlib.pyplot as plt from sklearn.linear_model import LinearRegression from sklearn.preprocessing import PolynomialFeatures from sklearn.pipeline import Pipeline from sklearn.preprocessing import StandardScaler # 內嵌畫圖 %matplotlib inline # 設置正常顯示中文標籤 plt.rcParams['font.sans-serif'] = ['SimHei'] # 讀取數據,在林驥的公眾號後台回復「1111」 df = pd.read_excel('./data/1111.xlsx') # x 年份 x = np.array(df.iloc[:, 0]).reshape(-1, 1) # y 交易額 y = np.array(df.iloc[:, 1]) # z 預測的年份 z = [[2019]] # 用管道的方式調用多項式回歸演算法 poly_reg = Pipeline([ ('ploy', PolynomialFeatures(degree=3)), ('std_scaler', StandardScaler()), ('lin_reg', LinearRegression()) ]) poly_reg.fit(x, y) # 用演算法進行預測 predict = poly_reg.predict(z) # 輸出預測結果 print('預測 2019 年雙 11 的交易額是', str(round(predict[0],0)), '億元。') print('線性回歸演算法的評分:', poly_reg.score(x, y))
預測 2019 年雙 11 的交易額是 2689.0 億元。 線性回歸演算法的評分:0.99939752363314
下面是用 matplotlib 畫圖的程式碼:
# 將數據可視化,設置影像大小 fig = plt.figure(figsize=(10, 8)) ax = fig.add_subplot(111) # 繪製散點圖 ax.scatter(x, y, color='#0085c3', s=100) ax.scatter(z, predict, color='#dc5034', marker='*', s=260) # 設置標籤等 plt.xlabel('年份', fontsize=20) plt.ylabel('雙 11 交易額', fontsize=20) plt.tick_params(labelsize=20) # 繪製預測的直線 x2 = np.concatenate([x, z]) y2 = poly_reg.predict(x2) plt.plot(x2, y2, '-', c='#7ab800') plt.title('用多項式回歸預測雙 11 的交易額', fontsize=26) plt.show()

這近乎完美地擬合了 2009 年以來十一年的數據,因此不禁讓人懷疑,阿里的數據是不是過於完美?
3. 優化
按照一般的機器學習演算法流程,應該把數據拆分為兩部分,分別稱為訓練數據集和測試數據集。從 2009 年到 2018 年,雙 11 的交易額總共才 10 個數據,我在預測的時候還捨棄了前 5 個數據,最後只剩下 5 個數據,我以為再拆分就沒有必要了。但機器學習演算法的表現好壞,有一個關鍵因素,就是要有足夠多的數據量。
另外,應該適當地使用網格搜索法,優化演算法的參數,必要時還要與交叉驗證法相結合,進行演算法評估,從而提高演算法的可信度和準確率。除了演算法的準確率,還可以使用其他的方法對模型進行評價,比如:召回率、F1 分數、ROC、AUC、MSE、RMSE、MAE 等等。
現實世界是錯綜複雜的,很難用一個演算法就解決問題,往往需要經過很多次的嘗試,才可能找到基本符合的模型。需要注意的是,多項式回歸的指數不宜過高,否則演算法太複雜,很可能出現「過擬合」的現象,從而泛化能力比較差,也就是說,對於訓練數據集能夠很好地擬合,但是對於測試數據集的預測誤差比較大。模型複雜度與預測誤差的大致關係如下圖所示:

小結
本文是我在用線性回歸演算法預測雙 11 的交易額之後,做的一次復盤,總結了改進的思路,學習優化的方法。
學以致用,是我學習的基本原則。如果害怕出錯,不去勇於實踐,學習再多演算法有什麼用?這就如同我們不能指望不下水就學會游泳一樣。
以上,希望能夠對你有所啟發。