Part1-逻辑回归练习
逻辑回归
1.1 可视化数据
1 2 3 import pandas as pddata = 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
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 optresult = 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' ) 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 pdimport numpy as npdata = 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 = {} 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 ): 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 optresult = 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_modelmodel = 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 pltx = 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()