Classification:
邏輯迴歸(Logistic Regression):
- 作用:
- hypothesis函數在這裏與線性迴歸是不同的:
- 當h(x)>0.5,就會被歸爲正向類;當h(x)<0.5時就會被歸爲負向類
- 在參數與特徵值已知的情況下,y=0或1的概率
- 下面這個圖像描述了g(z)與z之間的關係:
1、當z<0,即theta的轉置特徵值<0:g(z)就會被歸到0類
2、當z>0,即theta的轉置特徵值>0:g(z)就會被歸到1類
現在假設我們有一個模型:
並且參數θ 是向量[-3 1 1],則當-3+x_1+x_2≥0,即x_1+x_2≥3時,模型將預測 y=1。 我們可以繪製直線x_1+x_2=3,這條線便是我們模型的分界線,將預測爲1的區域和預測爲 0的區域分隔開。
同樣的,如果有個更復雜的模型,會用一條更擬合的線來分割
- 代價函數:
若我們繼續使用計算線性迴歸代價函數的公式去計算Logistic迴歸的圖,那麼我們就會得到下面的左圖這樣的結果,就不能夠獲取全局最優解。
所以我們將代價函數重新定義:
其中:
代價函數與x函數的關係如下:
當我們的y=1時,當h函數趨於0時,Cost趨於無窮大。也就是說,本來一個人是患有腫瘤的機率很大,那麼預測一個人不患有腫瘤,我們會付出很大的代價。
當y=0時
代價函數化簡組合:
- 梯度下降函數計算最優代價函數:
實例練習:
- 首先定義一個函數用來分割特徵值和標籤值
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.metrics import classification_report#這個包是評價報告
def getXY(Data):
"""獲取特徵值列和標籤列
Params:
Data:原始數據
return:
特徵值列;標籤列"""
m = Data.shape[0]
x0 = pd.DataFrame(np.ones(m)) #增加一列x0初始化爲1
data = pd.concat([x0,Data],axis=1) #組合數據
return np.array(data.iloc[:,:-1])#返回0到倒數第二列,np.array(data.iloc[:,-1])#返回最後一列,即標籤列
def normalize(data):
"""縮放數據"""
return data.apply(lambda x : (x-x.mean())/x.std())
if __name__ == '__mian__':
Data = pd.Data=pd.read_csv('ex2data1.txt',names=['eaxm1','exam2','admitted'])
Data.head()
運行結果如下:
- 寫代價函數:
def sigmoid(theta,X):
"""計算hypothesis函數
Params:
theta:初始化的參數
X:特徵值數據
return h函數值"""
return 1/(1+np.exp(-(X @ theta)))
- 更具上邊的公式計算代價函數
def cost(theta,X,Y):
"""根據公式計算代價函數
"""
return np.mean(-Y*np.log(sigmoid(theta,X))- (1-Y)*np.log(1-sigmoid(theta,X)))
- 根據上面公式計算代價函數的導數
def gradDscent(theta,X,Y):
theta_ = theta.copy()
h = sigmoid(theta_,X)
error = h-Y
g = (1/len(X))*(X.T@error)
return g
- 利用scipy.optimize庫來計算最優擬合theta
import scipy.optimize as opt
def getXY(Data):
"""獲取特徵值列和標籤列
Params:
Data:原始數據
return:
特徵值列;標籤列"""
m = Data.shape[0]
x0 = pd.DataFrame(np.ones(m)) #增加一列x0初始化爲1
data = pd.concat([x0,Data],axis=1) #組合數據
return np.array(data.iloc[:,:-1])#返回0到倒數第二列,np.array(data.iloc[:,-1])#返回最後一列,即標籤列
def cost(theta,X,Y):
"""根據公式計算代價函數
Params:
theta:初始化的theta
X:特徵值
Y:分類變量
return:
cost函數的值"""
return np.mean(-Y*np.log(sigmoid(theta,X))- (1-Y)*np.log(1-sigmoid(theta,X)))
def gradDscent(theta,X,Y):
"""根據公式計算cost函數的導數
Params:
theta:初始化的theta
X:特徵值
Y:分類變量
return:
g: cost函數的導數"""
theta_ = theta.copy()
h = sigmoid(theta_,X)
error = h-Y
g = (1/len(X))*(X.T@error)
return g
if __name__=='__main__':
Data = pd.Data=pd.read_csv('ex2data1.txt',names=['eaxm1','exam2','admitted'])
X,Y=getXY(Data)
n = X.shape[1]
theta = np.zeros(n)
res = opt.minimize(fun=cost,x0=theta,args=(X,Y),method = 'Newton-CG',jac=gradDsecent)
print(res)
print(res.x)#最優擬合參數
- 寫一個測試函數:
def predict(X,final_theta):
"""計算預測的結果
Params:
X:特徵值
final_theta:最優擬合值
return:
預測的分類結果"""
prob = sigmoid(theta,X)
return (prob>=0.5).astype(int) #用0,1代替bool值
if __name__=='__main__':
final_theta = res.x
y_pred = predict(X,final_theta)
print(y_pred)
print(classification_report(Y,y_pred))#預測報告
結果如下:
- 計算決策邊界線,並畫圖:
(注:如果特徵值有兩個,那麼通常把最後一個當做y,然後根據上面的公式即可計算。)
y = (-res.x[0]-res.x[1]*X[:,1])/res.x[2]
sns.set(context="notebook", style="ticks", font_scale=1.5) #圖片的風格
sns.lmplot('eaxm1','exam2',hue='admitted',data=Data,size=6,fit_reg=False,scatter_kws={"s":50})
# 列名;hue:分類變量;data:要檢索的數據集;size:圖片大小;scatter_kws:散點大小
plt.plot(X[:,1],y)
plt.xlim(0,130)#顯示x的邊界
plt.ylim(0,130)
plt.show()
結果如下:
參考資料: