【机器学习】之逻辑回归

Author:Robin Chen
Motto:Talk with the shortest sentence.

一、 逻辑回归用来干什么?

  逻辑回归并不是回归的,是用来分类的,而分类是有监督学习的一种。
  比如:左边的是漫威阵营,右边的是DC阵营。就是一个二分类,但是我们是知道每个英雄是属于哪个阵营,假如不知道的话,那就叫无监督学习了。


在这里插入图片描述

二、逻辑回归的适用范围

  (一)逻辑回归一般适用于 【二】分类,较少用于多分类。
  (二)数据要求:自变量可以是:离散型和连续型变量,因变量一般是二分类的离散型变量。
     比如:上一幅图的英雄,不是Marvel阵营就是DC阵营。

三、逻辑回归的思想

  首先介绍一个函数,Sigmoid函数。之所以取这个函数,是因为它的值域为[0,1]。

Sigmoid函数
图1 Sigmoid函数
在这里插入图片描述
图2 Sigmoid函数的图像

  LR就是引用了这个函数,把类似于 y = α x 1 + β x 2 + ε y = \alpha x_{1}+\beta x_{2}+\varepsilon y=αx1+βx2+ε 的多元回归的函数形式代入到Sigmoid函数中,转换成: Y ( x ) = 1 1 + e − ( α x 1 + β x 2 + ε ) Y(x) = \frac{1}{1+e^{-( \alpha x_{1}+\beta x_{2}+\varepsilon)}} Y(x)=1+e(αx1+βx2+ε)1 这个样子了。其中的X为用于分类的数据标签就将Y值压缩在0-1之间,可以坚持如下规则来进行分类:

   假如Y>0.5的话,那么我们可以把它分为【Marvel】阵营,
   假如Y<0.5的话,那么我们可以把它分为【DC】阵营。

  至于为什么是0.5,这个是结合实际情况,以及用途来决定了。大多数情况是以0.5为界定的。那么就可以分类了,就这么简单.

四、损失函数之交叉熵

  【熵】的概念。它是热力学中表征物质状态的参量之一,利用【熵】是为了测量指标的混乱程度。表达形式为:

H ( u ) = E ( − l o g &ThinSpace; p i ) = − ∑ i = 1 n p i ⋅ l o g &ThinSpace; p i H(u)=E(-log\, p_{i})= - \sum_{i=1}^{n}p_{i}\cdot log\, p_{i} H(u)=E(logpi)=i=1npilogpi

  从上面的式子可以看出,【熵】其实就是某个信息量的期望值。 p i p_{i} pi为众多事件中,第 i i i个事件发生的概率。为了更好的理解【交叉熵】,首先介绍一下【相对熵】的概念。相对熵(relative entropy)又称为KL散度(Kullback-Leibler divergence),用来测量是两个随机分布间的距离。记为 D k l D{_{kl}} Dkl(p||q) 。它度量当真实分布为p时,假设分布q的无效性。【相对熵】的公式为

D k l ( p ∣ ∣ q ) = E p [ l o g p ( x ) q ( x ) ] = ∑ p ( x ) l o g p ( x ) q ( x ) D{_{kl}}(p||q) = E_{p}[log\frac{p(x)}{q(x)}]= \sum p(x)log\frac{p(x)}{q(x)} Dkl(pq)=Ep[logq(x)p(x)]=p(x)logq(x)p(x),  x ϵ X x\epsilon X xϵX
D k l ( p ∣ ∣ q ) = ∑ [ p ( x ) l o g &ThinSpace;&ThinSpace; p ( x ) − p ( x ) l o g &ThinSpace; q ( x ) ] D{_{kl}}(p||q)= \sum[p(x)log\,\,p(x)-p(x)log\,q(x)] Dkl(pq)=[p(x)logp(x)p(x)logq(x)]  
D k l ( p ∣ ∣ q ) = H ( u ) − ∑ [ p ( x ) l o g &ThinSpace; q ( x ) ] D{_{kl}}(p||q)= H(u)-\sum[p(x)log\,q(x)] Dkl(pq)=H(u)[p(x)logq(x)]      

  这时的 − ∑ [ p ( x ) &ThinSpace; ⋅ l o g &ThinSpace; q ( x ) ] -\sum[p(x)\,\cdot log\,q(x)] [p(x)logq(x)]就是交叉熵,定义为:

