当前位置: 首页 > news >正文

使用 scikit-learn 库对乌克兰冲突事件数据集进行多维度分类分析

使用scikit-learn库对乌克兰冲突事件数据集进行多维度分类分析

背景

在现代冲突研究中,对冲突事件进行多维度分析和可视化可以帮助我们更好地理解冲突的模式、趋势和影响因素。本次作业将使用开源冲突数据,构建一个完整的机器学习分类流程,从数据预处理到模型构建,再到结果可视化,全面展示如何使用scikit-learn库处理多维度分类问题。

数据说明

本次使用的是2022-2025年乌克兰冲突事件数据集,该数据集包含了从2022年俄乌战争开始到2025年初乌克兰境内的详细地理定位冲突事件。数据集包含以下重要字段:

  • event_id_cnty:事件标识符
  • event_date:事件日期
  • year:事件发生年份
  • time_precision:时间精度
  • disorder_type:冲突类型
  • event_type:事件类型(如战斗、爆炸/远程攻击等)
  • sub_event_type:子事件类型
  • actor1:主要参与方
  • assoc_actor_1:关联参与方1
  • inter1:参与方1类型代码
  • actor2:次要参与方
  • assoc_actor_2:关联参与方2
  • inter2:参与方2类型代码
  • interaction:参与方交互类型代码
  • civilian_targeting:是否针对平民
  • admin1/2/3:行政区域划分(省/州、区、市/镇)
  • location:地点名称
  • latitude/longitude:地理位置坐标
  • fatalities:死亡人数
  • timestamp:数据记录时间戳

需求

本次要求使用scikit-learn库对乌克兰冲突事件数据集进行多维度分类分析,具体包括:

  1. 数据预处理:清洗数据、处理缺失值、特征编码
  2. 特征工程:选择和构建有意义的特征集
  3. 模型构建:使用随机森林算法构建分类模型,预测事件类型
  4. 模型评估:计算模型准确率、精确率、召回率等指标
  5. 结果可视化:使用PCA降维和t-SNE可视化分类结果

代码说明

实现一个完整的多维度分类分析流程,主要包含以下几个部分:

  1. 数据加载与预处理:读取CSV文件,处理缺失值,提取时间特征(月份、季度)

  2. 特征工程

    • 选择与事件类型预测相关的特征
    • 对分类特征进行标签编码
    • 对数值特征进行标准化处理
  3. 模型构建与训练

    • 使用随机森林算法构建分类模型
    • 训练模型预测事件类型
  4. 模型评估

    • 计算模型准确率、精确率、召回率和F1分数
    • 生成并可视化混淆矩阵
  5. 特征重要性分析

    • 计算并展示各特征对分类结果的重要性
    • 可视化特征重要性排序
  6. 结果可视化

    • 使用PCA降维展示数据的实际分类情况
    • 使用t-SNE降维展示模型的预测分类结果

通过这个完整的流程,你可以了解如何使用scikit-learn进行多维度分类分析,并通过可视化直观地理解分类结果和特征重要性。

使用说明

  1. 请将代码中的file_path变量替换为你实际的CSV文件路径
  2. 运行代码后,会在当前目录生成三个可视化图片文件
  3. 代码中的特征选择和模型参数可以根据实际需求进行调整
  4. 如需增加更多特征或改进模型性能,可以扩展feature_engineeringtrain_model函数

安装依赖

pip install --upgrade numpy pandas matplotlib seaborn scikit-learn loky

导包

