import pandas as pd import numpy as np import joblib import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt import seaborn as sns import os # 添加项目根目录到Python路径 import sys sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))) def create_visualizations(): """ 创建各种可视化图表来解释模型和数据 """ # 读取数据 print("读取信贷数据...") df = pd.read_csv('data/credit_data.csv') # 设置图表样式 plt.style.use('seaborn-v0_8') fig_size = (10, 6) # 1. 违约分布 print("创建违约分布图...") plt.figure(figsize=fig_size) default_counts = df['default'].value_counts() plt.pie(default_counts.values, labels=['正常', '违约'], autopct='%1.1f%%', startangle=90) plt.title('信贷违约分布') plt.tight_layout() plt.savefig('visualization/default_distribution.png', dpi=300, bbox_inches='tight') plt.close() # 2. 年龄分布 print("创建年龄分布图...") plt.figure(figsize=fig_size) plt.hist(df['age'], bins=30, alpha=0.7, color='skyblue', edgecolor='black') plt.xlabel('年龄') plt.ylabel('频数') plt.title('客户年龄分布') plt.tight_layout() plt.savefig('visualization/age_distribution.png', dpi=300, bbox_inches='tight') plt.close() # 3. 收入分布 print("创建收入分布图...") plt.figure(figsize=fig_size) plt.hist(df['income'], bins=30, alpha=0.7, color='lightgreen', edgecolor='black') plt.xlabel('年收入') plt.ylabel('频数') plt.title('客户年收入分布') plt.tight_layout() plt.savefig('visualization/income_distribution.png', dpi=300, bbox_inches='tight') plt.close() # 4. 信用评分分布 print("创建信用评分分布图...") plt.figure(figsize=fig_size) plt.hist(df['credit_score'], bins=30, alpha=0.7, color='salmon', edgecolor='black') plt.xlabel('信用评分') plt.ylabel('频数') plt.title('客户信用评分分布') plt.tight_layout() plt.savefig('visualization/credit_score_distribution.png', dpi=300, bbox_inches='tight') plt.close() # 5. 违约与年龄的关系 print("创建违约与年龄关系图...") plt.figure(figsize=fig_size) df.boxplot(column='age', by='default', ax=plt.gca()) plt.xlabel('是否违约 (0:正常, 1:违约)') plt.ylabel('年龄') plt.title('违约与年龄的关系') plt.suptitle('') # 移除自动生成的标题 plt.tight_layout() plt.savefig('visualization/default_vs_age.png', dpi=300, bbox_inches='tight') plt.close() # 6. 违约与收入的关系 print("创建违约与收入关系图...") plt.figure(figsize=fig_size) df.boxplot(column='income', by='default', ax=plt.gca()) plt.xlabel('是否违约 (0:正常, 1:违约)') plt.ylabel('年收入') plt.title('违约与年收入的关系') plt.suptitle('') # 移除自动生成的标题 plt.tight_layout() plt.savefig('visualization/default_vs_income.png', dpi=300, bbox_inches='tight') plt.close() # 7. 违约与信用评分的关系 print("创建违约与信用评分关系图...") plt.figure(figsize=fig_size) df.boxplot(column='credit_score', by='default', ax=plt.gca()) plt.xlabel('是否违约 (0:正常, 1:违约)') plt.ylabel('信用评分') plt.title('违约与信用评分的关系') plt.suptitle('') # 移除自动生成的标题 plt.tight_layout() plt.savefig('visualization/default_vs_credit_score.png', dpi=300, bbox_inches='tight') plt.close() # 8. 特征相关性热力图 print("创建特征相关性热力图...") plt.figure(figsize=(12, 10)) # 只选择数值特征 numerical_features = ['age', 'income', 'employment_length', 'loan_amount', 'credit_score', 'debt_to_income', 'num_credit_lines', 'default'] correlation_matrix = df[numerical_features].corr() sns.heatmap(correlation_matrix, annot=True, cmap='coolwarm', center=0, square=True, linewidths=0.5) plt.title('特征相关性热力图') plt.tight_layout() plt.savefig('visualization/correlation_heatmap.png', dpi=300, bbox_inches='tight') plt.close() # 9. 教育水平与违约关系 print("创建教育水平与违约关系图...") plt.figure(figsize=fig_size) education_default = pd.crosstab(df['education'], df['default'], normalize='index') education_default.plot(kind='bar', stacked=True, color=['skyblue', 'salmon']) plt.xlabel('教育水平') plt.ylabel('比例') plt.title('不同教育水平的违约率') plt.legend(['正常', '违约']) plt.xticks(rotation=45) plt.tight_layout() plt.savefig('visualization/education_default.png', dpi=300, bbox_inches='tight') plt.close() # 10. 房产情况与违约关系 print("创建房产情况与违约关系图...") plt.figure(figsize=fig_size) home_default = pd.crosstab(df['home_ownership'], df['default'], normalize='index') home_default.plot(kind='bar', stacked=True, color=['skyblue', 'salmon']) plt.xlabel('房产情况') plt.ylabel('比例') plt.title('不同房产情况的违约率') plt.legend(['正常', '违约']) plt.xticks(rotation=45) plt.tight_layout() plt.savefig('visualization/home_default.png', dpi=300, bbox_inches='tight') plt.close() print("所有可视化图表已生成并保存到 visualization 目录") def create_dashboard_html(): """ 创建一个HTML仪表板来展示所有可视化图表 """ html_content = '''