python train 函数_机器学习:Logistic回归解释及Python实现

在本文中,我们将深入研究机器学习中的广义线性回归模型来进行分类而不是预测。机器学习中的逻辑回归被称为线性分类器。它计算两个类在0和1之间的概率。如果一个项目的概率分数小于0.5,我们可以简单地对它进行分类,分类到Class 1,否则分类到Class 2。

为了得到逻辑回归的公式,由于它在概率模型上工作,我们必须通过logit(log odds)给出线性方程的值。

线性模型由下式给出:

078bef2f4dc61b33ecc60bf0b38ff2e7.png

Logit:

758e3e5d5e3a952a1c3261bbb07ae87a.png

Logistic回归公式由下式给出:

8b09b650f0f00d63ded27c2ec1724c18.png

由logistic回归形成的图形如下图所示,通常为“s”形,y轴上的值始终在0 - 1之间:

df024a6cb79a5d1e1e4a2addca6f5e3d.png

现在我们必须找到β0和β1的值,但是像线性回归一样,没有这样直接的公式来计算系数。这些系数的估计方法有很多种,如极大似然法、对数似然法、Newton Raphson法等。

Newton Raphson法

Newton Raphson方法是泰勒展开的迭代过程,用于找到图的根,根是图与x轴相交的点,这是我们的系数之一。系数可以通过Newton Raphson方法给出:

78104accfa97e747216bb15114d5aae4.png

βi是系数的估计值之一,βi-1是在最后一次迭代中估计的相同系数的值。我们将迭代相同的过程直到βi的值稳定。现在我们需要找到函数的一阶和二阶导数。

伯努利分布的似然函数:

094ac1831dd40511c5a6e3762af8b906.png

注意:我可以用上面等式中的P值替换它并将其设置为零,如果我这样做,我可以通过找出β0和β1函数的最大值来估计β0和β1的值。这种方法称为最大似然法。但是找到这样的值将非常困难,或者我们可能无法估计正确的值。现在用log来化简这个方程:

ff6af5040a4ea559470e531239210a12.png

代入P值并化简

b35b72f1957ec6fea88d7c9d3827bd5f.png

现在,一阶导数是

4637d4fae9713d01a06f13e5277621f8.png

注意:我们可以将上面的等式设置为零,并尝试找出β0和β1的值,该方法称为对数似然法。但同样,我们将无法将其设置为零并解决它,因此采用二阶导数并进行generalizing:

926228791a843b01ed0d632bc1e3784c.png

Python实现

我们已经推导出了概率函数,一阶导数和二阶导数。让我们进入python来实现同样的功能。创建一个logsticregression类,并添加如下方法,Python实现如下:

class LogisticRegression: def __init__(self, X): self.beta_old_i = [] #initializing b_i, always one additional coefficient than number of features of predictor #because eq β_0 + β_1*x having two coefficients β_0, β_1 where x has only one dimension self.beta_new_i = np.zeros(X.shape[1] + 1)  #p(x) = e^(β_0 + β_1*x)/(1 + e^(β_0 + β_1*x)) def probabilityFun(self, X): z = np.dot(self.beta_new_i, X.T) p = math.e**z/(1 + math.e**z) return p#f'(β_j) = dl/d(β_j) = (i=1 to N)_Σ (y_i - p(x_i))*x_ij def firstDerivative(self, X, Y, P): firstDer = np.dot((Y-P), X) return firstDer#f''(β_k) = dl/d(β_j)d(β_k) = - (i=1 to N)_Σ x_ij*x_ik*p(x_i)*(1 - p(x_i)) def secondDerivative(self, X, P): probMul = P*(1-P) xMulp = np.array([x*y for (x,y) in zip(X, probMul)]) secondDer = -1*np.dot(xMulp.T,X) return secondDer#β_(i+1) = β_i - (f'(β_i))/(f''(β_i)) def newtonRaphson(self, firstDer, secondDer): self.beta_new_i = self.beta_old_i - np.dot(linalg.inv(secondDer), firstDer)
3d3c47f3f7fc105c359fa53e91575595.png

所有函数都是按照导出的公式定义的。现在我们来写一个迭代过程,直到系数稳定下来。Python代码如下:

#training the modeldef fit(self, X, Y, maxIteration=50, diffThreshHold=10**-5): #adding one additional column since we will have additional coefficient X = np.c_[X, np.array([1]*X.shape[0])] iteration = 0 diffBetaList = []while(list(self.beta_new_i) != list(self.beta_old_i)): self.beta_old_i = self.beta_new_i P = self.probabilityFun(X) firstDer = self.firstDerivative(X, Y, P) secondDer = self.secondDerivative(X, P) self.newtonRaphson(firstDer, secondDer) #difference between last calcuated coefficients and current coefficients diff = linalg.norm(self.beta_new_i - self.beta_old_i) diffBetaList.append(diff) iteration += 1 if(diff <= diffThreshHold or iteration > maxIteration): break  return diffBetaList
8f4e0f9b142af5424ee8a8ef39bf4842.png

现在创建一个预测和分类方法来计算概率和分类。Python代码如下:

#predict probability any new data pointsdef predict(self, X): X = np.c_[X, np.array([1]*X.shape[0])] probability = self.probabilityFun(X) return probability#classify based on provided classesdef classify(self, X, dataClass): Y = self.predict(X) #if probability is less than 0.5 than categorized as class one else class two return [0 if item <= 0.05 else 1 for item in Y]
1c2e3f65a34fffd559c3e91e542ebda5.png

最后使用iris数据训练和测试上面的代码,我将只使用两类iris数据:

iris = datasets.load_iris()#iris data is 50 each three classes so only taking to 100 for two classesx_train, x_test, y_train, y_test = train_test_split(iris['data'][:100], iris['target'][:100])reg = LogisticRegression(x_train)reg.fit(x_train,y_train)pred = reg.classify(x_test, iris["target_names"][:2])print("Accuracy: {:.2f}%".format(100*np.mean(pred == y_test)))
f0edf2727cabdb4210c6481bc43c7af2.png

Output

Accuracy: 100.00%

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值