# 先设置环境变量,避免CPU核心数警告
import os# 设置使用的CPU核心数(根据实际情况调整,建议为逻辑核心数的一半)
os.environ["LOKY_MAX_CPU_COUNT"] = "4"# 导入必要的库
import pandas as pd  # 用于数据处理和分析
import numpy as np  # 用于数值计算
from sklearn.model_selection import train_test_split  # 用于划分训练集和测试集
from sklearn.preprocessing import LabelEncoder, StandardScaler  # 用于特征编码和标准化
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score  # 模型评估指标
from sklearn.decomposition import PCA  # 主成分分析,用于降维
from sklearn.manifold import TSNE  # t-SNE算法,用于高维数据可视化
import matplotlib.pyplot as plt  # 绘图库
import seaborn as sns  # 高级数据可视化库# 配置matplotlib支持中文字体和LaTeX数学符号
plt.rcParams.update({# 优先使用中文字体,同时保留serif用于LaTeX数学符号"font.family": ["SimHei", "serif"],"mathtext.fontset": "cm",  # 使用Computer Modern字体渲染数学符号"axes.unicode_minus": False,  # 解决负号显示问题"text.usetex": False,  # 不强制使用外部LaTeX,依赖matplotlib内置渲染
})

步骤1: 加载数据

# 步骤1: 加载数据
def load_data(file_path):"""加载冲突事件数据"""try:data = pd.read_csv(file_path)print(f"数据加载成功,共{len(data)}条记录,{len(data.columns)}个字段")return dataexcept FileNotFoundError:print(f"错误:文件 {file_path} 不存在")return None
# 文件路径 - 需要替换为实际数据文件路径
file_path = 'data/06/russia_ukraine_conflict.csv'# 步骤1: 加载数据
data = load_data(file_path)
数据加载成功,共154251条记录,31个字段

步骤2: 数据预处理

# 步骤2: 数据预处理
def preprocess_data(data):"""预处理冲突事件数据"""# 复制数据,避免修改原始数据df = data.copy()# 处理缺失值print("处理缺失值...")# 对于分类变量,用最频繁的值填充for col in df.select_dtypes(include=['object']).columns:# 避免链式赋值和inplace=Truedf[col] = df[col].fillna(df[col].mode()[0])# 对于数值变量,用中位数填充for col in df.select_dtypes(include=['int64', 'float64']).columns:if df[col].isnull().sum() > 0:# 避免链式赋值和inplace=Truedf[col] = df[col].fillna(df[col].median())# 将event_date转换为日期格式df['event_date'] = pd.to_datetime(df['event_date'])# 从日期中提取月份和季度作为新特征df['month'] = df['event_date'].dt.monthdf['quarter'] = df['event_date'].dt.quarterreturn df
# 步骤2: 数据预处理
preprocessed_data = preprocess_data(data)
处理缺失值...

步骤3: 特征工程

# 步骤3: 特征工程
def feature_engineering(df):"""特征工程处理"""# 选择用于分析的特征selected_features = ['disorder_type', 'time_precision', 'interaction', 'civilian_targeting','admin1', 'latitude', 'longitude', 'fatalities', 'month', 'quarter']# 目标变量:事件类型target_variable = 'event_type'# 提取特征和目标变量X = df[selected_features].copy()y = df[target_variable].copy()# 对分类特征进行编码categorical_features = X.select_dtypes(include=['object']).columnsfor feature in categorical_features:le = LabelEncoder()X[feature] = le.fit_transform(X[feature])# 对目标变量进行编码le_target = LabelEncoder()y_encoded = le_target.fit_transform(y)# 特征标准化scaler = StandardScaler()X_scaled = scaler.fit_transform(X)return X_scaled, y_encoded, X.columns, le_target
# 步骤3: 特征工程
X, y, feature_names, target_encoder = feature_engineering(preprocessed_data)

步骤4: 划分训练集和测试集

# 步骤4: 划分训练集和测试集
def split_data(X, y):"""划分训练集和测试集"""X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)print(f"训练集大小: {len(X_train)}, 测试集大小: {len(X_test)}")return X_train, X_test, y_train, y_test
# 步骤4: 划分训练集和测试集
X_train, X_test, y_train, y_test = split_data(X, y)
训练集大小: 123400, 测试集大小: 30851

步骤5: 模型训练

# 步骤5: 模型训练
def train_model(X_train, y_train):"""训练随机森林分类模型"""# 创建随机森林分类器model = RandomForestClassifier(n_estimators=100,  # 树的数量max_depth=10,  # 树的最大深度random_state=42,  # 随机种子,保证结果可重现n_jobs=-1  # 使用所有CPU核心)# 训练模型model.fit(X_train, y_train)return model
# 步骤5: 模型训练
model = train_model(X_train, y_train)

