数据分析--预测医疗费用

数据分析--预测医疗费用,第1张

数据分析--预测医疗费用

背景
不同年龄性别的人医疗费用数据集,患者的治疗费用由诸多因素决定。如诊断、居住城市、年龄等。该文章采用线性回归、多项式回归、随机森林三种模型进行患者医疗花费的预测

数据来源
数据来源于kaggle

数据说明
age:主要受益人的年龄
sex:保险承包商性别,女性,男性
bmi:体重指数,提供对身体的理解,相对于身高相对较高或较低的重量,使用身高与体重之比的体重客观指数(kg /平方公尺),理想情况下为18.5至24.9
children:健康保险覆盖的儿童人数/家属人数
smoker:吸烟
region:受益人的住宅区位于美国,东北,东南,西南,西北。
charges:由健康保险计费的个人医疗费用

数据分析及代码
1、查看数据

import pandas as pd
import os 
import matplotlib.pyplot as plt
import seaborn as sns
import warnings
import bokeh
import numpy as np

warnings.filterwarnings('ignore')
data = pd.read_csv(r'D:datainsuance.csv')

导入所需要的第三库和读取数据

data.head()


查看数据集前面部分数据

data.tail()


查看数据集后面部分数据

data.isnull().sum()


查看整个数据集每个特征值内是否存在空值,并进行讨论

2、数据之间的关联性

from sklearn.preprocessing import LabelEncoder

zz=LabelEncoder()
zz.fit(data.sex.drop_duplicates())
data.sex=zz.transform(data.sex)

zz.fit(data.smoker.drop_duplicates())
data.smoker=zz.transform(data.smoker)

zz.fit(data.region.drop_duplicates())
data.region=zz.transform(data.region)

data.corr()['charges'].sort_values()

f,ax=plt.subplots(figsize=(10,8))
corr=data.corr()
sns.heatmap(corr,mask=np.zeros_like(corr,dtype=np.bool),cmap=sns.diverging_palette(240,10,as_cmap=True),square=True,ax=ax)


通过上图发现医疗费用与患者是否为吸烟者有高度相关

3、charges的分布
3.1费用的总分布

import numpy as np
from bokeh.io import output_notebook,show
from bokeh.plotting import figure
output_notebook()
import scipy.special
from bokeh.layouts import gridplot
from bokeh.plotting import figure,show,output_file

p=figure(title="charges分布",tools="save",background_fill_color="#E8DDCB")
hist,edges=np.histogram(data.charges)
p.quad(top=hist,bottom=0,left=edges[:-1],right=edges[1:],fill_color="#036564",line_color="#033649")
p.xaxis.axis_label='x'
p.yaxis.axis_label='Pr(x)'
show(p)


有助于帮助了解患者平均在治疗上花费了多少

3.2吸烟者与非吸烟者费用分布

f=plt.figure(figsize=(12,5))
ax=f.add_subplot(121)
sns.distplot(data[(data.smoker==1)]["charges"],color='c',ax=ax)
ax.set_title("Distribution of medical costs for smokers")

ax=f.add_subplot(122)
sns.distplot(data[(data.smoker==0)]["charges"],color='b',ax=ax)
ax.set_title("Distribution of medical costs for non-smokers")


从上图看出吸烟者在治疗上花费更多,但是查看非吸烟者的治疗花费,感觉非吸烟者的数量更多,应该好好检查一下。

3.3、性别对费用的影响分布

sns.catplot(x="smoker",kind="count",hue="sex",palette="pink_r",data=data)


男性编码为“0”,女性编码为“1”,男性吸烟者比女性吸烟者多。假定男性的治疗费用高于女性,我们进一步进行数据可视化。

sns.catplot(x="sex",y="charges",hue="smoker",kind="violin",data=data,palette="magma")

plt.figure(figsize=(12,5))
plt.title("The woman hospitallization costs of box")
sns.boxplot(x="charges",y="smoker",data=data[(data.sex==1)],orient="h",palette="magma")

plt.figure(figsize=(12,5))
plt.title("Man hospitalization costs of box")
sns.boxplot(x="charges",y="smoker",data=data[(data.sex==0)],orient="h",palette="rainbow")


通过比较箱型图的中位数,发现男性与女性的费用要低。

3.4、年龄对治疗费用是否有影响

plt.figure(figsize=(12,5))
plt.title("age distribution")
ax=sns.distplot(data["age"],color='cyan')


数据集中有20岁以下的病人,是这组病人中年纪最小的,最大的年纪是64岁

5、18岁吸烟者与非吸烟者费用情况

sns.catplot(x="smoker",hue="sex",kind="count",data=data[(data.age==18)],palette="magma")
plt.title("Number of smokers and non-smokers aged 18")


在18岁的病人中有吸烟者

plt.figure(figsize=(10,10))
plt.title("the number of smokers and non-smokers aged 18 costs of box")
sns.boxplot(x="smoker",y="charges",data=data[(data.age==18)],palette="summer",orient="v")


18岁的时候,吸烟者在治疗上的花费比不吸烟者要多的多,在非吸烟者中,有一些异常点,可以假设这是因为严重的疾病或者事故导致。

6、吸烟者与非吸烟者情况

g = sns.jointplot(x="age", y="charges", data = data[(data.smoker == 0)],kind="kde", color="c")
g.plot_joint(plt.scatter, c="black", s=30, linewidth=1, marker="+")
g.ax_joint.collections[0].set_alpha(0)
g.set_axis_labels("$X$", "$Y$")
ax.set_title('吸烟者的医疗花费和年龄分布')

