基于线性回归对男性体脂率的预测

本项目包含:
1.数据探索性分析
2.线性回归预测体脂率

数据集和代码链接放在文末

一、数据说明

二、前置知识

三、数据导入

import pandas as pd
df = pd.read_csv('/home/mw/input/bodyfat8096/bodyfat.csv')
df.head()

df.isnull().sum()

Density 0
BodyFat 0
Age 0
Weight 0
Height 0
Neck 0
Chest 0
Abdomen 0
Hip 0
Thigh 0
Knee 0
Ankle 0
Biceps 0
Forearm 0
Wrist 0
dtype: int64

四、EDA

4.1 单位转换

体重单位是磅,身高单位是英寸,根据说明,其他字段单位都是cm,所以我们先做一个单位的转换
1磅 = 0.45359237kg
1英寸 = 2.54cm

df['Weight'] = df['Weight']*0.45359237
df['Height'] = df['Height']*2.54
df.head()

4.2 年龄分布

我们可以看出,本数据的最大年龄为81岁,最小年龄为22岁;根据年龄分布图来看,大部分被调查者处于60岁以下,根据下图的对照表来说,这个范围内男性标准的体脂率应该为11~22%,下面我们看一下实际的体脂率

print('最大年龄为:{}岁;最小年龄为:{}岁。'.format(max(df['Age']),min(df['Age'])))

最大年龄为:81岁;最小年龄为:22岁。