步骤6: 模型评估

# 步骤6: 模型评估
def evaluate_model(model, X_test, y_test, target_encoder):"""评估模型性能"""# 预测测试集y_pred = model.predict(X_test)# 计算准确率accuracy = accuracy_score(y_test, y_pred)print(f"模型准确率: {accuracy:.4f}")# 打印分类报告target_names = target_encoder.classes_print("\n分类报告:")print(classification_report(y_test, y_pred, target_names=target_names))# 绘制混淆矩阵plt.figure(figsize=(10, 8))cm = confusion_matrix(y_test, y_pred)sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',xticklabels=target_names, yticklabels=target_names)plt.xlabel('预测类别')plt.ylabel('实际类别')plt.title('混淆矩阵')plt.tight_layout()plt.savefig('confusion_matrix.png')plt.show()plt.close()return accuracy
# 步骤6: 模型评估
accuracy = evaluate_model(model, X_test, y_test, target_encoder)
print("混淆矩阵图已保存为'confusion_matrix.png'")
模型准确率: 0.9114分类报告:precision    recall  f1-score   supportBattles       0.77      0.92      0.84      7830
Explosions/Remote violence       0.97      0.91      0.94     23021accuracy                           0.91     30851macro avg       0.87      0.91      0.89     30851weighted avg       0.92      0.91      0.91     30851

scikit-learn 评估模型绘制混淆矩阵
混淆矩阵图已保存为’confusion_matrix.png’

步骤7: 特征重要性分析

# 步骤7: 特征重要性分析
def feature_importance_analysis(model, feature_names):"""分析特征重要性"""# 获取特征重要性importances = model.feature_importances_indices = np.argsort(importances)[::-1]# 打印特征重要性排名print("\n特征重要性排名:")for f in range(len(feature_names)):print(f"{f + 1}. {feature_names[indices[f]]} ({importances[indices[f]]:.4f})")# 绘制特征重要性图plt.figure(figsize=(12, 6))plt.title('特征重要性')plt.bar(range(len(feature_names)), importances[indices], align='center')plt.xticks(range(len(feature_names)), [feature_names[i] for i in indices], rotation=90)plt.xlim([-1, len(feature_names)])plt.tight_layout()plt.savefig('feature_importance.png')plt.show()plt.close()
# 步骤7: 特征重要性分析
feature_importance_analysis(model, feature_names)
print("特征重要性图已保存为'feature_importance.png'")
特征重要性排名:
1. interaction (0.6118)
2. longitude (0.1800)
3. latitude (0.0971)
4. fatalities (0.0726)
5. admin1 (0.0236)
6. month (0.0084)
7. quarter (0.0040)
8. time_precision (0.0024)
9. civilian_targeting (0.0000)
10. disorder_type (0.0000)

scikit-learn 特征重要性分析
特征重要性图已保存为’feature_importance.png’

步骤8: 可视化分类结果

# 步骤8: 可视化分类结果
def visualize_results(X_test, y_test, y_pred, target_encoder):"""可视化分类结果"""# 使用PCA降维到2Dpca = PCA(n_components=2)X_test_pca = pca.fit_transform(X_test)# 使用t-SNE降维(计算量较大)tsne = TSNE(n_components=2, random_state=42)X_test_tsne = tsne.fit_transform(X_test)# 获取类别名称target_names = target_encoder.classes_# 创建画布fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 8))# 绘制PCA可视化结果scatter1 = ax1.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=y_test,cmap='viridis', s=50, alpha=0.7)legend1 = ax1.legend(*scatter1.legend_elements(), title="实际类别",bbox_to_anchor=(1.05, 1), loc='upper left')ax1.add_artist(legend1)ax1.set_title('PCA降维后的实际分类结果')ax1.set_xlabel('主成分1')ax1.set_ylabel('主成分2')# 绘制t-SNE可视化结果scatter2 = ax2.scatter(X_test_tsne[:, 0], X_test_tsne[:, 1], c=y_pred,cmap='plasma', s=50, alpha=0.7)legend2 = ax2.legend(*scatter2.legend_elements(), title="预测类别",bbox_to_anchor=(1.05, 1), loc='upper left')ax2.add_artist(legend2)ax2.set_title('t-SNE降维后的预测分类结果')ax2.set_xlabel('t-SNE维度1')ax2.set_ylabel('t-SNE维度2')plt.tight_layout()plt.savefig('classification_visualization.png')plt.show()plt.close()
# 步骤8: 可视化分类结果
visualize_results(X_test, y_test, model.predict(X_test), target_encoder)
print("分析完成!分类结果可视化已保存为'classification_visualization.png'")

