@@ -106,7 +106,7 @@ from sklearn.preprocessing import StandardScaler #引入缩放的包
106106 result = model.predict(x_test)
107107```
108108
109- ## 二、逻辑回归
109+ ## 二、[ 逻辑回归] ( /LogisticRegression )
110110- [ 全部代码] ( /LogisticRegression/LogisticRegression.py )
111111
112112### 1、代价函数
@@ -256,11 +256,147 @@ import numpy as np
256256```
257257
258258
259+ -------------
260+
261+ ## [ 逻辑回归_手写数字识别_OneVsAll] ( /LogisticRegression )
262+ - [ 全部代码] ( /LogisticRegression/LogisticRegression_OneVsAll.py )
263+
264+ ### 1、随机显示100个数字
265+ - 我没有使用scikit-learn中的数据集,像素是20* 20px,彩色图如下
266+ ![ enter description here] [ 9 ]
267+ 灰度图:
268+ ![ enter description here] [ 10 ]
269+ - 实现代码:
270+ ```
271+ # 显示100个数字
272+ def display_data(imgData):
273+ sum = 0
274+ '''
275+ 显示100个数(若是一个一个绘制将会非常慢,可以将要画的数字整理好,放到一个矩阵中,显示这个矩阵即可)
276+ - 初始化一个二维数组
277+ - 将每行的数据调整成图像的矩阵,放进二维数组
278+ - 显示即可
279+ '''
280+ pad = 1
281+ display_array = -np.ones((pad+10*(20+pad),pad+10*(20+pad)))
282+ for i in range(10):
283+ for j in range(10):
284+ display_array[pad+i*(20+pad):pad+i*(20+pad)+20,pad+j*(20+pad):pad+j*(20+pad)+20] = (imgData[sum,:].reshape(20,20,order="F")) # order=F指定以列优先,在matlab中是这样的,python中需要指定,默认以行
285+ sum += 1
286+
287+ plt.imshow(display_array,cmap='gray') #显示灰度图像
288+ plt.axis('off')
289+ plt.show()
290+ ```
291+
292+ ### 2、OneVsAll
293+ - 如何利用逻辑回归解决多分类的问题,OneVsAll就是把当前某一类看成一类,其他所有类别看作一类,这样有成了二分类的问题了
294+ - 如下图,把途中的数据分成三类,先把红色的看成一类,把其他的看作另外一类,进行逻辑回归,然后把蓝色的看成一类,其他的再看成一类,以此类推...
295+ ![ enter description here] [ 11 ]
296+ - 可以看出大于2类的情况下,有多少类就要进行多少次的逻辑回归分类
297+
298+ ### 3、手写数字识别
299+ - 共有0-9,10个数字,需要10次分类
300+ - 由于** 数据集y** 给出的是` 0,1,2...9 ` 的数字,而进行逻辑回归需要` 0/1 ` 的label标记,所以需要对y处理
301+ - 说一下数据集,前` 500 ` 个是` 0 ` ,` 500-1000 ` 是` 1 ` ,` ... ` ,所以如下图,处理后的` y ` ,** 前500行的第一列是1,其余都是0,500-1000行第二列是1,其余都是0....**
302+ ![ enter description here] [ 12 ]
303+ - 然后调用** 梯度下降算法** 求解` theta `
304+ - 实现代码:
305+ ```
306+ # 求每个分类的theta,最后返回所有的all_theta
307+ def oneVsAll(X,y,num_labels,Lambda):
308+ # 初始化变量
309+ m,n = X.shape
310+ all_theta = np.zeros((n+1,num_labels)) # 每一列对应相应分类的theta,共10列
311+ X = np.hstack((np.ones((m,1)),X)) # X前补上一列1的偏置bias
312+ class_y = np.zeros((m,num_labels)) # 数据的y对应0-9,需要映射为0/1的关系
313+ initial_theta = np.zeros((n+1,1)) # 初始化一个分类的theta
314+
315+ # 映射y
316+ for i in range(num_labels):
317+ class_y[:,i] = np.int32(y==i).reshape(1,-1) # 注意reshape(1,-1)才可以赋值
318+
319+ #np.savetxt("class_y.csv", class_y[0:600,:], delimiter=',')
320+
321+ '''遍历每个分类,计算对应的theta值'''
322+ for i in range(num_labels):
323+ result = optimize.fmin_bfgs(costFunction, initial_theta, fprime=gradient, args=(X,class_y[:,i],Lambda)) # 调用梯度下降的优化方法
324+ all_theta[:,i] = result.reshape(1,-1) # 放入all_theta中
325+
326+ all_theta = np.transpose(all_theta)
327+ return all_theta
328+ ```
329+
330+ ### 4、预测
331+ - 之前说过,预测的结果是一个** 概率值** ,利用学习出来的` theta ` 代入预测的** S型函数** 中,每行的最大值就是是某个数字的最大概率,所在的** 列号** 就是预测的数字的真实值,因为在分类时,所有为` 0 ` 的将` y ` 映射在第一列,为1的映射在第二列,依次类推
332+ - 实现代码:
333+ ```
334+ # 预测
335+ def predict_oneVsAll(all_theta,X):
336+ m = X.shape[0]
337+ num_labels = all_theta.shape[0]
338+ p = np.zeros((m,1))
339+ X = np.hstack((np.ones((m,1)),X)) #在X最前面加一列1
340+
341+ h = sigmoid(np.dot(X,np.transpose(all_theta))) #预测
342+
343+ '''
344+ 返回h中每一行最大值所在的列号
345+ - np.max(h, axis=1)返回h中每一行的最大值(是某个数字的最大概率)
346+ - 最后where找到的最大概率所在的列号(列号即是对应的数字)
347+ '''
348+ p = np.array(np.where(h[0,:] == np.max(h, axis=1)[0]))
349+ for i in np.arange(1, m):
350+ t = np.array(np.where(h[i,:] == np.max(h, axis=1)[i]))
351+ p = np.vstack((p,t))
352+ return p
353+ ```
354+
355+ ### 5、运行结果
356+ - 10次分类,在训练集上的准确度:
357+ ![ enter description here] [ 13 ]
358+
359+ ### 6、[ 使用scikit-learn库中的逻辑回归模型实现] ( /LogisticRegression/LogisticRegression_OneVsAll_scikit-learn.py )
360+ - 1、导入包
361+ ```
362+ from scipy import io as spio
363+ import numpy as np
364+ from sklearn import svm
365+ from sklearn.linear_model import LogisticRegression
366+ ```
367+ - 2、加载数据
368+ ```
369+ data = loadmat_data("data_digits.mat")
370+ X = data['X'] # 获取X数据,每一行对应一个数字20x20px
371+ y = data['y'] # 这里读取mat文件y的shape=(5000, 1)
372+ y = np.ravel(y) # 调用sklearn需要转化成一维的(5000,)
373+ ```
374+ - 3、拟合模型
375+ ```
376+ model = LogisticRegression()
377+ model.fit(X, y) # 拟合
378+ ```
379+ - 4、预测
380+ ```
381+ predict = model.predict(X) #预测
382+
383+ print u"预测准确度为:%f%%"%np.mean(np.float64(predict == y)*100)
384+ ```
385+ - 5、输出结果(在训练集上的准确度)
386+ ![ enter description here] [ 14 ]
387+
388+
259389 [ 1 ] : ./images/LinearRegression_01.png " LinearRegression_01.png "
260390 [ 2 ] : ./images/LogisticRegression_01.png " LogisticRegression_01.png "
261391 [ 3 ] : ./images/LogisticRegression_02.png " LogisticRegression_02.png "
262392 [ 4 ] : ./images/LogisticRegression_03.jpg " LogisticRegression_03.jpg "
263393 [ 5 ] : ./images/LogisticRegression_04.png " LogisticRegression_04.png "
264394 [ 6 ] : ./images/LogisticRegression_05.png " LogisticRegression_05.png "
265395 [ 7 ] : ./images/LogisticRegression_06.png " LogisticRegression_06.png "
266- [ 8 ] : ./images/LogisticRegression_07.png " LogisticRegression_07.png "
396+ [ 8 ] : ./images/LogisticRegression_07.png " LogisticRegression_07.png "
397+ [ 9 ] : ./images/LogisticRegression_08.png " LogisticRegression_08.png "
398+ [ 10 ] : ./images/LogisticRegression_09.png " LogisticRegression_09.png "
399+ [ 11 ] : ./images/LogisticRegression_11.png " LogisticRegression_11.png "
400+ [ 12 ] : ./images/LogisticRegression_10.png " LogisticRegression_10.png "
401+ [ 13 ] : ./images/LogisticRegression_12.png " LogisticRegression_12.png "
402+ [ 14 ] : ./images/LogisticRegression_13.png " LogisticRegression_13.png "
0 commit comments