文中的所有数据集链接:https://pan.baidu测试数据/s/1TV4RQseo6bVd9xKJdmsNFw
提取码:8mm4
什么是逻辑回归
回想一下线性回归,它被用于确定一个连续因变量的值。逻辑回归通常用于分类目的。与线性回归不同,因变量只能采用有限数量的值,即因变量是分类的。当可能结果的数量只有两个时,它被称为二元逻辑回归。
从大的类别上来说,逻辑回归是一种有监督的统计学习方法,主要用于对样本进行 分类 。
逻辑回归与线性回归的关系
逻辑回归也被称为广义线性回归模型,它与线性回归模型的形式基本上相同,都具有 ax+b,其中a和b是待求参数,其区别在于他们的因变量不同,多重线性回归直接将ax+b作为因变量,即y = ax+b,而logistic回归则通过函数S将ax+b对应到一个隐状态p,p = S(ax+b),然后根据p与1-p的大小决定因变量的值。这里的函数S就是Sigmoid函数, 就是因为这个函数的使用才能分类
在这里插入图片描述
该函数具有如下的特性:当x趋近于负无穷时,y趋近于0;当x趋近于正无穷时,y趋近于1;当x= 0时,y=0.5.
假设现在有一个函数 y = a*x1 +b *x2 +c*x3 +b ?x1,x2,x3 带入sigmoid函数中 得到y 如果大于0.5,分类为1,小于0.5,分类为0
德国信用卡欺诈数据集
欧洲的信用卡持卡人在2013年9月2天时间里的284807笔交易数据,其中有492笔交易是欺诈交易,占比0.172%。数据采用PCA变换映射为V1,V2,…,V28 数值型属性,只有交易时间和金额这两个变量没有经过PCA变换。输出变量为二值变量,1为正常,0为欺诈交易。
在这里插入图片描述 读取excel文件
data?=?pd.read_csv("credit-a.csv",?header=None)? data.head()
在这里插入图片描述 我们可以从图上可以看到有15个特征,一个分类结果 相当于y = a1*x1 +…… ?+a15 *x15 +b
逻辑回归和分类数据集
from?sklearn.model_selection?import?train_test_split from?sklearn.linear_model.logistic?import??LogisticRegression
将x 作为特征数据,y作为分类结果,因为输出变量为二值变量,1为正常,0为欺诈交易,而我这是-1代表欺诈和交易,所以用replace方法把-1,变为0
x?=?data[data.columns[:-1]]?# y?=?data[data.columns[15]].replace(-1,0)
将x和y分为训练集和测试集
x_train,x_test,y_train,y_test?=?train_test_split(x,y) len(x_train),len(x_test) OUT: (489,?164)
和线性回归一样的操作
model?=?LogisticRegression()??#用逻辑回归建立模型 model.fit(x_train,y_train)??#fit?和predict? model.predict(x_test) OUT: array([1,?1,?1,?1,?0,?0,?0,?0,?1,?1,?1,?1,?0,?0,?0,?0,?0,?1,?0,?0,?1,?0, ???????0,?0,?1,?0,?0,?0,?0,?1,?1,?1,?0,?0,?1,?1,?1,?1,?1,?1,?1,?0,?1,?0, ???????0,?1,?1,?1,?0,?1,?0,?0,?1,?0,?1,?1,?0,?0,?1,?0,?1,?0,?0,?1,?1,?0, ???????0,?0,?0,?1,?1,?1,?1,?1,?0,?1,?1,?1,?0,?0,?1,?0,?1,?1,?1,?0,?1,?0, ???????0,?0,?1,?1,?0,?1,?1,?0,?1,?1,?0,?1,?0,?1,?1,?0,?0,?0,?0,?1,?1,?0, ???????1,?1,?0,?1,?1,?1,?1,?0,?1,?1,?0,?1,?1,?0,?1,?0,?0,?0,?0,?0,?1,?0, ???????0,?0,?0,?0,?0,?1,?0,?0,?0,?0,?0,?1,?0,?0,?0,?0,?1,?0,?1,?1,?1,?0, ???????1,?0,?0,?1,?0,?1,?1,?0,?1,?1],?dtype=int64) ???????#这里有164个结果
predict_proba 方法可以得到概率(Sigmoid的x和y)
model.predict_proba(x_test)
在这里插入图片描述
第一个数[1.42575343e-02, 9.85742466e-01] 也就是x = 0.014, y=0.9>0.5 分类结果为1
对于精确性如何,导入accuracy_score
from?sklearn.metrics?import?accuracy_score? accuracy_score(model.predict(x_test),?y_test) OUT: 0.8719512195121951
也就是在168个测试样本中168*0.8719512195121951个是正确的
预测Titanic乘客是否生还
来源kaggle 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")?#设置seaborn画图的背景为白色 sns.set(style="whitegrid",?color_codes=True) #?将数据读入?DataFrame df?=?pd.read_csv("./titanic_data.csv") #?预览数据 df.head()
print('数据集包含的数据个数?{}.'.format(df.shape[0]))
数据集包含的数据个数 1310.
2. 查看缺失数据
#?查看数据集中各个特征缺失的情况 df.isnull().sum() out: ????pclass?????????1 ????survived???????1 ????name???????????1 ????sex????????????1 ????age??????????264 ????sibsp??????????1 ????parch??????????1 ????ticket?????????1 ????fare???????????2 ????cabin???????1015 ????embarked???????3 ????dtype:?int64
2.1. ? ?年龄
#?"age"?缺失的百分比? print('"age"?缺失的百分比??%.2f%%'?%((df['age'].isnull().sum()/df.shape[0])*100)) "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()
在这里插入图片描述 由于“年龄”的偏度不为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)))
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))
"Cabin"?缺失的百分比?77.48%
约 77% 的乘客的仓位都是缺失的, 最佳的选择是不使用这个特征的值.
2.3. 登船地点
#?登船地点的缺失率 print('"Embarked"?缺失的百分比?%.2f%%'?%((df['embarked'].isnull().sum()/df.shape[0])*100))
"Embarked"?缺失的百分比?0.23%
只有 0.23% 的乘客的登船地点数据缺失, 可以使用众数替代缺失的值.
print('按照登船地点分组?(C?=?Cherbourg,?Q?=?Queenstown,?S?=?Southampton):') print(df['embarked'].value_counts()) sns.countplot(x='embarked',?data=df,?palette='Set2') plt.show()
按照登船地点分组?(C?=?Cherbourg,?Q?=?Queenstown,?S?=?Southampton): S????914 C????270 Q????123 Name:?embarked,?dtype:?int64
在这里插入图片描述
print('乘客登船地点的众数为?%s.'?%df['embarked'].value_counts().idxmax())
乘客登船地点的众数为?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()
pclass??????1 survived????1 name????????1 sex?????????1 age?????????0 sibsp???????1 parch???????1 ticket??????1 fare????????2 embarked????0 dtype:?int64
#处理仍然存在缺失数据的情况 final.dropna(inplace=True)
#?预览调整过的数据 data.head()
查看年龄在调整前后的分布
plt.figure(figsize=(15,8)) ax?=?df["age"].hist(bins=15,?normed=True,?stacked=True,?color='teal',?alpha=0.6) df["age"].plot(kind='density',?color='teal') ax?=?data["age"].hist(bins=15,?normed=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()
在这里插入图片描述
[
2.4.1. 其它特征的处理
数据中的两个特征 “sibsp” (一同登船的兄弟姐妹或者配偶数量)与“parch”(一同登船的父母或子女数量)都是代表是否有同伴同行. 为了预防这两个特征具有多重共线性, 我们可以将这两个变量转为一个变量 “TravelAlone” (是否独自一人成行)
注: 多重共线性(multicollinearity)是指多变量线性回归中,变量之间由于存在高度相关关系而使回归估计不准确。比如虚拟变量陷阱(英语:Dummy variable trap)即有可能触发多重共线性问题。
##?创建一个新的变量'TravelAlone'记录是否独自成行,?丢弃“sibsp”?(一同登船的兄弟姐妹或者配偶数量)与“parch”(一同登船的父母或子女数量) data['TravelAlone']=np.where((data["sibsp"]+data["parch"])>0,?0,?1) data.drop('sibsp',?axis=1,?inplace=True) data.drop('parch',?axis=1,?inplace=True)
对类别变量(categorical variables)使用独热编码(One-Hot Encoding), 将字符串类别转换为数值
#?对?Embarked","Sex"进行独热编码,?丢弃?'name',?'ticket' final?=pd.get_dummies(data,?columns=["embarked","sex"]) final.drop('name',?axis=1,?inplace=True) final.drop('ticket',?axis=1,?inplace=True) final.head()
3. 数据分析
3.1. 年龄
plt.figure(figsize=(15,8)) 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()
在这里插入图片描述 生还与遇难群体的分布相似, 唯一大的区别是生还群体中用一部分低年龄的乘客. 说明当时的人预先保留了孩子的生还机会.
3.2. 票价
plt.figure(figsize=(15,8)) 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()
在这里插入图片描述
生还与遇难群体的票价分布差异比较大, 说明这个特征对预测乘客是否生还非常重要. 票价和仓位相关, 也许是仓位影响了逃生的效果, 我们接下来看仓位的分析.
3.3. 仓位
sns.barplot('pclass',?'survived',?data=df,?color="darkturquoise") plt.show()
在这里插入图片描述 如我们所料, 一等舱的乘客生还几率最高.
3.4. 登船地点
sns.barplot('embarked',?'survived',?data=df,?color="teal") plt.show()
在这里插入图片描述
从法国 Cherbourge 登录的乘客生还率最高
3.5. 是否独自成行
sns.barplot('TravelAlone',?'survived',?data=final,?color="mediumturquoise") plt.show()
在这里插入图片描述
独自成行的乘客生还率比较低. 当时的年代, 大多数独自成行的乘客为男性居多.
3.6. 性别
sns.barplot('sex',?'survived',?data=df,?color="aquamarine") plt.show()
在这里插入图片描述 很明显, 女性的生还率比较高
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?和?y?分为两个部分 X_train,?X_test,?y_train,?y_test?=?train_test_split(X,?y,?test_size=0.2,?random_state=2) #?训练模型,?? model?=?LogisticRegression() model.fit(X_train,y_train.values.reshape(-1,1)) #?根据模型,?以?X_test?为输入,?生成变量?y_pred print('Train/Test?split?results:') y_pred?=?model.predict(X_test) print("准确率为?%2.3f"?%?accuracy_score(y_test,?y_pred))
Train/Test split results: 准确率为 0.817
一直原创,从未转载
请认准我, 将我置标
转发,好看支持一下,感谢