scikit-learn
分析完成!分类结果可视化已保存为’classification_visualization.png’

完整代码

# 先设置环境变量,避免CPU核心数警告
import os# 设置使用的CPU核心数(根据实际情况调整,建议为逻辑核心数的一半)
os.environ["LOKY_MAX_CPU_COUNT"] = "4"# 导入必要的库
import pandas as pd  # 用于数据处理和分析
import numpy as np  # 用于数值计算
from sklearn.model_selection import train_test_split  # 用于划分训练集和测试集
from sklearn.preprocessing import LabelEncoder, StandardScaler  # 用于特征编码和标准化
from sklearn.ensemble import RandomForestClassifier  # 随机森林分类器
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score  # 模型评估指标
from sklearn.decomposition import PCA  # 主成分分析,用于降维
from sklearn.manifold import TSNE  # t-SNE算法,用于高维数据可视化
import matplotlib.pyplot as plt  # 绘图库
import seaborn as sns  # 高级数据可视化库# 配置matplotlib支持中文字体和LaTeX数学符号
plt.rcParams.update({# 优先使用中文字体,同时保留serif用于LaTeX数学符号"font.family": ["SimHei", "serif"],"mathtext.fontset": "cm",  # 使用Computer Modern字体渲染数学符号"axes.unicode_minus": False,  # 解决负号显示问题"text.usetex": False,  # 不强制使用外部LaTeX,依赖matplotlib内置渲染
})# 步骤1: 加载数据
def load_data(file_path):"""加载冲突事件数据"""try:data = pd.read_csv(file_path)print(f"数据加载成功,共{len(data)}条记录,{len(data.columns)}个字段")return dataexcept FileNotFoundError:print(f"错误:文件 {file_path} 不存在")return None# 步骤2: 数据预处理
def preprocess_data(data):"""预处理冲突事件数据"""# 复制数据,避免修改原始数据df = data.copy()# 处理缺失值print("处理缺失值...")# 对于分类变量,用最频繁的值填充for col in df.select_dtypes(include=['object']).columns:# 避免链式赋值和inplace=Truedf[col] = df[col].fillna(df[col].mode()[0])# 对于数值变量,用中位数填充for col in df.select_dtypes(include=['int64', 'float64']).columns:if df[col].isnull().sum() > 0:# 避免链式赋值和inplace=Truedf[col] = df[col].fillna(df[col].median())# 将event_date转换为日期格式df['event_date'] = pd.to_datetime(df['event_date'])# 从日期中提取月份和季度作为新特征df['month'] = df['event_date'].dt.monthdf['quarter'] = df['event_date'].dt.quarterreturn df# 步骤3: 特征工程
def feature_engineering(df):"""特征工程处理"""# 选择用于分析的特征selected_features = ['disorder_type', 'time_precision', 'interaction', 'civilian_targeting','admin1', 'latitude', 'longitude', 'fatalities', 'month', 'quarter']# 目标变量:事件类型target_variable = 'event_type'# 提取特征和目标变量X = df[selected_features].copy()y = df[target_variable].copy()# 对分类特征进行编码categorical_features = X.select_dtypes(include=['object']).columnsfor feature in categorical_features:le = LabelEncoder()X[feature] = le.fit_transform(X[feature])# 对目标变量进行编码le_target = LabelEncoder()y_encoded = le_target.fit_transform(y)# 特征标准化scaler = StandardScaler()X_scaled = scaler.fit_transform(X)return X_scaled, y_encoded, X.columns, le_target# 步骤4: 划分训练集和测试集
def split_data(X, y):"""划分训练集和测试集"""X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)print(f"训练集大小: {len(X_train)}, 测试集大小: {len(X_test)}")return X_train, X_test, y_train, y_test# 步骤5: 模型训练
def train_model(X_train, y_train):"""训练随机森林分类模型"""# 创建随机森林分类器model = RandomForestClassifier(n_estimators=100,  # 树的数量max_depth=10,  # 树的最大深度random_state=42,  # 随机种子,保证结果可重现n_jobs=-1  # 使用所有CPU核心)# 训练模型model.fit(X_train, y_train)return model# 步骤6: 模型评估
def evaluate_model(model, X_test, y_test, target_encoder):"""评估模型性能"""# 预测测试集y_pred = model.predict(X_test)# 计算准确率accuracy = accuracy_score(y_test, y_pred)print(f"模型准确率: {accuracy:.4f}")# 打印分类报告target_names = target_encoder.classes_print("\n分类报告:")print(classification_report(y_test, y_pred, target_names=target_names))# 绘制混淆矩阵plt.figure(figsize=(10, 8))cm = confusion_matrix(y_test, y_pred)sns.heatmap(cm, annot=True, fmt='d', cmap='Blues',xticklabels=target_names, yticklabels=target_names)plt.xlabel('预测类别')plt.ylabel('实际类别')plt.title('混淆矩阵')plt.tight_layout()plt.savefig('confusion_matrix.png')plt.show()plt.close()return accuracy# 步骤7: 特征重要性分析
def feature_importance_analysis(model, feature_names):"""分析特征重要性"""# 获取特征重要性importances = model.feature_importances_indices = np.argsort(importances)[::-1]# 打印特征重要性排名print("\n特征重要性排名:")for f in range(len(feature_names)):print(f"{f + 1}. {feature_names[indices[f]]} ({importances[indices[f]]:.4f})")# 绘制特征重要性图plt.figure(figsize=(12, 6))plt.title('特征重要性')plt.bar(range(len(feature_names)), importances[indices], align='center')plt.xticks(range(len(feature_names)), [feature_names[i] for i in indices], rotation=90)plt.xlim([-1, len(feature_names)])plt.tight_layout()plt.savefig('feature_importance.png')plt.show()plt.close()# 步骤8: 可视化分类结果
def visualize_results(X_test, y_test, y_pred, target_encoder):"""可视化分类结果"""# 使用PCA降维到2Dpca = PCA(n_components=2)X_test_pca = pca.fit_transform(X_test)# 使用t-SNE降维(计算量较大)tsne = TSNE(n_components=2, random_state=42)X_test_tsne = tsne.fit_transform(X_test)# 获取类别名称target_names = target_encoder.classes_# 创建画布fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(20, 8))# 绘制PCA可视化结果scatter1 = ax1.scatter(X_test_pca[:, 0], X_test_pca[:, 1], c=y_test,cmap='viridis', s=50, alpha=0.7)legend1 = ax1.legend(*scatter1.legend_elements(), title="实际类别",bbox_to_anchor=(1.05, 1), loc='upper left')ax1.add_artist(legend1)ax1.set_title('PCA降维后的实际分类结果')ax1.set_xlabel('主成分1')ax1.set_ylabel('主成分2')# 绘制t-SNE可视化结果scatter2 = ax2.scatter(X_test_tsne[:, 0], X_test_tsne[:, 1], c=y_pred,cmap='plasma', s=50, alpha=0.7)legend2 = ax2.legend(*scatter2.legend_elements(), title="预测类别",bbox_to_anchor=(1.05, 1), loc='upper left')ax2.add_artist(legend2)ax2.set_title('t-SNE降维后的预测分类结果')ax2.set_xlabel('t-SNE维度1')ax2.set_ylabel('t-SNE维度2')plt.tight_layout()plt.savefig('classification_visualization.png')plt.show()plt.close()# 主函数
def main():# 文件路径 - 需要替换为实际数据文件路径file_path = 'data/06/russia_ukraine_conflict.csv'# 步骤1: 加载数据data = load_data(file_path)if data is None:return# 步骤2: 数据预处理preprocessed_data = preprocess_data(data)# 步骤3: 特征工程X, y, feature_names, target_encoder = feature_engineering(preprocessed_data)# 步骤4: 划分训练集和测试集X_train, X_test, y_train, y_test = split_data(X, y)# 步骤5: 模型训练model = train_model(X_train, y_train)# 步骤6: 模型评估accuracy = evaluate_model(model, X_test, y_test, target_encoder)# 步骤7: 特征重要性分析feature_importance_analysis(model, feature_names)# 步骤8: 可视化分类结果visualize_results(X_test, y_test, model.predict(X_test), target_encoder)print("\n分析完成!分类结果可视化已保存为'classification_visualization.png'")print("特征重要性图已保存为'feature_importance.png'")print("混淆矩阵图已保存为'confusion_matrix.png'")if __name__ == "__main__":main()
数据加载成功,共154251条记录,31个字段
处理缺失值...
训练集大小: 123400, 测试集大小: 30851
模型准确率: 0.9114分类报告:precision    recall  f1-score   supportBattles       0.77      0.92      0.84      7830
Explosions/Remote violence       0.97      0.91      0.94     23021accuracy                           0.91     30851macro avg       0.87      0.91      0.89     30851weighted avg       0.92      0.91      0.91     30851

