跳到主要内容Python 数据分析:相关分析与回归模型 | 极客日志PythonAI算法
Python 数据分析:相关分析与回归模型
本文介绍了使用 Python 进行数据分析中的相关分析与回归模型。内容涵盖协方差与相关系数的概念,线性回归算法的原理及实现,以及逻辑回归在二分类问题中的应用。通过泰坦尼克号生存预测案例,演示了数据预处理、特征工程(如 One-hot 编码)、模型训练与评估的完整流程,展示了如何利用 scikit-learn 库构建机器学习模型并评估准确率。
雪落无声2 浏览 近年来,各种机器学习算法越来越多地被应用于数据挖掘与其相关性分析中,旨在实现通过输入数据(特征)即能准确地预测输出数据(标签),从而辅助我们作判断与决策。
本篇首先学习两种最基本的机器学习算法:线性回归与逻辑回归。在 Python 中,使用机器学习算法须导入专用的包 scikit-learn,导入方式与 numpy/pandas 类似。
一、线性回归(Linear Regression)
1. 描述相关性的参数
线性相关含 3 种关系:正相关、负相关与不相关(随机)。因此,描述相关性的参数需具备两个功能:相关方向与相关程度。比如,线性正相关时,该参数>0;线性负相关时,该参数<0。且该参数值越大,线性相关性越强。
协方差 Cov(X,Y)=E[(X−μx)(Y−μy)] 能满足上述要求。如果协方差为正,则说明 X,Y 同向变化,协方差值越大,说明同向程度越高;反之亦然。
但协方差有个缺点,那就是其值不仅与 X,Y 的相关程度有关,而且还与 X,Y 本身的变化幅度有关。为了把变化幅度的影响从协方差中剔除,定义了相关系数:ρ = Cov(X,Y) / (σX * σY)。即,X,Y 的协方差除以 X 与 Y 各自的标准差,以剔除变量自身幅度的波动。
这样一来,相关系数就能专注地表征变量间的相关性了。其值范围 [-1,1],1 表示完全线性正相关,-1 表示完全线性负相关,0 表示完全不相关(随机)。
Python 中可用 corr() 函数直接求出两个数据集之间的相关系数。如下代码,首先建立学习时间(特征)与考试分数(标签)两个数据集,然后绘制散点图,并用 corr() 函数求出两个数据集的相关系数约 0.92。即表明,考试分数与学习时间是高度正相关的。
'''建立数据集'''
from collections import OrderedDict
import pandas as pd
import matplotlib.pyplot as plt
examDict={
'学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,2.00,2.25,
2.50,2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
'分数': [10, 22, 13, , , , , , ,
, , , , , , , , , , ]
}
examOrderDict = OrderedDict(examDict)
examDf = pd.DataFrame(examOrderDict)
(examDf.head())
exam_X=examDf[]
exam_Y=examDf[]
plt.scatter(exam_X, exam_Y, color=, label=)
plt.xlabel()
plt.ylabel()
plt.show()
rDf=examDf.corr()
()
rDf
相关免费在线工具
- 加密/解密文本
使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online
- RSA密钥对生成器
生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online
- Mermaid 预览与可视化编辑
基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online
- curl 转代码
解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online
- Base64 字符串编码/解码
将字符串编码和解码为其 Base64 格式表示形式即可。 在线工具,Base64 字符串编码/解码在线工具,online
- Base64 文件转换器
将字符串、文件或图像转换为其 Base64 表示形式。 在线工具,Base64 文件转换器在线工具,online
43
20
22
33
50
62
48
55
75
62
73
81
76
64
82
90
93
print
'学习时间'
'分数'
"b"
"exam data"
"Hours"
"Score"
print
'相关系数矩阵:'
2. 线性回归算法
所谓线性回归,就是找一条直线方程(线性回归方程) y=a+b*x 来模拟两数据集{x}与{y}的相关性,其中 a 称为截距,b 称为回归系数。
线性回归的目标是,找到一条直线(即截距与回归系数),使其能尽可能多地拟合散点图中的数据点,该直线也被称为最佳拟合线。
然而,何谓'最佳拟合'?定义决定系数 R²来评估拟合优度,决定系数越接近 1,拟合越精确。
R² = 1 - SSE/SST = 1 - Σ(y_实际值 - y_预测值)² / Σ(y_实际值 - y_均值)²
如下代码,先从数据集中随机拆分出训练数据集与测试数据集。其中训练数据集占比 80%,用于计算出最佳拟合线;余下 20% 为测试数据集,用于评估拟合优度(决定系数)。
'''线性回归'''
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
X_train , X_test , Y_train , Y_test = train_test_split(exam_X,exam_Y,train_size=0.8)
print('原始数据特征:',exam_X.shape ,
',训练数据特征:', X_train.shape ,
',测试数据特征:',X_test.shape )
print('原始数据标签:',exam_Y.shape ,
'训练数据标签:', Y_train.shape,
'测试数据标签:' ,Y_test.shape)
plt.scatter(X_train, Y_train, color="blue", label="train data")
plt.scatter(X_test, Y_test, color="red", label="test data")
plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Score")
plt.show()
Python 中可调用 LinearRegression() 函数建立线性回归模型,并用 fit() 函数计算出最佳拟合线。如上所述时间与分数的数据集,其最佳拟合直线为:
score = 15.3 + 14.3 * hours
model = LinearRegression()
X_train=X_train.values.reshape(-1,1)
X_test=X_test.values.reshape(-1,1)
model.fit(X_train,Y_train)
'''
最佳拟合线:z= + x
截距 intercept:a
回归系数:b
'''
a=model.intercept_
b=model.coef_
print('最佳拟合线:截距 a=',a,',回归系数 b=',b)
plt.scatter(X_train, Y_train, color='blue', label="train data")
plt.scatter(X_test, Y_test, color='red', label="test data")
Y_train_pred = model.predict(X_train)
plt.plot(X_train, Y_train_pred, color='black', linewidth=3, label="best line")
plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Score")
plt.show()
Python 中可用 score() 函数直接求出拟合直线的决定系数。
二、逻辑回归(Logistic Regression)
逻辑回归是一种解决二分类问题的机器学习方法,用于估计某种情况发生的可能性。与线性回归不同,逻辑回归的标签是二分类型(0 或 1),比如:考试通过或未通过、西瓜甜或不甜、这首歌喜欢或不喜欢等等。下面代码以考试通过(1)或未通过(0)为标签,评估其与输入特征(学习时间)之间的相关性。
首先建立特征与标签的数据集(20 组),并随机选取其中 80% 的数据为训练数据,余下的 20% 的数据为测试数据,用于评估模型预测准确性。
'''建立数据集'''
from collections import OrderedDict
from sklearn.model_selection import train_test_split
import pandas as pd
import matplotlib.pyplot as plt
examDict={
'学习时间':[0.50,0.75,1.00,1.25,1.50,1.75,1.75,2.00,2.25,2.50,
2.75,3.00,3.25,3.50,4.00,4.25,4.50,4.75,5.00,5.50],
'通过考试':[0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1]
}
examOrderDict=OrderedDict(examDict)
examDf=pd.DataFrame(examOrderDict)
exam_X=examDf['学习时间']
exam_Y=examDf['通过考试']
X_train , X_test , Y_train , Y_test = train_test_split(exam_X,exam_Y,train_size=0.8)
print('原始数据特征:',exam_X.shape ,
',训练数据特征:', X_train.shape ,
',测试数据特征:',X_test.shape )
print('原始数据标签:',exam_Y.shape ,
'训练数据标签:', Y_train.shape,
'测试数据标签:' ,Y_test.shape)
plt.scatter(X_train, Y_train, color="blue", label="train data")
plt.scatter(X_test, Y_test, color="red", label="test data")
plt.legend(loc=2)
plt.xlabel("Hours")
plt.ylabel("Pass")
plt.show()
在绘制出输入特征数据与标签的散点图后,会发现一个问题:用线性回归的最佳拟合直线方法很难表征出实际的相关性。
这时,便需要引入一个辅助工具:Sigmoid 函数,又称逻辑函数。该函数曲线为 S 形,它能把一个实数(如线性回归方程)映射到(0,1)的区间,用来表示通过考试(发生 1)的概率,从而巧妙地把线性回归方法与二分类问题耦合起来。
方便起见,一般以概率 0.5 为分类决策面。即,当 Sigmoid 函数返回值>0.5 时,预测考试通过(输出 1);反之,当 Sigmoid 函数返回值<0.5 时,预测考试未通过(输出 0)。
用 Python 实现逻辑回归的代码与线性回归相近,其中,可用 score 函数评估预测结果的正确率(0.75)。也可类似线性回归提取截距与回归系数,再代入特征数据计算相应的预测概率值(如学习时间为 2 小时,则考试通过的概率仅为约 23%,预测考试未通过)
'''逻辑回归'''
from sklearn.linear_model import LogisticRegression
X_train=X_train.values.reshape(-1,1)
X_test=X_test.values.reshape(-1,1)
model = LogisticRegression()
model.fit(X_train,Y_train)
accuracy = model.score(X_test,Y_test)
print('模型准确率 = ',accuracy)
import numpy as np
a=model.intercept_
b=model.coef_
x=2
z=a+b*x
y_pred=1/(1+np.exp(-z))
print('预测的概率值:',y_pred)
三、Kaggle 项目实操——泰坦尼克号生存率预测
项目题目:根据数据建立泰坦尼克号上乘客生存情况(标签)的预测模型,已知数据中包含乘客的姓名、性别、年龄、登船港口与船舱号等特征信息。
合并训练数据集与待测数据集,以便统一预处理。由于导入的原始数据中存在不少缺失值,首先应按数据类型进行缺失值处理(补充或删除),生成一个完整的表格数据信息(1309 行*12 列)。
'''数据导入与预处理'''
import numpy as np
import pandas as pd
train = pd.read_csv('./train.csv')
test = pd.read_csv("./test.csv")
print ('训练数据集:',train.shape,'待测数据集:',test.shape)
rowNum_train = train.shape[0]
rowNum_test = test.shape[0]
full = train.append( test,ignore_index = True )
full['Age']=full['Age'].fillna(full['Age'].mean())
full['Fare'] = full['Fare'].fillna(full['Fare'].mean())
full['Embarked'].value_counts()
full['Embarked'] = full['Embarked'].fillna( 'S' )
full['Cabin'] = full['Cabin'].fillna( 'U' )
full.info()
full.head()
获取完整的数据后,下一步进行特征工程,即最大限度地从数据中提取特征,以供机器学习算法和模型使用。
根据不同的数据类型有不同的特征提取方法:1、数值类型(如年龄、船票价格等)可直接使用;2、分类数据(如客舱等级、登船港口等)需要通过 One-hot 编码转换成虚拟变量;3、字符串类型(如乘客姓名、客舱号等)需要按自定义的方法提取出其中的类别特征。
如下代码中,二分类的数据(性别)可直接用 map 函数映射;三种及以上类型的分类数据(登船港口与客舱等级)则需用 pandas 包中的 get_dummies 函数进行 One-hot 编码,生成虚拟变量。字符串类型数据,乘客姓名提取其 Title 作为类别特征;客舱号则提取首字母作为类别特征。最后,根据船上乘客的亲属数量,再补充了一个按家庭大中小规模为类别的特征信息。
提取完特征信息后,即可用 corr() 函数计算出各特征与标签之间的相关系数。
'''特征工程'''
sex_mapDict = {'male':1,'female':0}
full['Sex']=full['Sex'].map(sex_mapDict)
embarkedDf = pd.DataFrame()
embarkedDf = pd.get_dummies(full['Embarked'],prefix='Embarked')
full = pd.concat([full,embarkedDf],axis=1)
full.drop('Embarked',axis=1,inplace=True)
pclassDf = pd.DataFrame()
pclassDf = pd.get_dummies( full['Pclass'],prefix='Pclass' )
full = pd.concat([full,pclassDf],axis=1)
full.drop('Pclass',axis=1,inplace=True)
def getTitle(name):
str1=name.split( ',' )[1]
str2=str1.split( '.' )[0]
str3=str2.strip()
return str3
titleDf = pd.DataFrame()
titleDf['Title'] = full['Name'].map(getTitle)
titleDf = pd.get_dummies(titleDf['Title'])
full = pd.concat([full,titleDf],axis=1)
full.drop('Name',axis=1,inplace=True)
cabinDf = pd.DataFrame()
full[ 'Cabin' ] = full[ 'Cabin' ].map( lambda c : c[0] )
cabinDf = pd.get_dummies( full['Cabin'] , prefix = 'Cabin' )
full = pd.concat([full,cabinDf],axis=1)
full.drop('Cabin',axis=1,inplace=True)
familyDf = pd.DataFrame()
familyDf[ 'FamilySize' ] = full[ 'Parch' ] + full[ 'SibSp' ] + 1
'''
家庭类别:
小家庭 Family_Single:家庭人数=1
中等家庭 Family_Small: 2<=家庭人数<=4
大家庭 Family_Large: 家庭人数>=5
'''
familyDf[ 'Family_Single' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if s == 1 else 0 )
familyDf[ 'Family_Small' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if 2 <= s <= 4 else 0 )
familyDf[ 'Family_Large' ] = familyDf[ 'FamilySize' ].map( lambda s : 1 if 5 <= s else 0 )
full = pd.concat([full,familyDf],axis=1)
'''相关分析'''
corrDf = full.corr()
corrDf['Survived'].sort_values(ascending=False).head(8)
选择几个相关性强的特征作为模型输入,用逻辑回归算法进行模型训练。经测试数据评估,模型预测的准确率可达约 79%。
'''构建模型'''
import warnings
warnings.filterwarnings('ignore')
full_X = pd.concat( [titleDf,
pclassDf,
familyDf,
full['Fare'],
cabinDf,
embarkedDf,
full['Sex']
] , axis=1 )
sourceRow=891
source_X = full_X.loc[0:sourceRow-1,:]
source_Y = full.loc[0:sourceRow-1,'Survived']
pred_X = full_X.loc[sourceRow:,:]
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
train_X, test_X, train_Y, test_Y = train_test_split(source_X,source_Y,train_size=.8)
print ('原始数据集特征:',source_X.shape,
'训练数据集特征:',train_X.shape ,
'测试数据集特征:',test_X.shape)
print ('原始数据集标签:',source_Y.shape,
'训练数据集标签:',train_Y.shape ,
'测试数据集标签:',test_Y.shape)
model = LogisticRegression()
model.fit(train_X,train_Y)
model.score(test_X,test_Y)
最后,用该模型对待测数据集中的乘客生存情况进行预测,预测结果(.csv)上传 Kaggle,项目完成。
'''方案实施'''
pred_Y = model.predict(pred_X)
pred_Y = pred_Y.astype(int)
passenger_id = full.loc[sourceRow:,'PassengerId']
predDf = pd.DataFrame(
{ 'PassengerId': passenger_id ,
'Survived': pred_Y } )
predDf.head()
总结
本文系统介绍了基于 Python 的数据分析方法,重点讲解了相关系数、线性回归与逻辑回归的核心原理及代码实现。通过 Titanic 案例,展示了从数据清洗、特征工程到模型训练评估的完整机器学习流程。掌握这些基础技能,有助于在实际业务中利用数据进行有效的预测与决策支持。