一、案例简介
企业财务风险分析,最麻烦的地方往往不是看懂某一个指标,而是同时处理几十个指标。资产负债率偏高可能意味着偿债压力,但如果企业现金流充足,也未必会陷入危机;利润下降可能只是短期波动,也可能是经营恶化的信号。
单独依靠某一项财务指标,很难准确判断企业是否存在风险。因此,这套案例把企业风险预警转化为一个机器学习分类问题:
企业财务数据 ↓数据清洗与变量构造 ↓划分训练集和测试集 ↓逻辑回归、随机森林、XGBoost ↓计算财务危机概率 ↓生成企业风险预警名单
1. 研究问题
案例主要回答三个问题:
2. 风险定义
将企业是否发生财务危机设置为二分类变量:
模型最终输出的不是简单的“正常”或“危机”,而是每家企业发生财务危机的预测概率。
3. 数据结构
案例数据包含3,200条企业观测,财务危机企业占比约20%。主要变量如下:
二、代码思路
1. 数据预处理
首先处理缺失值和异常值,再将样本按照80%和20%的比例划分为训练集与测试集。
由于正常企业数量通常远多于危机企业,划分时需要使用分层抽样,保证两个数据集中危机企业的占比基本一致。
2. 建立三个模型
案例同时训练三种模型:
- • XGBoost:通过逐步修正预测误差,提高风险识别能力。
3. 评价模型效果
企业财务风险预警不能只看准确率。假设100家企业中只有10家出现危机,即使模型将全部企业预测为正常,准确率也能达到90%,但这个模型没有识别出任何真正的风险企业。
因此,案例重点使用以下指标:
对于风险预警任务,Recall和AUC通常比单纯的准确率更加重要。
4. 输出风险名单
模型训练完成后,为每家企业计算财务危机概率,并划分风险等级:
三、核心代码
1. 读取企业数据
import pandas as pddata = pd.read_csv( "data/enterprise_financial_data.csv", encoding="utf-8-sig")feature_columns = [ "debt_ratio", "current_ratio", "cashflow_ratio", "roa", "revenue_growth", "receivable_turnover", "firm_size", "firm_age", "ownership_concentration"]X = data[feature_columns]y = data["financial_distress"]
代码从CSV文件读取企业财务指标,并将financial_distress设置为预测目标。
2. 处理缺失值
from sklearn.impute import SimpleImputerimputer = SimpleImputer(strategy="median")X_imputed = pd.DataFrame( imputer.fit_transform(X), columns=feature_columns)
这里使用中位数填补缺失值。相比均值,中位数对极端财务数据更加稳健。
3. 划分训练集与测试集
from sklearn.model_selection import train_test_splitX_train, X_test, y_train, y_test = train_test_split( X_imputed, y, test_size=0.2, random_state=42, stratify=y)
stratify=y表示分层抽样,避免训练集和测试集中的危机企业比例相差过大。
4. 训练逻辑回归
from sklearn.pipeline import Pipelinefrom sklearn.preprocessing import StandardScalerfrom sklearn.linear_model import LogisticRegressionlogistic_model = Pipeline([ ("scaler", StandardScaler()), ("model", LogisticRegression( class_weight="balanced", max_iter=1000, random_state=42 ))])logistic_model.fit(X_train, y_train)
class_weight="balanced"会提高少数类别的权重,使模型更加重视财务危机企业。
5. 训练随机森林
from sklearn.ensemble import RandomForestClassifierrf_model = RandomForestClassifier( n_estimators=500, max_depth=8, min_samples_leaf=5, class_weight="balanced", random_state=42, n_jobs=-1)rf_model.fit(X_train, y_train)
随机森林通过建立多棵决策树进行综合判断,可以识别资产负债率、盈利能力和现金流之间的复杂关系。
6. 训练XGBoost
from xgboost import XGBClassifiernegative_num = (y_train == 0).sum()positive_num = (y_train == 1).sum()xgb_model = XGBClassifier( n_estimators=400, max_depth=4, learning_rate=0.05, subsample=0.8, colsample_bytree=0.8, scale_pos_weight=negative_num / positive_num, eval_metric="logloss", random_state=42)xgb_model.fit(X_train, y_train)
scale_pos_weight用于处理类别不平衡,提高模型对危机企业的敏感度。
7. 比较模型表现
from sklearn.metrics import ( accuracy_score, precision_score, recall_score, f1_score, roc_auc_score)models = { "逻辑回归": logistic_model, "随机森林": rf_model, "XGBoost": xgb_model}results = []for model_name, model in models.items(): prediction = model.predict(X_test) probability = model.predict_proba(X_test)[:, 1] results.append({ "模型": model_name, "准确率": accuracy_score(y_test, prediction), "精确率": precision_score(y_test, prediction), "召回率": recall_score(y_test, prediction), "F1值": f1_score(y_test, prediction), "AUC": roc_auc_score(y_test, probability) })result_table = pd.DataFrame(results)print(result_table)
8. 生成风险名单
data["distress_probability"] = xgb_model.predict_proba( X_imputed)[:, 1]data["risk_level"] = pd.cut( data["distress_probability"], bins=[0, 0.3, 0.6, 1.0], labels=["低风险", "中风险", "高风险"], include_lowest=True)risk_list = data[ [ "firm_id", "firm_name", "distress_probability", "risk_level" ]].sort_values( "distress_probability", ascending=False)risk_list.to_csv( "output/企业财务风险预警名单.csv", index=False, encoding="utf-8-sig")
四、结果展示
1. 模型效果对比
测试集包含640家企业,其中128家企业属于财务危机样本。三种模型的预测结果如下:
| | | | | |
|---|
| | | | | |
| | | | | |
| 0.906 | 0.743 | 0.813 | 0.776 | 0.921 |
结果表明,XGBoost的综合表现最好,AUC达到0.921,并成功识别出81.3%的财务危机企业。
2. XGBoost识别结果
在128家实际发生财务危机的企业中,模型成功识别104家,遗漏24家。与此同时,有36家正常企业被提前列入风险名单。
对于财务预警场景,适当增加误报可以换取更高的危机企业识别率,为后续人工核查争取时间。
3. 重要风险指标
XGBoost给出的变量重要性如下:
从结果来看,企业风险主要集中在三个方面:
- 1. 债务压力较高:资产负债率越高,财务风险越明显;
- 2. 现金流持续恶化:经营现金流不足时,企业可能难以维持日常经营;
- 3. 盈利能力下降:ROA和营业收入增长率降低,会明显提高危机概率。
4. 高风险企业名单
按照XGBoost输出的危机概率,风险最高的部分企业如下:
进一步查看这些企业的财务数据可以发现,它们普遍具有资产负债率偏高、现金流不足、盈利能力下降和收入负增长等特征。
通过这套流程,原本分散在财务报表中的指标被转换为直观的风险概率和预警等级。后续还可以继续加入行业特征、审计意见、股票交易数据和企业年报文本,构建更加完整的企业财务风险预警系统。