预习
- 逻辑回归用于分类问题
- 决策边界
- 逻辑回归的预测函数
关于sigmoid函数
Sigmoid函数是一个在生物学中常见的S型函数,也称为S型生长曲线。在信息科学中,由于其单增以及反函数单增等性质,Sigmoid函数常被用作神经网络的激活函数,将变量映射到0,1之间。
sigmoid函数也叫Logistic函数,用于隐层神经元输出,取值范围为(0,1),它可以将一个实数映射到(0,1)的区间,可以用来做二分类。
S
(
x
)
=
1
1
+
e
−
x
S(x)=\frac{1}{1+e^{-x}}
S(x)=1+e−x1
S
′
(
x
)
=
S
(
x
)
(
1
−
S
(
x
)
)
S'(x)=S(x)(1-S(x))
S′(x)=S(x)(1−S(x))
值域
[
0
,
1
]
[0,1]
[0,1]
- 逻辑回归的代价函数(求min)
分类模型的性能评估
- 混淆矩阵
- 准确率、正确率、召回率
- F-score
- ROC&AUC
决策边界
当
θ
0
+
θ
1
x
1
+
.
.
.
+
θ
n
x
n
≥
0
,
y
=
1
\theta_0+\theta_1x_1+...+\theta_nx_n \ge 0,y=1
θ0+θ1x1+...+θnxn≥0,y=1
当
θ
0
+
θ
1
x
1
+
.
.
.
+
θ
n
x
n
≤
0
,
y
=
0
\theta_0+\theta_1x_1+...+\theta_nx_n \le 0,y=0
θ0+θ1x1+...+θnxn≤0,y=0
线性可分的
非线性可分的:引入高次项
建模:找出决策边界的系数
θ
i
\theta_i
θi
模型
θ
\theta
θ,样本
x
x
x,真实值
y
y
y
θ
T
x
=
θ
0
x
0
+
θ
1
x
1
+
.
.
.
+
θ
n
x
n
\theta^Tx=\theta_0x_0+\theta_1x_1+...+\theta_nx_n
θTx=θ0x0+θ1x1+...+θnxn
找出一组
θ
i
\theta_i
θi使得n维向量
X
X
X降维成一维
x
x
x
x
≥
0
x \ge 0
x≥0为一类,
x
<
0
x<0
x<0为另一类。
预测函数
h
θ
(
x
)
=
g
(
θ
T
x
)
h_{\theta}(x)=g(\theta^Tx)
hθ(x)=g(θTx),其中
g
(
x
)
g(x)
g(x)函数是sigmoid函数
g
(
x
)
=
1
1
+
e
−
x
g(x)=\frac{1}{1+e^{-x}}
g(x)=1+e−x1
h
θ
(
x
)
=
1
1
+
e
−
θ
T
x
h_{\theta}(x)=\frac{1}{1+e^{-\theta^Tx}}
hθ(x)=1+e−θTx1
表示分类为
y
=
1
y=1
y=1的概率
当
x
≥
0
,
h
θ
(
x
)
≥
0.5
x \ge0,h_{\theta}(x) \ge 0.5
x≥0,hθ(x)≥0.5,归为1类的概率大于0.5
代价函数
c
o
s
t
(
h
θ
(
x
)
,
y
)
=
−
y
l
o
g
(
h
θ
(
x
)
)
−
(
1
−
y
)
l
o
g
(
1
−
h
θ
(
x
)
)
cost(h_{\theta}(x),y)=-ylog(h_{\theta}(x))-(1-y)log(1-h_{\theta}(x))
cost(hθ(x),y)=−ylog(hθ(x))−(1−y)log(1−hθ(x))
J ( θ ) = − 1 m ∑ i = 1 m [ y l o g ( h θ ( x ) ) + ( 1 − y ) l o g ( 1 − h θ ( x ) ) ] J(\theta)=-\frac{1}{m}\sum_{i=1}^m \Big[ylog(h_{\theta}(x))+(1-y)log(1-h_{\theta}(x)) \Big] J(θ)=−m1∑i=1m[ylog(hθ(x))+(1−y)log(1−hθ(x))]
代价函数形式的推导:
模型的求解
梯度下降法
import matplotlib.pyplot as plt
import numpy as np
from sklearn.metrics import classification_report #用于评估模型的性能
from sklearn import preprocessing #用于数据标准化预处理
scale = False # 数据是否需要标准化
# 载入数据
data = np.genfromtxt("LR-testSet.csv", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1]
print(x_data)
print(y_data)
def plot():
x1_0 = []
x2_0 = []
x1_1 = []
x2_1 = []
# 切分不同类别的数据
for i in range(len(x_data)):
if y_data[i]==0:
x1_0.append(x_data[i,0])
x2_0.append(x_data[i,1])
else:
x1_1.append(x_data[i,0])
x2_1.append(x_data[i,1])
# 画图
scatter0 = plt.scatter(x1_0, x2_0, c='b', marker='o')
scatter1 = plt.scatter(x1_1, x2_1, c='r', marker='x')
#画图例
plt.legend(handles=[scatter0,scatter1],labels=['label0','label1'],loc='best') #loc表示图例的位置
plot()
plt.show()
# 数据处理,添加偏置项
print(x_data.shape)
print(y_data.shape)
print(np.mat(x_data).shape)
print(np.mat(y_data).shape)
# 给样本添加偏置项
X_data = np.concatenate((np.ones((100,1)),x_data),axis=1)
print(X_data)
print(X_data.shape)
y_data = data[:,-1,np.newaxis]
print(y_data.shape)
def sigmoid(x):
return 1.0/(1+np.exp(-x))
def cost(xMat, yMat, ws): #计算代价
left = np.multiply(yMat, np.log(sigmoid(xMat*ws))) # multiply表示矩阵按对应位置相乘
right = np.multiply(1 - yMat, np.log(1 - sigmoid(xMat*ws)))
return np.sum(left + right) / -(len(xMat))
def gradAscent(xArr, yArr): #梯度下降
if scale == True:
xArr = preprocessing.scale(xArr)
xMat = np.mat(xArr)
yMat = np.mat(yArr)
lr = 0.001
epochs = 10000
costList = []
# 计算数据行列数
# 行代表数据个数,列代表权值个数
m,n = np.shape(xMat)
# 初始化权值
ws = np.mat(np.ones((n,1)))
for i in range(epochs+1): #迭代10001次,最后一次i=10000
# xMat和weights矩阵相乘
h = sigmoid(xMat*ws) #xMat:(100,3); ws:(3,1); h:(100,1)
# 计算误差
ws_grad = xMat.T*(h - yMat)/m # xMat.T: (3,100) ; h - yMat:(100,1); ws_grad:(3,1)
ws = ws - lr*ws_grad
if i % 50 == 0:
costList.append(cost(xMat,yMat,ws))
return ws,costList
# 训练模型,得到权值和cost值的变化
ws,costList = gradAscent(X_data, y_data)
print(ws)
if scale == False:
# 画图决策边界
plot()
x_test = [[-4],[3]]
y_test = (-ws[0] - x_test*ws[1])/ws[2]
plt.plot(x_test, y_test, 'k') #k:black
plt.show()
# 画图 loss值的变化
x = np.linspace(0,10000,201)
print(x)
plt.plot(x, costList, c='r')
plt.title('Train')
plt.xlabel('Epochs')
plt.ylabel('Cost')
plt.show()
# 预测
def predict(x_data, ws):
if scale == True:
x_data = preprocessing.scale(x_data)
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_data, ws)
y_data = data[:,-1]
print(y_data)
print(predictions)
print(classification_report(y_data, predictions))
sklearn
import numpy as np
from sklearn.metrics import classification_report
from sklearn import preprocessing
from sklearn import linear_model
# 数据是否需要标准化
scale = False
# 载入数据
data = np.genfromtxt("LR-testSet.csv", delimiter=",")
x_data = data[:,:-1]
y_data = data[:,-1]
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()
logistic = linear_model.LogisticRegression()
logistic.fit(x_data, y_data)
if scale == False:
# 画图决策边界
plot()
x_test = np.array([[-4],[3]])
print(logistic.coef_)
y_test = (-logistic.intercept_ - x_test*logistic.coef_[0][0])/logistic.coef_[0][1]
plt.plot(x_test, y_test, 'k')
plt.show()
predictions = logistic.predict(x_data)
print(classification_report(y_data, predictions))