机器学习5- 对数几率回归+Python实现

简介:

机器学习5- 对数几率回归+Python实现

目录

  1. 对数几率回归
    1.1 求解 ω 和 b
  2. 对数几率回归进行垃圾邮件分类
    2.1 垃圾邮件分类

2.2 模型评估
混淆举证
精度
交叉验证精度
准确率召回率
F1 度量
ROC AUC

  1. 对数几率回归
    考虑二分类任务,其输出标记 y∈{0,1}y∈{0,1},记线性回归模型产生的预测值 z=wTx+bz=wTx+b 是实值,于是我们需要一个将实值 zz 转换为 0/10/1 的 g−(⋅)g−(⋅)。

最理想的单位阶跃函数(unit-step function)

y=⎧⎩⎨0,0.5,1,z<0z=0z>0(1.1)(1.1)y={0,z<00.5,z=01,z>0
并不是连续函数,因此不能作为 g−(⋅)g−(⋅) 。于是我们选用对数几率函数(logistics function)作为单位阶跃函数的替代函数(surrogate function):

y=11+e−z(1.2)(1.2)y=11+e−z
如下图所示:

对数几率函数是 Sigmoid 函数(即形似 S 的函数)的一种。

将对数几率函数作为 g−(⋅)g−(⋅) 得到

y=11+e−(wTx+b)(1.3)(1.3)y=11+e−(wTx+b)
lny1−y=wTx+b(1.4)(1.4)ln⁡y1−y=wTx+b
若将 yy 视为样本 xx 为正例的可能性,则 1−y1−y 是其为反例的可能性,两者的比值为

y1−y(1.5)(1.5)y1−y
称为几率(odds),反映了 xx 作为正例的相对可能性。对几率取对数得到对数几率(log odds,或 logit):

lny1−y(1.6)(1.6)ln⁡y1−y
所以,式 (1.3) 实际上是用线性回归模型的预测结果取逼近真实标记的对数几率,因此其对应的模型又称为对数几率回归(logistic regression, 或 logit regression)。

这种分类学习方法直接对分类可能性进行建模,无需事先假设数据分布,避免了假设分布不准确带来的问题;
它能得到近似概率预测,这对需要利用概率辅助决策的任务很有用;
对率函数是任意阶可导的凸函数,有很好的数学性质,许多数值优化算法都可直接用于求解最优解。

1.1 求解 ω 和 b
将式 (1.3) 中的 yy 视为类后验概率估计 p(y=1|x)p(y=1|x),则式 (1.4) 可重写为

lnp(y=1|x)p(y=0|x)=wTx+b(1.7)(1.7)ln⁡p(y=1|x)p(y=0|x)=wTx+b

p(y=1|x)=ewTx+b1+ewTx+b(1.8)(1.8)p(y=1|x)=ewTx+b1+ewTx+b
p(y=0|x)=11+ewTx+b(1.9)(1.9)p(y=0|x)=11+ewTx+b
通过极大似然法(maximum likelihood method)来估计 ww 和 bb 。

给定数据集 {(xi,yi)}mi=1{(xi,yi)}i=1m,对率回归模型最大化对数似然(log-likelihood):

ℓ(w,b)=∑i=1mlnp(yi|xi;w,b)(1.10)(1.10)ℓ(w,b)=∑i=1mln⁡p(yi|xi;w,b)
即令每个样本属于其真实标记的概率越大越好。

令 β=(w;b)β=(w;b),x^=(x;1)x^=(x;1),则 wTx+bwTx+b 可简写为 βTx^βTx^。再令 p1(x^;β)=p(y=1|x^;β)p1(x^;β)=p(y=1|x^;β),p0(x^;β)=p(y=0|x^;β)=1−p1(x^;β)p0(x^;β)=p(y=0|x^;β)=1−p1(x^;β) 。则式 (1.10) 可简写为:

p(yi|xi;w,b)=yip1(x^;β)+(1−yi)p0(x^;β)(1.11)(1.11)p(yi|xi;w,b)=yip1(x^;β)+(1−yi)p0(x^;β)
将式 (1.11) 带入 (1.10),并根据式 (1.8) 和 (1.9) 可知,最大化式 (1.10) 等价于最小化

ℓ(β)=∑i=1m(−yiβTx^i+ln(1+eβT+x^i))(1.12)(1.12)ℓ(β)=∑i=1m(−yiβTx^i+ln⁡(1+eβT+x^i))
式 (1.12) 是关于 ββ 的高阶可导凸函数,根据凸优化理论,经典的数值优化算法如梯度下降法(gradient descent method)、牛顿法(Newton method)等都可求得其最优解,于是得到:

β∗=arg min βℓ(β)(1.13)(1.13)β∗=arg min βℓ(β)
以牛顿法为例, 其第 t+1t+1 轮迭代解的更新公式为:

βt+1=βt−(∂2ℓ(β)∂β ∂βT)−1∂ℓ(β)∂β(1.14)(1.14)βt+1=βt−(∂2ℓ(β)∂β ∂βT)−1∂ℓ(β)∂β
其中关于 ββ 的一阶、二阶导数分别为:

∂ℓ(β)∂β=−∑i=1mx^i(yi−p1(x^i;β))(1.15)(1.15)∂ℓ(β)∂β=−∑i=1mx^i(yi−p1(x^i;β))
∂2ℓ(β)∂β∂βT=∑i=1mx^ix^Tip1(x^i;β)(1−p1(x^i;β))(1.16)(1.16)∂2ℓ(β)∂β∂βT=∑i=1mx^ix^iTp1(x^i;β)(1−p1(x^i;β))

  1. 对数几率回归进行垃圾邮件分类
    2.1 垃圾邮件分类

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.linear_model.logistic import LogisticRegression
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.feature_extraction.text import TfidfVectorizer
from matplotlib.font_manager import FontProperties
df = pd.read_csv("SMSSpamCollection", delimiter='t', header=None)
df.head()

print("spam 数量: ", df[df[0] == 'spam'][0].count())
print("ham 数量: ", df[df[0] == 'ham'][0].count())
spam 数量: 747
ham 数量: 4825
X_train_raw, X_test_raw, y_train, y_test = train_test_split(df[1], df[0])

计算TF-IDF权重

vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train_raw)
X_test = vectorizer.transform(X_test_raw)

