做实证研究的朋友应该都遇过这种尴尬:手上已经有了很完整的财务数据,ROE、营收增速、资产负债率都整理好了,却缺一个能衡量“这家公司内部治理到底靠不靠谱”的统一标尺。填问卷拿到的样本太小,用某几项财务比率硬凑又不严谨。后来我在几个公司治理方向的课题里反复用到了迪博内部控制指数,发现这套数据解决问题确实很顺手,但也踩了不少坑。这篇就把我对“2000—2024年上市公司迪博内部控制指数评分及评级数据”的完整理解和使用经验写出来,适合正在做相关论文、想构建治理质量指标,或者单纯想搞懂这类数据怎么入手的读者。
先说结论:这套数据的核心价值,是它把上市公司的内部控制质量量化成一个可以跨公司、跨年份比较的分数和评级。分数用什么方法算的、评级档位怎么划分、早期数据为什么稀疏、后期数据为什么口径会变,这些如果不提前搞清楚,后面做回归或者做分组对比时会发现结论非常脆弱。我尽量按实操顺序来讲,把数据背后的逻辑和用数据时最容易忽略的细节都摊开。
1. 为什么这套数据在研究和投资场景里这么抢手
1.1 实证研究里的“治理质量代理变量”
公司治理、审计质量、信息透明度、企业风险……这些方向做实证研究时,最大的痛点是要给“内部控制质量”找一个可以被计量的代理变量。财务数据虽然容易拿到,但它反映的是经营结果,不是过程控制。一家公司利润很高,不代表它的内部审批流程、风险排查机制、信息披露质量就同样高。
迪博内部控制指数正好补上了这个缺口。它利用上市公司公开披露的内控评价报告、内控审计报告、公司年报等公开信息,把内控领域的多个维度映射成一套连续分数,同时提供离散评级。这意味着在回归模型里,你可以直接用连续分数作为被解释变量或解释变量,也可以把评级转化成虚拟变量做分组分析。
我做过的课题里,比较多见的用法包括:
- 研究股权结构对内控质量的影响:用内控指数作为被解释变量;
- 研究内控质量对盈余管理程度的抑制作用:把内控指数作为核心解释变量;
- 研究分析师预测误差是否受公司内控水平影响:把内控指数和评级作为分组依据;
- 研究审计费用、审计意见与内控质量的关系:内控指数作为控制变量。
几乎每一个场景,这套数据都能稳定提供支撑。这也是它在学术圈被高频引用的直接原因。
1.2 投资决策中的“非财务风险信号”
投资分析里,传统财务指标往往只能告诉你公司过去赚了多少钱,很难告诉你公司未来会不会因为内部失控而突然爆雷。内控指数和评级,本质上是一个风险信号前置的工具。
举个例子,如果一家公司连续几年内控评级都在下滑,或者从较高级别跌到了比较低的档位,这往往意味着它在业务流程、信息披露、风险应对上存在一些被外部审计师或公司自评报告记录下来的问题。这些问题可能要等一两个季度之后,才会通过坏账、诉讼、资产减值等财务科目体现出来。
所以一些做量化基本面选股分析的人,会把这类评级数据作为负面筛选条件:先剔除评级过低的样本,再在剩余股票池里做财务指标打分。我不建议用它作为唯一信号,但如果把它和其他非财务数据叠加使用,确实能提升整体判断的稳健性。
1.3 公司合规自查与同业对标场景
这个场景经常被忽略,但在董办、内审部门里其实很常见。公司做年度内控评价时,光看自己内部的底稿很难判断水平高低。如果能把同行业公司的内控指数和评级拉出来做一个横向对比,管理者就能比较直观地看出自己处在什么位置。
我接触过一些内审岗位的朋友,他们会把这类数据用来回答类似问题:我们的内控信息披露程度是否比同行详细?我们被指出的内控缺陷数量属于偏多还是偏少?我们的整体评级在行业里是不是长期垫底?虽然第三方指数的计算方法与公司内部评价口径并不完全一致,但作为客观参照物,价值是实实在在的。
2. 迪博内部控制指数的编制逻辑与评级维度
2.1 内控五要素如何落到打分模型
想用好这套数据,不能只把它当成一个黑盒分数,至少要了解它的底层框架。迪博内部控制指数的理论基础,基本是围绕内部控制的五要素展开的:内部环境、风险评估、控制活动、信息与沟通、内部监督。
这五个要素本身是抽象的,打分时必须把它们操作化为可观察的信息。实际操作中,来源主要是公司披露的内控评价报告、内控审计报告、年报中的相关章节等公开文本。系统中会把这些文本内容拆解成结构化字段,比如是否存在内部控制重大缺陷、是否发生内部控制评价范围变动、财务报告内控是否有效、非财务报告内控是否有效等。
不同版本的数据生成逻辑会有差异,但大体思路是一致的:以公开披露为基础,把文本信息映射成规则得分,再按一定权重合成指数。权重设计属于商业数据库的核心算法,外界能拿到的是最终分数,而不是每一条打分细则。
2.2 评级区间的含义与“分数转评级”的路径
除了连续分数,这套数据通常还会给一个评级结果。评级档位设置在不同年份可能略有不同,但通常是从高到低排列的字母档位,比如AAA、AA、A、BBB、BB、B、C、D这一类。高分对应高评级,低分对应低评级。
实际使用中,我建议把“分数”和“评级”看成两种不同粒度的信息:
- 连续分数:适合做回归、做趋势变化分析,优点是平滑、信息量大;
- 字母评级:适合做分组、做截面比较,优点是直观、不容易受微小分数波动干扰。
要注意的是,评级边界附近的公司可能分数差异很小,但评级差距会显得很大。假设同一档位上下界相差0.5分,一家公司可能刚好卡在高一级的边界线上,另一家稍微低了0.2分就落到下一档。这时候如果直接按评级分组做对比,看似的组间差异可能只是边界效应导致的结果。稳妥做法是同时看分数和评级,或者在分数连续变量的基础上构造稳健性检验。
2.3 2000—2024年的样本周期:早期为何数据稀疏
标题里的2000—2024是一个很长的区间,但它不代表每年样本量都很充足。国内上市公司内控信息的系统化披露是逐步建立的,早期很多公司根本没有完整的内控评价报告,更谈不上被纳入指数评级体系。
所以你会看到,2000年前后几年真正有评级的公司数量非常少。越往后,随着披露规则逐渐细化,纳入评价范围的公司数量才明显上升。如果你在做面板数据分析,千万不要直接把2000年和2015年之后的样本当成同一生成逻辑的数据混合使用。通常的做法是对样本区间做分阶段处理,或者干脆把早期数据只用来做参考,回归主样本放在披露相对完整的年份区间。
3. 拿到这套数据后,先要理清字段结构和口径
3.1 常见字段清单:从证券代码到评级
不同渠道拿到的数据字段命名会有点差别,但核心字段基本一致。我整理了一份通用字段清单,供你对照:
| 字段名 | 字段含义 | 使用说明 |
|---|---|---|
| 证券代码 | 上市公司股票代码 | 用于与财务数据、行情数据合并 |
| 证券简称 | 公司名称简称 | 做展示时使用 |
| 年份 | 数据所属年度 | 通常对应财报年份 |
| 内控指数 | 内部控制综合评分 | 连续变量,用于回归 |
| 内控评级 | 综合评级结果 | 离散变量,用于分组 |
| 内控审计意见类型 | 标准无保留/保留意见等 | 通常作为补充变量 |
| 内控重大缺陷数量 | 披露的重大缺陷个数 | 数量指标 |
| 内控重要缺陷数量 | 披露的重要缺陷个数 | 数量指标 |
| 所在行业 | 行业分类 | 做行业对比时需要 |
拿到数据表的第一件事,先看字段覆盖度,再看主键是否唯一。常见问题是:同一家公司同一年可能有多条记录,原因可能是数据源合并了不同批次的披露信息,也可能是年份口径不一致。建议先用证券代码和年份做去重检查,再进入后续分析。
3.2 两类易混淆指标:内控缺陷、内控审计意见
新手最容易混淆的是“内控缺陷数量”和“内控审计意见类型”。它们都来自审计相关披露,但含义完全不同。
内控缺陷数量反映的是公司在业务流程上被识别出的具体问题,比如重大缺陷、重要缺陷、一般缺陷。缺陷数量多,通常说明内控体系存在薄弱环节,但也要结合公司规模来看,一个超大型集团披露出的缺陷数量天然会比一家小公司多。
内控审计意见类型则是外部审计师对公司内控有效性的总体判断。如果被出具非标准意见,通常意味着审计师认为内控体系存在重大问题。在实证分析里,这个变量更常用作“内控存在重大问题的硬信号”,适合构造虚拟变量,比如“是否获得非标内控审计意见”。
3.3 披露规则调整对连续年份可比性的冲击
跨年度做对比时,最大的隐藏风险是评分口径并不是完全固定不变的。随着披露框架调整,公司需要披露的内控信息范围、详实程度都可能变化,第三方指数算法为了适配这些变化也会相应更新。
结果是,你在数据里看到某一年的指数平均值整体上升,可能并不是因为当年所有公司内控质量突然变好了,而是因为披露范围扩大或算法评分项目增加,给公司带来了更多得分点。
处理这个问题的标准做法是:在面板回归里控制年度固定效应,这样可以把每年整体口径差异吸收掉。如果不加年度固定效应,直接用原始分数跨年比较,很容易得到“内控质量逐年改善”的伪结论。
4. 数据清洗与实证建模的实操步骤(附Python代码)
4.1 合并公司基本信息和内控数据的关键字段
拿到数据后,我一般会先把内控数据和公司基本信息表合并。这里的核心字段是证券代码,但要注意代码格式问题。有的表里证券代码是带后缀的,比如“600000.SH”,有的则只有6位数字。合并前必须统一格式。
下面这段代码演示了基本的数据读取和字段处理逻辑:
import pandas as pd # 读取数据 dic_df = pd.read_csv("dib_internal_control.csv") stock_info = pd.read_csv("stock_basic_info.csv") # 统一证券代码格式:统一转为去掉交易所后缀的6位数字 dic_df["sec_code"] = dic_df["sec_code"].astype(str).str.split(".").str[0] stock_info["sec_code"] = stock_info["sec_code"].astype(str).str.split(".").str[0] # 检查主键是否唯一 print(dic_df.groupby(["sec_code", "year"]).size().reset_index(name="cnt")["cnt"].max()) # 合并 merged = dic_df.merge( stock_info, on=["sec_code"], how="left" )这段代码看起来简单,但实际操作中“证券代码格式不统一”是合并时最高频的错误来源。有时候某张表里代码是“000001”,另一张表里是“000001.SZ”,中间还有个别值被读成浮点数导致变成“1.0”,这些都要提前清洗。
4.2 处理缺失年份、退市样本与ST标记
面板数据最怕的是样本前后不连续。公司可能在某几年没有披露内控评价报告,或者在期间被特别处理,甚至退市。如果直接保留这些行,回归样本会不平滑;如果直接删除,又会造成幸存者偏差。
我的习惯是分几步处理:
- 先区分“完全缺失”和“零值缺失”。没有披露记录不代表内控指数为0,不要用0去填充。
- 对退市公司,如果研究区间内曾持续披露多年,通常保留至退市前最后一期,这能避免只研究存活公司的偏差。
- ST标记单独建一个字段,不直接丢弃,因为是否被特别处理本身就可能是一个重要的控制变量。
# 标记ST状态(假设已有ST标记字段) merged["is_st"] = merged["st_status"].apply(lambda x: 1 if x == "ST" else 0) # 过滤样本:仅保留内控指数非空的记录 sample = merged.dropna(subset=["dib_index"]).copy() # 检查各年度样本量 sample.groupby("year")["sec_code"].nunique().plot()遇到连续多年缺失的公司,建议在做稳健性检验时单独跑一个“剔除缺失样本”的版本。如果结论在两种处理方式下方向一致,那说明结果不是由缺失样本的处理方式驱动的。
4.3 面板数据构造与滞后变量的生成
实证研究里经常需要把当年的内控指数作为解释变量,或者用上一年的内控指数预测今年的某个结果变量。由于内控执行效果的传导通常需要时间,当期数值不一定立刻产生作用,滞后一期或两期更符合业务逻辑。
构造滞后变量时,最方便的是先把数据按证券代码和年份排序,然后用groupby做移位操作。
sample = sample.sort_values(["sec_code", "year"]).reset_index(drop=True) sample["dib_index_lag1"] = sample.groupby("sec_code")["dib_index"].shift(1) sample["dib_index_lag2"] = sample.groupby("sec_code")["dib_index"].shift(2) # 检查滞后是否正确:同一家公司上年值是否对上 print(sample.loc[sample["sec_code"] == "000001", ["year", "dib_index", "dib_index_lag1"]].head(10))这里有个很容易犯的错:如果不做groupby,而是直接对全表排序后shift,会把不同公司的上一年值串到另一家公司身上。每一行必须对应同一家证券代码的上一期数据,所以“先排序、再分组、再移位”这三个动作一个都不能少。
4.4 稳健性检验中的替代指标思路
一组实证结果要让人信服,通常不能只靠单一指标。拿内控质量来说,除了迪博指数,还可以尝试以下替代口径:
| 替代指标 | 构造方式 | 适用场景 |
|---|---|---|
| 评级虚拟变量 | 评级为AA及以上时取1,否则取0 | 截面分组分析 |
| 非标意见虚拟变量 | 内控审计意见为非标时取1 | 稳健性检验 |
| 缺陷数量指标 | 重大缺陷与重要缺陷之和 | 风险信号研究 |
| 内控信息披露质量得分 | 根据自评报告披露项目数量构造 | 信息透明度研究 |
如果核心解释变量换成任何替代指标后,结论方向和显著性基本不变,那么这个结论就比较牢靠。如果只在某一个指标下显著,必须谨慎解释,不能说“内控质量显著影响某变量”,只能说“在某种内控质量度量方式下存在相关关系”。
5. 用这套数据做分析时最容易踩的坑
5.1 “指数提升”不等于“内控变好”:年报发布时间差异
我刚开始用这套数据时犯过一个错误,把一个公司连续两年的指数上升直接解读成内控改善,后来发现这中间藏着一个时间口径问题。
年报和内控评价报告的披露是有时滞的。2024年的内控数据,真正披露时间可能已经到了2025年4月。不同公司披露时间从1月到4月不等,个别公司甚至更晚。如果拿2024年的内控指数去解释2024年当年的股价表现,实际上是在用未来信息解释过去,存在前视偏差。
正确的处理方式有两种:一是把内控指数当作“t+1年可得的信息”,让它解释未来一年的结果变量;二是明确区分“披露年度”和“报告所属年度”。如果数据表里只有年份字段,没有具体披露日期,用滞后变量相对更安全。
5.2 评级集中度高时,分组对比的效度问题
大多数上市公司的内控评级通常集中在中间档位,极端高和极端低的公司数量较少。如果按评级把样本分成“高质量组”和“低质量组”,两组样本量可能严重不平衡。
低评级组样本太少,会导致检验功效下降,而且少数极端样本容易被个别异常值带偏。这时候建议先用连续指数分数做分组,比如按年份和行业计算三分位数或四分位数,再按分数高低分组建虚拟变量。
如果学术期刊要求报告标准化的效应量,连续分数往往比字母评级更敏感,因为它没有把相邻分数粗暴地切成不同类别。
5.3 跨行业比较需谨慎:行业差异很大
制造业、金融业、信息技术行业在内控披露格式和复杂程度上天然不同。金融业受监管约束更严格,披露的框架更细,内控相关信息往往更充分,得分可能整体偏高;一些传统行业由于业务链条相对简单,披露的详尽程度可能不如金融业,但并不意味着它们的内控执行能力一定更差。
跨行业比较时,一定要控制行业固定效应或使用行业调整后的指标。比如可以构造“内控指数减去当年行业中位数”这个相对指标,再做跨行业对比。这样得到的结论更接近“相对水平”,而不是“绝对水平”。
6. 案例演练:一个虚拟公司的内控指数解读
这里我不提任何真实公司,只演示一套解读的逻辑。假设有一家制造业A股上市公司,证券代码记作“6000X1”,其近五年数据如下:
| 年份 | 内控指数 | 内控评级 | 行业内指数中位数 | 披露的重大缺陷数量 |
|---|---|---|---|---|
| 2020 | 680.5 | BBB | 650.2 | 1 |
| 2021 | 692.3 | BBB | 658.7 | 0 |
| 2022 | 710.6 | A | 661.4 | 0 |
| 2023 | 705.8 | A | 668.9 | 1 |
| 2024 | 723.4 | A | 675.3 | 0 |
先看绝对分位:这家公司指数一直高于行业中位数,说明在整个行业的相对位置并不差。再看年度变化:2020年到2021年有小幅提升,2022年有明显跳升并达到A级,2023年有小幅回落,但回落幅度不大,2024年再创新高。整体趋势向上,且相对行业平均水平始终保持领先。
但注意2023年有一个“披露重大缺陷数量=1”的细节。如果只看评级A会认为内控一直很好,但这个缺陷提示公司在该年度可能存在某些突出问题。第三种细看方式是交叉验证:缺陷数量与指数走势不完全是同步关系,不能因为评级未变就忽略缺陷信息。
这套逻辑拿到任何一家公司都可以复用:绝对位置、时间趋势、行业对比、缺陷信号四个维度综合看,比单看一个分数或一个评级要全面得多。
7. 个人经验与后续扩展
我在实际使用中还有一个小习惯:拿到迪博内控数据后,会先画一张年份-样本量分布图和年份-指数平均分趋势图,确认每个年度的样本量和分数分布没有明显断层。很多数据问题在回归结果出来之前,就已经能从这两张图里看出端倪了。
如果你用它做长期研究,也可以试着把它和其他公开数据做交叉,比如公司年报中的审计费用数据、分析师盈余预测数据、ESG评级数据。内控质量本质上反映的是公司内部治理的底层状态,和很多外部信息都能形成对照关系。多一个维度的交叉验证,结论就多一分可信度。