逻辑回归和线性回归的区别_第三次课_线性回归&逻辑回归

  • 线性回归用于拟合数据,寻找数据的规律,只适用于预测类型的回归问题,由于其算法简单,通常作为项目的BaseLine,损失函数通常使用最小二乘法,最小二乘法(又称最小平方法)是一种数学优化技术。它通过最小化误差的平方和寻找数据的最佳函数匹配。利用最小二乘法可以简便地求得未知的数据,并使得这些求得的数据与实际数据之间误差的平方和为最小。用函数表示为:

d2e273cfb6a12103892ba85e19a99c47.png

使误差(所谓误差,当然是观察值与实际真实值的差量)平方和达到最小以寻求估计值的方法,就叫做最小二乘法,用最小二乘法得到的估计,叫做最小二乘估计。

  • 线性回归容易过拟合,为了防止过拟合,可以使用L2正则化,即在损失函数后面增加惩罚项,用于限制模型变得太过复杂。
  • L1范数: 为x向量各个元素绝对值之和。
    L2范数: 为x向量各个元素平方和的1/2次方,L2范数又称Euclidean范数或者Frobenius范数
  • L1范数可以使权值稀疏,方便特征提取。 L2范数可以防止过拟合,提升模型的泛化能力。
  • L1和L2的差别,为什么一个让绝对值最小,一个让平方最小,会有那么大的差别呢?

看导数一个是1一个是w便知, 在靠近0附近, L1以匀速下降到零, 而L2则完全停下来了. 这说 明L1是将不重要的特征(或者说, 重要性不在一个数量级上)尽快剔除, L2则是把特征贡献尽量压缩最小但不至于为零. 两者一起作用, 就是把重要性在一个数量级(重要性最高的)的那些特征一起平等共事(简言之, 不养闲人也不要超人)。

  • 逻辑回归是用于分类问题!用于分类问题!用于分类问题!本质上是在线性回归的表达式外面套了一个sigmod函数。Logistic回归目的是从特征学习出一个0/1分类模型,而这个模型是将特征的线性组合作为自变量,由于自变量的取值范围是负无穷到正无穷。因此,使用logistic函数(或称作sigmoid函数)将自变量映射到(0,1)上,映射后的值被认为是属于y=1的概率。

38954257f41939c48a48804708a31f5d.png

逻辑回归看似简单,在工业界却使用颇多,因为模型简单,分类效果还好。虽然现在深度学习盛行,但在一些传统行业,比如金融领域,使用逻辑回归的还是偏多。

通过Logistic Regression预测Titanic乘客是否能在事故中生还

1.导入工具库和数据

import numpy as np
import pandas as pd
from sklearn import preprocessing
import matplotlib.pyplot as plt
plt.rc("font", size=14)
import seaborn as sns
sns.set(style="white")  # 设置背景色为白色
sns.set(style="whitegrid", color_codes=True)

df = pd.read_csv("./titanic_data.txt")
df.head()

3f6c2f73abf6da552d471a088ef4008a.png

特征含义解释:

pclass: 1,2,3分别代表仓位等级;

sibsp: 兄妹妻子等的个数;

parch: 老人孩子的个数;

fare: 票价;

cabin:仓位分布编号;

embarked: 上船港口。

print("数据集包含的数据个数{}.".format(df.shape[0]))

out: 数据集包含的数据个数1310.

2.查看缺失数据

# 查看数据集中各个特征缺失的情况
df.isnull().sum()

ea357130a0bca16cc7b9ffa6cd760d85.png

2.1 年龄

print('"age"缺失的百分比 %.2f%%' % ((df['age'].isnull().sum() / df.shape[0]) * 100))

out: "age"缺失的百分比 20.15%

可以看出,年龄有20%左右缺失,接下来查看年龄分布情况

ax = df['age'].hist(bins=15, color='teal', alpha=0.6)
ax.set(xlabel='age')
plt.xlim(-10, 85)
plt.show()

ce21f3a5558c586d6970775f339a7b52.png

