首页 > 其他分享 >医学数据分析实训 项目八 医疗保险欺诈行为分析

医学数据分析实训 项目八 医疗保险欺诈行为分析

时间:2024-09-24 21:52:41浏览次数:3  
标签:数据分析 医疗保险 provider 金额 医疗机构 实训 支付 print 投保人

文章目录

综合实践一:医疗保险欺诈行为分析

实践项目概述

本实践项目的数据集包括:

  • 投保人信息(Policy_Holder.csv)
  • 医疗机构信息(Provider.csv)
  • 索赔信息(Claim.csv)

索赔信息中主要为医疗机构与投保人两者进行索赔的记录。

医疗机构信息

  • ProviderID:医疗机构编号
  • ProviderType:医疗机构大类
  • ProviderSpecialty:医疗机构细类
  • Location:位置编码

投保人信息

  • Policy_HolderID:投保人编号
  • ProgramCode:保险条款
  • MEDcode:治疗措施编码
  • Age:年龄
  • Sex:性别

一 分析目标

  1. 结合业务理解和分析,分别为投保人和医疗机构构建特征;
  2. 对投保人和医疗机构的行为进行特征分析;
  3. 通过聚类算法发现投保人和医疗机构中存在的疑似欺诈行为。

二 实现步骤

  1. 抽取医疗保险的历史数据;
  2. 对抽取的医疗保险的历史数据进行描述性统计分析,分析投保人信息和医疗机构信息;
  3. 采用聚类算法发现投保人和医疗机构中存在的疑似欺诈行为;
  4. 对疑似欺诈行为结果和聚类结果进行性能度量分析,并进行模型优化。

三 数据准备

  1. 对投保人信息、医疗机构信息、索赔信息进行描述性统计分析;
  2. 对数据集中的缺失值、重复值、异常值,以及格式与内容不规范的数据进行数据清洗;
  3. 绘制饼图分析保险条款种类;
  4. 绘制条形图分析治疗措施编码类别;
  5. 绘制条形图分析投保人所投保险的年龄分布情况;
  6. 绘制条形图分析医疗机构大类分布情况。

四 特征工程

对不同主题对象构建特征,通过分别对投保人、医疗机构的出险和索赔模式前后发生变化判断疑似医疗保险的欺诈行为。

  1. 结合投保人信息和索赔信息,挑选有效的投保人相关特征;
  2. 通过医疗机构信息和索赔信息提取有效的医疗机构特征;
  3. 根据投保人的住院开始时间将其划分为上半年(1Y)和下半年(2Y)两部分;
  4. 选取索赔订单中保费覆盖额、账单金额、支付金额特征,分别按上半年和下半年进行统计,从而得到投保人半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数;
  5. 将投保人信息中的年龄、性别、治疗措施编码、保险条款属性特征进行编码转换,按值展开(年龄除外);
  6. 组合上述特征,构成投保人特征;
  7. 按医疗机构编号和所属时间段分组,统计投保人数和处理过程数量;
  8. 选取索赔订单中保费覆盖额、账单金额、支付金额特征,分别按上半年和下半年进行统计,从而得到医疗机构半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数;
  9. 选取医疗机构信息中的医疗机构大类、医疗机构细类和位置编码,与上述特征(第7条和第8条)构成医疗机构特征;
  10. 通过编码转换将医疗机构大类、医疗机构细类转化为数值型数据。

五 模型训练

数据集中不存在真实标签,因此,采用机器学习中的无监督算法构建医疗保险的欺诈模型。通过聚类算法分别对经过特征变换后投保人和医疗机构的特征集进行分群,输出分群结果。

六 性能度量

  1. 将投保人聚类成 5 类类群,选取投保人数量、平均支付金额、平均支付笔数等具有代表性的指标,进行类群间的差异性比较;
  2. 分析投保人上半年和下半年的索赔变化情况,即投保人类群的迁移统计;
  3. 根据上述分析判断投保人是否疑似存在医疗保险欺诈行为,并输出投保人信息;
  4. 将医疗机构聚类成 5 类类群,选取医疗机构数量、平均投保人数量、平均账单金额等具有代表性的指标,进行类群间相关属性的差异性比较;
  5. 使用 pd.crosstab() 创建交叉表,分析医疗机构上半年和下半年的类群迁移情况;
  6. 根据上述分析判断医疗机构是否疑似存在医疗保险欺诈行为,并输出医疗机构信息;
  7. 采用轮廓系数和 Calinski-Harabasz 指标对投保人和医疗机构的聚类模型进行评价,并可视化评价结果。

七 提交要求

  1. 提交实现本实践任务的所有代码(可执行,非.doc、.txt等文本格式);
  2. 提交综合实践任务书(word格式),包括小组成员分工、分析目的、数据预处理、算法介绍、结果分析等内容;
  3. 提交预处理之后的数据集,以及所有可视化图表。

代码块

import pandas as pd
import numpy as np
import matplotlib.pyplot as plt

# 显示中文和负号
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
import seaborn as sns
from sklearn.cluster import KMeans
from sklearn.preprocessing import StandardScaler
from sklearn.metrics import silhouette_score, calinski_harabasz_score

import os

policy_holder = pd.read_csv('./data/Policy_Holder.csv', encoding='gbk')
provider = pd.read_csv('./data/Provider.csv', encoding='gbk')
claim = pd.read_csv('./data/Claim.csv', encoding='gbk')

policy_holder = policy_holder[(policy_holder['Age'] >= 0) & (policy_holder['Age'] <= 100)]

# 统一日期格式
claim['住院开始时间'] = pd.to_datetime(claim['住院开始时间'], errors='coerce')
claim['住院结束时间'] = pd.to_datetime(claim['住院结束时间'], errors='coerce')

# Policy_HolderID,ProgramCode,MEDcode,Age,Sex 转换成 投保人编号,保险条款,治疗措施编码,年龄,性别
field_mapping1 = {
    "Policy_HolderID": "投保人编号",
    "ProgramCode": "保险条款",
    "MEDcode": "治疗措施编码",
    "Age": "年龄",
    "Sex": "性别"
}
# 更换表头
policy_holder.rename(columns=field_mapping1, inplace=True)
# print(policy_holder.head())
# 列名称映射字典
field_mapping2 = {
    "ProviderID": "医疗机构编号",
    "ProviderType": "医疗机构大类",
    "ProviderSpecialty": "医疗机构细类",
    "Location": "位置编码"
}
# 更换表头
provider.rename(columns=field_mapping2, inplace=True)
# 打印处理后的数据,以确认变化
print(provider.head())

# 保存处理后的数据
output_file = '结果分析'
if not os.path.exists(f'{output_file}'):
    os.mkdir(f'{output_file}')
provider.to_csv(f'./{output_file}/Provider.csv', index=False)
claim.to_csv(f'./{output_file}/Claim.csv', index=False)
policy_holder.to_csv(f'./{output_file}/Policy_Holder.csv', index=False)

三 数据准备