from matplotlib import pyplot as plt
%matplotlib inline
import seaborn as sns
fig,ax = plt.subplots(figsize=(6,3), dpi=120)plt.hist(x = df.Age, # 指定绘图数据bins = 15, # 指定直方图中条块的个数color = 'skyblue', # 指定直方图的填充色edgecolor = 'black' # 指定直方图的边框色)
# 添加x轴和y轴标签
plt.xlabel('年龄')
plt.ylabel('频数')
# 添加标题
plt.title('年龄分布')

4.3 体脂率分布

可以看出,体脂率偏高的人多一些,但是数据存在异常,最小体脂率竟然为0?我们查出来是哪一行数据,后续将其剔除。

fig,ax = plt.subplots(figsize=(6,3), dpi=120)plt.hist(x = df.BodyFat, # 指定绘图数据bins = 15, # 指定直方图中条块的个数color = 'skyblue', # 指定直方图的填充色edgecolor = 'black' # 指定直方图的边框色)
# 添加x轴和y轴标签
plt.xlabel('体脂率')
plt.ylabel('频数')
# 添加标题
plt.title('体脂率分布')

4.4 矩阵图分析体脂率和其他变量的关系

可以看出,除了密度和身高外,其他变量和体脂率的趋势关系都差不多

plt.figure(figsize=(10,8), dpi= 80)
for index in range(len(list(df))):sns.pairplot(df, x_vars=list(df)[index],height = 4,aspect=2,y_vars=['BodyFat'],kind="reg")





4.5各变量热力图

五、建模分析

5.1 相关性分析

#特征多了,不好挑,写个相关系数高于就选出来的函数
def corr_del(df,rate):feature_names = list(df.columns)df_corr = df.corr()corr_nums = df_corr.shape[0]corr_cols = df_corr.columnsSimCol = []corr_val = []for i in range(corr_nums):for j in range(i+1,corr_nums):if abs(df_corr.iloc[i,j]) > rate:SimCol.append((corr_cols[i],corr_cols[j]))corr_val.append(df_corr.iloc[i,j])return SimCol,corr_val
SimCol,corr_val = corr_del(df,0.6)
dic_corr = dict(zip(SimCol, corr_val))
dic_corr

{(‘Density’, ‘BodyFat’): -0.9880100628473627,
(‘Density’, ‘Chest’): -0.6733369791259974,
(‘Density’, ‘Abdomen’): -0.7947118404395511,
(‘Density’, ‘Hip’): -0.600660354089649,
(‘BodyFat’, ‘Weight’): 0.6050478447082646,
(‘BodyFat’, ‘Chest’): 0.6956065964708372,
(‘BodyFat’, ‘Abdomen’): 0.8097250131267841,
(‘BodyFat’, ‘Hip’): 0.6179803940078904,
(‘Weight’, ‘Neck’): 0.8284683139329283,
(‘Weight’, ‘Chest’): 0.8923815280868261,
(‘Weight’, ‘Abdomen’): 0.8859966850412094,
(‘Weight’, ‘Hip’): 0.9398562247117858,
(‘Weight’, ‘Thigh’): 0.8662642452804185,
(‘Weight’, ‘Knee’): 0.8505789330735126,
(‘Weight’, ‘Ankle’): 0.608315072705449,
(‘Weight’, ‘Biceps’): 0.7983816192935411,
(‘Weight’, ‘Forearm’): 0.6240866005036086,
(‘Weight’, ‘Wrist’): 0.725655446125877,
(‘Neck’, ‘Chest’): 0.782091547883973,
(‘Neck’, ‘Abdomen’): 0.7506565937224198,
(‘Neck’, ‘Hip’): 0.731289751695859,
(‘Neck’, ‘Thigh’): 0.6912527144821207,
(‘Neck’, ‘Knee’): 0.6677702222416465,
(‘Neck’, ‘Biceps’): 0.7283751397304583,
(‘Neck’, ‘Forearm’): 0.618470595979317,
(‘Neck’, ‘Wrist’): 0.741548026075172,
(‘Chest’, ‘Abdomen’): 0.9142550084986067,
(‘Chest’, ‘Hip’): 0.8261023400678932,
(‘Chest’, ‘Thigh’): 0.723367490537425,
(‘Chest’, ‘Knee’): 0.7136089462374152,
(‘Chest’, ‘Biceps’): 0.7252536409866253,
(‘Chest’, ‘Wrist’): 0.6542751000589216,
(‘Abdomen’, ‘Hip’): 0.8717828189481807,
(‘Abdomen’, ‘Thigh’): 0.7619183177868154,
(‘Abdomen’, ‘Knee’): 0.73232810062617,
(‘Abdomen’, ‘Biceps’): 0.6813947740808934,
(‘Abdomen’, ‘Wrist’): 0.613794264693361,
(‘Hip’, ‘Thigh’): 0.8944771771358432,
(‘Hip’, ‘Knee’): 0.8203181202814968,
(‘Hip’, ‘Biceps’): 0.7364316136795688,
(‘Hip’, ‘Wrist’): 0.6243634101702451,
(‘Thigh’, ‘Knee’): 0.7952254144765618,
(‘Thigh’, ‘Biceps’): 0.7591002761702224,
(‘Knee’, ‘Ankle’): 0.6061087576231976,
(‘Knee’, ‘Biceps’): 0.6750434364944304,
(‘Knee’, ‘Wrist’): 0.659266466451139,
(‘Biceps’, ‘Forearm’): 0.6746310817723552,
(‘Biceps’, ‘Wrist’): 0.628100342036711}

5.2 线性回归模型

我们先做以下几个模型
1.根据上面的表格来看,Density跟BodyFat的相关性极高,可以说是一定存在线性关系,而且根据已有公式,确实可以单独拿出来,我们单独将Density取出,做一个线性模型
2.排除Density,我们分成几步去做,首先选用相关系数大于0.6的特征作为输入;
3.如果2效果不好,我们再利用现有特征生成新的指标去计算,比如BMI

5.2.1 Density与BodyFat的线性模型

from sklearn.linear_model import LinearRegression
X_data = pd.DataFrame(df['Density'])
y_data = df['BodyFat']
from sklearn.metrics import mean_squared_error, r2_score
from sklearn.model_selection import train_test_split
X_train, x_test, y_train, y_test = train_test_split(X_data, y_data, test_size = 0.2,random_state=2022)lr_model = LinearRegression()
lr_model.fit(X_train,y_train)
y_predictions = lr_model.predict(x_test)
print(r2_score(y_test,y_predictions))
print(lr_model.coef_)
print(lr_model.intercept_)

0.9754079369106297
[-434.10203913]
477.38901572061883

fig,ax = plt.subplots(figsize=(4,3), dpi=150)plt.scatter(x_test, y_test, color = 'skyblue', label = '真实值')
#设定X,Y轴标签和title
plt.ylabel('体脂率')
plt.xlabel('身体密度')#绘制最佳拟合曲线
plt.plot(x_test, y_predictions, color = 'black', label = '预测曲线')
#来个图例
plt.legend(loc = 'best')

def dens2bf1(x):y = 457/x-414return y
def dens2bf2(x):y = 495/x-450return y
p_dens2bf1 = pd.DataFrame(dens2bf1(x_test))
p_dens2bf2 = pd.DataFrame(dens2bf2(x_test))
df_pre = pd.DataFrame()
df_pre['p_dens2bf1'] = p_dens2bf1['Density']
df_pre['p_dens2bf2'] = p_dens2bf1['Density']
df_pre['y_predictions'] = y_predictions
df_pre['Density'] = x_test
df_pre.sort_values(by="y_predictions" , inplace=True, ascending=True)
df_pre.reset_index(drop=True,inplace=True)
df_pre.head()
fig,ax = plt.subplots(figsize=(4,3), dpi=150)plt.ylabel('体脂率')
plt.xlabel('身体密度')#绘制曲线
plt.plot(df_pre['Density'],df_pre['p_dens2bf1'], color = 'blue', label = '公式1的计算曲线')plt.plot(df_pre['Density'],df_pre['p_dens2bf2'], color = 'green', label = '公式2的计算曲线')plt.plot(df_pre['Density'],df_pre['y_predictions'], color = 'red', label = '我们的预测曲线')plt.scatter(x_test, y_test, color = 'skyblue', label = '真实值')#图例
plt.legend(loc = 'best')

5.2.2 相关系数>0.6的特征组成的第二个模型

看R^2效果不是很好,模型弃用

X2_data = df[['Weight','Chest','Abdomen','Hip']]
y2_data = df['BodyFat']
X2_train, X2_test, y2_train, y2_test = train_test_split(X2_data, y2_data, test_size = 0.2,random_state=2022)lr2_model = LinearRegression()
lr2_model.fit(X2_train,y2_train)
y2_predictions = lr2_model.predict(X2_test)
print(r2_score(y2_test,y2_predictions))
print(lr2_model.coef_)
print(lr2_model.intercept_)
0.6835334134948379
[-0.34316868  0.09032488  0.9425218   0.02511257]
-51.98931074554292
import numpy as np
fig,ax = plt.subplots(figsize=(4,3), dpi=150)plt.ylabel('体脂率')#绘制曲线
x_ax = np.arange(len(y2_predictions))plt.plot(x_ax,y2_predictions, color = 'red', label = '预测曲线')
plt.plot(x_ax,y2_test, color = 'skyblue', label = '真实值')#图例
plt.legend(loc = 'best')

5.2.3 计算指标模型

找到一些目前常用的指标,利用已有数据做一些新指标
体质指数(BMI)=体重(kg)÷身高^2(m)
ACratio - 腹部胸部比例
HTratio - 臀部大腿比率

df['BMI'] = df['Weight']/((df['Height']/100)*(df['Height']/100))
df['ACratio'] = df['Abdomen']/df['Chest']
df['HTratio'] = df['Hip']/df['Thigh']
df.head()
plt.figure(figsize=(24,16))
ax = sns.heatmap(df.corr(), square=True, annot=True, fmt='.2f')
ax.set_xticklabels(ax.get_xticklabels(), rotation=90)
bottom, top = ax.get_ylim()
ax.set_ylim(bottom + 0.5, top - 0.5)

SimCol,corr_val = corr_del(df,0.6)
dic_corr = dict(zip(SimCol, corr_val))
dic_corr
{('Density', 'BodyFat'): -0.9880100628473627,('Density', 'Chest'): -0.6733369791259974,('Density', 'Abdomen'): -0.7947118404395511,('Density', 'Hip'): -0.600660354089649,('Density', 'ACratio'): -0.6949473525887486,('BodyFat', 'Weight'): 0.6050478447082646,('BodyFat', 'Chest'): 0.6956065964708372,('BodyFat', 'Abdomen'): 0.8097250131267841,('BodyFat', 'Hip'): 0.6179803940078904,('BodyFat', 'ACratio'): 0.6931515157069884,('Weight', 'Neck'): 0.8284683139329283,('Weight', 'Chest'): 0.8923815280868261,('Weight', 'Abdomen'): 0.8859966850412094,('Weight', 'Hip'): 0.9398562247117858,('Weight', 'Thigh'): 0.8662642452804185,('Weight', 'Knee'): 0.8505789330735126,('Weight', 'Ankle'): 0.608315072705449,('Weight', 'Biceps'): 0.7983816192935411,('Weight', 'Forearm'): 0.6240866005036086,('Weight', 'Wrist'): 0.725655446125877,('Height', 'BMI'): -0.6412508451276566,('Neck', 'Chest'): 0.782091547883973,('Neck', 'Abdomen'): 0.7506565937224198,('Neck', 'Hip'): 0.731289751695859,('Neck', 'Thigh'): 0.6912527144821207,('Neck', 'Knee'): 0.6677702222416465,('Neck', 'Biceps'): 0.7283751397304583,('Neck', 'Forearm'): 0.618470595979317,('Neck', 'Wrist'): 0.741548026075172,('Chest', 'Abdomen'): 0.9142550084986067,('Chest', 'Hip'): 0.8261023400678932,('Chest', 'Thigh'): 0.723367490537425,('Chest', 'Knee'): 0.7136089462374152,('Chest', 'Biceps'): 0.7252536409866253,('Chest', 'Wrist'): 0.6542751000589216,('Abdomen', 'Hip'): 0.8717828189481807,('Abdomen', 'Thigh'): 0.7619183177868154,('Abdomen', 'Knee'): 0.73232810062617,('Abdomen', 'Biceps'): 0.6813947740808934,('Abdomen', 'Wrist'): 0.613794264693361,('Abdomen', 'ACratio'): 0.7516469696482908,('Hip', 'Thigh'): 0.8944771771358432,('Hip', 'Knee'): 0.8203181202814968,('Hip', 'Biceps'): 0.7364316136795688,('Hip', 'Wrist'): 0.6243634101702451,('Thigh', 'Knee'): 0.7952254144765618,('Thigh', 'Biceps'): 0.7591002761702224,('Thigh', 'HTratio'): -0.6048325482252465,('Knee', 'Ankle'): 0.6061087576231976,('Knee', 'Biceps'): 0.6750434364944304,('Knee', 'Wrist'): 0.659266466451139,('Biceps', 'Forearm'): 0.6746310817723552,('Biceps', 'Wrist'): 0.628100342036711}

我们可以发现,好像和实际公式不太一致,BMI与体脂率的相关性并不是很强,反而ACratio - 腹部胸部比例有一定的相关性,但是比进行组合前相关性要低,组合并没有得到十分有用的特征,可能是由于数据量较小的原因。

完整代码可点击下方链接,fork后可在线运行也可以下载:
点击fork下载代码

数据集也上传了
数据集

基于线性回归对男性体脂率的预测相关推荐

  1. 测试不同体重体型软件样子的,为什么有的人身高、体重相同,体型却不一样?这是体脂率在作祟...

    原标题:为什么有的人身高.体重相同,体型却不一样?这是体脂率在作祟 原创内容,擅自搬运者必究! 胖子若想要减肥,那么你首先要知道导致肥胖的原因是什么,只有从根源下手,才能有效达到目标身材. 首先,肥胖 ...

  2. Python - 体脂率

    刚开始学ptyhon,记录下第一个作业,体脂率 1 输入: 身高,体重,年龄,性别. 性别需输入 0 或者 1,这里没有用到判断是否是字符. 2 数据处理: 体脂率计算: 将4个变量输入公式,并得出体 ...

  3. 怎么用计算机测出来体脂,如何简单测算出自己的体脂率?

    原标题:如何简单测算出自己的体脂率? 想了解自己是否肥胖,必须从掌握你的体脂率(BFR,Body Fat Ratio)开始,它是了解身体脂肪含量的一个重要指数. 什么是"体脂率"? ...

  4. 用计算机算出用不用减肥,体脂率计算器有什么用

    我们在健身房进行体检的时候,都会有一个项目叫做体脂率,现在网上也有很多体脂率计算器,只要输入自己的身高和体重就可以自动计算出体内的体脂率.体脂率是有一个标准的偏瘦和偏胖,都会有相关的体脂率值范围.很多 ...

  5. 计算体脂率,并给出评价

    #计算体脂率,并给出评价 ##收集参数 height = input ("请输入您的身高(m):") weight = input ("请输入您的体重(kg):" ...

  6. python第一个程序:计算体脂率

    主要是为了提醒自己要--保重 height = input('请输入身高(m):') weight = input('请输入体重(KG):') age = input('请输入年龄:') sex = ...

  7. python案例——体脂率项目

    通过一个人的身高.体重.年龄.性别,判断这个人的体脂率,并且反馈是否正常? 首先接到项目后一定要一步步细分任务,直到每个细分的任务都可以用代码来实现. 写代码之前,先要确定python版本的问题 然后 ...

  8. 智能体脂秤方案——基于4位单片机体脂秤方案设计_西城微科

    智能体脂秤又称健康秤,能测出不同时间人体的脂肪和水分等所占比例,从而反映出人体在不同时间的健康状况.由于测试人体电阻时,需要人体和测试电极直接接触,所以脂肪秤产品要有很强的抗ESD静电干扰性能,本文介 ...

  9. 基于51单片机的体脂检测系统设计(51+oled+hx711+us100)

    功能说明: 1.身高测量(us100触发模式) 2.体重测量(hx711) 3.体脂计算(通过按键进行计算) 4.体脂预警(通过按键调整阈值) 资料说明: 体重测量部分采用自写体重秤初始清零程序,实测 ...

  10. 06 体脂率案例优化

    In [14]: personHeight = input('请输入你的身高(m):') personHeight = float(personHeight) personWeight = input ...

最新文章

  1. INS-20802 PRVF-9802 PRVF-5184 PRVF-5186 After Successful Upgradeto 11gR2 Grid Infrastructure
  2. PHP中session与cookie的简单使用
  3. jQuery formValidator表单验证插件4.1.0 下载 演示 文档 可换肤 代码生成器
  4. java 注解原理_在java中实现组合注解原理分析(注解继承)
  5. mysql行级锁unique_MySQL行级锁,表级锁,页级锁详解
  6. Git Commit failed with error The Git process exited with the code -1,073,741,819
  7. SQLServer 统计数据量
  8. 华为手机使用应用沙盒动态修改cpu数据
  9. 【深度学习】Transformer温故知新
  10. 计算机wps应用题题目,WPS Office模拟试题「附答案」
  11. 如何选择好用的企业级沟通工具
  12. 闭包,一个浪漫的故事
  13. 2022--2023
  14. Py_GUI:证件照压缩处理工具
  15. 步道乐跑怎么刷有效成绩_注会考试成绩5年有效期怎么计算?附报考建议
  16. 百度发布《绿萝算法2.0解读》是想告诉大家这样做
  17. 百度输入法每天语音被调度3.35亿次!它的成功可以复制?
  18. python 最小堆类型: heapq
  19. python大学公众号_几个清华、交大学霸的公众号,值得关注
  20. Navicat Premium 安装 注册

热门文章

  1. 计算机专业老师教案,技能大赛-2015年全国中等职业学校计算机应用基础及计算机类专业课程“创新杯”教师信息化教学设计和说课比赛总结...
  2. 如何有效运维管理光伏电站?
  3. 入股不亏!LINQ凭什么被誉为最好的技术?
  4. Markdown超链接本地文件
  5. 卡内基梅隆大学计算机专业类别,卡内基梅隆大学计算机专业优势介绍
  6. 笔记本计算机无法开机怎么办,笔记本开机按了没反应 笔记本电脑开不了机怎么办...
  7. 惠普HP Deskjet F4238 多功能一体机驱动
  8. 习题:求1-n的阶乘之和,用一个非递归函数fac(n)求n!,n的值由主函数输入,最终得到的结果在主函数中输出。
  9. 51单片机数码管动态显示数字
  10. oracle auto failover,dg设置auto failover