1、逻辑回归简介
1、二分类问题
逻辑回归也称为对数几率回归,主要处理的是二分类问题,虽然名字带有回归,但是处理的是分类问题,那
什么是二分类问题呢?
二分类问题就是y取值为{0,1}
,转化成函数表达式如下:
y = { 0 , z < 0 ; 0.5 , z = 0 ; 1 , z > 0 , \left.y=\left\{\begin{array}{cc}0,&z<0 ;\\0.5,&z=0 ;\\1,&z>0 ,\end{array}\right.\right. y=⎩ ⎨ ⎧0,0.5,1,z<0;z=0;z>0,
从这个表达式就可以看出:
- Z > 0,判断为正例
- Z < 0,判断为反例
- Z = 0,为临界值,可以任意判断
但是,这个表达式属于分段函数,不连续,无法求导,故我们希望有一个函数来替代它,这个函数成为**“对数几率”**函数,表达式如下:
y = 1 1 + e − z . y=\frac1{1+e^{-z}} . y=1+e−z1.
也称为:**“Sigmoid”**函数,结合回归,我们可以得到如下表达式:
y = 1 1 + e − ( w T x + b ) . y=\frac1{1+e^{-(\boldsymbol{w}^\mathrm{T}\boldsymbol{x}+b)}} . y=1+e−(wTx+b)1.
提示:W 和 b
求解的方法是极大似然估计,有兴趣的同学可以阅读机器学习西瓜书
从上图中可以分析出如下几个特征:
y
的取值范围为[0, 1]- 分界点为:0.5,大于0.5的为一类,小于0.5的为一类
- 在
Z 属于 (-6, 6)
的时候,变化比较大,尤其是在(-3, 3)
的时候变化大,实际证明在这些区间的时候预测效果也比较好,故很多时候需要结合数据情况来决定是否需要对数据进行归一化 - 对数几率函数是凸函数,有很好的数学性质,在深度学习中也经常用来作为处理二分类的激活函数
2、多分类问题浅谈
多分类问题可以此份为多个二分类问题,假色我们有这么一组数据:
D = { ( x 1 , y 1 ) , ( x 2 , y 2 ) , … , ( x m , y m ) } , y i ∈ { C 1 , C 2 , … , C N } . D=\{(\boldsymbol{x}_1,y_1),(\boldsymbol{x}_2,y_2),\ldots,(\boldsymbol{x}_m,y_m)\}, y_i\in\{C_1,C_2,\ldots,C_N\}. D={(x1,y1),(x2,y2),…,(xm,ym)},yi∈{C1,C2,…,CN}.
最后,通过累加计算出不同类别的概率,属于那个类别的概率大,就属于哪一类。
3、与线性回归的区别
- 问题类别不同:线性回归属于回归问题,逻辑回归属于分类问题
- 分布不同,线性回归的
y
值服从正态分布,逻辑回归的y
值服从伯努利分布
2、案例展示
背景:一组探究消费等级是否与年龄、收入有关,消费等级分为两类。
1、数据预处理
1、导入数据
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
data = pd.read_csv('./Social_Network_Ads.csv')
data
User ID | Gender | Age | EstimatedSalary | Purchased | |
---|---|---|---|---|---|
0 | 15624510 | Male | 19 | 19000 | 0 |
1 | 15810944 | Male | 35 | 20000 | 0 |
2 | 15668575 | Female | 26 | 43000 | 0 |
3 | 15603246 | Female | 27 | 57000 | 0 |
4 | 15804002 | Male | 19 | 76000 | 0 |
... | ... | ... | ... | ... | ... |
395 | 15691863 | Female | 46 | 41000 | 1 |
396 | 15706071 | Male | 51 | 23000 | 1 |
397 | 15654296 | Female | 50 | 20000 | 1 |
398 | 15755018 | Male | 36 | 33000 | 0 |
399 | 15594041 | Female | 49 | 36000 | 1 |
400 rows × 5 columns
# 设置头
columns = {
'User ID': '用户ID',
'Gender': '性别',
'Age': '年龄',
'EstimatedSalary': '工资',
'Purchased': '购买等级'
}
data.rename(columns=columns, inplace=True)
data
用户ID | 性别 | 年龄 | 工资 | 购买等级 | |
---|---|---|---|---|---|
0 | 15624510 | Male | 19 | 19000 | 0 |
1 | 15810944 | Male | 35 | 20000 | 0 |
2 | 15668575 | Female | 26 | 43000 | 0 |
3 | 15603246 | Female | 27 | 57000 | 0 |
4 | 15804002 | Male | 19 | 76000 | 0 |
... | ... | ... | ... | ... | ... |
395 | 15691863 | Female | 46 | 41000 | 1 |
396 | 15706071 | Male | 51 | 23000 | 1 |
397 | 15654296 | Female | 50 | 20000 | 1 |
398 | 15755018 | Male | 36 | 33000 | 0 |
399 | 15594041 | Female | 49 | 36000 | 1 |
400 rows × 5 columns
2、选取目标变量和划分数据集
from sklearn.model_selection import train_test_split
X = data.iloc[:, [2, 3]].values
y = data.iloc[:, 4].values
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
3、数据标准化
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
X_train_scaler = scaler.fit_transform(X_train)
X_test_scaler = scaler.transform(X_test)
2、模型的创建与训练
from sklearn.linear_model import LogisticRegression
model = LogisticRegression()
model.fit(X_train_scaler, y_train) # 模型训练
3、模型预测
y_pred = model.predict(X_test_scaler)
4、误差计算
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
# 计算误差
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)
print("Accuracy", accuracy)
print("Precision", precision)
print("recall", recall)
print("f1", f1)
Accuracy 0.875
Precision 0.95
recall 0.6785714285714286
f1 0.7916666666666667
从准确率和召回率来看,模型分类效果显著。
5、结果可视化
1、训练集可视化
from matplotlib.colors import ListedColormap # 颜色映射类,将颜色映射到列表中,用于观察分布
# 年龄为:x, 工资为:y
x = np.arange(start=X_train[:, 0].min() - 1, stop=X_train[:, 0].max() + 1, step=0.1)
y = np.arange(start=X_train[:, 1].min() - 1, stop=X_train[:, 1].max() + 1, step=100)
# 将x,y绑定为网格形状
x1, x2 = np.meshgrid(x, y)
plt.xlim(x1.min(),x1.max())
plt.ylim(x2.min(),x2.max())
for i,j in enumerate(np.unique(y_test)):
plt.scatter(X_train[y_train==j, 0],
X_train[y_train==j, 1],
color = ListedColormap(['red', 'green'])(i), # i 为不同类别
label=j)
plt.title('LOGISTIC(Training set)')
plt.xlabel('Age')
plt.ylabel('Estimated Salary')
plt.legend()
plt.show()
2、测试集可视化
# 年龄为:x, 工资为:y
x = np.arange(start=X_test[:, 0].min() - 1, stop=X_test[:, 0].max() + 1, step=0.1)
y = np.arange(start=X_test[:, 1].min() - 1, stop=X_test[:, 1].max() + 1, step=100)
# 将x,y绑定为网格形状
x1, x2 = np.meshgrid(x, y)
plt.xlim(x1.min(),x1.max())
plt.ylim(x2.min(),x2.max())
for i,j in enumerate(np.unique(y_test)):
plt.scatter(X_test[y_test==j, 0],
X_test[y_test==j, 1],
color = ListedColormap(['red', 'green'])(i), # i 为不同类别
label=j)
plt.title('LOGISTIC(Test set)')
plt.xlabel('Age')
plt.ylabel('Estimated Salary')
plt.legend()
plt.show()
6、对数据分析结果进行分析
- 收入的高低与年龄有关,年纪较小的,收入普遍较低,年龄大的收入可以分为三类:高收入、中等收入和低收入人群。
- 消费等级与年龄,年龄越大的人,消费等级为
1
,年龄较小的人,消费等级为0
。 - 消费等级与收入,收入高人群中和,消费等级为
1
的占比居多。