由于“age”的偏度不为0,使用均值代替缺失值不是最佳选择,这里可以选择使用中间值代替缺失值。

# 年龄的均值
print('The mean of "Age" is %.2f' % (df['age'].mean(skipna=True)))
# 年龄的中间值
print('The median of "Age" is %.2f' % (df['age'].median(skipna=True)))

out: The mean of "Age" is 29.88

The median of "Age" is 28.00

2.2 仓位

# 仓位缺失百分比
print('"Cabin"缺失的百分比 %.2f%%'%((df['cabin'].isnull().sum()/df.shape[0]) * 100))

out: "Cabin"缺失的百分比 77.48%

约77%的乘客的仓位都是缺失的,最佳的选择是不使用这个特征

2.3 登船地点

# 登船地点的缺失率
print('"Embarked"缺失的百分比 %.2f%%'%((df['embarked'].isnull().sum()/df.shape[0]) * 100))

out: "Embarked"缺失的百分比 0.23%

只有0.23%的乘客的登船地点数据缺失,可以使用众数替代缺失的值

print('按照登船地点分组(C = Cherbourg, Q = Queuetown, S = Southampton):')
print(df['embarked'].value_counts())
sns.countplot(x='embarked', data=df, palette='Set2')
plt.show()

dbec9499fd1f41395005c0e7aba8ddb7.png
print('乘客登船地点的众数为 %s.' %df['embarked'].value_counts().idxmax())

out: 乘客登船地点的众数为 S.

由于大多数人是在南安普顿(southhampton)登船,可以使用“S”替代缺失的数据值。

2.4 根据缺失数据情况调整数据

基于以上分析,我们可以进行如下调整: ·如果一条数据的“Age”缺失,使用年龄的中位数28替代 ·如果一条数据的“Embarked”缺失,使用登船地点的众数“S”替代 ·如果太多数乘客的“Cabin”数据缺失,从所有数据中丢弃这个特征值。

data = df.copy()
data['age'].fillna(df['age'].median(skipna=True), inplace=True)
data['embarked'].fillna(df['embarked'].value_counts().idxmax(), inplace=True)
data.drop('cabin',axis=1, inplace=True)

# 确认数据是否还包含缺失数据
data.isnull().sum()

1ee5f318a5f35faaf7907778c50e8568.png

按照以上处理的方式,处理仍然存在缺失数据的情况

TODO:

# 姓名和船票编号应该对结果没有影响,这两个特征直接删除
data = data.drop(["name","ticket"], axis=1)

#survived为标签,缺失的话,直接删除该样本
data = data.dropna(subset=['survived'], axis=0)
# pclass仓位等级缺失,使用众数代替
data['pclass'].fillna(df['pclass'].value_counts().idxmax(), inplace=True)
# sex性别缺失,使用众数代替
data['sex'].fillna(df['sex'].value_counts().idxmax(), inplace=True)
# sibsp缺失,使用众数代替
data['sibsp'].fillna(df['sibsp'].value_counts().idxmax(), inplace=True)
# parch缺失,使用众数代替
data['parch'].fillna(df['parch'].value_counts().idxmax(), inplace=True)
# fare缺失,使用众数代替
data['fare'].fillna(df['fare'].value_counts().idxmax(), inplace=True)
data.isnull().sum()

0d6beafa77bf099bb1a4de013419418a.png

查看年龄在调整前后的分布

plt.figure(figsize=(15,8))
ax = df['age'].hist(bins=15, density=True, stacked=True, color='teal', alpha=0.6)
df["age"].plot(kind='density', color='teal')
ax=data['age'].hist(bins=15, density=True, stacked=True, color='orange', alpha=0.5)
data["age"].plot(kind='density', color='orange')
ax.legend(['Raw Age', 'Adjusted Age'])
ax.set(xlabel="Age")
plt.xlim(-10, 85)
plt.show()

55584b8f2d7fda1ad7298d281335a05a.png

2.4.1 其它特征的处理