scikit-learn 评估模型绘制混淆矩阵

特征重要性排名:
1. interaction (0.6118)
2. longitude (0.1800)
3. latitude (0.0971)
4. fatalities (0.0726)
5. admin1 (0.0236)
6. month (0.0084)
7. quarter (0.0040)
8. time_precision (0.0024)
9. civilian_targeting (0.0000)
10. disorder_type (0.0000)

scikit-learn 特征重要性分析
scikit-learn

分析完成!分类结果可视化已保存为'classification_visualization.png'
特征重要性图已保存为'feature_importance.png'
混淆矩阵图已保存为'confusion_matrix.png'

相关文章:

  • MATLAB实现音频参数均衡器(PEQ)
  • 麒麟系统 Linux(aarch64处理器)系统java项目接入海康SDK问题
  • mediapipe标注视频姿态关键点
  • JavaScript 中 this 指向详解
  • 力扣四道题,力扣LCR 016无重复字符的最长子串力扣452.用最小数量的箭引爆气球LCR026.重排链表力扣.1765地图中的最高点
  • 分布式项目保证消息幂等性的常见策略
  • 视频监控汇聚平台EasyCVR工业与安全监控:防爆摄像机的安全应用与注意事项
  • 嵌入式Linux快速入门第1~2章
  • redis五种数据结构底层实现
  • React--》掌握react组件库设计与架构规划
  • 卷积神经网络(CNN)入门学习笔记
  • 递归函数,数学表达式转化成递归函数
  • JavaSE核心知识点04工具04-03(Maven)
  • Electron 桌面程序读取dll动态库
  • 【React】-组件中实现高性能鼠标跟随提示框的完整优化过程
  • 模板应用更新同步到所有开发中的应用
  • 图片压缩工具 | Electron+Vue3+Rsbuild开发桌面应用
  • React useEffect和useEffectLa
  • 鸿蒙OSUniApp 实现带搜索功能的下拉菜单#三方框架 #Uniapp
  • element的el-table翻页选中功能
  • 做设计的公司的网站/百度官网app下载
  • 域名注册以后怎样做网站/怎么在百度上面打广告
  • dreamweaver做的网站/seo品牌优化百度资源网站推广关键词排名
  • 给别人做网站/深圳在线制作网站
  • 设计有关的网站/百度seo优化策略
  • 南宁公司官网建站/长春网站建设路