逻辑回归那些事儿(附模板代码)

逻辑回归(logistic regression)被广泛用于分类预测,例如:银行通过客户的用户行为判断客户是否会流失,医院通过病人肿瘤的形态特征判断肿瘤是否为良性,电子邮箱通过对邮件信息的识别判断是否为垃圾邮件等等。作为目前最流行使用的一种学习算法,逻辑回归能非常有效地对数据进行分类。

1. 回归假设

h_θ (x)=g(θ^T X),其中: X代表特征向量(即影响因子向量),θ^T代表参数的转置矩阵,g 代表一个常用的逻辑函数,为S形函数(Sigmoid function),公式为:g(z)=1/(1+e^{(-z)} )。合起来,我们可以得到逻辑回归的假设函数为:
h_θ (x)=1/(1+e^{(-θ^T X)} )
其中,θ^T X是参数θ和特征X的向量运算,展开就是:
θ^T X=θ_0+θ_1 x_1+θ_2 x_2+...+θ_n x_n(n代表特征的数量)

1)S形函数

  • 实际上,我们套用了S形函数进行逻辑回归的计算。这是个非常经典的分类函数,是机器学习入门必须掌握的基础知识。
  • 函数是一个分数,取值在0-1之间。
  • z<0时,g(z)<0.5;当z=0时,g(z)=0.5;当z>0时,g(z)>0.5
    image.png
  • S函数用python代码实现为:
import numpy as np
def sigmoid(z):
   return 1 / (1 + np.exp(-z))

2)假设判断

  • h_θ (x)表示的是:根据参数得出因变量y为1的概率/可能性(estimated probablity),即h_θ (x)=P(y=1|x;θ)
  • 一般地,我们判断:
    • h_θ (x)<=0.5,则分类为y=0h_θ (x)>0.5,则分类为y=1

=举个栗子=
假设病人患恶性肿瘤为y=1,未患恶性肿瘤为y=0。现根据肿瘤大小(x_1)和肿瘤颜色(x_2)两个特征可以得到逻辑回归模型为:h_θ (x)=g(θ^T X)=g(θ_0+θ_1 x_1+θ_2 x_2)=1/(1+e^{-(θ_0+θ_1 x_1+θ_2 x_2)})
其中,参数θ_0=-0.8,θ_1=0.01,θ_2=-0.05,则模型为:
h_θ (x)=1/(1+e^{-(-0.8+0.01 x_1-0.05 x_2)})
已知一名病人的肿瘤大小为1cm,肿瘤颜色分类为5,则代入模型计算得到h_θ (x)=0.26,说明病人患恶性肿瘤的概率为0.26,概率低于0.5,由此我们将病人分类为“未患肿瘤(y=0)”。

3)决策边界

  • 决策边界是对分类预测的可视化。如上文所说,一般以h_θ (x)=0.5进行分类,而此时z=θ^T X=0
    image.png
  • 当特征变量X只有1-3个时,我们可以通过散点图画出θ^T X=0的决策边界,帮助我们更好地理解分类正确率,但画出决策边界不是必须的。因为大部分时候,特征变量都会多于3个,这时,我们就很难画出决策边界,一般通过混淆矩阵判断预测的准确度。

2.特征缩放

  • 特征缩放(feature scaling)其实就是将所有的特征变量缩放到相近的尺度,以便减少计算量,更快地构建模型,最常用的方法是通过均值归一化(mean normalization)将所有特征的尺度都尽量缩放到-1到1之间。即:
    x_n=(x_n-μ_n)/s_n ,(μ_n是平均值,s_n为标准差)
  • 这是模型构建前必做的数据预处理动作,能有效减少计算量。
  • 特征缩放用Python代码实现为:
import numpy as np
def featurescaling(X):
  X=(X-np.average(X))/np.std(X)
  return X

3. 损失函数

  • 构建预测模型就需要定义损失函数。损失函数也叫代价函数(loss function),简单理解,就是计算预测值与实际值之间的误差。通过计算损失(loss),我们才能判断模型的准确度。通用公式如下:

J(θ)=1/m ∑_{(i=1)}^mCost(h_θ (x^{(i)} ),y^{(i)})(m表示样本数量)
对于逻辑回归,我们采用对数计算损失,其中:

image.png

简化可以得到:

最终可以得到逻辑回归的代价函数为:

  • 损失函数用Python代码实现为:
import numpy as np
def costfunction(theta, X, y):
  theta = np.matrix(theta)
  X = np.matrix(X)
  y = np.matrix(y)
  part_1 = np.multiply(-y, np.log(sigmoid(X @ theta.T)))# 引用了sigmoid函数
  part_2 = np.multiply((1 - y), np.log(1 - sigmoid(X @ theta.T)))
  return np.sum(part_1 - part_2) / (len(X))

4.优化算法:梯度下降

  • 既然我们通过损失函数计算了损失,那么为了减少损失,我们就需要对参数进行不断的优化。
  • 梯度下降(gradient descent)是一个用来求函数最小值的算法,非常强大可靠,主要是通过代价函数的导数更新优化参数,直至达到代价函数的局部最小值,通用公式为:
    Repeat { θ_j:=θ_j-α ∂/∂θ_j J(θ) (同时更新所有的θ_j ) }
    根据微积分知识,简化后可以得到θ_j:=θ_j-α /m ∑_{(i=1)}^m[(h_θ (x^{(i)})-y^{(i)})x_j^{(i)} ], (α为学习速度(learning rate),m为样本数量)
  • α控制我们按多大的幅度去更新参数。如果a太小,梯度下降计算慢;如果a太大,那么梯度下降可能会越过最低点,导致无法收敛,甚至发散。
  • 梯度下降用Python代码实现为:
def gradientDescent(X, y, theta, alpha, iters):#iters表示更新迭代次数
    theta = np.matrix(theta)
    X = np.matrix(X)
    y = np.matrix(y)
    
    temp = np.matrix(np.zeros(theta.shape))# 设置temp作为theta的转换
    parameters = int(theta.ravel().shape[1]) # 计算参数的数量
    cost = np.zeros(iters)
    
    # 设置迭代循环
    for i in range(iters): 
        error = sigmoid(X @ theta.T) - y # 引用sigmoid函数
        
        for j in range(parameters):
            term = np.multiply(error, X[:,j])
            temp[0,j] = theta[0,j] - ((alpha / len(X)) * np.sum(term))
            
        theta = temp
        cost[i] = costfunction(theta, X, y) # 引用costfunction函数
        
    return theta, cost
  • 除了梯度下降算法以外,还有很多其他更高级的优化算法,本文就不多赘述了。

4. 模板代码

  • 了解了逻辑回归的数学知识之后,实际工作中,我们不需要自己定义损失函数和优化算法,有成熟的机器学习库可供我们直接调用。比如,sklearn中逻辑回归函数可调用的优化算法就有:liblinear, newton-cg, lbfgs, sag 和 saga,默认使用lbfgs。
  • 下面是调用sklearn库的模板代码:
# 1.创建X和y
X = df.iloc[:,:-1].values # 需根据实际情况更改
y = df.iloc[:,-1].values # 需根据实际情况更改

# 2.将数据分成训练集和测试集
from sklearn.model_selection import train_test_split
X_train,X_test,y_train,y_test = train_test_split(X,y,test_size=0.2,random_state=0)

# 3.特征缩放(Feature Scaling)
from sklearn.preprocessing import StandardScaler
sc_X = StandardScaler()
X_train = sc_X.fit_transform(X_train)#转换变量
X_test = sc_X.fit_transform(X_test)#转换变量

# 4.利用逻辑回归进行分类
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state=0)
classifier.fit(X_train,y_train)

# 5.预测测试集中的y值
y_pred = classifier.predict(X_test)

# 6.用混淆矩阵检测准确率
from sklearn.metrics import confusion_matrix
cm = confusion_matrix(y_test,y_pred)

如有错误,请指正。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,902评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 84,037评论 2 377
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,978评论 0 332
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,867评论 1 272
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,763评论 5 360
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,104评论 1 277
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,565评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,236评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,379评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,313评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,363评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,034评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,637评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,719评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,952评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,371评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,948评论 2 341