数据中的两个特征 “sibsp” (一同登船的兄弟姐妹或者配偶数量)与“parch”(一同登船的父母或子女数量)都是代表是否有同伴同行. 为了预防这两个逼啊了可能的多重共线性, 我们可以将这两个变量转为一个变量 “TravelAlone” (是否独自一人成行)

# 创建一个新的变量‘TravelAlone’记录是否独自旅行,
data['TravelAlone'] = np.where((data["sibsp"] + data["parch"]) > 0, 0, 1)

8af12165f82d5d644b48065cd20023bd.png
# 删除sibsp和parch两个特征
data.drop('sibsp', axis=1, inplace=True)
data.drop('parch', axis=1, inplace=True)
data.head()

043419dbf208e78ecdda15574cdf330b.png

对类别变量(categorical variables)使用独热编码(One-Hot Encoding),将字符串类别转换为数值。

# 对Embarked, Sex 进行独热编码
final = pd.get_dummies(data, columns=["embarked", "sex"])   # 类别类型向量化
final.head()

1c6062a05ba8f4fc60d8b6f72be6f635.png

数据分析

3.1 年龄

plt.figure(figsize=(10,5))
ax = sns.kdeplot(final["age"][final.survived == 1], color="darkturquoise", shade=True)
sns.kdeplot(final["age"][final.survived == 0], color="lightcoral", shade=True)
plt.legend(['Survived', 'Died'])
plt.title('Density Plot of Age for Surviving Population and Deceased Population')
ax.set(xlabel='Age')
plt.xlim(-10,85)
plt.show()

a5f09730f0aa0513e2377368e2cf0c3a.png

生还和遇难群体的分布相似,唯一的最大区别是生还群体中有一部分年龄小的乘客,说明当时的人预先保留了孩子的生还机会。

3.2 票价

plt.figure(figsize=(10, 5))
ax = sns.kdeplot(final["fare"][final.survived == 1], color="darkturquoise", shade=True)
sns.kdeplot(final["fare"][final.survived == 0], color="lightcoral", shade=True)
plt.legend(["Survived", "Died"])
plt.title("Density Plot of Fare for Surviving Population and Deceased Population")
ax.set(xlabel="Fare")
plt.xlim(-20, 200)
plt.show()

e7f372bc276e8c4cea1270fcc554c662.png

生还和遇难群体的票价分布差异比较大,说明这个特征对预测乘客是否生还还是非常重要,票价和仓位相关,也许是仓位影响了逃生的效果。接下来看仓位的分析。

3.3仓位

sns.barplot('pclass', 'survived', data=df, color="darkturquoise")
plt.show()

1a7c289a743d6c9280feaca5f7483da5.png

由图看以看出,一等舱的乘客生还几率最高。

3.4 登船地点

sns.barplot('embarked','survived', data=df, color="teal")
plt.show()

ebf2b6e7fdbd5426685d5137006cf0b9.png

由图可以看出,从法国Cherbourge登录的乘客生还率最高。

3.5 是否独自旅行

sns.barplot('TravelAlone', 'survived', data=final, color="mediumturquoise")
plt.show()

55c16fd105d4be170a90e5c50a6494e8.png

由上图可以看出,独自旅行的乘客生还率较低,当时的年代,独自旅行的乘客多为男性。

3.6 性别

sns.barplot('sex', 'survived', data=df, color="aquamarine")
plt.show()

510fbb520fecefcd16f5b3fc35aa7d08.png

很明显,女性的生还率高。

4.使用Logistic Regression做预测

from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import accuracy_score

# 使用如下特征做预测
cols = ["age", "fare", "TravelAlone", "pclass", "embarked_C", "embarked_S", "sex_male"]

# 创建X(特征)和y(类别标签)
X = final[cols]
y = final['survived']

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=2)

TODO:训练模型, 根据模型,输出准确率

lr = LogisticRegression(solver='liblinear')
lr.fit(X_train, y_train)
y_pred = lr.predict(X_test)
print("准确率为%2.3f" % accuracy_score(y_test, y_pred))

out: 准确率为0.836

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值