0%

Part1-逻辑回归练习

Part1-逻辑回归练习

逻辑回归

1.1 可视化数据

1
2
3
import pandas as pd
data = pd.read_csv('ex2data1.txt', names=['Exam1 score','Exam2 score','Class'])
data.head()

1
2
data_class0 = data[data.Class==0]
data_class1 = data[data.Class==1]
1
2
3
4
5
6
7
8
import matplotlib.pyplot as plt
_, ax = plt.subplots()
ax.scatter(data_class0['Exam1 score'],y=data_class0['Exam2 score'], c='yellow', edgecolors='black', label='No admitted')
ax.scatter(data_class1['Exam1 score'],y=data_class1['Exam2 score'], c='black', marker='+', label='Admitted')
ax.set_xlabel('Exam1 score')
ax.set_ylabel('Exam2 score')
ax.legend()
plt.show()
image-20210707210801462
image-20210707210801462

1.2 sigmoid函数

1
2
def sigmoid(z):
return 1/(1+np.exp(-z))
1
2
# 测试
plt.plot(np.arange(-10,10,step=0.5),sigmoid(np.arange(-10,10,step=0.5)))

1.3 代价函数和梯度

1
2
def compute_cost(theta, X, y):
return 1/X.shape[0]*np.sum(-y*np.log(sigmoid(X@theta))-(1-y)*np.log(1-sigmoid(X@theta)))
1
2
3
4
5
X = data.iloc[:,:2]
X.insert(0, 'Ones', np.ones(X.shape[0]))
X = X.values
y = data.iloc[:, 2].values
theta = np.zeros(X.shape[1])
1
compute_cost(theta, X, y)

0.6931471805599453

1
2
def compute_grad(theta, X, y):
return X.T@(sigmoid(X@theta)-y)/X.shape[0]
1
compute_grad(X, y, theta)

array([ -0.1 , -12.00921659, -11.26284221])

1.4 使用fminunc学习参数

1
2
3
import scipy.optimize as opt
result = opt.fmin_tnc(func=compute_cost, x0=theta, fprime=compute_grad, args=(X, y))
result

(array([-25.16131878, 0.20623159, 0.20147149]), 36, 0)

1
compute_cost(result[0], X, y)

0.20349770158947394

1.5 评估

1
2
def predict(theta, X):
return [1 if x>=0.5 else 0 for x in sigmoid(X@theta)]
1
2
3
pre = predict(result[0],X)
acc = np.sum(pre==y)/X.shape[0]
f'acc={acc*100}%'

acc=89.0%

1
2
3
4
5
6
7
8
9
10
11
import matplotlib.pyplot as plt
_, ax = plt.subplots()
ax.scatter(data_class0['Exam1 score'],y=data_class0['Exam2 score'], c='yellow', edgecolors='black', label='No admitted')
ax.scatter(data_class1['Exam1 score'],y=data_class1['Exam2 score'], c='black', marker='+', label='Admitted')
# theta0+theta1*x+theta2y=0
# y = (theta0+theta1*x)/theta2
ax.plot(np.arange(30,100), -(result[0][0]+np.arange(30,100)*result[0][1])/result[0][2])
ax.set_xlabel('Exam1 score')
ax.set_ylabel('Exam2 score')
ax.legend()
plt.show()

正则化逻辑回归

2.1 数据可视化

1
2
3
4
import pandas as pd
import numpy as np
data = pd.read_csv('ex2data.txt', names=['Microchip Test1','Microchip Test2', 'Class'])
data.head()

1
2
data_class1 = data[data.Class==1]
data_class0 = data[data.Class==0]
1
2
3
4
5
6
import matplotlib.pyplot as plt
_, ax = plt.subplots()
ax.scatter(data_class0['Microchip Test1'],data_class0['Microchip Test2'],c='yellow', edgecolors='black', label='y=0')
ax.scatter(data_class1['Microchip Test1'],data_class1['Microchip Test2'],c='black', marker='+' , label='y=1')
ax.legend()
plt.show()

2.2 特征映射