C E H ( p , q ) = E p [ − l o g &ThinSpace; q ] CEH(p,q) = E_{p}[-log\,q] CEH(p,q)=Ep[logq] = − ∑ [ p ( x ) &ThinSpace; ⋅ l o g &ThinSpace; q ( x ) ] -\sum[p(x)\,\cdot log\,q(x)] [p(x)logq(x)]

  因而,【交叉熵】和【相对熵】的关系为:

交叉熵= H ( P ) H(P) H(P) + 相对熵
  现在,再回到LR的问题中。
  p:真实样本分布,服从参数为p的0-1分布,即X∼B(1,p)
  q:待估计的模型,服从参数为q的0-1分布,即X∼B(1,q)

C E H ( p , q ) = − ∑ [ p ( x ) &ThinSpace; ⋅ l o g &ThinSpace; q ( x ) ] CEH(p,q) = -\sum[p(x)\,\cdot log\,q(x)] CEH(p,q)=[p(x)logq(x)] msp;  msp; 
          C E H ( p , q ) = − [ P p ( x = 1 ) &ThinSpace; l o g P q ( x = 1 ) + P p ( x = 0 ) &ThinSpace; l o g P q ( x = 0 ) ] CEH(p,q) = -[P_{p}(x=1)\,logP_{q}(x=1)+P_{p}(x=0)\,logP_{q}(x=0)] CEH(p,q)=[Pp(x=1)logPq(x=1)+Pp(x=0)logPq(x=0)]
   C E H ( p , q ) = − [ y &ThinSpace; l o g h Θ ( x ) + ( 1 − y ) &ThinSpace; l o g ( 1 − h Θ ( x ) ) ] CEH(p,q) = -[y\,logh_{\Theta }(x)+(1-y)\,log(1-h_{\Theta }(x))] CEH(p,q)=[yloghΘ(x)+(1y)log(1hΘ(x))]

  最后,LR的代价函数是使用的【交叉熵】函数来做的,至于为什么使用【交叉熵】函数,我个人感觉是LR是二分类的算法,考虑到【交叉熵】与【相对熵】的关系(上文提及:交叉熵用来测量是两个随机分布间的距离),所以选择的这个函数吧。另外,通过构造似然函数,然后函数对数求导,结果和交叉熵的计算结果是一样的。
此时,代价函数为:

J ( Θ ) = − 1 m ∑ i = 1 m [ y &ThinSpace; l o g h Θ ( x ) + ( 1 − y ) &ThinSpace; l o g ( 1 − h Θ ( x ) ) ] J(\Theta)= -\frac{1}{m}\sum_{i=1}^{m}[y\,logh_{\Theta }(x)+(1-y)\,log(1-h_{\Theta }(x))] JΘ=m1i=1m[yloghΘ(x)+(1y)log(1hΘ(x))]

  最后求导数为(推导过程在这里,这个最好自己推导下):

∂ ∂ Θ J ( θ ) = − 1 m ∑ i = 1 m [ ( h Θ ( x i ) − y i ) ⋅ x j i ] \frac{\partial }{\partial \Theta }J\left ( \theta \right )= -\frac{1}{m}\sum_{i=1}^{m}[\left ( h_{\Theta}\left(x^{i}\right)-y^{i} \right )\cdot x_{j}^{i}] ΘJ(θ)=m1i=1m[(hΘ(xi)yi)xji]

  其中 h Θ ( x i ) − y i h_{\Theta}\left(x^{i}\right)-y^{i} hΘ(xi)yi就是预测值与真实值之间的误差。在后面梯度下降的时候,就是用数据矩阵与误差项的乘积来梯度下降的。

五、代码

  这里使用的泰坦尼克号幸存与否的数据,来简单举个例子。
  下面是提取建模前的变量,把与【幸存与否】的代码去掉,留下相关的变量。
  数据介绍:
  PassengerId:乘客Id   Survived:0代表死掉了,1代表活下来了
  Pclass:1,2,3代表经济社会地位1最高,3最低
  Name:乘客姓名,   Sex:代表性别 ,  Age:年龄
  SibSp:由两部分组成,
  Sibling(兄弟姐妹,堂妹都合适),
  Spouse代表(丈夫或妻子)
  Parch:父母和孩子组成,若只跟保姆写0
  Ticket:票的数字   Fare:乘客票价  Cabin:船舱数字
  Embarked:登船仓:C=Cherbourg,Q=Queenstown,S=Southampton

