非線性邏輯回歸的代碼實作(梯度下降法)
當我們需要分類這樣的資料集的時候,線性的邏輯回歸就派不上用場了
前期的代碼子產品都與線性邏輯回歸的步驟一緻。
線性邏輯回歸的代碼實作:
https://mp.csdn.net/mdeditor/90899227#
載入資料
data = np.genfromtxt(r'data.txt',delimiter=',')
x_data = data[:, :-1]
y_data = data[:, -1, np.newaxis]
對原始資料畫圖
def plot():
x0 = []
x1 = []
y0 = []
y1 = []
# 切分不同資料
for i in range(len(x_data)):
if y_data[i] == 0:
x0.append(x_data[i, 0])
y0.append(x_data[i, 1])
else:
x1.append(x_data[i, 0])
y1.append(x_data[i, 1])
# 畫圖
scatter0 = plt.scatter(x0, y0, c='b', marker='o')
scatter1 = plt.scatter(x1, y1, c='r', marker='x')
#畫圖例
plt.legend(handles=[scatter0, scatter1], labels=['label0', 'label1'], loc='best')
plot()
plt.show()
生成非線性項:
from sklearn.preprocessing import PolynomialFeatures
# 定義多項式回歸,degree的值可以調節多項式的特征
poly_reg = PolynomialFeatures(degree=3)
# 特征處理
x_poly = poly_reg.fit_transform(x_data)
利用sklearn.preprocessing import PolynomialFeatures來建構特征項,其中degree控制多項式的度。
例如,如果有a,b兩個特征,那麼它的2次多項式為(1,a,b,a^2,ab, b^2)
利用代碼來看一看,這裡a=2,b=3,degree=3,
是以它列印出來的是1,a,b,a²,ab,b²,a³,a²b,ab²,b³
定義sigmoid函數、代價函數、梯度下降法
def sigmoid(x):
return 1.0/(1+np.exp(-x))
def cost(xMat, yMat, ws):
left = np.multiply(yMat, np.log(1-sigmoid(xMat*ws)))
right = np.multiply(1-yMat, np.log(1-sigmoid(xMat * ws)))
return np.sum(left + right) / -(len(xMat))
def gradDscent(xArr, yArr):
if scale == True:
xArr = preprocessing(xArr)
xMat = np.mat(xArr)
yMat = np.mat(yArr)
lr = 0.03
epochs = 50000
costList = []
#計算資料列數,有幾列就有幾個權值
m, n = np.shape(xMat)
#初始化權值
ws = np.mat(np.ones((n, 1)))
for i in range(epochs+1):
# xMat和weights矩陣相乘
h = sigmoid(xMat*ws)
# 計算誤差
ws_grad = xMat.T*(h-yMat)/m
ws = ws - lr * ws_grad
if i % 50 == 0:
costList.append(cost(xMat, yMat, ws))
return ws, costList
得到degree=3時各項的權值
#訓練模型,得到權值和cost值的變化
ws, costList = gradDscent(x_poly, y_data)
print(ws)
至此,結果已經得出。
接下來就是作圖
作圖
# 擷取資料所在的範圍
x_min, x_max = x_data[:, 0].min() - 1, x_data[:, 0].max() + 1
y_min, y_max = x_data[:, 1].min() - 1, x_data[:, 1].max() + 1
# 生成網格矩陣
xx, yy = np.meshgrid(np.arange(x_min, x_max, 0.02), np.arange(y_min, y_max, 0.02))
# 進行判斷
z = sigmoid(poly_reg.fit_transform(np.c_[xx.ravel(), yy.ravel()]).dot(np.array(ws)))
# ravel與flatten類似,多元資料轉一維
for i in range(len(z)):
if z[i] > 0.5:
z[i] = 1
else:
z[i] = 0
z = z.reshape(xx.shape)
注:ravel與flatten類似,多元資料轉一維
flatten不會改變原始資料,ravel會改變原始資料
做等高線圖觀察
z的值隻會是0或1,在等高線圖中,z代表高度,是以屬于不同類的資料可以很直覺地觀察出來。
cs = plt.contourf(xx, yy, z)
plot()
plt.show()
預測
def predict(x_data, ws):
xMat = np.mat(x_data)
ws = np.mat(ws)
return [1 if x >= 0.5 else 0 for x in sigmoid(xMat*ws)]
predictions = predict(x_poly, ws)
print(classification_report(y_data, predictions))