@@ -106,7 +106,7 @@ from sklearn.preprocessing import StandardScaler #引入缩放的包
106
106
result = model.predict(x_test)
107
107
```
108
108
109
- ## 二、逻辑回归
109
+ ## 二、[ 逻辑回归] ( /LogisticRegression )
110
110
- [ 全部代码] ( /LogisticRegression/LogisticRegression.py )
111
111
112
112
### 1、代价函数
@@ -256,11 +256,147 @@ import numpy as np
256
256
```
257
257
258
258
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
+
259
389
[ 1 ] : ./images/LinearRegression_01.png " LinearRegression_01.png "
260
390
[ 2 ] : ./images/LogisticRegression_01.png " LogisticRegression_01.png "
261
391
[ 3 ] : ./images/LogisticRegression_02.png " LogisticRegression_02.png "
262
392
[ 4 ] : ./images/LogisticRegression_03.jpg " LogisticRegression_03.jpg "
263
393
[ 5 ] : ./images/LogisticRegression_04.png " LogisticRegression_04.png "
264
394
[ 6 ] : ./images/LogisticRegression_05.png " LogisticRegression_05.png "
265
395
[ 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