多类别分类——吴恩达课程作业python代码实现
多类别分类
- 一、模型建立
- 二、一对多分类方法(one-vs-all)
- 三、分类器实现
- 1,加载数据集(Dateset),可视化
- 2,向量化逻辑回归
- 2.1向量化正则化的代价函数
- 2.2向量化梯度
- 3,一对多分类器(one-vs-all)
- 4,One-vs-all Prediction
一、模型建立
对于二元分类的数据模型如下;
使用两种符号表示两个不同的数据集。
对于二元分类,上一篇博客已经给出分析:二元分类原理分析,及代码实现过程
运用逻辑回归,很好地实现了分类的功能。
对于一个多分类问题,以三元分类为例,建立数据模型如下,
使用三种符号,表示三种不同类别的数据集。
现在已经知道如何进行二元分类,可以使用逻辑回归,对于直线,同时可以将数据集一分为二为正类和负类。用一对多的分类思想,我们可以将其用在多类分类问题上。有时这个方法也被称为"一对余"(one-vs-rest)方法。
二、一对多分类方法(one-vs-all)
以三元分类为例,有一个训练集,好比上图表示的有3 个类别,我们用三角形表示 ? = 1,方框表示? = 2,叉叉表示 ? = 3。通过使用一个训练集,将其分成3 个二元分类问题。
先从用三角形代表的类别1 开始,实际上可以创建一个,新的"伪"训练集,类型2 和类型3 定为负类,类型1 设定为正类,创建一个新的训练集,如下图所示的那样,要拟合出一个合适的分类器。
这里的三角形是正样本,而圆形代表负样本。可以这样想,设置三角形的值为1,圆形的值为0,下面来训练一个标准的逻辑回归分类器,这样我们就得到一个正边界。为了能实现这样的转变,我们将多个类中的一个类标记为正向类(? = 1),然后将其他所有类都标记为负向类,这个模型记作 h θ 1 ( x ) h_{\theta1}(x) hθ1(x);接着,类似地选择另一个类标记为正向类(? = 2),再将其它类都标记为负向类,将这个模型记作 h θ 2 ( x ) h_{\theta2}(x) hθ2(x);依此类推。
最后得到一系列的模型简记为:
最后,在需要做预测时,将所有的分类机都运行一遍,然后对每一个输入变量,都选择最高可能性的输出变量。
三、分类器实现
以数字字迹识别为例,讨论多类别分类问题。
1,加载数据集(Dateset),可视化
首先,加载数据集。这里的数据为MATLAB的格式,所以要使用SciPy.io的loadmat函数。
def load_data(path):data = loadmat(path)X = data['X']y = data['y']return X,y
X, y = load_data('ex3data1.mat')
print(np.unique(y)) # 看下有几类标签
# [ 1 2 3 4 5 6 7 8 9 10]
X.shape, y.shape
# ((5000, 400), (5000, 1))
控制台输出数据中的类别
其中有5000个训练样本,每个样本是20*20像素的数字的灰度图像。每个像素代表一个浮点数,表示该位置的灰度强度。20×20的像素网格被展开成一个400维的向量。在我们的数据矩阵X中,每一个样本都变成了一行,这给了我们一个5000×400矩阵X,每一行都是一个手写数字图像的训练样本。
由Y数组,查看得到数据集分为,[1,2,3,4,5,6,7,8,9,10]十个类别。
随机查看1个训练样本,查看100个训练样本。
def plot_an_image(X):"""随机打印一个数字"""pick_one = np.random.randint(0, 5000)image = X[pick_one, :]fig, ax = plt.subplots(figsize=(1, 1))ax.matshow(image.reshape((20, 20)), cmap='gray_r')plt.xticks([]) # 去除刻度,美观plt.yticks([])plt.show()print('this should be {}'.format(y[pick_one]))def plot_100_image(X):""" 随机画100个数字"""sample_idx = np.random.choice(np.arange(X.shape[0]), 100) # 随机选100个样本sample_images = X[sample_idx, :] # (100,400)fig, ax_array = plt.subplots(nrows=10, ncols=10, sharey=True, sharex=True, figsize=(8, 8))for row in range(10):for column in range(10):ax_array[row, column].matshow(sample_images[10 * row + column].reshape((20, 20)),cmap='gray_r')plt.xticks([])plt.yticks([]) plt.show()
2,向量化逻辑回归
使用多个one-vs-all(一对多)logistic回归模型来构建一个多类别分类器。由于有10个类,需要训练10个独立的分类器。为了提高训练效率,重要的是向量化。
2.1向量化正则化的代价函数
正则化的logistic回归的代价函数是:
J ( θ ) = − 1 m [ ∑ i = 1 m y ( i ) log ( h θ ( x ( i ) ) − ( 1 − y ( i ) ) log ( 1 − h θ ( x ( i ) ) ) ] + λ 2 m ∑ j = 1 n θ j 2 J(\theta)=-\frac{1}{m}[\sum_{i=1}^{m}y^{(i)}\log(h_\theta(x^{(i)})-(1-y^{(i)})\log(1-h_\theta(x^{(i)}))]+\frac{\lambda}{2m}\sum_{j=1}^{n}\theta_j^2 J(θ)=−m1[∑i=1my(i)log(hθ(x(i))−(1−y(i))log(1−hθ(x(i)))]+2mλ∑j=1nθj2
对于每个样本 i i i要计算, h θ ( x ( i ) ) h_\theta(x^{(i)}) hθ(x(i)), h θ ( x ( i ) ) = g ( θ T x ( i ) ) h_\theta(x^{(i)})=g(\theta^Tx^{(i)}) hθ(x(i))=g(θTx(i)), g ( z ) g(z) g(z)是sigmoid函数
事实上我们可以对所有的样本用矩阵乘法来快速的计算。
定义X,与 θ \theta θ
通过计算X θ \theta θ
在最后一个等式中,我们用到了一个定理,如果 a a a和 b b b都是向量,那么 a T b = b T a a^Tb=b^Ta aTb=bTa 这样我们就可以用一行代码计算出所有的样本。
def sigmoid(z):return 1 / (1 + np.exp(-z))
def regularized_cost(theta, X, y, l):"""don't penalize theta_0args:X: feature matrix, (m, n+1) # 插入了x0=1y: target vector, (m, )l: lambda constant for regularization"""thetaReg = theta[1:]first = (-y*np.log(sigmoid(X@theta))) + (y-1)*np.log(1-sigmoid(X@theta))reg = (thetaReg@thetaReg)*l / (2*len(X))return np.mean(first) + reg
2.2向量化梯度
未正则化逻辑回归代价函数的梯度为:
∂ ∂ / θ j J ( θ ) = − 1 m ∑ i = 1 m ( h θ ( x ( i ) ) − y ( i ) ) x j ( i ) \frac{\partial }{\partial /\theta_j}J(\theta)=-\frac{1}{m}\sum_{i=1}^{m} (h_\theta(x^{(i)})-y^{(i)})x_j^{(i)} ∂/θj∂J(θ)=−m1∑i=1m(hθ(x(i))−y(i))xj(i)
使用向量化的方法表示
其中,
注意, h θ ( x ( i ) ) − y ( i ) h_\theta(x^{(i)})-y^{(i)} hθ(x(i))−y(i)是一个标量,令 β i = h θ ( x ( i ) ) − y ( i ) \beta_i=h_\theta(x^{(i)})-y^{(i)} βi=hθ(x(i))−y(i)
得到:
正则化后的梯度下降算法表示如下,不惩罚 θ 0 \theta_0 θ0
代码实现
def regularized_gradient(theta, X, y, l):"""don't penalize theta_0args:l: lambda constantreturn:a vector of gradient"""thetaReg = theta[1:]first = (1 / len(X)) * X.T @ (sigmoid(X @ theta) - y)# 这里人为插入一维0,使得对theta_0不惩罚,方便计算reg = np.concatenate([np.array([0]), (l / len(X)) * thetaReg])return first + reg
3,一对多分类器(one-vs-all)
这部分通过训练多个正则化logistic回归分类器实现一对多分类,每个分类器对应数据集中K类中的一个。
对于这个任务,我们有10个可能的类,并且由于logistic回归只能一次在2个类之间进行分类,每个分类器在“类别 i”和“不是 i”之间决定。 我们将把分类器训练包含在一个函数中,该函数计算10个分类器中的每个分类器的最终权重,并将权重返回shape为(k, (n+1))数组,其中 n 是参数数量。
from scipy.optimize import minimizedef one_vs_all(X, y, l, K):"""generalized logistic regressionargs:X: feature matrix, (m, n+1) # with incercept x0=1y: target vector, (m, )l: lambda constant for regularizationK: numbel of labelsreturn: trained parameters"""all_theta = np.zeros((K, X.shape[1])) # (10, 401)for i in range(1, K+1):theta = np.zeros(X.shape[1])y_i = np.array([1 if label == i else 0 for label in y])ret = minimize(fun=regularized_cost, x0=theta, args=(X, y_i, l), method='TNC',jac=regularized_gradient, options={'disp': True})all_theta[i-1,:] = ret.xreturn all_theta
这里需要注意的几点:首先,我们为X添加了一列常数项 1 ,以计算截距项(常数项)。 其次,我们将y从类标签转换为每个分类器的二进制值(要么是类i,要么不是类i)。 最后,我们使用SciPy的较新优化API来最小化每个分类器的代价函数。 如果指定的话,API将采用目标函数,初始参数集,优化方法和jacobian(渐变)函数。 然后将优化程序找到的参数分配给参数数组。
4,One-vs-all Prediction
在训练多类别分类器之后,现在可以用它来预测给定图像中包含的数字。对于每个输入,您应该使用以下方法计算它属于每个类的“概率” 训练的Logistic回归分类器。One-vs-all预测函数将选择相应的逻辑回归分类器输出概率最高的类和ret。 将类标签(1、2、…或K)作为输入示例的预测。
实现向量化代码的一个更具挑战性的部分是正确地写入所有的矩阵,保证维度正确。
def predict_all(X, all_theta):# compute the class probability for each class on each training instance h = sigmoid(X @ all_theta.T) # 注意的这里的all_theta需要转置# create array of the index with the maximum probability# Returns the indices of the maximum values along an axis.h_argmax = np.argmax(h, axis=1)# because our array was zero-indexed we need to add one for the true label predictionh_argmax = h_argmax + 1return h_argmax
这里的h共5000行,10列,每行代表一个样本,每列是预测对应数字的概率。我们取概率最大对应的index加1就是我们分类器最终预测出来的类别。返回的h_argmax是一个array,包含5000个样本对应的预测值。
raw_X, raw_y = load_data('ex3data1.mat')
X = np.insert(raw_X, 0, 1, axis=1) # (5000, 401)
y = raw_y.flatten() # 这里消除了一个维度,方便后面的计算 or .reshape(-1) (5000,)all_theta = one_vs_all(X, y, 1, 10)
all_theta # 每一行是一个分类器的一组参数
y_pred = predict_all(X, all_theta)
accuracy = np.mean(y_pred == y)
print ('accuracy = {0}%'.format(accuracy * 100))
通过预测的y值与实际y值进行比对,得出结果在这次练习中的多类别分类器的准确率是0.9446。
多类别分类——吴恩达课程作业python代码实现相关推荐
- Ex6_机器学习_吴恩达课程作业(Python):SVM支持向量机(Support Vector Machines)
Ex6_机器学习_吴恩达课程作业(Python):SVM支持向量机(Support Vector Machines) 文章目录 Ex6_机器学习_吴恩达课程作业(Python):SVM支持向量机(Su ...
- 吴恩达机器学习作业Python实现(三):多类分类和前馈神经网络
吴恩达机器学习系列作业目录 1 多类分类(多个logistic回归) 我们将扩展我们在练习2中写的logistic回归的实现,并将其应用于一对多的分类(不止两个类别). import numpy as ...
- 吴恩达机器学习作业Python实现(六):SVM支持向量机
吴恩达机器学习系列作业目录 1 Support Vector Machines 1.1 Example Dataset 1 %matplotlib inline import numpy as np ...
- 吴恩达机器学习作业Python实现(八):异常检测和推荐系统
吴恩达机器学习系列作业目录 1 Anomaly detection 这部分,您将实现一个异常检测算法来检测服务器计算机中的异常行为.他的特征是测量每个服务器的响应速度(mb/s)和延迟(ms).当你的 ...
- 吴恩达机器学习作业Python实现(七):K-means和PCA主成分分析
吴恩达机器学习系列作业目录 1 K-means Clustering 在这个练习中,您将实现K-means算法并将其用于图像压缩.通过减少图像中出现的颜色的数量,只剩下那些在图像中最常见的颜色. 1. ...
- 吴恩达机器学习作业Python实现(五):偏差和方差
吴恩达机器学习系列作业目录 在本练习中,您将实现正则化的线性回归和多项式回归,并使用它来研究具有不同偏差-方差属性的模型 1 Regularized Linear Regression 正则线性回归 ...
- 吴恩达机器学习作业Python实现(四):神经网络(反向传播)
吴恩达机器学习系列作业目录 1 Neural Networks 神经网络 在这个练习中,你将实现反向传播算法来学习神经网络的参数.依旧是上次预测手写数数字的例子. 1.1 Visualizing th ...
- 吴恩达机器学习作业Python实现(二):logistic回归
吴恩达机器学习系列作业目录 1 Logistic regression 在这部分的练习中,你将建立一个逻辑回归模型来预测一个学生是否能进入大学.假设你是一所大学的行政管理人员,你想根据两门考试的结果, ...
- 第一章-机器学习简介 深度之眼_吴恩达机器学习作业训练营
目录 专栏简介: 一,机器学习简介 1.1 机器学习定义 1.1 机器学习的重要性 1.2 应用领域 二.监督学习 三.无监督学习 四.总结 专栏简介: 本栏主要内容为吴恩达机器学习公开课的学习笔记, ...
最新文章
- mcse 2000 认证介绍
- 中文整合包_MIMOSA2: 基于微生物组和代谢组数据的整合分析
- FastReport v3.2.5在BDS2006中的安装方法
- 合作开发过程产生的专利_被起诉专利侵权怎么办?专利律师给你出招!
- 飞鸽传书2009绿色版 官方网站下载地址
- 全站仪与计算机之间的数据传输,必看!全站仪数据传输的三种方式详解,都安排得明明白白(上)...
- 乱斗西游2服务器修改,为我们的友谊干杯《乱斗西游2》转服功能邀你面基
- ASP.NET MVC 3和Razor中的@helper 语法
- 最强开发资源平台大合集
- 跟论文作者要源码和数据集的邮件怎么写
- JavaWeb中的四大作用域对象
- 万圣节到了,来讲鬼故事吧!(大家可以在回复中继续讲)
- mac iTunes 下载慢,如何加速
- 大学生体育课期末大作业
- H5页面input输入框,在ios手机中被顶出页面解决方案
- “国防七子”、“C9联盟”、“华东五虎”,中国最顶尖的大学都在这!
- 王国保卫战Kingdom Rush 单机游戏金币消耗降低
- matlab逐步积分,第17章 隐式逐步积分法.ppt
- 整理的一些代码优化细节
- 【Wiki】XWiki数据备份