g = sns.jointplot(x="age", y="charges", data = data[(data.smoker == 1)],kind="kde", color="green")
g.plot_joint(plt.scatter, c="b", s=30, linewidth=1, marker="*")
g.ax_joint.collections[0].set_alpha(0)
g.set_axis_labels("$X$", "$Y$")
ax.set_title('非吸烟者的医疗花费和年龄分布')

p=figure(plot_width=500,plot_height=450,title="非吸烟者")
p.circle(x=data[(data.smoker==0)].age,y=data[(data.smoker==0)].charges,size=10,
        line_color="navy",
        fill_color="red",
        fill_alpha=0.9)
show(p)

p=figure(plot_width=500,plot_height=450,title="吸烟者")
p.circle(x=data[(data.smoker==1)].age,y=data[(data.smoker==1)].charges,size=10,line_color="black",fill_color="blue",fill_alpha=0.9)
show(p)

sns.lmplot(x="age",y="charges",hue="smoker",data=data,palette="inferno_r",size=7)
ax.set_title("吸烟者和非吸烟者")


以上分析表明,在非吸烟者中,治疗费用随着年龄增长二而增还在增长。但从吸烟者的分析看,发现不了这种相关性,个人认为这是由于数据集的特殊性,吸烟对治疗费用的影响之大,应用一组大量的记录和迹象的数据进行判断。

7、BMI的影响

plt.figure(figsize=(12,5))
plt.title("BMI Distribution")
ax=sns.distplot(data["bmi"],color="m")


BMI大于30开始肥胖

g=sns.jointplot(x="bmi",y="charges",data=data,kind="kde",color="c")
g.plot_joint(plt.scatter,c="orchid",s=30,linewidth=1,marker="+")
g.ax_joint.collections[0].set_alpha(0)
g.set_axis_labels("$x$","$Y$")
ax.set_title("BMI和医疗花费的分布")

plt.figure(figsize=(10,6))
ax=sns.scatterplot(x="bmi",y="charges",data=data,palette='magma',hue="smoker")
ax.set_title("Scatter plot of medical costs and BMI")

sns.lmplot(x="bmi",y="charges",hue="smoker",data=data,palette="magma",size=8)

plt.figure(figsize=(12,5))
plt.title("Distribution of charges for patients with a BMI greater than 30")
ax=sns.distplot(data[(data.bmi>=30)]['charges'],color='c')

plt.figure(figsize=(12,5))
plt.title("Distribution of charges for patients with a BMI lower than 30")
ax=sns.distplot(data[(data.bmi<30)]["charges"],color='orchid')


进行数据可视化的比较发现,BMI在30以上的患者在医疗上花费更多的Money。

8、患者中是否有孩子

sns.catplot(x="children",kind="count",palette="ch:.25",data=data,size=6)

sns.catplot(x="smoker",kind="count",palette="rainbow",hue="sex",data=data[(data.children>0)],size=6)
ax.set_title("吸烟者和非吸烟者是否有孩子")


从上面的图看出大多数病人没有孩子,有些病人中有5个孩子,但是不吸烟的父母更多一些

9、预测成本
9.1线性回归

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score,mean_squared_error
from sklearn.ensemble import RandomForestRegressor

x = data.drop(['charges','sex','region'], axis = 1)
y = data.charges

x_train,x_test,y_train,y_test = train_test_split(x,y, random_state = 0)
lr = LinearRegression().fit(x_train,y_train)

y_train_pred = lr.predict(x_train)
y_test_pred = lr.predict(x_test)

print(lr.score(x_test,y_test))


9.2多项式回归

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score,mean_squared_error
from sklearn.ensemble import RandomForestRegressor

X = data.drop(['charges','sex','region'], axis = 1)
Y = data.charges

quad = PolynomialFeatures (degree = 4)
x_quad = quad.fit_transform(X)

X_train,X_test,Y_train,Y_test = train_test_split(x_quad,Y, random_state = 0)

plr = LinearRegression().fit(X_train,Y_train)

Y_train_pred = plr.predict(X_train)
Y_test_pred = plr.predict(X_test)

print(plr.score(X_test,Y_test))


9.3随机森林

from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import PolynomialFeatures
from sklearn.metrics import r2_score,mean_squared_error
from sklearn.ensemble import RandomForestRegressor

forest = RandomForestRegressor(n_estimators = 100,
                              criterion = 'mse',
                              random_state = 1,
                              n_jobs = -1)
forest.fit(x_train,y_train)
forest_train_pred = forest.predict(x_train)
forest_test_pred = forest.predict(x_test)

print('MSE train data: %.3f, MSE test data: %.3f' % (
mean_squared_error(y_train,forest_train_pred),
mean_squared_error(y_test,forest_test_pred)))
print('R2 train data: %.3f, R2 test data: %.3f' % (
r2_score(y_train,forest_train_pred),
r2_score(y_test,forest_test_pred)))
plt.figure(figsize=(10,6))

plt.scatter(forest_train_pred,forest_train_pred - y_train,
          c = 'black', marker = 'o', s = 35, alpha = 0.5,
          label = 'Train data')
plt.scatter(forest_test_pred,forest_test_pred - y_test,
          c = 'c', marker = 'o', s = 35, alpha = 0.7,
          label = 'Test data')
plt.xlabel('Predicted values')
plt.ylabel('Tailings')
plt.legend(loc = 'upper left')
plt.hlines(y = 0, xmin = 0, xmax = 60000, lw = 2, color = 'red')
plt.show()

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5490959.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存