\(mapFeature(x)=\left[\begin{matrix} 1 \\ x_1 \\ x_2 \\ x_1^2 \\ x_1x_2 \\ x_2^2 \\ \cdots \\ x_1x_2^5 \\ x_2^6 \end{matrix} \right]\)

1
2
3
4
5
6
7
8
def feature_map(x1, x2, power=6):
new_data = {}
# new_data['Ones'] = np.ones(x1.shape[0])
for i in np.arange(power+1):
for p in np.arange(i+1):
new_data[f'F{i-p}{p}'] = np.power(x1, i-p)*np.power(x2, p)

return pd.DataFrame(new_data)

1
2
3
4
5
x1 = data['Microchip Test1']
x2 = data['Microchip Test2']
X = feature_map(x1, x2).values
y = data.Class.values
theta = np.zeros(X.shape[1])

2.3 计算损失和梯度

1
2
3
4
def compute_cost(theta, X, y, param_lambda): # m*n n*1
cost = np.sum(-y*np.log(sigmoid(X@theta))-(1-y)*np.log(1-sigmoid(X@theta)))/X.shape[0]
reg = param_lambda*theta[1:]@theta[1:]/(2*X.shape[0])
return cost + reg
1
2
3
4
5
def compute_grad(theta, X, y, param_lambda):
grad = X.T@(sigmoid(X@theta)-y)/X.shape[0]
reg = (param_lambda*theta)/X.shape[0]
reg[0] = 0
return grad + reg
1
compute_cost(theta, X, y, param_lambda=1)

0.6931471805599454

1
compute_grad(theta, X, y, 1)

array([8.47457627e-03, 1.87880932e-02, 7.77711864e-05, 5.03446395e-02, 1.15013308e-02, 3.76648474e-02, 1.83559872e-02, 7.32393391e-03, 8.19244468e-03, 2.34764889e-02, 3.93486234e-02, 2.23923907e-03, 1.28600503e-02, 3.09593720e-03, 3.93028171e-02, 1.99707467e-02, 4.32983232e-03, 3.38643902e-03, 5.83822078e-03, 4.47629067e-03, 3.10079849e-02, 3.10312442e-02, 1.09740238e-03, 6.31570797e-03, 4.08503006e-04, 7.26504316e-03, 1.37646175e-03, 3.87936363e-02])

2.4 学习参数

1
2
3
import scipy.optimize as opt
result = opt.fmin_tnc(func=compute_cost, x0=theta, fprime=compute_grad, args=(X,y,1))
result

(array([ 1.27271026, 0.62529965, 1.18111686, -2.01987399, -0.91743189, -1.43166928, 0.12393227, -0.36553118, -0.35725404, -0.17516292, -1.45817009, -0.05098418, -0.61558556, -0.27469165, -1.19271299, -0.24217841, -0.206033 , -0.04466178, -0.27778949, -0.29539513, -0.45645981, -1.04319155, 0.02779373, -0.29244867, 0.0155576 , -0.32742405, -0.1438915 , -0.92467488]), 32, 1)

2.5 结果评估

1
2
3
pre = predict(result[0],X)
acc = np.sum(pre==y)/X.shape[0]
f'acc={acc*100}%'

acc=83.05084745762711%

整个过程其实还可以使用高级Python库来解决:

1
2
3
4
from sklearn import linear_model
model = linear_model.LogisticRegression(penalty='l2', C=1.0)
model.fit(X, y.ravel())
model.score(X, y)

0.8305084745762712

2.6 结果可视化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import matplotlib.pyplot as plt

x = np.linspace(-1, 1.5, 250)
xx, yy = np.meshgrid(x, x)

z = feature_map(xx.ravel(), yy.ravel(), 6)
z = z @ result[0]
z = z.to_numpy().reshape(xx.shape)

_, ax = plt.subplots()
ax.scatter(data_class0['Microchip Test1'],data_class0['Microchip Test2'],c='yellow', edgecolors='black', label='y=0')
ax.scatter(data_class1['Microchip Test1'],data_class1['Microchip Test2'],c='black', marker='+' , label='y=1')
ax.legend()
plt.contour(xx, yy, z, 0)
plt.show()