当前位置: 首页 > 科技观察

Python机器学习免费课程五:多类分类Logistic回归

时间:2023-03-13 09:04:22 科技观察

Logistic回归两种方法:梯度下降和优化函数Logistic回归是一种非常流行的机器学习技术。当因变量是分类变量时,我们使用逻辑回归。本文将重点介绍多类分类问题的逻辑回归的实现。我假设您已经知道如何使用逻辑回归来实现二元分类。如果您还没有使用Logistic回归进行二元分类,那么我建议您在深入阅读本文之前先阅读这篇文章。因为多分类是建立在二分类之上的。在本文中,您将学习二元分类的概念、公式和工作示例多类分类多类分类的实现遵循与二元分类相同的思想。如您所知,在二元分类中,我们解决是或否的问题。就像上面文章中的例子一样,输出回答了一个人是否有心脏病的问题。我们只有两类:有心脏病的和没有心脏病的。如果输出为1,则此人有心脏病,如果输出为0,则此人没有心脏病。在多类分类中,我们有两个以上的类。这是一个例子。比如说,我们将汽车、卡车、自行车和轮船的不同特征和属性作为输入特征。我们的工作是预测标签(汽车、卡车、自行车或船)。如何?我们将以解决心脏病或无心脏病的相同方式将每个类别视为二元分类问题。这种方法称为“一对多”方法。在一对多方法中,当我们使用一个类时,该类用1表示,其余类变为0。例如,如果我们有四个类:汽车、卡车、自行车和船。当我们处理汽车时,我们将汽车用作1,将其余类别用作零。同样,当我们处理卡车时,卡车的元素将为1,其余类别将为零。当你实现它时,它会更容易理解。我建议您在阅读时继续编码和运行代码。在这里,我将以两种不同的方式实现这个算法:梯度下降。优化函数方法。重要方程式及其工作原理:逻辑回归使用S型函数来预测输出。sigmoid函数返回一个从0到1的值。通常我们采用一个阈值,比如0.5。如果sigmoid函数返回的值大于等于0.5,则认为是1;如果sigmoid函数返回的值小于0.5,则视为0。z是输入特征乘以随机初始化值theta的乘积。X是输入特征。在大多数情况下,有几个输入函数。所以这个公式就变得很大了:X1,X2,X3是输入特征,每一个输入特征都会随机初始化一个theta。开头的Theta0是偏置项。该算法的目标是在每次迭代时更新此theta,以便它可以在输入特征和输出标签之间建立关系。成本函数和梯度下降成本函数给出了我们的预测与原始输出的差距。下面是公式:其中:m是训练示例或训练数据的数量,y是原始输出标签,h是假设或预测的输出。这是梯度下降的方程式。使用这个公式,我们将在每次迭代中更新theta值:梯度下降实施先决条件:您需要能够舒适地读写python代码。基本的Numpy和Pandas库。在这里,我将逐步展示实现。(1)导入必要的包和数据集。我从AndrewNg在Coursera上的机器学习课程中获取了数据集。这是一个手写识别数据集。从1到10的数字。我们需要从像素数据集中识别数字。在此数据集中,输入变量和输出变量组织在Excel文件的不同工作表中。请随时从本页末尾的链接下载数据集。如果您正在阅读本文,请运行每一段代码来学习算法。我们导入必要的包和数据集,importpandasaspdimportnumpyasnpxl=pd.ExcelFile('ex3d1.xlsx')df=pd.read_excel(xl,'X',header=None)(2)importy,即输出变量y=pd.read_excel(xl,'y',header=None)(3)定义采用输入变量和theta的假设。它返回计算出的输出变量。defhypothesis(theta,X):return1/(1+np.exp(-(np.dot(theta,X.T))))-0.0000001(4)使用输入变量、输出变量和theta构建成本函数。它返回假定成本。这意味着它给出了预测与原始输出的差距。defcost(X,y,theta):y1=假设(X,theta)返回-(1/len(X))*np.sum(y*np.log(y1)+(1-y)*np.log(1-y1))(5)现在,是时候进行数据预处理了。数据干净。不需要太多的预处理。我们需要为输入变量添加一个偏差列。请检查df和y的长度。如果长度不同,模型将无法工作。打印(len(df))打印(len(y))X=pd.concat([pd.Series(1,index=df.index,name='00'),df],axis=1)(6)y列有从1到10的数字。这意味着我们有10个类别。y是一个不需要的DataFrame。我只会将列保留为包含值的系列。yy=y.iloc[:,0]我们将为每个类创建一个与y长度相同的列。当类为5时,为包含1的行创建一个列,否则为5和0。为了检查,我们有几个类,y.unique()输出:array([10,1,2,3,4,5,6,7,8,9],dtype=int64)因此,我们有10个类。启动一个包含10列和df.shape[0]行数的DataFrame。y1=np.zeros([df.shape[0],len(y.unique())])y1=pd.DataFrame(y1)我们将使用一些简单的代码以编程方式完成它:foriinrange(0,len(y.unique())):forjinrange(0,len(y1)):ify[j]==y.unique()[i]:y1.iloc[j,i]=1else:y1.iloc[j,i]=0y1.head()(7)现在定义函数“gradient_descent”。此函数将输入变量、输出变量、theta、alpha和历元数作为参数。这里,alpha是学习率。您应该根据需要选择它。学习率太小或太大都会减慢您的算法。我喜欢针对不同学习率运行算法并获得正确学习率的想法。选择正确的学习率可能需要多次迭代。对于y1中的每一列,我们将实施二元分类。例如,当我考虑数字2时,数字2应该返回1,其余的应该返回0。因为我们有10个类,所以每个epoch(迭代)运行10次。所以我们这里有一个嵌套的for循环。defgradient_descent(X,y,theta,alpha,epochs):m=len(X)foriinrange(0,epochs):forjinrange(0,10):theta=pd.DataFrame(theta)h=假设(theta.iloc[:,j],X)forkinrange(0,theta.shape[0]):theta.iloc[k,j]-=(alpha/m)*np.sum((h-y.iloc[:,j])*X.iloc[:,k])theta=pd.DataFrame(theta)returntheta,cost(8)初始化theta。请记住,我们将为每个类实施逻辑回归。每个班级也将有一个范围的theta。我跑了1500个纪元。我相信准确性会随着时间的推移而提高。theta=np.zeros([df.shape[1]+1,y1.shape[1]])theta=gradient_descent(X,y1,theta,0.02,1500)(9)使用更新后的theta,计算输出变量.output=[]foriinrange(0,10):theta1=pd.DataFrame(theta)h=假设(theta1.iloc[:,i],X)output.append(h)output=pd.DataFrame(输出)(10)将计算出的输出与原始输出变量进行比较,以计算模型的准确率。accuracy=0forcolinrange(0,10):forrowinrange(len(y1)):ify1.iloc[row,col]==1andoutput.iloc[col,row]>=0.5:accuracy+=1accuracyaccuracy=accuracy/len(X)accurate度为72%。我相信,准确率会更高。我没有重新运行算法,因为它花了很多时间。如果你正在运行它,请随意尝试更多的epochs,并在评论部分告诉我你的准确性。您可以使用已经为您内置的优化函数,而不是梯度下降法。在这种方法中,您使用优化函数来优化算法的theta。这是一个更快的方法。优化实施(1)我们将使用与之前相同的数据集。如果使用同一个笔记本,导入不同名称的数据集:xls=pd.ExcelFile('ex3d1.xlsx')df=pd.read_excel(xls,'X',header=None)(2)我们仍然需要偏差termin添加一列全1。X=np.c_[np.ones((df.shape[0],1)),df](3)导入“y”的数据。y=pd.read_excel(xls,'y',header=None)由于这是一个DataFrame,只需将第0列作为一个序列并使其成为二维以匹配X的维度。yy=y[0]yy=y[:,np.newaxis]这里,“y”只有一列。将它设为10列,代表10个类。每列将处理一个类。比如我们在处理第10类时,会保留10的位置,将剩余的值替换为0。这是函数y_change,它将接受y本身和一个类(比如3)。然后它将1替换为3,每个其他类将它替换为0。此功能将在稍后的步骤中很快使用。defy_change(y,cl):y_pr=[]foriinrange(0,len(y)):ify[i]==cl:y_pr.append(1)else:y_pr.append(0)returny_pr数据准备完成。现在开发模型:(4)定义假设函数。这与前面的方法相同。defhypothesis(X,theta):z=np.dot(X,theta)return1/(1+np.exp(-(z)))(5)开发成本函数。这个方法也和前面的方法一样:defcost_function(theta,X,y):m=X.shape[0]y1=hypothesis(X,theta)return-(1/len(X))*np.sum(y*np.log(y1)+(1-y)*np.log(1-y1))(6)定义梯度。这是不同的。这个函数定义了如何更新theta。defgradient(theta,X,y):m=X.shape[0]y1=hypothesis(X,theta)return(1/m)*np.dot(X.T,y1-y)(7)现在,导入优化函数并初始化theta。我把零作为初始theta值。任何其他值也应该有效。fromscipy.optimizeimportminimize,fmin_tnctheta=np.zeros((X.shape[1],1))8.让我们创建一个以X、y和theta作为输入的拟合函数。它将使用优化函数并为我们输出优化后的theta。它采用以下三个参数:要最小化的函数、要优化的参数和要优化的参数。在这个例子中,成本函数应该被最小化,并且需要为此优化theta。输入和输出变量X和y是要使用的参数。此优化函数采用另一个参数,即梯度。但这是可选的。这里我们有一个梯度的公式或函数。所以我们正在努力解决它。deffit(X,y,theta):opt_weigths=fmin_tnc(func=cost_function,x0=theta,fprime=gradient,args=(X,y.flatten()))returnoopt_weigths[0](9)用这个拟合方法求优化的theta。我们必须分别为每个类别优化theta。让我们开发一个函数,在第3步中使用y_change方法对每个类“y”进行相应修改。deffind_param(X,y,theta):y_uniq=list(set(y.flatten()))theta_list=[]foriiny_uniq:y_tr=pd.Series(y_change(y,i))y_try_tr=y_tr[:,np.newaxis]theta1=fit(X,y,theta)theta_list.append(theta1)returntheta_list使用此方法找到最终的thetatheta_list=find_param(X,y,theta)(10)现在是预测输出的时候了。我们还必须单独预测类别。defpredict(theta_list,x,y):y_uniq=list(set(y.flatten()))y_hat=[0]*len(y)foriinrange(0,len(y_uniq)):y_tr=y_change(y,y_uniq[i])y1=hypothesis(X,theta_list[i])forkinrange(0,len(y)):ify_tr[k]==1andy1[k]>=0.5:y_hat[k]=y_uniq[i]returny_hat使用上面的预测方法和计算预测输出y_hat:y_hat=predict(theta_list,X,y)(11)计算精度accuracy=0foriinrange(0,len(y)):ify_hat[i]==y.flatten()[i]:accuracy+=1print(accuracy/len(df)*100)这个过程给出了100%的准确度。现在。由您决定在您的项目中使用哪种逻辑回归方法。本文还使用神经网络解决了同样的问题。检查此GitHub页面以获取数据集:https://github.com/rashida048/Machine-Learning-With-Python/blob/master/ex3d1.xlsx