# 读取数据集
policy_holder = pd.read_csv('结果分析/Policy_Holder.csv')
provider = pd.read_csv('结果分析/Provider.csv')
claim = pd.read_csv('结果分析/Claim.csv')

# # 查看数据集的前几行
# print(policy_holder.head())
# print(provider.head())
# print(claim.head())

print(policy_holder.shape)
print(claim.shape)
print(provider.shape)
# 1 描述性统计分析
print(policy_holder.describe())
print(provider.describe())
print(claim.describe())
# 2 缺失值、重复值处理
# 缺失值处理
print(policy_holder.isnull().sum())
print(provider.isnull().sum())
print(claim.isnull().sum())

# 重复值处理
policy_holder.drop_duplicates(inplace=True)
provider.drop_duplicates(inplace=True)
claim.drop_duplicates(inplace=True)


# 绘制饼图分析保险条款种类
insurance_counts = policy_holder['保险条款'].value_counts()

# 绘制饼图
plt.figure(figsize=(8, 6))
plt.pie(insurance_counts, labels=insurance_counts.index, autopct='%1.1f%%', startangle=90)
plt.title('保险条款种类分布')
plt.axis('equal')  # 保证饼图是圆的
plt.show()

在这里插入图片描述

# 绘制条形图分析治疗措施编码类别
plt.figure(figsize=(10, 6))
sns.countplot(data=policy_holder, x='治疗措施编码')
plt.title('治疗措施编码类别分布')
plt.xticks(rotation=45)
plt.show()

在这里插入图片描述

# 绘制条形图分析投保人所投保险的年龄分布情况
plt.figure(figsize=(10, 6))
sns.histplot(policy_holder['年龄'], bins=30, kde=True)
plt.title('投保人年龄分布情况')
plt.xlabel('年龄')
plt.ylabel('频率')
plt.show()

在这里插入图片描述

# 绘制条形图分析医疗机构大类分布
plt.figure(figsize=(10, 6))
provider_counts = provider['医疗机构大类'].value_counts()  # 医疗机构大类数量
sns.barplot(x=provider_counts.index, y=provider_counts.values)
plt.title('医疗机构大类分布情况')
plt.xlabel('医疗机构大类')
plt.ylabel('数量')
plt.xticks(rotation=45)
plt.show()

在这里插入图片描述

4 特征工程

# 3 根据投保人的住院开始时间将其划分为上半年(1Y)和下半年(2Y)两部分
# 3 合并数据集
merged_df = pd.merge(policy_holder, claim, on='投保人编号', how='inner')
merged_df = pd.merge(merged_df, provider, on='医疗机构编号', how='inner')
print(merged_df.shape)



# 将住院开始时间转换为 datetime 格式
merged_df['住院开始时间'] = pd.to_datetime(merged_df['住院开始时间'])
# 新建一个列 '时间段',将住院开始时间划分为 '1Y' 和 '2Y' 两部分
merged_df['时间段'] = merged_df['住院开始时间'].apply(lambda x: '1Y' if x.month < 7 else '2Y')
print(merged_df.head())
print(merged_df.dtypes)
print(merged_df.shape)
# 5 将投保人信息中的年龄、性别、治疗措施编码、保险条款属性特征进行编码转换,按值展开(年龄除外);查看保险条例有那些
# 查看保险条例有那些
print(merged_df['保险条款'].unique())
# 查看治疗措施编码有那些
print(merged_df['治疗措施编码'].unique())
# 性别编码
gender_mapping = {'男': 1, '女': 0}
merged_df['性别'] = merged_df['性别'].map(gender_mapping)
# 保险条款编码
insurance_mapping = {'老年保障险': 0, '伤残险': 1}
merged_df['保险条款'] = merged_df['保险条款'].map(insurance_mapping)
# 治疗措施编码
cure_mapping = {'MCD': 0, 'RegularMedicare': 1, 'MCbuy': 2, 'Undocumented': 3, 'MCQ': 4}
merged_df['治疗措施编码'] = merged_df['治疗措施编码'].map(cure_mapping)

print(merged_df[['性别', '年龄', '保险条款', '治疗措施编码']].head(20))
print(merged_df[['性别', '年龄', '保险条款', '治疗措施编码']].dtypes)
print(merged_df[['性别', '年龄', '保险条款', '治疗措施编码']].shape)

[‘伤残险’ ‘老年保障险’]
[‘MCQ’ ‘RegularMedicare’ ‘MCD’ ‘MCbuy’ ‘Undocumented’]
性别 年龄 保险条款 治疗措施编码
0 0 90 1 4
1 0 90 1 4
2 0 90 1 4
3 0 90 1 4
4 0 90 1 4
5 0 90 1 4
6 0 90 1 4
7 0 90 1 4
8 0 90 1 4
9 0 90 1 4
10 0 90 1 4
11 0 90 1 4
12 0 90 1 4
13 0 90 1 4
14 0 90 1 4
15 0 90 1 4
16 0 90 1 4
17 0 90 1 4
18 0 90 1 4
19 0 90 1 4
性别 int64
年龄 int64
保险条款 int64
治疗措施编码 int64
dtype: object
(9448, 4)

医疗机构大类:
['emerg phys' 'hear aid' 'home health' 'hosp - III' 'optometrist'
 'pharmacist' 'physician' 'podiatrist' 'prsth/ortho' 'trans amb only'
 'psychiatrist' 'amb srg center' 'optician' 'school dist' 'dme suppliers'
 'anesthesiologist' 'nurse svc' 'substance abuse' 'oxy - cont' 'hmo'
 'lab fac' 'day health' 'maternity' 'phys therapist' 'oxy - noncontract'
 'radiology' 'neuromuscular ctr' 'psychologist']
