import os # 导入操作系统库以兼容跨平台数据路径。
import pandas as pd # 导入 Pandas 以拼接财务表与公司基本信息表。
from sklearn.discriminant_analysis import LinearDiscriminantAnalysis # 导入 LDA 作为线性基准方法。
from sklearn.model_selection import train_test_split # 导入训练测试集划分工具。
from sklearn.preprocessing import StandardScaler # 导入标准化器以服务 SVM 训练。
from sklearn.svm import SVC # 导入支持向量分类器。
data_dir = 'C:/qiufei/data' if os.name == 'nt' else '/home/ubuntu/r2_data_mount/qiufei/data' # 根据系统定位本地金融数据路径。
financial = pd.read_hdf(os.path.join(data_dir, 'stock/financial_statement.h5'), columns=['order_book_id', 'quarter', 'current_assets', 'current_liabilities', 'total_assets', 'total_liabilities', 'net_profit', 'operating_revenue']) # 选择性读取财务困境识别所需字段。
stock_basic = pd.read_hdf(os.path.join(data_dir, 'stock/stock_basic_data.h5'))[['order_book_id', 'symbol', 'province']] # 读取公司基本信息中的简称与省份字段。
yrd_panel = financial.merge(stock_basic[stock_basic['province'].isin(['上海市', '江苏省', '浙江省', '安徽省'])], on='order_book_id', how='inner') # 将样本限制在长三角上市公司范围内。
yrd_panel = yrd_panel[yrd_panel['quarter'] >= '2020q1'].copy() # 仅保留近年财务样本以提升现实相关性。
yrd_panel['current_ratio'] = yrd_panel['current_assets'] / (yrd_panel['current_liabilities'] + 1) # 计算流动比率衡量短期偿债能力。
yrd_panel['debt_ratio'] = yrd_panel['total_liabilities'] / (yrd_panel['total_assets'] + 1) # 计算资产负债率衡量杠杆压力。
yrd_panel['profit_margin'] = yrd_panel['net_profit'] / (yrd_panel['operating_revenue'] + 1) # 计算销售净利率衡量盈利质量。
yrd_panel['distress'] = (yrd_panel['net_profit'] < 0).astype(int) # 将亏损定义为财务困境标签。
yrd_panel = yrd_panel[['current_ratio', 'debt_ratio', 'profit_margin', 'distress']].replace([float('inf'), float('-inf')], pd.NA).dropna() # 清除无穷值与缺失值。
yrd_panel = yrd_panel[(yrd_panel['current_ratio'].between(0, 15)) & (yrd_panel['debt_ratio'].between(0, 2)) & (yrd_panel['profit_margin'].between(-1, 1))] # 保留合理财务区间内的样本。
distressed = yrd_panel[yrd_panel['distress'] == 1] # 取出亏损企业样本。
healthy = yrd_panel[yrd_panel['distress'] == 0] # 取出健康企业样本。
sample_size = min(len(distressed), len(healthy), 300) # 设定平衡抽样规模以控制运行时间并避免类别失衡。
balanced_panel = pd.concat([distressed.sample(sample_size, random_state=42, replace=len(distressed) < sample_size), healthy.sample(sample_size, random_state=42)], ignore_index=True) # 生成平衡训练样本。
train_x, test_x, train_y, test_y = train_test_split(balanced_panel[['current_ratio', 'debt_ratio', 'profit_margin']], balanced_panel['distress'], test_size=0.3, random_state=42, stratify=balanced_panel['distress']) # 按分层抽样划分训练集与测试集。
scaler = StandardScaler() # 创建标准化器以统一财务指标量纲。
train_x_scaled = scaler.fit_transform(train_x) # 在训练集上拟合并转换特征。
test_x_scaled = scaler.transform(test_x) # 用训练集参数变换测试集特征。
classification_models = {'LDA': LinearDiscriminantAnalysis(), '线性 SVC': SVC(kernel='linear', C=1, probability=True, random_state=42), 'RBF SVC': SVC(kernel='rbf', C=1, gamma=0.5, probability=True, random_state=42)} # 同时配置三类候选模型供 ROC 比较。
for model in classification_models.values(): # 遍历模型集合完成拟合。
model.fit(train_x_scaled, train_y) # 在标准化训练集上拟合各自分类器。