背景
不同年龄性别的人医疗费用数据集,患者的治疗费用由诸多因素决定。如诊断、居住城市、年龄等。该文章采用线性回归、多项式回归、随机森林三种模型进行患者医疗花费的预测
数据来源
数据来源于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()
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)