建立模型

classifier = LogisticRegression()
classifier.fit(X_train, y_train)
y_preds = classifier.predict(X_test)
for i, y_pred in enumerate(y_preds[-10:]):

print("预测类型: %s -- 信息: %s" % (y_pred, X_test_raw.iloc[i]))

预测类型: ham -- 信息: Aight no rush, I'll ask jay
预测类型: ham -- 信息: Sos! Any amount i can get pls.
预测类型: ham -- 信息: You unbelievable faglord
预测类型: ham -- 信息: Carlos'll be here in a minute if you still need to buy
预测类型: spam -- 信息: Meet after lunch la...
预测类型: ham -- 信息: Hey tmr maybe can meet you at yck
预测类型: ham -- 信息: I'm on da bus going home...
预测类型: ham -- 信息: O was not into fps then.
预测类型: ham -- 信息: Yes..he is really great..bhaji told kallis best cricketer after sachin in world:).very tough to get out.
预测类型: ham -- 信息: Did you show him and wot did he say or could u not c him 4 dust?
2.2 模型评估
混淆举证
test = y_test
test[test == "ham"] = 0
test[test == "spam"] = 1

pred = y_preds
pred[pred == "ham"] = 0
pred[pred == "spam"] = 1
from sklearn.metrics import confusion_matrix
test = test.astype('int')
pred = pred.astype('int')
confusion_matrix = confusion_matrix(test.values, pred)
print(confusion_matrix)
plt.matshow(confusion_matrix)
font = FontProperties(fname=r"/usr/share/fonts/opentype/noto/NotoSansCJK-Regular.ttc")
plt.title(' 混淆矩阵',fontproperties=font)
plt.colorbar()
plt.ylabel(' 实际类型',fontproperties=font)
plt.xlabel(' 预测类型',fontproperties=font)
plt.show()
[[1191 1]
[ 50 151]]

精度
from sklearn.metrics import accuracy_score

print(accuracy_score(test.values, pred))
0.9633883704235463
交叉验证精度
df = pd.read_csv("sms.csv")
df.head()

X_train_raw, X_test_raw, y_train, y_test = train_test_split(df['message'], df['label'])
vectorizer = TfidfVectorizer()
X_train = vectorizer.fit_transform(X_train_raw)
X_test = vectorizer.transform(X_test_raw)
classifier = LogisticRegression()
classifier.fit(X_train, y_train)
scores = cross_val_score(classifier, X_train, y_train, cv=5)
print(' 精度:',np.mean(scores), scores)
精度: 0.9562200956937799 [0.94736842 0.95933014 0.95574163 0.95574163 0.96291866]
准确率召回率
precisions = cross_val_score(classifier, X_train, y_train, cv=5, scoring='precision')
print('准确率:', np.mean(precisions), precisions)
recalls = cross_val_score(classifier, X_train, y_train, cv=5, scoring='recall')
print('召回率:', np.mean(recalls), recalls)
准确率: 0.9920944081237428 [0.98550725 1. 1. 0.98701299 0.98795181]
召回率: 0.6778796653796653 [0.61261261 0.69642857 0.66964286 0.67857143 0.73214286]
F1 度量
f1s = cross_val_score(classifier, X_train, y_train, cv=5, scoring='f1')
print(' 综合评价指标:', np.mean(f1s), f1s)
综合评价指标: 0.8048011339652206 [0.75555556 0.82105263 0.80213904 0.8042328 0.84102564]
ROC AUC
from sklearn.metrics import roc_curve, auc
predictions = classifier.predict_proba(X_test)
false_positive_rate, recall, thresholds = roc_curve(y_test, predictions[:, 1])
roc_auc = auc(false_positive_rate, recall)
plt.title('Receiver Operating Characteristic')
plt.plot(false_positive_rate, recall, 'b', label='AUC = %0.2f' % roc_auc)
plt.legend(loc='lower right')
plt.plot([0, 1], [0, 1], 'r--')
plt.xlim([0.0, 1.0])
plt.ylim([0.0, 1.0])
plt.ylabel('Recall')
plt.xlabel('Fall-out')
plt.show()

