跳到主要内容
极客日志极客日志面向AI+效率的开发者社区
首页博客我的书AI学习GitHub 精选镜像AI 生图工具UI配色美学关于
搜索内容 / 工具 / 仓库 / 镜像...⌘K搜索
注册
博客列表
PythonAI算法

Python 数据分析:相关分析与回归模型

使用 Python 进行数据分析中的相关分析与回归模型。内容涵盖协方差与相关系数的概念,线性回归算法的原理及实现,以及逻辑回归在二分类问题中的应用。通过泰坦尼克号生存预测案例,演示了数据预处理、特征工程(如 One-hot 编码)、模型训练与评估的完整流程,展示了如何利用 scikit-learn 库构建机器学习模型并评估准确率。

雪落无声发布于 2025/2/6更新于 2026/9/1159 浏览
Python 数据分析:相关分析与回归模型

近年来,各种机器学习算法越来越多地被应用于数据挖掘与其相关性分析中,旨在实现通过输入数据(特征)即能准确地预测输出数据(标签),从而辅助我们作判断与决策。

本篇首先学习两种最基本的机器学习算法:线性回归与逻辑回归。在 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                 #导入 Pandas
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,  43,  20,  22,  33,  50,  62,  
              48,  55,  75,  62,  73,  81,  76,  64,  82,  90,  93]
}
examOrderDict = OrderedDict(examDict)
examDf = pd.DataFrame(examOrderDict)
print(examDf.head())

#提取特征和标签
exam_X=examDf['学习时间']
exam_Y=examDf['分数']

#绘制特征与标签对应的散点图
plt.scatter(exam_X, exam_Y, color="b", label="exam data")
plt.xlabel("Hours")
plt.ylabel("Score")
plt.show()

#用 corr 函数提取两个数据集的相关系数:corr 返回结果是一个数据框,存放的是相关系数矩阵
rDf=examDf.corr()
print('相关系数矩阵:')
rDf
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)

#print('训练数据特征:',X_train)
#print('训练数据标签:',Y_train)

#绘制散点图
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()

#sklearn 要求输入的特征必须是二维数组的类型,但是因为我们目前只有 1 个特征,所以需要用 reshape 转行成二维数组的类型
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)
#examDf

#提取特征与标签
exam_X=examDf['学习时间']
exam_Y=examDf['通过考试']

#建立训练数据和测试数据,其中训练数据占比 80%
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   #导入 Numpy 包

#回归方程:z= + x,提取截距 a 与回归系数 b
a=model.intercept_
b=model.coef_

x=2
z=a+b*x

#将 z 值带入逻辑回归函数中,得到概率值
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()           #计算出频数最高的类别为'S'
full['Embarked'] = full['Embarked'].fillna( 'S' )
full['Cabin'] = full['Cabin'].fillna( 'U' )  #缺失数据比较多时,缺失值填充'U',意为 Unkown

full.info()
full.head()

获取完整的数据后,下一步进行特征工程,即最大限度地从数据中提取特征,以供机器学习算法和模型使用。

根据不同的数据类型有不同的特征提取方法:1、数值类型(如年龄、船票价格等)可直接使用;2、分类数据(如客舱等级、登船港口等)需要通过 One-hot 编码转换成虚拟变量;3、字符串类型(如乘客姓名、客舱号等)需要按自定义的方法提取出其中的类别特征。

如下代码中,二分类的数据(性别)可直接用 map 函数映射;三种及以上类型的分类数据(登船港口与客舱等级)则需用 pandas 包中的 get_dummies 函数进行 One-hot 编码,生成虚拟变量。字符串类型数据,乘客姓名提取其 Title 作为类别特征;客舱号则提取首字母作为类别特征。最后,根据船上乘客的亲属数量,再补充了一个按家庭大中小规模为类别的特征信息。

提取完特征信息后,即可用 corr() 函数计算出各特征与标签之间的相关系数。

'''特征工程'''

###用数值类数据替换分类数据
##二分类别(乘客性别'Sex': 男(male)对应数值 1,女(female)对应数值 0)
sex_mapDict = {'male':1,'female':0}
full['Sex']=full['Sex'].map(sex_mapDict)  #map 函数:对 Series 每个数据应用自定义的函数计算

##多个类别 (One-hot 编码)
#登船港口:南安普顿(S)、瑟堡市(C)、昆士敦(Q)
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)

#客舱等级:1/2/3 等舱
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] #Mr. Owen Harris
    str2=str1.split( '.' )[0] #Mr
    str3=str2.strip()
    return str3