import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt

df = pd.read_csv(r"C:\Users\73918\Desktop\T\project\Titanic-dataset\train.csv",encoding = 'GBK')
tdf = pd.read_csv(r"C:\Users\73918\Desktop\T\project\Titanic-dataset\test.csv",encoding = 'GBK')
combine = [df,tdf]

df["Sex"]= df["Sex"].replace(["male","female"],[1,0])
df["Embarked"]= df["Embarked"].replace(["S","C","Q"],[2,1,0])

a =df[['Pclass','Survived']].groupby(['Pclass'],as_index=False).mean().sort_values(by='Survived',ascending=False)
b =df[["Embarked",'Survived']].groupby(["Embarked"],as_index=False).mean().sort_values(by='Survived',ascending=False)
c =df[["Sex",'Survived']].groupby(["Sex"],as_index=False).mean().sort_values(by='Survived',ascending=False)
d =df[['SibSp','Survived']].groupby(['SibSp'],as_index=False).mean().sort_values(by='Survived',ascending=False)
e =df[['Parch','Survived']].groupby(['Parch'],as_index=False).mean().sort_values(by='Survived',ascending=False)
print(a)
print(b)
print(c)
print(d)
print(e)

g = sns.FacetGrid(df,col='Survived')
g.map(plt.hist,'Age',bins=20)
plt.show()

g = sns.FacetGrid(df,col='Survived')
g.map(plt.hist,'Pclass',bins=3)
plt.show()

grid = sns.FacetGrid(df,col='Survived',row='Pclass',size=2.2,aspect=3.8)
grid.map(plt.hist,'Age',alpha=.5,bins=20)
grid.add_legend()
plt.show()

for dataset in df:
    dataset.loc[dataset['Fare'] <= 7.91, 'Fare'] = 0
    dataset.loc[(dataset['Fare'] > 7.91) & (dataset['Fare'] <= 14.454), 'Fare'] = 1
    dataset.loc[(dataset['Fare'] > 14.454) & (dataset['Fare'] <= 31), 'Fare'] = 2
    dataset.loc[dataset['Fare'] > 31, 'Fare'] = 3
    dataset['Fare'] = dataset['Fare'].astype(int)
f =df[['Fare','Survived']].groupby(['Fare'],as_index=False).mean().sort_values(by='Survived',ascending=False)
print(f)

for i in range(len(df)):
    row = df.iloc[i]
    if row['Fare'] <= 7.91:
        df.iloc[[i],[8]] = 0
    elif 7.91 < row['Fare'] < 14.454:
        df.iloc[[i],[8]] = 1
    elif 14.454 < row['Fare'] < 31:
        df.iloc[[i], [8]] = 2
    else:
        df.iloc[[i], [8]] = 3
f =df[['Fare','Survived']].groupby(['Fare'],as_index=False).mean().sort_values(by='Survived',ascending=False)
print(f)

agePclass
sex  Fare  在这里插入图片描述
  其中,sex=0为女性,sex=1为男性,
  最后确定要提取的变量有:年龄、性别、经济地位、票价。这里提取的比较粗糙,重在举例,海涵海涵(数据中的缺失值,我直接删了)。关于数据预处理的东西,可以参考数据分析之泰但尼克号这篇博客,个人感觉处理的很到位。
下面简单试一下LR的模型。可以得出来模型得分是79.27。

import pandas as pd
from sklearn.linear_model import LogisticRegression
df = pd.read_csv(r"C:\Users\73918\Desktop\data.csv",encoding="GBK")
X_train = df.drop(['Survived','PassengerId'],axis=1)
Y_train = df['Survived']
tdf = pd.read_csv(r"C:\Users\73918\Desktop\test.csv",encoding="GBK")
X_test = tdf.drop(['PassengerId','Embarked'],axis=1)

Logreg = LogisticRegression()
Logreg.fit(X_train,Y_train)
Y_pred = Logreg.predict(X_test)
acc_log = round(Logreg.score(X_train,Y_train) * 100,2)
print(acc_log)
#输出79.27

参考文献:
数据分析
交叉熵
逻辑回归
交叉熵求导
这是我的第一篇博客,欢迎大家指出错误!互相讨论,共同进步!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值