原文地址https://www.cnblogs.com/raina/p/12777725.html

相关文章
|
16天前
|
机器学习/深度学习 人工智能 算法
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
手写数字识别系统,使用Python作为主要开发语言,基于深度学习TensorFlow框架,搭建卷积神经网络算法。并通过对数据集进行训练,最后得到一个识别精度较高的模型。并基于Flask框架,开发网页端操作平台,实现用户上传一张图片识别其名称。
53 0
【手写数字识别】Python+深度学习+机器学习+人工智能+TensorFlow+算法模型
|
19天前
|
机器学习/深度学习 数据采集 人工智能
探索机器学习:从理论到Python代码实践
【10月更文挑战第36天】本文将深入浅出地介绍机器学习的基本概念、主要算法及其在Python中的实现。我们将通过实际案例,展示如何使用scikit-learn库进行数据预处理、模型选择和参数调优。无论你是初学者还是有一定基础的开发者,都能从中获得启发和实践指导。
40 2
|
21天前
|
机器学习/深度学习 数据采集 搜索推荐
利用Python和机器学习构建电影推荐系统
利用Python和机器学习构建电影推荐系统
39 1
|
21天前
|
机器学习/深度学习 算法 PyTorch
用Python实现简单机器学习模型:以鸢尾花数据集为例
用Python实现简单机器学习模型:以鸢尾花数据集为例
47 1
|
27天前
|
机器学习/深度学习 数据采集 算法
Python机器学习:Scikit-learn库的高效使用技巧
【10月更文挑战第28天】Scikit-learn 是 Python 中最受欢迎的机器学习库之一,以其简洁的 API、丰富的算法和良好的文档支持而受到开发者喜爱。本文介绍了 Scikit-learn 的高效使用技巧,包括数据预处理(如使用 Pipeline 和 ColumnTransformer)、模型选择与评估(如交叉验证和 GridSearchCV)以及模型持久化(如使用 joblib)。通过这些技巧,你可以在机器学习项目中事半功倍。
38 3
|
1月前
|
机器学习/深度学习 人工智能 算法
机器学习基础:使用Python和Scikit-learn入门
机器学习基础:使用Python和Scikit-learn入门
33 1
|
2月前
|
机器学习/深度学习 算法 Java
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
机器学习、基础算法、python常见面试题必知必答系列大全:(面试问题持续更新)
|
10天前
|
存储 数据挖掘 开发者
Python编程入门:从零到英雄
在这篇文章中,我们将一起踏上Python编程的奇幻之旅。无论你是编程新手,还是希望拓展技能的开发者,本教程都将为你提供一条清晰的道路,引导你从基础语法走向实际应用。通过精心设计的代码示例和练习,你将学会如何用Python解决实际问题,并准备好迎接更复杂的编程挑战。让我们一起探索这个强大的语言,开启你的编程生涯吧!
|
16天前
|
机器学习/深度学习 人工智能 TensorFlow
人工智能浪潮下的自我修养:从Python编程入门到深度学习实践
【10月更文挑战第39天】本文旨在为初学者提供一条清晰的道路,从Python基础语法的掌握到深度学习领域的探索。我们将通过简明扼要的语言和实际代码示例,引导读者逐步构建起对人工智能技术的理解和应用能力。文章不仅涵盖Python编程的基础,还将深入探讨深度学习的核心概念、工具和实战技巧,帮助读者在AI的浪潮中找到自己的位置。
|
16天前
|
机器学习/深度学习 数据挖掘 Python
Python编程入门——从零开始构建你的第一个程序
【10月更文挑战第39天】本文将带你走进Python的世界,通过简单易懂的语言和实际的代码示例,让你快速掌握Python的基础语法。无论你是编程新手还是想学习新语言的老手,这篇文章都能为你提供有价值的信息。我们将从变量、数据类型、控制结构等基本概念入手,逐步过渡到函数、模块等高级特性,最后通过一个综合示例来巩固所学知识。让我们一起开启Python编程之旅吧!