學習機器學習-二分類問題分類器,梯度下降法,程式碼展示。
阿新 • • 發佈:2022-04-22
要求:自己生成一個樣本總數為20的兩類資料集,每類分別為10個樣本。實現線性分類器。
基礎知識參考了這份部落格,它是我找到的最詳細的一篇講解。
另外附上GitHub地址:https://github.com/microsoft/ai-edu
這份作業快到截止時間了,我還沒學會神經網路,又沒有找到相關程式碼,於是自己用笨辦法寫了一下程式碼來實現線性分類器。
import matplotlib.pyplot as plt import numpy as np #樣本特徵值 def randrange(n, vmin, vmax): return (vmax - vmin)*np.random.rand(n) + vmin x1_data = np.concatenate((randrange(10, 0, 48),randrange(10, 52, 100))) x2_data = np.concatenate((randrange(10, 0, 48),randrange(10, 52, 100))) #標籤值 list_y=[] for i in range(20): if(i/10<1): list_y.append(0) else: list_y.append(1) y_data = np.asarray(list_y) x_train = np.stack((x1_data,x2_data,y_data)) print(x_train)
這裡生成兩類資料集做訓練用,在生成時要附上標籤值,用來判斷其為哪一類資料。
資料集展示
[[23.56666375 25.09075631 47.12803743 5.8850233 39.49089641 16.8659462 9.44996442 10.05850374 36.45182739 11.74453997 78.19518409 99.49470411 66.32145363 73.78367965 57.99214184 62.30056474 97.47532927 75.63052221 62.84388756 66.49887471] [37.35435583 26.14989834 1.75216991 26.70968015 1.33685583 23.60078884 24.64790623 47.900654 30.20381661 22.00034265 75.20267327 57.68395067 65.05356895 59.25574098 86.86977068 94.68262277 68.93671045 89.87274462 78.86753854 65.03568956] [ 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 1. 1. 1. 1. 1. 1. 1. 1. 1. 1. ]]
#展示樣本資料集
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
這裡可視化了生成的資料集。
#初始化引數 W=np.array([1,1]) rate=0.01 #學習速率 B=40 temp=1000 #學習次數
這一步是初始化訓練相關的引數,在神經網路的介紹裡也能看到對應的值,猶豫我還不會神經網路,所以我將其提出來直接使用。
#訓練函式
def training(W,B,rate,temp):
for j in range(temp):
for i in range(20):
Z=np.dot(x_train[0:2,i],W)+B
a =1.0 / (1.0 + np.exp(-Z))
loss=a-x_train[2,i]
W=W-np.dot(x_train[0:2,i],loss)*rate
B=B-loss*rate
# print(x_train[0:2,i])
# print("W=",W)
# print("B=",B)
# print(Z)
# print(a)
# print(x_train[2,i])
# print(loss)
print("W=",W)
print("B=",B)
return(W,B)
#驗證函式
def verify(x):
Z=np.dot(x,W)+B
a =1.0 / (1.0 + np.exp(-Z))
if (a<0.5):
print(a)
return 0
else:
print(a)
return 1
這裡定義了兩個函式
for i in range(20):
Z=np.dot(x_train[0:2,i],W)+B
a =1.0 / (1.0 + np.exp(-Z))
loss=a-x_train[2,i]
W=W-np.dot(x_train[0:2,i],loss)*rate
B=B-loss*rate
訓練函式裡這一段算是主要函式,在我開頭提到的部落格中有介紹這些公式是怎麼產生的,以及其意義是什麼。
在我的理解中,Z即分類的直線,a即物體所屬的分類,W,B按照loss函式的結果與rate的值進行更新。
後面驗證時算出物體的a的值,即可知道其屬於哪一類。
#訓練過程展示
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
for i in range(20):
x1 = np.linspace(0, 100, 100)
W,B=training(W,B,rate,temp)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
W,B的值隨訓練的變化情況
W= [0.35948076 0.1748828 ]
B= 13.26780449826064
W= [0.77210068 0.75313404]
B= -6.3703509972183925
W= [0.14469182 0.10921083]
B= -10.477108967713642
W= [0.15191845 0.11642575]
B= -11.117629746272264
W= [0.15417136 0.12109126]
B= -11.661601613466757
W= [0.15539298 0.12437233]
B= -12.108067343382372
W= [0.15685185 0.12712868]
B= -12.481884452303593
W= [0.15848816 0.12957921]
B= -12.803578372149296
W= [0.16017228 0.13179975]
B= -13.08645575299053
W= [0.16183213 0.13383368]
B= -13.339239644353153
W= [0.16343551 0.1357114 ]
B= -13.567933719883142
W= [0.16497061 0.13745581]
B= -13.776863359466688
W= [0.16643522 0.13908479]
B= -13.969261581756376
W= [0.16783145 0.14061275]
B= -14.147615946501244
W= [0.16916313 0.14205153]
B= -14.313885256376384
W= [0.17043466 0.14341102]
B= -14.469641425088682
W= [0.17165047 0.14469957]
B= -14.616166033139798
W= [0.17281475 0.14592431]
B= -14.754518171875178
W= [0.17393139 0.14709136]
B= -14.88558338672208
W= [0.17500392 0.14820602]
B= -15.010109775334383
#訓練結果展示
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
x1 = np.linspace(0, 100, 100)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
以上出現的展示程式碼多是重複的,建議去學習一下matplotlib的畫圖操作,自己按需更改程式碼。
#驗證一個點(55,55)的分類
x=[55,55]
print(verify(x))
fig = plt.figure(dpi=144)
ax = fig.add_subplot()
ax.scatter(x_train[0,0:10], x_train[1,0:10], marker="o")
ax.scatter(x_train[0,10:20], x_train[1,10:20], marker="s")
ax.scatter(x[0], x[1], marker="^")
x1 = np.linspace(0, 100, 100)
y1=-(W[0]*x1+B)/W[1]
plt.plot(x1, y1)
ax.set_xlabel('X Label')
ax.set_ylabel('Y Label')
plt.show()
0.9408349606570592
1
綠色三角點,即x點,為自己選擇驗證那個點。也可以用上測試集來驗證。
關於訓練函式部分開頭給出的部落格講的比我清楚,我便不再贅述,程式碼不分,我也不是最好的,但自認為適合初學者參考來理解數學原理與程式碼的結合。
其他部分程式碼都可簡單搜出,不懂可留言討論。