医疗机构细类:
['gen pract' 'med supply' 'non-phys' 'hosp peer 5' 'optical' 'radiology'
 'podiatry' 'med trans' 'clinic' 'psychiatry' 'misc physician'
 'hosp peer 3' 'pathology' 'hosp peer 4' 'fam pract' 'anesthesia'
 'dermatology' 'gen surg' 'int medicine' '31' 'lab diagnostic'
 'ophthalmology' 'fed qual health ctr' 'ob-gyn' 'phys therapy'
# 10 通过编码转换将医疗机构大类、医疗机构细类转化为数值型数据;
# print(merged_df.dtypes)
# print('医疗机构大类:\n',merged_df['医疗机构大类'].unique())
# print('医疗机构细类:\n',merged_df['医疗机构细类'].unique())
# 医疗机构大类映射字典
institution_type_mapping = {'amb srg center': 0, 'anesthesiologist': 1, 'day health': 2, 'dme suppliers': 3,
                            'emerg phys': 4, 'hear aid': 5, 'hmo': 6, 'home health': 7, 'hosp - III': 8, 'lab fac': 9,
                            'maternity': 10,
                            'neuromuscular ctr': 11, 'nurse svc': 12, 'optician': 13, 'optometrist': 14,
                            'oxy - cont': 15, 'oxy - noncontract': 16, 'pharmacist': 17, 'phys therapist': 18,
                            'physician': 19,
                            'podiatrist': 20, 'prsth/ortho': 21, 'psychiatrist': 22, 'psychologist': 23,
                            'radiology': 24,
                            'school dist': 25, 'substance abuse': 26, 'trans amb only': 27}

# 医疗机构细类映射字典
institution_subtype_mapping = {'misc physician': 0, 'anesthesia': 1, 'clinic': 2, 'med supply': 3, 'gen pract': 4,
                               '31': 5, 'non-phys': 6, 'hosp peer 3': 7, 'hosp peer 4': 8, 'hosp peer 5': 9,
                               'lab diagnostic': 10, 'pathology': 11,
                               'fed qual health ctr': 12, 'speech path': 13, 'optical': 14, 'phys therapy': 15,
                               'cardiovasc': 16,
                               'dermatology': 17, 'endocrinology': 18, 'ent': 19, 'fam pract': 20, 'gastroent': 21,
                               'gen surg': 22,
                               'int medicine': 23, 'nephrology': 24, 'neuro surg': 25, 'neurology': 26, 'ob-gyn': 27,
                               'oncology': 28,
                               'ophthalmology': 29, 'ortho surgery': 30, 'pediatrics': 31, 'pulmonary': 32,
                               'radiology': 33,
                               'podiatry': 34, 'psychiatry': 35, 'psychology': 36, 'med trans': 37}
# 应用医疗机构大类映射字典
merged_df['医疗机构大类'] = merged_df['医疗机构大类'].map(institution_type_mapping)
# 应用医疗机构细类映射字典
merged_df['医疗机构细类'] = merged_df['医疗机构细类'].map(institution_subtype_mapping)
print(merged_df.head())
print(merged_df.dtypes)
print(merged_df.shape)
     投保人编号  保险条款  治疗措施编码  年龄  性别             索赔编号       医疗机构编号  \

0 11700010743 1 4 90 0 217460001631126 10017613409
1 11700010743 1 4 90 0 217460001631126 10017613409
2 11700010743 1 4 90 0 196080001529503 10019614301
3 11700010743 1 4 90 0 196080001529503 10019614301
4 11700010743 1 4 90 0 196080001529503 10019614301

       投保人状态         医疗机构服务类别     诊断  ...     住院开始时间      住院结束时间  保费覆盖额  \

0 StillPatient OutpatientOther V72.4 … 2001-06-12 2001-06-19 14800
1 HomeDischarge OutpatientOther V72.2 … 2001-04-24 2001-04-29 78200
2 Missing PhysicianOther 518.1 … 2001-12-04 2001-12-05 9500
3 Missing PhysicianOther 707.2 … 2001-12-04 2001-12-05 16200
4 StillPatient PhysicianOther 707.2 … 2001-12-18 2001-12-20 74700

账单金额   支付金额    服务地点  医疗机构大类 医疗机构细类  位置编码  时间段  

0 14926 14739 nh_snf 4 4 104 1Y
1 78457 78161 nh_icf 4 4 104 1Y
2 10512 9443 office 5 3 410 2Y
3 16714 15845 office 5 3 410 2Y
4 74930 74108 nh_snf 5 3 410 2Y

[5 rows x 22 columns]
投保人编号 int64
保险条款 int64
治疗措施编码 int64
年龄 int64
性别 int64
索赔编号 int64
医疗机构编号 int64
投保人状态 object
医疗机构服务类别 object
诊断 object
处理过程代码 int64
住院时长 int64
住院开始时间 datetime64[ns]
住院结束时间 object
保费覆盖额 int64
账单金额 int64
支付金额 int64
服务地点 object
医疗机构大类 int64
医疗机构细类 int64
位置编码 int64
时间段 object
dtype: object
(9448, 22)

# 1 结合投保人信息和索赔信息,挑选有效的投保人相关特征

# 选择有效的特征
selected_features_1 = merged_df[
    [
        '投保人编号',
        '保费覆盖额',
        '账单金额',
        '支付金额',
        '保险条款',
        '治疗措施编码',
        '年龄',
        '性别',
        '时间段',
    ]
]

policy_holder_features = merged_df[selected_features_1.columns]
print(policy_holder_features.head())
print(policy_holder_features.dtypes)
print(policy_holder_features.shape)

    医疗机构编号        投保人编号  保费覆盖额   账单金额   支付金额    服务地点  医疗机构大类  医疗机构细类  位置编码

0 10017613409 11700010743 14800 14926 14739 nh_snf 4 4 104
1 10017613409 11700010743 78200 78457 78161 nh_icf 4 4 104
2 10019614301 11700010743 9500 10512 9443 office 5 3 410
3 10019614301 11700010743 16200 16714 15845 office 5 3 410
4 10019614301 11700010743 74700 74930 74108 nh_snf 5 3 410
医疗机构编号 int64
投保人编号 int64
保费覆盖额 int64
账单金额 int64
支付金额 int64
服务地点 object
医疗机构大类 int64
医疗机构细类 int64
位置编码 int64
dtype: object

# 4 选取索赔订单中保费覆盖额、账单金额、支付金额特征,分别按上半年和下半年进行统计,从而得到投保人半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数;
# 选取索赔订单中保费覆盖额、账单金额、支付金额特征
selected_features_3 = merged_df[
    [
        '投保人编号',
        '保费覆盖额',
        '账单金额',
        '支付金额',
        '时间段',
    ]
]
# 按时间段统计特征
grouped_features = selected_features_3.groupby(['投保人编号', '时间段']).agg(
    保费覆盖额=('保费覆盖额', 'sum'),
    账单金额=('账单金额', 'sum'),
    支付金额=('支付金额', 'sum'),
    支付金额笔数=('支付金额', 'count')
).reset_index()
print('投保人半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数:')
print(grouped_features.head())
print(grouped_features.dtypes)
print(grouped_features.shape)

保人半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数:
投保人编号 时间段 保费覆盖额 账单金额 支付金额 支付金额笔数
0 10300010118 1Y 1240200 1254890 1225159 30
1 10300010118 2Y 1051400 1065577 1039617 24
2 10500010200 1Y 247800 250520 245811 4
3 10600010291 2Y 785400 797520 776217 21
4 10700010301 2Y 43800 44633 43172 1
投保人编号 int64
时间段 object
保费覆盖额 int64
账单金额 int64
支付金额 int64
支付金额笔数 int64
dtype: object
(433, 6)

# 6.组合 4 和 5 中的特征,构成投保人特征;
# 从原始数据中选择需要合并的属性
additional_features = merged_df[
    [
        '投保人编号',
        '年龄',
        '性别',
        '治疗措施编码',
        '保险条款',
        '时间段',
    ]
].drop_duplicates(subset='投保人编号')
# 合并数据
final_features = grouped_features.merge(additional_features, on=['投保人编号', '时间段'], how='inner')
# print('投保人特征:')
# print(final_features.head())
# print(final_features.dtypes)
# print(final_features.shape)
# 清理重复值
selected_features_4 = merged_df[
    [
        '投保人编号',
        '性别',
        '年龄',
        '保险条款',
        '治疗措施编码',
        '时间段',
    ]
].drop_duplicates(inplace=False)

# 合并特征
policyholder_characteristics = pd.merge(grouped_features, selected_features_4, on=['投保人编号', '时间段'], how='inner')

print('投保人特征:')
print(policyholder_characteristics.head())
print(policyholder_characteristics.dtypes)
print(policyholder_characteristics.shape)

投保人特征:
投保人编号 时间段 保费覆盖额 账单金额 支付金额 支付金额笔数 性别 年龄 保险条款 治疗措施编码
0 10300010118 1Y 1240200 1254890 1225159 30 1 27 1 1
1 10300010118 2Y 1051400 1065577 1039617 24 1 27 1 1
2 10500010200 1Y 247800 250520 245811 4 1 49 1 1
3 10600010291 2Y 785400 797520 776217 21 1 28 1 1
4 10700010301 2Y 43800 44633 43172 1 0 92 1 1
投保人编号 int64
时间段 object
保费覆盖额 int64
账单金额 int64
支付金额 int64
支付金额笔数 int64
性别 int64
年龄 int64
保险条款 int64
治疗措施编码 int64
dtype: object
(433, 10)

# 7.按医疗机构编号和所属时间段分组,统计投保人数和处理过程数量;
number_of_providers_grouped = merged_df.groupby(['医疗机构编号', '时间段']).agg(
    投保总人数=('投保人编号', 'count'),
    处理过程数量=('处理过程代码', 'count')
).reset_index()
print('按医疗机构编号和所属时间段分组,统计投保人数和处理过程数量:')
print(number_of_providers_grouped.head(20))
print(number_of_providers_grouped.dtypes)
print(number_of_providers_grouped.shape)

按医疗机构编号和所属时间段分组,统计投保人数和处理过程数量:
医疗机构编号 时间段 投保总人数 处理过程数量
0 10010410197 1Y 2 2
1 10010610221 1Y 2 2
2 10010710275 1Y 5 5
3 10010710275 2Y 6 6
4 10010910429 1Y 46 46
5 10010910429 2Y 33 33
6 10011210467 2Y 1 1
7 10011310519 2Y 1 1
8 10011410627 2Y 7 7
9 10011610682 1Y 1 1
10 10011810781 1Y 1 1
11 10011910901 1Y 1 1
12 10012110993 1Y 4 4
13 10012110993 2Y 6 6
14 10012611269 1Y 17 17
15 10012611269 2Y 5 5
16 10012811329 1Y 10 10
17 10012811329 2Y 8 8
18 10013011335 1Y 12 12
19 10013011335 2Y 4 4
医疗机构编号 int64
时间段 object
投保总人数 int64
处理过程数量 int64
dtype: object
(717, 4)

# 8. 选取索赔订单中保费覆盖额、账单金额、支付金额特征,分别按上半年和下半年进行统计,从而得到医疗机构半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数;
selected_features_5 = merged_df[
    [
        '医疗机构编号',
        '投保人编号',
        '保费覆盖额',
        '账单金额',
        '支付金额',
        '时间段'
    ]
]
provider_grouped_features = selected_features_5.groupby(['医疗机构编号', '时间段']).agg(
    投保人数=('投保人编号', 'count'),
    保费覆盖额=('保费覆盖额', 'sum'),
    账单金额=('账单金额', 'sum'),
    支付金额=('支付金额', 'sum'),
    支付金额笔数=('支付金额', 'count')
).reset_index()
print('医疗机构投保人数、半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数:')
print(provider_grouped_features.head(30))
print(provider_grouped_features.dtypes)
print(provider_grouped_features.shape)


医疗机构投保人数、半年保费覆盖额、半年账单金额、半年支付金额和半年支付金额笔数:
医疗机构编号 时间段 投保人数 保费覆盖额 账单金额 支付金额 支付金额笔数
0 10010410197 1Y 2 64500 66133 63381 2
1 10010610221 1Y 2 41300 42029 40428 2
2 10010710275 1Y 5 201900 206048 199630 5
3 10010710275 2Y 6 252300 256399 249037 6
4 10010910429 1Y 46 1705500 1728328 1681188 46
5 10010910429 2Y 33 1533200 1549347 1513867 33
6 10011210467 2Y 1 83400 83877 82791 1
7 10011310519 2Y 1 99900 99925 99674 1
8 10011410627 2Y 7 245500 250332 240543 7
9 10011610682 1Y 1 32400 32639 31442 1
10 10011810781 1Y 1 45100 45618 44556 1
11 10011910901 1Y 1 21200 22073 20871 1
12 10012110993 1Y 4 161600 163706 159618 4
13 10012110993 2Y 6 252200 255580 249057 6
14 10012611269 1Y 17 504500 512906 495515 17
15 10012611269 2Y 5 199000 201279 196669 5
16 10012811329 1Y 10 359700 364645 353434 10
17 10012811329 2Y 8 230600 235969 226320 8
18 10013011335 1Y 12 656700 660945 649501 12
19 10013011335 2Y 4 262500 264325 260483 4
20 10013111430 1Y 4 181800 184076 178648 4
21 10013111430 2Y 4 254400 256127 253272 4
22 10013311562 1Y 3 59600 60529 57231 3
23 10013311562 2Y 6 237100 240810 233658 6
24 10013511628 1Y 4 148700 150800 146582 4
25 10013511628 2Y 1 12000 12966 11112 1
26 10013611711 1Y 5 166700 169037 164376 5
27 10013611711 2Y 5 169700 171198 167818 5
28 10013811720 1Y 5 157300 159500 154269 5
29 10013811720 2Y 7 296500 300456 293180 7
医疗机构编号 int64
时间段 object
投保人数 int64
保费覆盖额 int64
账单金额 int64
支付金额 int64
支付金额笔数 int64
dtype: object
(717, 7)

# 9.选取医疗机构信息中的医疗机构大类、医疗机构细类和位置编码,与 7和 8 中的特征,构成医疗机构特征;
additional_features_2 = merged_df[
    [
        '医疗机构编号',
        '医疗机构大类',
        '医疗机构细类',
        '位置编码',
        '时间段'
    ]
].drop_duplicates(subset='医疗机构编号')
# 合并数据
final_features_2 = provider_grouped_features.merge(additional_features_2, on=['医疗机构编号', '时间段'], how='inner')
# print('医疗机构特征:')
# print(final_features_2.head())
# print(final_features_2.dtypes)
# print(final_features_2.shape)
# 清理重复值
selected_features_6 = merged_df[
    [
        '医疗机构编号',
        '医疗机构大类',
        '医疗机构细类',
        '位置编码',
        '时间段'
    ]
].drop_duplicates(inplace=False)
# 合并特征
provider_characteristics = pd.merge(provider_grouped_features, selected_features_6, on=['医疗机构编号', '时间段'],
                                    how='inner')
print('医疗机构特征:')
print(provider_characteristics.head(20))
print(provider_characteristics.dtypes)
print(provider_characteristics.shape)
provider_characteristics.to_csv('结果分析/provider_characteristics.csv', index=False, encoding='utf-8')

医疗机构特征:
医疗机构编号 时间段 投保人数 保费覆盖额 账单金额 支付金额 支付金额笔数 医疗机构大类 医疗机构细类
0 10010410197 1Y 2 64500 66133 63381 2 0 0
1 10010610221 1Y 2 41300 42029 40428 2 0 0
2 10010710275 1Y 5 201900 206048 199630 5 1 1
3 10010710275 2Y 6 252300 256399 249037 6 1 1
4 10010910429 1Y 46 1705500 1728328 1681188 46 1 1
5 10010910429 2Y 33 1533200 1549347 1513867 33 1 1
6 10011210467 2Y 1 83400 83877 82791 1 1 1
7 10011310519 2Y 1 99900 99925 99674 1 1 1
8 10011410627 2Y 7 245500 250332 240543 7 1 1
9 10011610682 1Y 1 32400 32639 31442 1 1 1
10 10011810781 1Y 1 45100 45618 44556 1 1 1
11 10011910901 1Y 1 21200 22073 20871 1 1 1
12 10012110993 1Y 4 161600 163706 159618 4 1 1
13 10012110993 2Y 6 252200 255580 249057 6 1 1
14 10012611269 1Y 17 504500 512906 495515 17 2 2
15 10012611269 2Y 5 199000 201279 196669 5 2 2
16 10012811329 1Y 10 359700 364645 353434 10 2 2
17 10012811329 2Y 8 230600 235969 226320 8 2 2
18 10013011335 1Y 12 656700 660945 649501 12 2 2
19 10013011335 2Y 4 262500 264325 260483 4 2 2

位置编码  

0 410
1 104
2 104
3 104
4 410
5 410
6 367
7 410
8 104
9 410
10 367
11 367
12 410
13 410
14 410
15 410
16 367
17 367
18 410
19 410
医疗机构编号 int64
时间段 object
投保人数 int64
保费覆盖额 int64
账单金额 int64
支付金额 int64
支付金额笔数 int64
医疗机构大类 int64
医疗机构细类 int64
位置编码 int64
dtype: object
(717, 10)

六、模型训练和性能度量

# 1.将投保人聚类成 5 类类群,选取投保人数量、平均支付金额、平均支付笔数等具有代表性的指标,进行类群间的差异性比较;

# 选取用于聚类的特征
cluster_features = policyholder_characteristics[
    ['投保人编号', '保费覆盖额', '账单金额', '支付金额', '支付金额笔数', '年龄']
]

# 聚类
kmeans = KMeans(n_clusters=5, random_state=42)
cluster_labels = kmeans.fit_predict(cluster_features)

# 将聚类标签添加到原始特征中
cluster_features['聚类标签'] = cluster_labels

# 计算各聚类的代表性指标
cluster_summary = cluster_features.groupby('聚类标签').agg(
    投保人数量=('投保人编号', 'count'),
    平均支付金额=('支付金额', 'mean'),
    平均支付笔数=('支付金额笔数', 'mean')
).reset_index()

print('聚类结果:')
print(cluster_summary)

# 详细描述每个聚类类群
for label in range(5):
    cluster_info = cluster_features[cluster_features['聚类标签'] == label]
    print(f'聚类 {label} 详细信息:')
    print(f'投保人数量:{len(cluster_info)}')
    print(f'平均支付金额:{cluster_info["支付金额"].mean()}')
    print(f'平均支付笔数:{cluster_info["支付金额笔数"].mean()}')
    print('\n')


聚类结果:
聚类标签 投保人数量 平均支付金额 平均支付笔数
0 0 91 7.490569e+05 19.406593
1 1 92 1.002300e+06 26.434783
2 2 78 9.326763e+05 24.487179
3 3 77 6.980571e+05 18.532468
4 4 95 7.660895e+05 20.136842
聚类 0 详细信息:
投保人数量:91
平均支付金额:749056.8791208791
平均支付笔数:19.406593406593405

聚类 1 详细信息:
投保人数量:92
平均支付金额:1002299.5869565217
平均支付笔数:26.434782608695652

聚类 2 详细信息:
投保人数量:78
平均支付金额:932676.3461538461
平均支付笔数:24.487179487179485

聚类 3 详细信息:
投保人数量:77
平均支付金额:698057.077922078
平均支付笔数:18.532467532467532

聚类 4 详细信息:
投保人数量:95
平均支付金额:766089.5368421052
平均支付笔数:20.13684210526316

# 2.分析投保人上半年和下半年的索赔变化情况,即投保人类群的迁移统计
# 选取上半年和下半年的数据
first_half = policyholder_characteristics[policyholder_characteristics['时间段'] == '1Y']
second_half = policyholder_characteristics[policyholder_characteristics['时间段'] == '2Y']
# print(first_half)
# print(first_half.dtypes)
# print(first_half.shape)# (232, 10)
# print(second_half)
# print(second_half.dtypes)
# print(second_half.shape)# (201, 10)
# 分别计算上半年和下半年的统计数据
first_half_summary = first_half.groupby('投保人编号').agg(
    上半年支付金额=('支付金额', 'sum'),
    上半年支付笔数=('支付金额笔数', 'sum')
).reset_index()
second_half_summary = second_half.groupby('投保人编号').agg(
    下半年支付金额=('支付金额', 'sum'),
    下半年支付笔数=('支付金额笔数', 'sum')
).reset_index()
# 合并上半年和下半年的数据
summary = pd.merge(first_half_summary, second_half_summary, on='投保人编号', how='outer').fillna(0)
print('上半年和下半年的支付金额和支付笔数:')
# print(summary)
# print(summary.dtypes)
# print(summary.shape) # (304, 5)
# 计算变化情况
summary['支付金额变化'] = summary['下半年支付金额'] - summary['上半年支付金额']
summary['支付笔数变化'] = summary['下半年支付笔数'] - summary['上半年支付笔数']

print('索赔变化情况:', summary)
# 按照支付金额和支付笔数的变化情况进行排序
summary = summary.sort_values(by=['支付金额变化', '支付笔数变化'], ascending=True)
print('按照支付金额和支付笔数的变化情况进行排序:', summary)
summary.to_csv('结果分析/summary.csv', index=False, encoding='utf-8')

上半年和下半年的支付金额和支付笔数:
索赔变化情况: 投保人编号 上半年支付金额 上半年支付笔数 下半年支付金额 下半年支付笔数 支付金额变化 支付笔数变化
0 10300010118 1225159.0 30.0 1039617.0 24.0 -185542.0 -6.0
1 10500010200 245811.0 4.0 0.0 0.0 -245811.0 -4.0
2 10600010291 0.0 0.0 776217.0 21.0 776217.0 21.0
3 10700010301 0.0 0.0 43172.0 1.0 43172.0 1.0
4 10800010360 814066.0 20.0 0.0 0.0 -814066.0 -20.0
… … … … … … … …
299 68400038040 664169.0 14.0 53343.0 2.0 -610826.0 -12.0
300 68500038167 3550826.0 88.0 1227891.0 40.0 -2322935.0 -48.0
301 68900038289 2144262.0 51.0 1457407.0 39.0 -686855.0 -12.0
302 69100038371 279869.0 8.0 450453.0 10.0 170584.0 2.0
303 69300038437 667440.0 19.0 335496.0 11.0 -331944.0 -8.0

[304 rows x 7 columns]
按照支付金额和支付笔数的变化情况进行排序: 投保人编号 上半年支付金额 上半年支付笔数 下半年支付金额 下半年支付笔数 支付金额变化 支付笔数变化
300 68500038167 3550826.0 88.0 1227891.0 40.0 -2322935.0 -48.0
222 53700030960 2142648.0 44.0 502231.0 16.0 -1640417.0 -28.0
184 46300027224 2696993.0 66.0 1260491.0 33.0 -1436502.0 -33.0
153 40400023860 2092201.0 54.0 673028.0 27.0 -1419173.0 -27.0
31 16500013059 2494316.0 61.0 1111212.0 32.0 -1383104.0 -29.0
… … … … … … … …
138 37500022787 0.0 0.0 864267.0 19.0 864267.0 19.0
290 66800037290 0.0 0.0 986847.0 24.0 986847.0 24.0
285 65500036707 236604.0 6.0 4259995.0 117.0 4023391.0 111.0
291 67000037367 279731.0 8.0 4721788.0 116.0 4442057.0 108.0
107 31200019485 198910.0 5.0 5420315.0 139.0 5221405.0 134.0

[304 rows x 7 columns]

# 3.根据 1 和 2 判断投保人是否疑似存在医疗保险欺诈行为,并输出投保人信息;
# 使用 Isolation Forest 算法确定欺诈标准
from sklearn.ensemble import IsolationForest

features = summary[['支付金额变化', '支付笔数变化']]
isolation_forest = IsolationForest(contamination=0.1, random_state=42)
isolation_forest.fit(features)

# 预测异常值
anomaly_scores = isolation_forest.decision_function(features)
outliers = isolation_forest.predict(features)

# 找出疑似欺诈投保人
fraud_suspects = summary[outliers == -1]
# 输出疑似欺诈投保人的信息
print('疑似欺诈投保人信息:')
print(fraud_suspects)
# print(fraud_suspects.dtypes)
# print(fraud_suspects.shape)
# 获取疑似欺诈投保人的详细信息
suspicious_policyholder = policyholder_characteristics[
    policyholder_characteristics['投保人编号'].isin(fraud_suspects['投保人编号'])]

# 输出详细信息
print('疑似欺诈投保人的详细信息:')
print(suspicious_policyholder)
suspicious_policyholder.to_csv('结果分析/suspicious_policyholder.csv', index=False, encoding='utf-8')

# 在 policyholder_characteristics 中增加一列 "是否疑似欺诈"
policyholder_characteristics['是否疑似欺诈'] = 0

# 更新疑似欺诈投保人的标记
fraud_indices = fraud_suspects['投保人编号']
policyholder_characteristics.loc[policyholder_characteristics['投保人编号'].isin(fraud_indices), '是否疑似欺诈'] = 1

# 输出最终结果
print('投保人的详细信息(包含是否疑似欺诈标记):')
print(policyholder_characteristics)

# 保存结果
policyholder_characteristics.to_csv('结果分析/policyholder_characteristics.csv', index=False, encoding='utf-8')

疑似欺诈投保人信息:
投保人编号 上半年支付金额 上半年支付笔数 下半年支付金额 下半年支付笔数 支付金额变化 支付笔数变化
300 68500038167 3550826.0 88.0 1227891.0 40.0 -2322935.0 -48.0
222 53700030960 2142648.0 44.0 502231.0 16.0 -1640417.0 -28.0
184 46300027224 2696993.0 66.0 1260491.0 33.0 -1436502.0 -33.0
153 40400023860 2092201.0 54.0 673028.0 27.0 -1419173.0 -27.0
31 16500013059 2494316.0 61.0 1111212.0 32.0 -1383104.0 -29.0
225 54500031427 3210912.0 75.0 1892716.0 58.0 -1318196.0 -17.0
164 42400024932 2706637.0 64.0 1408757.0 39.0 -1297880.0 -25.0
16 12900011570 3000471.0 77.0 1773806.0 49.0 -1226665.0 -28.0
209 51400029676 1215350.0 30.0 0.0 0.0 -1215350.0 -30.0
244 58200033387 2048805.0 54.0 849658.0 20.0 -1199147.0 -34.0
199 49600028891 1190440.0 32.0 0.0 0.0 -1190440.0 -32.0
105 31000019438 3026729.0 68.0 1863217.0 51.0 -1163512.0 -17.0
147 39300023401 1334020.0 40.0 189494.0 5.0 -1144526.0 -35.0
252 60000033912 1830418.0 53.0 777558.0 20.0 -1052860.0 -33.0
59 21700015465 2802028.0 80.0 1926306.0 46.0 -875722.0 -34.0
44 19000014307 2522924.0 78.0 1733163.0 40.0 -789761.0 -38.0
279 64500036177 1889143.0 56.0 1209423.0 28.0 -679720.0 -28.0
229 55200031755 2094073.0 55.0 2291033.0 71.0 196960.0 16.0
217 52600030461 0.0 0.0 581719.0 15.0 581719.0 15.0
6 11200010435 0.0 0.0 624589.0 17.0 624589.0 17.0
241 57600033140 0.0 0.0 638502.0 14.0 638502.0 14.0
90 28000018414 0.0 0.0 643894.0 17.0 643894.0 17.0
32 16700013144 13585.0 1.0 723847.0 21.0 710262.0 20.0
150 39800023603 683897.0 20.0 1430553.0 33.0 746656.0 13.0
2 10600010291 0.0 0.0 776217.0 21.0 776217.0 21.0
73 24800016667 0.0 0.0 797242.0 17.0 797242.0 17.0
138 37500022787 0.0 0.0 864267.0 19.0 864267.0 19.0
290 66800037290 0.0 0.0 986847.0 24.0 986847.0 24.0
285 65500036707 236604.0 6.0 4259995.0 117.0 4023391.0 111.0
291 67000037367 279731.0 8.0 4721788.0 116.0 4442057.0 108.0
107 31200019485 198910.0 5.0 5420315.0 139.0 5221405.0 134.0

# 4.将医疗机构聚类成 5 类类群,选取医疗机构数量、平均投保人数量、平均账单金额等具有代表性的指标,进行类群间相关属性的差异性比较
# 选取用于聚类的特征
cluster_features_2 = provider_characteristics[
    ['医疗机构编号', '保费覆盖额', '账单金额', '支付金额', '支付金额笔数']
]
# 聚类
kmeans = KMeans(n_clusters=5, random_state=42)
cluster_labels = kmeans.fit_predict(cluster_features_2)

# 将聚类标签添加到原始特征中
provider_characteristics['聚类标签'] = cluster_labels

# 计算各聚类的代表性指标
cluster_summary = provider_characteristics.groupby('聚类标签').agg(
    医疗机构数量=('医疗机构编号', 'count'),
    平均投保人数量=('投保人数', 'mean'),
    平均账单金额=('账单金额', 'mean'),
).reset_index()

print('聚类结果:')
print(cluster_summary)

# 详细描述每个聚类类群
for label in range(5):
    cluster_info = provider_characteristics[provider_characteristics['聚类标签'] == label]
    print(f'聚类 {label} 详细信息:')
    print(f'医疗机构数量:{len(cluster_info)}')
    print(f'平均投保人数量:{cluster_info["投保人数"].mean()}')
    print(f'平均账单金额:{cluster_info["账单金额"].mean()}')
print(provider_characteristics)

聚类结果:
聚类标签 医疗机构数量 平均投保人数量 平均账单金额
0 0 133 11.428571 448874.586466
1 1 151 20.099338 798955.602649
2 2 164 18.054878 696830.981707
3 3 130 7.076923 271182.838462
4 4 139 7.280576 282314.093525
聚类 0 详细信息:
医疗机构数量:133
平均投保人数量:11.428571428571429
平均账单金额:448874.58646616543
聚类 1 详细信息:
医疗机构数量:151
平均投保人数量:20.09933774834437
平均账单金额:798955.6026490066
聚类 2 详细信息:
医疗机构数量:164
平均投保人数量:18.054878048780488
平均账单金额:696830.981707317
聚类 3 详细信息:
医疗机构数量:130
平均投保人数量:7.076923076923077
平均账单金额:271182.8384615385
聚类 4 详细信息:
医疗机构数量:139
平均投保人数量:7.280575539568345
平均账单金额:282314.09352517984
医疗机构编号 时间段 投保人数 保费覆盖额 账单金额 支付金额 支付金额笔数 医疗机构大类 医疗机构细类
0 10010410197 1Y 2 64500 66133 63381 2 0 0
1 10010610221 1Y 2 41300 42029 40428 2 0 0
2 10010710275 1Y 5 201900 206048 199630 5 1 1
3 10010710275 2Y 6 252300 256399 249037 6 1 1
4 10010910429 1Y 46 1705500 1728328 1681188 46 1 1
… … … … … … … … … …
712 10085944077 2Y 35 1441700 1455746 1423935 35 27 37
713 10086044118 1Y 40 1688500 1708070 1668403 40 27 37
714 10086044118 2Y 31 1203500 1218676 1188260 31 27 37
715 10086244135 1Y 56 2085300 2116268 2058121 56 27 37
716 10086244135 2Y 93 3691800 3738201 3650195 93 27 37

 位置编码  聚类标签  

0 410 2
1 104 2
2 104 2
3 104 2
4 410 2
… … …
712 367 1
713 475 1
714 475 1
715 367 1
716 367 1

[717 rows x 11 columns]

# 5.使用 pd.crosstab()创建交叉表,分析医疗机构上半年和下半年的类群迁移情况
crosstab = pd.crosstab(
    index=provider_characteristics['聚类标签'],
    columns=provider_characteristics['时间段'],
    margins=True,
    margins_name='总计'
)
print('类群迁移交叉表:')
print(crosstab)

类群迁移交叉表:
时间段 1Y 2Y 总计
聚类标签
0 68 65 133
1 74 77 151
2 84 80 164
3 67 63 130
4 70 69 139
总计 363 354 717

# 6. 根据 4 和 5 判断医疗机构是否疑似存在医疗保险欺诈行为,并输出医疗机构信息
# 使用 Isolation Forest 算法确定欺诈标准

# 选取用于聚类的特征
features = ['投保人数', '账单金额']

# 使用 Isolation Forest 进行异常检测
isolation_forest = IsolationForest(contamination=0.1, random_state=42)
anomaly_scores = isolation_forest.fit_predict(provider_characteristics[features])

# 将异常得分添加到原始特征中
provider_characteristics['异常得分'] = anomaly_scores

# 筛选出疑似存在医疗保险欺诈行为的医疗机构
suspicious_hospitals = provider_characteristics[provider_characteristics['异常得分'] == -1]
print(suspicious_hospitals.shape)
print(suspicious_hospitals)

# 输出疑似存在医疗保险欺诈行为的医疗机构信息
if not suspicious_hospitals.empty:
    print('疑似存在医疗保险欺诈行为的医疗机构信息:')
    print(suspicious_hospitals[['医疗机构编号', '时间段', '投保人数', '账单金额', '异常得分']])
else:
    print('没有发现疑似存在医疗保险欺诈行为的医疗机构。')

# 保存信息
# 在 provider_characteristics 中增加一列 "是否疑似欺诈"
provider_characteristics['是否疑似欺诈'] = 0
# 更新疑似欺诈医疗机构的标记
fraud_indices = suspicious_hospitals['医疗机构编号']
provider_characteristics.loc[provider_characteristics['医疗机构编号'].isin(fraud_indices), '是否疑似欺诈'] = 1

print('医疗机构的详细信息(包含是否疑似欺诈标记):')
# 删除异常得分列
provider_characteristics = provider_characteristics.drop(columns=['异常得分'])
print(provider_characteristics)

provider_characteristics.to_csv('结果分析/provider_characteristics.csv', index=False, encoding='utf-8')
suspicious_hospitals.to_csv('结果分析/suspicious_hospitals.csv', index=False, encoding='utf-8')

 位置编码  聚类标签  是否疑似欺诈  

0 410 2 0
1 104 2 0
2 104 2 0
3 104 2 0
4 410 2 1
… … … …
712 367 1 1
713 475 1 1
714 475 1 1
715 367 1 1
716 367 1 1

[717 rows x 12 columns]

# 7. 采用轮廓系数(Silhouette Coefficient)和 Calinski-Harabasz 指标对投保人和医疗机构的聚类模型进行评价,并可视化评价结果。
# 选择投保人的特征
policy_holder_features = policyholder_characteristics[['保费覆盖额', '账单金额', '支付金额', '支付金额笔数', '年龄']]
# 选择医疗机构的特征
provider_features = provider_characteristics[['保费覆盖额', '账单金额', '支付金额', '投保人数']]

# 定义轮廓系数和 Calinski-Harabasz 指标函数
def evaluate_clustering(X, n_clusters):
    kmeans = KMeans(n_clusters=n_clusters, random_state=42)
    kmeans.fit(X)
    labels = kmeans.labels_
    silhouette_coefficient = silhouette_score(X, labels)
    calinski_harabasz = calinski_harabasz_score(X, labels)
    return silhouette_coefficient, calinski_harabasz

# 计算不同聚类数量下的评估指标
n_clusters_range = range(2, 11)
silhouette_policy_holder = []
silhouette_provider = []
calinski_harabasz_policy_holder = []
calinski_harabasz_provider = []

for n_clusters in n_clusters_range:
    # 轮廓系数
    silhouette_coefficient, _ = evaluate_clustering(policy_holder_features, n_clusters)
    silhouette_policy_holder.append(silhouette_coefficient)

    silhouette_coefficient, _ = evaluate_clustering(provider_features, n_clusters)
    silhouette_provider.append(silhouette_coefficient)

    # Calinski-Harabasz 指标
    _, calinski_harabasz = evaluate_clustering(policy_holder_features, n_clusters)
    calinski_harabasz_policy_holder.append(calinski_harabasz)

    _, calinski_harabasz = evaluate_clustering(provider_features, n_clusters)
    calinski_harabasz_provider.append(calinski_harabasz)

print('投保人的轮廓系数:', silhouette_policy_holder)
print('医疗机构的轮廓系数:', silhouette_provider)
print('投保人的Calinski-Harabasz 指标:', calinski_harabasz_policy_holder)
print('医疗机构的Calinski-Harabasz 指标:', calinski_harabasz_provider)

投保人的轮廓系数: [0.7226576777826208, 0.6498671347052347, 0.618970915450915, 0.6237002142602882, 0.5955120448436585, 0.5855233844947134, 0.5794357656635699, 0.555326045559005, 0.547333033009528]
医疗机构的轮廓系数: [0.7785465109052467, 0.7609298198820077, 0.6900841337647167, 0.6837587113024827, 0.6825109306135511, 0.6661725708984757, 0.5922838124312444, 0.5710308788377823, 0.5708757328209078]
投保人的Calinski-Harabasz 指标: [1307.7392539661294, 1244.3024083699274, 1481.7483768675309, 1932.443305130993, 2403.9120164318338, 2753.709599448324, 2603.6129576594244, 2741.3658307581945, 3218.467874193788]
医疗机构的Calinski-Harabasz 指标: [1029.6332630705906, 2016.279549942104, 2234.879350227129, 2690.536124127273, 2424.4476994513816, 3384.947478415253, 3908.10583144836, 4630.653312728189, 5288.283282198831]

# 可视化轮廓系数
plt.figure(figsize=(12, 6))

plt.subplot(1, 2, 1)
plt.plot(n_clusters_range, silhouette_policy_holder, label='投保人')
plt.plot(n_clusters_range, silhouette_provider, label='医疗机构')
plt.xlabel('Number of clusters')
plt.ylabel('Silhouette Coefficient')
plt.legend()
plt.title('Silhouette Coefficient for Clustering Evaluation')

# 可视化 Calinski-Harabasz 指标
plt.subplot(1, 2, 2)
plt.plot(n_clusters_range, calinski_harabasz_policy_holder, label='投保人')
plt.plot(n_clusters_range, calinski_harabasz_provider, label='医疗机构')
plt.xlabel('Number of clusters')
plt.ylabel('Calinski-Harabasz Index')
plt.legend()
plt.title('Calinski-Harabasz Index for Clustering Evaluation')

plt.tight_layout()
plt.show()

在这里插入图片描述

轮廓系数的取值范围为[-1, 1],轮廓系数越大聚类效果越好
Calinski-Harabasz数的分数越大说明越好

标签:数据分析,医疗保险,provider,金额,医疗机构,实训,支付,print,投保人
From: https://blog.csdn.net/m0_73678713/article/details/142447537

相关文章

  • 头歌实践教学平台 Python程序设计 实训答案(三)
    第七阶段文件实验一文本文件的读取第1关:学习-Python文件之文本文件的读取任务描述本关任务:使用open函数以只写的方式打开文件,打印文件的打开方式。相关知识为了完成本关任务,你需要掌握:文本文件;open函数及其参数;文件打开模式;文件对象常用属性;关闭文件close......
  • 头歌实践教学平台 Python程序设计实训答案(二)
    第四阶段组合数据类型实验一列表的基本操作第1关:列表增删改:客人名单的变化任务描述列表是由按一定顺序排列的元素组成,其中的元素根据需要可能会发生变化。其中,列表元素的添加、删除或修改等是最常见的操作。下面以一则请客的故事来说明列表元素操作的应用场景。有个人邀......
  • EXCEL进行数据分析
    一、周报业务逻辑讲解1.成果可根据平台和日期变动所有数据 转化率和变化趋势      进店转化率=进店人数/曝光人数      下单转化率=下单人数/进店人数      数据趋势:流量变大,承接能力跟不上,转化率会下降结果指标和过程指标......
  • Axure大屏可视化模板:跨领域数据分析平台原型案例
    随着信息技术的飞速发展,数据可视化已成为各行各业提升管理效率、优化决策过程的重要手段。Axure作为一款强大的原型设计工具,其大屏可视化模板在农业、园区、城市、企业数据可视化、医疗等多个领域得到了广泛应用。本文将通过几个具体案例,展示Axure大屏可视化模板在不同领域中的......
  • 大数据毕业设计选题推荐-安顺旅游景点数据分析系统-Hive-Hadoop-Spark
    ✨作者主页:IT研究室✨个人简介:曾从事计算机专业培训教学,擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。☑文末获取源码☑精彩专栏推荐⬇⬇⬇Java项目Python项目安卓项目微信小程序项目......
  • 机器学习实战25-用多种机器学习算法实现各种数据分析与预测
    大家好,我是微学AI,今天给大家介绍一下机器学习实战25-用多种机器学习算法实现各种数据分析与预测。本文主要介绍了使用机器学习算法进行数据分析的过程。首先阐述了项目背景,说明进行数据分析的必要性。接着详细介绍了机器学习算法中的随机森林、聚类分析以及异常值分析等方法......
  • Capital许可使用数据分析工具
    在数字化浪潮中,软件已成为企业运营的核心。然而,随着软件种类和数量的激增,如何有效管理、分析和优化软件许可使用,已成为众多企业面临的难题。Capital许可使用数据分析工具,作为一款领先的软件资产管理解决方案,正是为解决这一问题而生。一、Capital许可使用数据分析工具的核心价值C......
  • 【计算机毕设-大数据方向】基于Hadoop的社交媒体数据分析可视化系统的设计与实现
    ......
  • 数据分析:主成分以及贡献变量解析
    禁止商业或二改转载,仅供自学使用,侵权必究,如需截取部分内容请后台联系作者!文章目录介绍分析目的变量的loadings的含义加载依赖包导入数据数据预处理PCA计算PCA图主成分分布系统信息介绍PCA分析,即主成分分析(PrincipalComponentAnalysis),是一种......
  • 快速上手SAP BI,数据分析从此简单
     在当今数字化的商业世界中,数据已经成为企业决策的核心依据。而SAPBI(BusinessIntelligence)作为一款强大的商业智能工具,为企业的数据分析提供了高效、全面的解决方案。对于想要深入挖掘数据价值的企业和个人来说,快速上手SAPBI是开启数据分析便捷之旅的关键。 一、SAPBI简介......