titleDf = pd.DataFrame()
titleDf['Title'] = full['Name'].map(getTitle)
titleDf = pd.get_dummies(titleDf['Title'])  #使用 get_dummies 进行 one-hot 编码

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()  #相关性矩阵
#查看各个特征与生成情况(Survived)的相关系数,并按降序排列 (显示正相关性最强的 8 个特征)
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 )
#full_X.head()

sourceRow=891  #原始训练数据集的行数

source_X = full_X.loc[0:sourceRow-1,:]          #特征
source_Y = full.loc[0:sourceRow-1,'Survived']   #标签

pred_X = full_X.loc[sourceRow:,:]               #891 行以后的为待测数据集,用于预测结果提交 Kaggle


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)

#score 函数计算模型正确率
model.score(test_X,test_Y)

最后,用该模型对待测数据集中的乘客生存情况进行预测,预测结果(.csv)上传 Kaggle,项目完成。

'''方案实施'''

#使用机器学习模型,对预测数据集中的生存情况进行预测
pred_Y = model.predict(pred_X)
pred_Y = pred_Y.astype(int)

#乘客 id
passenger_id = full.loc[sourceRow:,'PassengerId']

#数据框:乘客 id,预测生存情况的值
predDf = pd.DataFrame( 
    { 'PassengerId': passenger_id , 
     'Survived': pred_Y } )

predDf.head()

总结

本文系统介绍了基于 Python 的数据分析方法,重点讲解了相关系数、线性回归与逻辑回归的核心原理及代码实现。通过 Titanic 案例,展示了从数据清洗、特征工程到模型训练评估的完整机器学习流程。掌握这些基础技能,有助于在实际业务中利用数据进行有效的预测与决策支持。

目录

  1. 一、线性回归(Linear Regression)
  2. 1. 描述相关性的参数
  3. 2. 线性回归算法
  4. 二、逻辑回归(Logistic Regression)
  5. 创建逻辑回归
  6. 三、Kaggle 项目实操——泰坦尼克号生存率预测
  7. 总结

更多推荐文章

查看全部
  • VS Code Copilot 深度使用指南:从安装到高级配置
  • OpenClaw 移动端部署实战:iOS/Android 语音唤醒与离线 AI 助手
  • mux.js 完全指南:轻量级视频容器处理工具入门
  • 如何为前端项目编写优秀的 AI Agent Skills
  • Whisper-large-v3 语音识别效果评估:100 条样本准确率与召回率分析
  • 无人机航拍目标检测与语义分割数据集汇总
  • 大模型竞争加剧,建议将重心转向垂直模型
  • 五大 AI 工具一站式提效指南:豆包、即梦、剪映、飞书与扣子
  • 利用 AI 助手实现自然语言到 SQL 的转换
  • LeetCode 239 滑动窗口最大值:单调队列解法
  • C++ 控制台常见错误码及调试方法
  • Android Studio 集成 GitHub Copilot GPT-4o:AI 辅助开发实战与避坑指南
  • RocketMQ 顺序消息详解:全局与分区实现
  • OpenClaw 本地 AI 助手飞书对接部署指南
  • YOLOv10n-SOEP-PST 助老机器人目标检测系统详解
  • 基于脱敏算法的综合医疗信息管理系统设计与实现
  • JBoss Seam 实战:使用 JBoss Tools 构建首个 CRUD 项目
  • Java ArrayList 核心解析:原理、用法与扩容机制
  • 18 款免费 AI 生成 3D 模型工具盘点
  • C++ 引用、内联函数与 nullptr 详解

相关免费在线工具

  • 加密/解密文本

    使用加密算法(如AES、TripleDES、Rabbit或RC4)加密和解密文本明文。 在线工具,加密/解密文本在线工具,online

  • RSA密钥对生成器

    生成新的随机RSA私钥和公钥pem证书。 在线工具,RSA密钥对生成器在线工具,online

  • Mermaid 预览与可视化编辑

    基于 Mermaid.js 实时预览流程图、时序图等图表,支持源码编辑与即时渲染。 在线工具,Mermaid 预览与可视化编辑在线工具,online

  • 随机西班牙地址生成器

    随机生成西班牙地址(支持马德里、加泰罗尼亚、安达卢西亚、瓦伦西亚筛选),支持数量快捷选择、显示全部与下载。 在线工具,随机西班牙地址生成器在线工具,online

  • Gemini 图片去水印

    基于开源反向 Alpha 混合算法去除 Gemini/Nano Banana 图片水印,支持批量处理与下载。 在线工具,Gemini 图片去水印在线工具,online

  • curl 转代码

    解析常见 curl 参数并生成 fetch、axios、PHP curl 或 Python requests 示例代码。 在线工具,curl 转代码在线工具,online