- 原文地址:Can Machine Learning model simple Math functions?
- 原文做者:Harsh Sahu
- 譯文出自:掘金翻譯計劃
- 本文永久連接:github.com/xitu/gold-m…
- 譯者:Minghao23
- 校對者:lsvih,zoomdong
使用機器學習建模一些基礎數學函數前端
近來,在各類任務上應用機器學習已經成爲了一個慣例。彷佛在每個 Gartner's 技術循環曲線 上的新興技術都對機器學習有所涉及,這是一種趨勢。這些算法被當作 figure-out-it-yourself 的模型:將任何類型的數據都分解爲一串特徵,應用一些黑盒的機器學習模型,對每一個模型求解並選擇結果最好的那個。python
可是機器學習真的能解決全部的問題嗎?仍是它只適用於一小部分的任務?在這篇文章中,咱們試圖回答一個更基本的問題,即機器學習可否推導出那些在平常生活中常常出現的數學關係。在這裏,我會嘗試使用一些流行的機器學習技術來擬合幾個基礎的函數,並觀察這些算法可否識別並建模這些基礎的數學關係。android
咱們將要嘗試的函數:ios
將會用到的機器學習算法:git
我會保持因變量(譯者注:原文錯誤,應該爲自變量)的維度爲 4(選擇這個特殊的數字並無什麼緣由)。因此,X(自變量)和 Y(因變量)的關係爲:github
f :- 咱們將要擬合的函數算法
Epsilon:- 隨機噪聲(使 Y 更加真實一點,由於現實生活中的數據中老是存在一些噪聲)後端
每一個函數類型都會用到一系列的參數。這些參數經過生成隨機數獲得,方法以下:網絡
numpy.random.normal()
numpy.random.randint()
複製代碼
randint() 用於獲取冪函數的參數,以避免 Y 的值特別小。normal() 用於全部其餘狀況。dom
生成自變量(即 X):
function_type = 'Linear'
if function_type=='Logarithmic':
X_train = abs(np.random.normal(loc=5, size=(1000, 4)))
X_test = abs(np.random.normal(loc=5, size=(500, 4)))
else:
X_train = np.random.normal(size=(1000, 4))
X_test = np.random.normal(size=(500, 4))
複製代碼
對於對數函數,使用均值爲 5(均值遠大於方差)的正態分佈來避省得到負值。
獲取因變量(即 Y):
def get_Y(X, function_type, paras):
X1 = X[:,0]
X2 = X[:,1]
X3 = X[:,2]
X4 = X[:,3]
if function_type=='Linear':
[a0, a1, a2, a3, a4] = paras
noise = np.random.normal(scale=(a1*X1).var(), size=X.shape[0])
Y = a0+a1*X1+a2*X2+a3*X3+a4*X4+noise
elif function_type=='Exponential':
[a0, a1, a2, a3, a4] = paras
noise = np.random.normal(scale=(a1*np.exp(X1)).var(), size=X.shape[0])
Y = a0+a1*np.exp(X1)+a2*np.exp(X2)+a3*np.exp(X3)+a4*np.exp(X4)+noise
elif function_type=='Logarithmic':
[a0, a1, a2, a3, a4] = paras
noise = np.random.normal(scale=(a1*np.log(X1)).var(), size=X.shape[0])
Y = a0+a1*np.log(X1)+a2*np.log(X2)+a3*np.log(X3)+a4*np.log(X4)+noise
elif function_type=='Power':
[a0, a1, a2, a3, a4] = paras
noise = np.random.normal(scale=np.power(X1,a1).var(), size=X.shape[0])
Y = a0+np.power(X1,a1)+np.power(X2,a2)+np.power(X2,a2)+np.power(X3,a3)+np.power(X4,a4)+noise
elif function_type=='Modulus':
[a0, a1, a2, a3, a4] = paras
noise = np.random.normal(scale=(a1*np.abs(X1)).var(), size=X.shape[0])
Y = a0+a1*np.abs(X1)+a2*np.abs(X2)+a3*np.abs(X3)+a4*np.abs(X4)+noise
elif function_type=='Sine':
[a0, a1, b1, a2, b2, a3, b3, a4, b4] = paras
noise = np.random.normal(scale=(a1*np.sin(X1)).var(), size=X.shape[0])
Y = a0+a1*np.sin(X1)+b1*np.cos(X1)+a2*np.sin(X2)+b2*np.cos(X2)+a3*np.sin(X3)+b3*np.cos(X3)+a4*np.sin(X4)+b4*np.cos(X4)+noise
else:
print('Unknown function type')
return Y
if function_type=='Linear':
paras = [0.35526578, -0.85543226, -0.67566499, -1.97178384, -1.07461643]
Y_train = get_Y(X_train, function_type, paras)
Y_test = get_Y(X_test, function_type, paras)
elif function_type=='Exponential':
paras = [ 0.15644562, -0.13978794, -1.8136447 , 0.72604755, -0.65264939]
Y_train = get_Y(X_train, function_type, paras)
Y_test = get_Y(X_test, function_type, paras)
elif function_type=='Logarithmic':
paras = [ 0.63278503, -0.7216328 , -0.02688884, 0.63856392, 0.5494543]
Y_train = get_Y(X_train, function_type, paras)
Y_test = get_Y(X_test, function_type, paras)
elif function_type=='Power':
paras = [2, 2, 8, 9, 2]
Y_train = get_Y(X_train, function_type, paras)
Y_test = get_Y(X_test, function_type, paras)
elif function_type=='Modulus':
paras = [ 0.15829356, 1.01611121, -0.3914764 , -0.21559318, -0.39467206]
Y_train = get_Y(X_train, function_type, paras)
Y_test = get_Y(X_test, function_type, paras)
elif function_type=='Sine':
paras = [-2.44751615, 1.89845893, 1.78794848, -2.24497666, -1.34696884, 0.82485303, 0.95871345, -1.4847142 , 0.67080158]
Y_train = get_Y(X_train, function_type, paras)
Y_test = get_Y(X_test, function_type, paras)
複製代碼
噪聲是在 0 均值的正態分佈中隨機抽樣獲得的。我設置了噪聲的方差等於 f(X) 的方差,藉此保證咱們數據中的「信號和噪聲」具備可比性,且噪聲不會在信號中有損失,反之亦然。
注意:在任何模型中都沒有作超參數的調參。 咱們的基本想法是隻在這些模型對所說起的函數上的表現作一個粗略的估計,所以沒有對這些模型作太多的優化。
model_type = 'MLP'
if model_type=='XGBoost':
model = xgb.XGBRegressor()
elif model_type=='Linear Regression':
model = LinearRegression()
elif model_type=='SVR':
model = SVR()
elif model_type=='Decision Tree':
model = DecisionTreeRegressor()
elif model_type=='Random Forest':
model = RandomForestRegressor()
elif model_type=='MLP':
model = MLPRegressor(hidden_layer_sizes=(10, 10))
model.fit(X_train, Y_train)
複製代碼
大多數的表現結果比平均基線要好不少。計算出的平均R方是 70.83%,咱們能夠說,機器學習技術對這些簡單的數學函數確實能夠有效地建模。
可是經過這個實驗,咱們不只知道了機器學習可否建模這些函數,同時也瞭解了不一樣的機器學習技術在各類基礎函數上的表現是怎樣的。
有些結果是使人驚訝的(至少對我來講),有些則是合理的。總之,這些結果從新認定了咱們的一些先前的想法,也給出了新的想法。
最後,咱們能夠獲得下列結論:
完整代碼見個人 github。
來點贊,評論和分享吧。建設性的批評和反饋老是受歡迎的!
若是發現譯文存在錯誤或其餘須要改進的地方,歡迎到 掘金翻譯計劃 對譯文進行修改並 PR,也可得到相應獎勵積分。文章開頭的 本文永久連接 即爲本文在 GitHub 上的 MarkDown 連接。
掘金翻譯計劃 是一個翻譯優質互聯網技術文章的社區,文章來源爲 掘金 上的英文分享文章。內容覆蓋 Android、iOS、前端、後端、區塊鏈、產品、設計、人工智能等領域,想要查看更多優質譯文請持續關注 掘金翻譯計劃、官方微博、知乎專欄。