2025HuazhongCup-c

话说一个ctf萌新的第一篇博客为什么是数模()

咳,如果你是新手想学这道题,建议出门去找大佬们的论文,这个就是一个新手写给自己的记录

问题一:数据提取与分析

处理53个变量以识别对就业状态影响显著的特征是一个复杂的过程。我们计划使用方差膨胀因子(VIF)进行多重共线性诊断,以评估变量之间的相关性并避免共线性问题。通过这种方法,我们可以筛选出对就业状态有显著影响的关键特征,从而提高模型的解释力和预测准确性。

方法论:VIF多重共线性诊断

在多变量统计分析中,多重共线性是一个常见的问题,它可能导致模型估计的不稳定性。为了解决这一问题,我们将采用VIF方法来诊断和处理多重共线性。VIF值可以帮助我们识别那些与其他变量高度相关的特征,从而在模型构建中做出适当的调整。通过这种方法,我们可以确保模型的稳健性,提高分析结果的可靠性。

人数统计

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
import pandas as pd
import numpy as np
from datetime import datetime
from sklearn.preprocessing import LabelEncoder, StandardScaler

# 设置选项以采用未来行为
pd.set_option('future.no_silent_downcasting', True)

# 获取当前日期
today = pd.to_datetime(datetime.today().date())

# 读取原始数据(这里假设已经安装了xlrd库用于读取xls格式)
df_raw = pd.read_excel(r"C:\\Users\\Desktop\\C.xls")

# 合并前两行作为真正的表头(index=0是拼音,1是中文)
new_columns = df_raw.iloc[0].fillna('') + "_" + df_raw.iloc[1].fillna('')
df_raw.columns = new_columns

# 去掉前两行,只保留实际数据
df = df_raw.iloc[2:].reset_index(drop=True)

# 将缺失值 \n 替换为 NaN
df.replace('\n', pd.NA, inplace=True)

# 转换相关日期字段为datetime格式
date_cols = [
'c_ajc090_失业时间',
'b_acc031_就业时间',
]
for col in date_cols:
if col in df.columns:
try:
df[col] = pd.to_datetime(df[col], errors='coerce')
if df[col].isna().sum() > 0:
print(f"在转换 {col} 时,有 {df[col].isna().sum()} 个值无法解析为日期。")
except Exception as e:
print(f"转换 {col} 时出现错误: {e}")

# 初始化标签,默认认为是“失业”状态
df['label'] = 0

# 如果列就业时间对应的时间晚于列失业时间对应的时间,label为1
df['label'] = np.where(pd.to_datetime(df['b_acc031_就业时间']) > pd.to_datetime(df['c_ajc090_失业时间']), 1, df['label'])

# 统计并打印1和0的个数
count_result = df['label'].value_counts()
print("0的个数:", count_result.get(0, 0))
print("1的个数:", count_result.get(1, 0))

# 设置保留字段
columns_to_keep = [
'people_id_人员编11号', 'name_姓名','sex_性别', 'birthday_生日', 'age_年龄',
'nation_民族','marriage_婚姻状态', 'edu_level_教育程度', 'politic_政治面貌',
'reg_address_户籍地址', 'profession_专业','religion_宗教信仰', 'c_aac009_户口性质',
'c_aab299_户口所在地区(代码)', 'c_aac010_户口所在地区(名称)', 'c_aac011_文化程度',
'c_aac180_毕业学校', 'c_aac181_毕业日期', 'c_aac182_所学专业代码', 'c_aac183_所学专业名称',
'type_人口类型','military_status_兵役状态', 'is_disability_是否残疾人',
'is_teen_是否青少年', 'is_elder_是否老年人', 'change_type_变动类型',
'is_living_alone_是否独居', 'live_status_居住状态', 'label'
]

# 剔除无关变量
valid_columns = [col for col in columns_to_keep if col in df.columns]
df = df[valid_columns]

# 筛选字段副本
df_result = df[columns_to_keep].copy()

# 居住状态这一列删除
df_result = df_result.drop(columns=['live_status_居住状态'])

# 找出所有类别型列(object 类型的列)
categorical_columns = df_result.select_dtypes(include=['object']).columns
# 对每一列使用众数填充缺失值
df_result[categorical_columns] = df_result[categorical_columns].apply(lambda x: x.fillna(x.mode()[0] if not x.mode().empty else np.nan))

# 找出所有非类别型列
non_categorical_columns = df_result.select_dtypes(exclude=['object']).columns
# 对每一列使用中位数填充缺失值
df_result[non_categorical_columns] = df_result[non_categorical_columns].apply(lambda x: x.fillna(x.median()))

# 生日
# 将生日列转换为 datetime 类型
df_result['birthday_生日'] = pd.to_datetime(df_result['birthday_生日'], errors='coerce')
# 新增出生年份、月份特征
df_result['birth_year'] = df_result['birthday_生日'].dt.year
df_result['birth_month'] = df_result['birthday_生日'].dt.month

# 户籍地址
df_result['province'] = df_result['reg_address_户籍地址'].str.extract(r'^(.+?)省', expand=False)
le = LabelEncoder()
df_result['reg_address_encoded'] = le.fit_transform(df_result['reg_address_户籍地址'])

# 提取主专业代码
df_result['main_profession'] = df_result['profession_专业'].astype(str).str.split().str[0]
# 编码为数字标签
df_result['main_profession_encoded'] = le.fit_transform(df_result['main_profession'])

# 户口所在地
df_result['c_aab299_户口所在地区(代码)'] = df_result['c_aab299_户口所在地区(代码)'].astype(str)
# 提取省、市、县代码
df_result['hukou_province_code'] = df_result['c_aab299_户口所在地区(代码)'].str[0:2]
df_result['hukou_city_code'] = df_result['c_aab299_户口所在地区(代码)'].str[2:4]
df_result['hukou_county_code'] = df_result['c_aab299_户口所在地区(代码)'].str[4:6]

# 毕业学校
df_result['school_encoded'] = le.fit_transform(df_result['c_aac180_毕业学校'])

# 毕业日期
# 转换为 datetime 类型
df_result['c_aac181_毕业日期'] = pd.to_datetime(df_result['c_aac181_毕业日期'], errors='coerce')
# 提取毕业年份
df_result['graduate_year'] = df_result['c_aac181_毕业日期'].dt.year
# 计算距今年数(以 2025 年为基准)
df_result['years_since_grad'] = 2025 - df_result['graduate_year']

# 专业代码
le_major_code = LabelEncoder()
df_result['major_code_encoded'] = le_major_code.fit_transform(df_result['c_aac182_所学专业代码'])

# 专业名称
le_major_name = LabelEncoder()
df_result['major_name_encoded'] = le_major_name.fit_transform(df_result['c_aac183_所学专业名称'])

# 需要编码的类别型字段
cat_cols = [
'sex_性别', 'nation_民族','marriage_婚姻状态', 'edu_level_教育程度',
'politic_政治面貌','religion_宗教信仰', 'type_人口类型','military_status_兵役状态',
'is_disability_是否残疾人', 'is_teen_是否青少年', 'is_elder_是否老年人',
'is_living_alone_是否独居', 'change_type_变动类型'
]

# 对所有类别型列进行 LabelEncoding
for col in cat_cols:
le = LabelEncoder()
df_result[col + '_enc'] = le.fit_transform(df_result[col].astype(str))

# 选取最终用于建模的字段
final_features = [
# 数值型与衍生信息
'age_年龄', 'birth_year', 'birth_month', 'graduate_year', 'years_since_grad',
# 已编码的字段
'reg_address_encoded','main_profession_encoded','school_encoded',
'major_code_encoded','major_name_encoded',
# 刚刚LabelEncode的类别变量
] + [col + '_enc' for col in cat_cols]

# 将年龄转为数值型(int)
df_result['age_年龄'] = pd.to_numeric(df_result['age_年龄'], errors='coerce')

# 取建模用数据子集
df_model = df_result[final_features + ['label']].copy()

# 最终建模用的特征
X = df_model[final_features]

# 初始化标准化器
scaler = StandardScaler()

# 拟合并变换
X_scaled = scaler.fit_transform(X)

# 转换为DataFrame并保留列名
X_scaled_df = pd.DataFrame(X_scaled, columns=final_features)

# 添加标签(label)列
X_scaled_df['label'] = df_model['label'].values

# 查看标准化后的结果
print(X_scaled_df.head())

# 保存为 CSV 文件
import os
if not os.path.exists('.\\processed_data'):
os.makedirs('.\\processed_data')
X_scaled_df.to_csv('.\\processed_data\\standardized_data.csv', index=False, encoding='utf - 8')

数据分析

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant
import os

# 读取标准化后的数据
df = pd.read_csv('.\\processed_data\\standardized_data.csv')

# 统计就业状态:0为失业,1为就业
label_counts = df['label'].value_counts()
print("就业状态分布:\n", label_counts)

# 设置字体支持中文`
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建保存图片的目录(如果不存在)
if not os.path.exists('.\\figure'):
os.makedirs('.\\figure')

# 绘制就业状态的饼图并保存`
plt.figure(figsize=(8, 8))`
labels = ['就业', '失业']`
plt.pie(label_counts, labels=labels, autopct='%1.1f%%', startangle=140)`
plt.title('就业状态分布饼图')`
plt.savefig('.\\figure\\employment_status_pie.jpg', dpi=500)`
plt.close()`

# 绘制各特征与就业状态的箱线图并保存`
features = df.columns[:-1] # 除了label列的所有特征`
num_cols = 4
num_rows = (len(features) + num_cols - 1) / num_cols
plt.figure(figsize=(15, 3 * num_rows))
for i, feature in enumerate(features):
plt.subplot(num_rows, num_cols, i + 1)
sns.boxplot(x='label', y=feature, data=df)
plt.title(f'{feature} 与就业状态的关系')
plt.tight_layout()
plt.savefig('.\\figure\\boxplot_feature_employment.jpg', dpi=500)
plt.close()

# 计算各特征与就业状态的相关性并排序
corr_with_label = df.corr()['label'].drop('label').sort_values(ascending=False)
print("\n各特征与就业状态的相关性:\n", corr_with_label)

# 相关系数矩阵
corr_matrix = df.corr(numeric_only=True)

# 绘制热力图并保存
plt.figure(figsize=(14, 12))
sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='coolwarm', square=True)
plt.title("Feature Correlation Heatmap")
plt.tight_layout()
plt.savefig('.\\figure\\heatmap.jpg', dpi=500)
plt.close()

# 计算VIF
X_features = df.drop(columns=['label'])
X_const = add_constant(X_features)
vif = pd.DataFrame()
vif["Variable"] = X_const.columns
vif["VIF"] = [variance_inflation_factor(X_const.values, i) for i in range(X_const.shape[1])]
print("\n特征的方差膨胀因子(VIF):")
print(vif)

# 保留的特征(排除多重共线性高的)
selected_columns = [
'birth_month',
'reg_address_encoded',
'main_profession_encoded',
'school_encoded',
'major_code_encoded',
'major_name_encoded',
'sex_性别_enc',
'nation_民族_enc',
'marriage_婚姻状态_enc',
'edu_level_教育程度_enc',
'politic_政治面貌_enc',
'religion_宗教信仰_enc',
'type_人口类型_enc',
'military_status_兵役状态_enc',
'is_disability_是否残疾人_enc',
'is_elder_是否老年人_enc',
'is_living_alone_是否独居_enc',
'label'
]

# 正确使用 df 而非未定义的 df_filtered`
df_final = df[selected_columns]

# 保存为 CSV`
df_final.to_csv(".\\processed_data\\final_processed_data.csv", index=False, encoding='utf-8')
print("数据已保存为 final_processed_data.csv")

图片1

问题二:预测结果

随机森林模型

对于类别型特征,使用众数填补

特征编码:对类别型特征进行独热编码,生成二元向量

特征标准化:对数值型特征进行标准化,以消除量纲影响

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder, StandardScaler
import os
from joblib import load

# 设置选项以采用未来行为
pd.set_option('future.no_silent_downcasting', True)

# 读取 Excel 文件
file_path = r'C:\\Users\\Desktop\\C.xls'
excel_file = pd.ExcelFile(file_path)

# 获取 sheet2 数据,这里假设 sheet2 的表名为 '预测集',你可按需修改
df = excel_file.parse('预测集')

# 将原始表头和第一行数据合并
new_headers = [str(col) + "_" + str(val) for col, val in zip(df.columns, df.iloc[0])]

# 设置新的表头
df.columns = new_headers

# 去掉第一行数据(因为已经合并到表头中)
df = df.iloc[1:]

# 重置索引
df = df.reset_index(drop=True)

# 设置保留字段
columns_to_keep = [
'name_姓名','sex_性别', 'birthday_生日', 'age_年龄',
'nation_民族','marriage_婚姻状态', 'edu_level_教育程度', 'politic_政治面貌',
'reg_address_户籍地址', 'profession_专业','religion_宗教信仰', 'c_aac009_户口性质',
'c_aab299_户口所在地区(代码)', 'c_aac010_户口所在地区(名称)', 'c_aac011_文化程度',
'c_aac180_毕业学校', 'c_aac181_毕业日期', 'c_aac182_所学专业代码', 'c_aac183_所学专业名称',
'type_人口类型','military_status_兵役状态', 'is_disability_是否残疾人',
'is_teen_是否青少年', 'is_elder_是否老年人', 'change_type_变动类型',
'is_living_alone_是否独居', 'live_status_居住状态'
]

# 筛选出保留字段对应的列
valid_columns = [col for col in columns_to_keep if col in df.columns]
df = df[valid_columns]

# 筛选字段副本
df_result = df[valid_columns].copy()

# 居住状态这一列删除
if 'live_status_居住状态' in df_result.columns:
df_result = df_result.drop(columns=['live_status_居住状态'])

# 找出所有类别型列(object 类型的列)
categorical_columns = df_result.select_dtypes(include=['object']).columns
# 对每一列使用众数填充缺失值
df_result[categorical_columns] = df_result[categorical_columns].apply(lambda x: x.fillna(x.mode()[0] if not x.mode().empty else np.nan))
# 处理警告
df_result = df_result.infer_objects(copy=False)

# 找出所有非类别型列
non_categorical_columns = df_result.select_dtypes(exclude=['object']).columns
# 对每一列使用中位数填充缺失值
df_result[non_categorical_columns] = df_result[non_categorical_columns].apply(lambda x: x.fillna(x.median()))

# 生日
# 将生日列转换为 datetime 类型
if 'birthday_生日' in df_result.columns:
df_result['birthday_生日'] = pd.to_datetime(df_result['birthday_生日'], errors='coerce')
# 新增出生年份、月份特征
df_result['birth_year'] = df_result['birthday_生日'].dt.year
df_result['birth_month'] = df_result['birthday_生日'].dt.month

# 户籍地址
if 'reg_address_户籍地址' in df_result.columns:
df_result['province'] = df_result['reg_address_户籍地址'].str.extract(r'^(.+?)省', expand=False)
le = LabelEncoder()
df_result['reg_address_encoded'] = le.fit_transform(df_result['reg_address_户籍地址'])

# 提取主专业代码
if 'profession_专业' in df_result.columns:
df_result['main_profession'] = df_result['profession_专业'].astype(str).str.split().str[0]
# 编码为数字标签
df_result['main_profession_encoded'] = le.fit_transform(df_result['main_profession'])

# 户口所在地
if 'c_aab299_户口所在地区(代码)' in df_result.columns:
df_result['c_aab299_户口所在地区(代码)'] = df_result['c_aab299_户口所在地区(代码)'].astype(str)
# 提取省、市、县代码
df_result['hukou_province_code'] = df_result['c_aab299_户口所在地区(代码)'].str[0:2]
df_result['hukou_city_code'] = df_result['c_aab299_户口所在地区(代码)'].str[2:4]
df_result['hukou_county_code'] = df_result['c_aab299_户口所在地区(代码)'].str[4:6]

# 毕业学校
if 'c_aac180_毕业学校' in df_result.columns:
df_result['school_encoded'] = le.fit_transform(df_result['c_aac180_毕业学校'])

# 毕业日期
if 'c_aac181_毕业日期' in df_result.columns:
# 转换为 datetime 类型
df_result['c_aac181_毕业日期'] = pd.to_datetime(df_result['c_aac181_毕业日期'], errors='coerce')
# 提取毕业年份
df_result['graduate_year'] = df_result['c_aac181_毕业日期'].dt.year
# 计算距今年数(以 2025 年为基准)
df_result['years_since_grad'] = 2025 - df_result['graduate_year']

# 专业代码
if 'c_aac182_所学专业代码' in df_result.columns:
le_major_code = LabelEncoder()
df_result['major_code_encoded'] = le_major_code.fit_transform(df_result['c_aac182_所学专业代码'])

# 专业名称
if 'c_aac183_所学专业名称' in df_result.columns:
le_major_name = LabelEncoder()
df_result['major_name_encoded'] = le_major_name.fit_transform(df_result['c_aac183_所学专业名称'])

# 需要编码的类别型字段
cat_cols = [
'sex_性别', 'nation_民族','marriage_婚姻状态', 'edu_level_教育程度',
'politic_政治面貌','religion_宗教信仰', 'type_人口类型','military_status_兵役状态',
'is_disability_是否残疾人', 'is_teen_是否青少年', 'is_elder_是否老年人',
'is_living_alone_是否独居', 'change_type_变动类型'
]

# 对所有类别型列进行 LabelEncoding
for col in cat_cols:
if col in df_result.columns:
le = LabelEncoder()
df_result[col + '_enc'] = le.fit_transform(df_result[col].astype(str))

# 选取最终用于建模的字段
final_features = [
# 数值型与衍生信息
'age_年龄', 'birth_year', 'birth_month', 'graduate_year', 'years_since_grad',
# 已编码的字段
'reg_address_encoded','main_profession_encoded','school_encoded',
'major_code_encoded','major_name_encoded',
# 刚刚LabelEncode的类别变量
] + [col + '_enc' for col in cat_cols if col in df_result.columns]

# 将年龄转为数值型(int)
if 'age_年龄' in df_result.columns:
df_result['age_年龄'] = pd.to_numeric(df_result['age_年龄'], errors='coerce')

# 最终建模用的特征
X = df_result[final_features]

# 初始化标准化器
scaler = StandardScaler()

# 拟合并变换
X_scaled = scaler.fit_transform(X)

# 转换为 DataFrame 并保留列名
X_scaled_df = pd.DataFrame(X_scaled, columns=final_features)

# 保存为 CSV 文件
if not os.path.exists('.\\processed_data'):
os.makedirs('.\\processed_data')
X_scaled_df.to_csv('.\\processed_data\\text_data.csv', index=False, encoding='utf-8')

# 加载保存的随机森林模型
model_path = r'C:\\Users\\Desktop\\python\\数模\\random_forest_model.pkl'
try:
rf_model = load(model_path)
# 获取训练时的特征名称
train_feature_names = rf_model.feature_names_in_ if hasattr(rf_model, 'feature_names_in_') else None
if train_feature_names is not None:
# 确保预测数据使用相同的特征
X_scaled_df = X_scaled_df[train_feature_names]

# 使用训练好的模型对 sheet2 数据进行预测
predictions = rf_model.predict(X_scaled_df)

# 将预测结果添加到原始数据中
df_result['predicted_label'] = predictions

# 保存包含预测结果的数据到新的 CSV 文件
df_result.to_csv('.\\processed_data\\predicted_data.csv', index=False, encoding='utf-8')
print("预测完成,结果已保存到 .\\processed_data\\predicted_data.csv")

# 打印预测的 label 值
print("预测的 label 值如下:")
print(predictions)
except FileNotFoundError:
print(f"未找到模型文件: {model_path}")
模型 准确率 查准率 召回率 F1
随机森林模型 0.8800 0.8878 0.9886 0.9355

问题三:预测模型优化

在本问题中,我们面临的任务是将宏观经济、政策、劳动力市场等外部因素融入到就业状态的预测模型中,并对预测集进行重新预测。这一步骤对于提升模型的预测准确性和适用性至关重要。为了实现这一目标,我们需要解决三个核心挑战:数据整合、特征工程和模型改进。

我们需要从外部数据中提取有意义的特征。这包括宏观经济指标的变化趋势、政策实施的效果等。特征工程的目标是识别和构建那些能够显著影响就业状态的特征,从而为模型提供更丰富的信息。

外部数据收集:

​ 宜昌市2018-2023年各地区年度生产总值(来源:国家统计局)

​ 宜昌市2018-2023年各城镇平均居民可支配收入(来源:国家统计局)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
import pandas as pd
import numpy as np
from datetime import datetime
from sklearn.preprocessing import LabelEncoder, StandardScaler
import os

# 设置选项以采用未来行为
pd.set_option('future.no_silent_downcasting', True)

# 获取当前日期
today = pd.to_datetime(datetime.today().date())

# 读取原始数据(这里假设已经安装了openpyxl库用于读取xlsx格式)
df = pd.read_excel(r"C:\\Users\\Desktop\\合并后的表格.xlsx")

# 将缺失值 \n 替换为 NaN
df.replace('\n', pd.NA, inplace=True)

# 转换相关日期字段为datetime格式
date_cols = [
'失业时间',
'就业时间',
]
for col in date_cols:
if col in df.columns:
try:
df[col] = pd.to_datetime(df[col], errors='coerce')
if df[col].isna().sum() > 0:
print(f"在转换 {col} 时,有 {df[col].isna().sum()} 个值无法解析为日期。")
except Exception as e:
print(f"转换 {col} 时出现错误: {e}")

# 初始化标签,默认认为是“失业”状态
df['label'] = 0

# 如果列就业时间对应的时间晚于列失业时间对应的时间,label为1
df['label'] = np.where(pd.to_datetime(df['就业时间']) > pd.to_datetime(df['失业时间']), 1, df['label'])

# 统计并打印1和0的个数
count_result = df['label'].value_counts()
print("0的个数:", count_result.get(0, 0))
print("1的个数:", count_result.get(1, 0))

# 处理列名
new_columns = {}
for col in df.columns:
parts = col.split('_')
if len(parts) == 3 and all([part.isalpha() for part in parts[:2]]):
new_columns[col] = parts[2]
else:
new_columns[col] = col
df.rename(columns=new_columns, inplace=True)

# 设置保留字段(同步修改列名)
columns_to_keep = [
'人员编11号', '姓名', '性别', '生日', '年龄',
'民族', '婚姻状态', '教育程度', '政治面貌',
'户籍地址', '专业', '宗教信仰', '户口性质',
'户口所在地区(代码)', '户口所在地区(名称)', '文化程度',
'毕业学校', '毕业日期', '所学专业代码', '所学专业名称',
'人口类型', '兵役状态', '是否残疾人',
'是否青少年', '是否老年人', '变动类型',
'是否独居', '居住状态', 'label', '地区生产总值'
]

# 剔除无关变量
valid_columns = [col for col in columns_to_keep if col in df.columns]
df = df[valid_columns]

# 筛选字段副本
df_result = df[columns_to_keep].copy()

# 居住状态这一列删除
df_result = df_result.drop(columns=['居住状态'])

# 找出所有类别型列(object 类型的列)
categorical_columns = df_result.select_dtypes(include=['object']).columns
# 对每一列使用众数填充缺失值
df_result[categorical_columns] = df_result[categorical_columns].apply(lambda x: x.fillna(x.mode()[0] if not x.mode().empty else np.nan))

# 找出所有非类别型列
non_categorical_columns = df_result.select_dtypes(exclude=['object']).columns
# 对每一列使用中位数填充缺失值
df_result[non_categorical_columns] = df_result[non_categorical_columns].apply(lambda x: x.fillna(x.median()))

# 生日
# 将生日列转换为 datetime 类型
df_result['生日'] = pd.to_datetime(df_result['生日'], errors='coerce')
# 新增出生年份、月份特征
df_result['出生年份'] = df_result['生日'].dt.year
df_result['出生月份'] = df_result['生日'].dt.month

# 户籍地址
df_result['省份'] = df_result['户籍地址'].str.extract(r'^(.+?)省', expand=False)
le = LabelEncoder()
df_result['户籍地址编码'] = le.fit_transform(df_result['户籍地址'])

# 提取主专业代码
df_result['主专业'] = df_result['专业'].astype(str).str.split().str[0]
# 编码为数字标签
df_result['主专业编码'] = le.fit_transform(df_result['主专业'])

# 户口所在地
df_result['户口所在地区(代码)'] = df_result['户口所在地区(代码)'].astype(str)
# 提取省、市、县代码
df_result['户口所在省份代码'] = df_result['户口所在地区(代码)'].str[0:2]
df_result['户口所在城市代码'] = df_result['户口所在地区(代码)'].str[2:4]
df_result['户口所在县代码'] = df_result['户口所在地区(代码)'].str[4:6]

# 毕业学校
df_result['毕业学校编码'] = le.fit_transform(df_result['毕业学校'])

# 毕业日期
# 转换为 datetime 类型
df_result['毕业日期'] = pd.to_datetime(df_result['毕业日期'], errors='coerce')
# 提取毕业年份
df_result['毕业年份'] = df_result['毕业日期'].dt.year
# 计算距今年数(以 2025 年为基准)
df_result['毕业至今年数'] = 2025 - df_result['毕业年份']

# 专业代码
le_major_code = LabelEncoder()
df_result['所学专业代码编码'] = le_major_code.fit_transform(df_result['所学专业代码'])

# 专业名称
le_major_name = LabelEncoder()
df_result['所学专业名称编码'] = le_major_name.fit_transform(df_result['所学专业名称'])

# 需要编码的类别型字段
cat_cols = [
'性别', '民族', '婚姻状态', '教育程度',
'政治面貌', '宗教信仰', '人口类型', '兵役状态',
'是否残疾人', '是否青少年', '是否老年人',
'是否独居', '变动类型'
]

# 对所有类别型列进行 LabelEncoding
for col in cat_cols:
le = LabelEncoder()
df_result[col + '编码'] = le.fit_transform(df_result[col].astype(str))

# 处理地区生产总值列
if '地区生产总值' in df_result.columns:
if df_result['地区生产总值'].dtype == 'object':
# 如果是类别型数据,进行 LabelEncoding
le_gdp = LabelEncoder()
df_result['地区生产总值编码'] = le_gdp.fit_transform(df_result['地区生产总值'])
else:
# 如果是数值型数据,进行标准化
scaler_gdp = StandardScaler()
df_result['地区生产总值'] = scaler_gdp.fit_transform(df_result[['地区生产总值']])

# 选取最终用于建模的字段
final_features = [
# 数值型与衍生信息
'年龄', '出生年份', '出生月份', '毕业年份', '毕业至今年数',
# 已编码的字段
'户籍地址编码', '主专业编码', '毕业学校编码',
'所学专业代码编码', '所学专业名称编码',
# 刚刚LabelEncode的类别变量
] + [col + '编码' for col in cat_cols]

# 如果处理后有编码列,添加到最终特征
if '地区生产总值编码' in df_result.columns:
final_features.append('地区生产总值编码')
else:
final_features.append('地区生产总值')

# 将年龄转为数值型(int)
df_result['年龄'] = pd.to_numeric(df_result['年龄'], errors='coerce')

# 取建模用数据子集
df_model = df_result[final_features + ['label']].copy()

# 最终建模用的特征
X = df_model[final_features]

# 初始化标准化器
scaler = StandardScaler()

# 拟合并变换
X_scaled = scaler.fit_transform(X)

# 转换为DataFrame并保留列名
X_scaled_df = pd.DataFrame(X_scaled, columns=final_features)

# 添加标签(label)列
X_scaled_df['label'] = df_model['label'].values

# 查看标准化后的结果
print(X_scaled_df.head())

# 使用绝对路径保存文件
output_dir = 'C:\\Users\\Desktop\\python\\数模\\processed_data'
output_file = os.path.join(output_dir, 'standardized_data001.csv')
if not os.path.exists(output_dir):
os.makedirs(output_dir)
X_scaled_df.to_csv(output_file, index=False, encoding='utf-8')
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant
import os

# 使用绝对路径读取文件
file_path = 'C:\\Users\\\\Desktop\\python\\数模\\processed_data\\standardized_data001.csv'
df = pd.read_csv(file_path)

# 统计就业状态:0为失业,1为就业
label_counts = df['label'].value_counts()
print("就业状态分布:\n", label_counts)

# 设置字体支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建保存图片的目录(如果不存在)
if not os.path.exists('.\\figure'):
os.makedirs('.\\figure')

# 绘制就业状态的饼图并保存
plt.figure(figsize=(8, 8))
labels = ['就业', '失业']
plt.pie(label_counts, labels=labels, autopct='%1.1f%%', startangle=140)
plt.title('就业状态分布饼图')
plt.savefig('.\\figure\\employment_status_pie001.jpg', dpi=500)
plt.close()

# 绘制各特征与就业状态的箱线图并保存,包含地区生产总值
features = df.columns[:-1].tolist()
if '地区生产总值' in df.columns:
features.append('地区生产总值')
num_cols = 4
num_rows = (len(features) + num_cols - 1) \\\\ num_cols
plt.figure(figsize=(15, 3 * num_rows))
for i, feature in enumerate(features):
plt.subplot(num_rows, num_cols, i + 1)
sns.boxplot(x='label', y=feature, data=df)
plt.title(f'{feature} 与就业状态的关系')
plt.tight_layout()
plt.savefig('.\\figure\\boxplot_feature_employment001.jpg', dpi=500)
plt.close()

# 计算各特征与就业状态的相关性并排序,包含地区生产总值
corr_with_label = df.corr()['label'].drop('label').sort_values(ascending=False)
print("\n各特征与就业状态的相关性:\n", corr_with_label)

# 相关系数矩阵,包含地区生产总值
corr_matrix = df.corr(numeric_only=True)

# 绘制热力图并保存
plt.figure(figsize=(14, 12))
sns.heatmap(corr_matrix, annot=True, fmt='.2f', cmap='coolwarm', square=True)
plt.title("Feature Correlation Heatmap")
plt.tight_layout()
plt.savefig('.\\figure\\heatmap001.jpg', dpi=500)
plt.close()

# 计算VIF,包含地区生产总值
X_features = df.drop(columns=['label'])
X_const = add_constant(X_features)
vif = pd.DataFrame()
vif["Variable"] = X_const.columns
vif["VIF"] = [variance_inflation_factor(X_const.values, i) for i in range(X_const.shape[1])]
print("\n特征的方差膨胀因子(VIF):")
print(vif)

# 保留的特征(排除多重共线性高的),包含地区生产总值
selected_columns = [
'出生月份',
'户籍地址编码',
'主专业编码',
'毕业学校编码',
'所学专业代码编码',
'所学专业名称编码',
'性别编码',
'民族编码',
'婚姻状态编码',
'教育程度编码',
'政治面貌编码',
'宗教信仰编码',
'人口类型编码',
'兵役状态编码',
'是否残疾人编码',
'是否老年人编码',
'是否独居编码',
'地区生产总值',
'label',
]

# 选取最终保留的特征
df_final = df[selected_columns]

# 使用绝对路径保存文件
output_dir = 'C:\\Users\\\\Desktop\\python\\数模\\processed_data'
output_file = os.path.join(output_dir, 'final_processed_data001.csv')
df_final.to_csv(output_file, index=False, encoding='utf-8')
print("数据已保存为 final_processed_data001.csv")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
from joblib import dump
import os

# 设置字体支持中文
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False

# 创建保存图片的目录(如果不存在)
if not os.path.exists('.\\figure'):
os.makedirs('.\\figure')

# 使用绝对路径读取预处理后的数据
data_file_path = 'C:\\Users\\\\Desktop\\python\\数模\\processed_data\\final_processed_data001.csv'
df = pd.read_csv(data_file_path)

# 目标变量(label)和特征(features)
X = df.drop(columns=['label'])
y = df['label']

# 分割数据为训练集和测试集(98% 训练,2% 测试)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.02, random_state=20)

# 初始化随机森林模型
rf_model = RandomForestClassifier(n_estimators=100, random_state=42)

# 训练模型
rf_model.fit(X_train, y_train)

# 使用训练好的模型对测试集进行预测
y_pred = rf_model.predict(X_test)

# 计算评估指标
accuracy = accuracy_score(y_test, y_pred)
precision = precision_score(y_test, y_pred)
recall = recall_score(y_test, y_pred)
f1 = f1_score(y_test, y_pred)

# 输出结果
print(f"准确率 (Accuracy): {accuracy:.4f}")
print(f"查准率 (Precision): {precision:.4f}")
print(f"召回率 (Recall): {recall:.4f}")
print(f"F1 值: {f1:.4f}")

# 使用绝对路径保存训练好的模型
model_output_dir = 'C:\\Users\\\\Desktop\\python\\数模\\processed_data'
model_output_file = os.path.join(model_output_dir, 'random_forest_model001.pkl')
if not os.path.exists(model_output_dir):
os.makedirs(model_output_dir)
dump(rf_model, model_output_file)
print(f"模型已保存为 '{model_output_file}'")
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
import pandas as pd
import numpy as np
from sklearn.preprocessing import LabelEncoder, StandardScaler
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant
import os

# 定义匹配关键词列表
keywords = ["宜都", "枝江", "当阳", "远安", "兴山", "秭归", "长阳", "五峰", "夷陵", "西陵", "伍家岗", "点军", "猇亭",
"宜昌"]


def check_match(original_value, external_value):
"""
根据新规则检查是否匹配成功
"""
for keyword in keywords:
if keyword in original_value and keyword in external_value:
return True
return False


def build_mapping(external_dfs):
"""
构建地区名到外部数据行的映射表
"""
mapping = {}
for external_df in external_dfs:
for _, row in external_df.iterrows():
area = row['地区名']
if area not in mapping:
mapping[area] = []
mapping[area].append(row)
return mapping


def merge_tables(original_df, external_dfs):
"""
合并原表格和多个外部表格
"""
merged_df = original_df.copy()
mapping = build_mapping(external_dfs)

def update_row(row):
original_area = row['户口所在地区(名称)']
for external_area, external_rows in mapping.items():
if check_match(original_area, external_area):
for external_row in external_rows:
for col in external_row.index:
if col != '地区名':
row[col] = external_row[col]
return row

merged_df = merged_df.apply(update_row, axis=1)
return merged_df

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
import pandas as pd

# 读取原表格,指定第三行作为表头
df1 = pd.read_excel(r'C:\\Users\\Desktop\\C.xls', header=2)

# 读取外部表格
df2 = pd.read_excel(r'C:\\Users\\Desktop\\外部数据\\02.xlsx')

# 定义匹配函数
def match_value(row):
name = row['户口所在地区(名称)']
for index, other_name in enumerate(df2['地区名']):
if other_name != '宜昌市':
if other_name[:2] in name:
return df2.loc[index, '地区生产总值']
elif '宜昌' in name:
return df2.loc[index, '地区生产总值']
return None

# 应用匹配函数
df1['地区生产总值'] = df1.apply(match_value, axis=1)

# 保存合并后的表格
df1.to_excel(r'C:\\Users\\Desktop\\合并后的表格.xlsx', index=False)

优化后的随机森林模型的各评估指标如下:

模型 准确率 查准率 召回率 F1
随机森林模型 0.9147 0.9267 0.9859 0.9554

方案四:人岗精准匹配

在问题四中,我们一方面要完成非线性模型的构造;另一方面应该提升建议与当地经济发展的契合度,做到地区的定制化。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
from sklearn.linear_model import LogisticRegression
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import accuracy_score

# 提取特征变量和目标变量
X = df[['个人基本信息_教育程度', '个人基本信息_政治面貌', '个人基本信息_兵役状态']]
y = df['就业信息_行业代码']

# 对特征变量进行编码
label_encoders = {}
for column in X.columns:
le = LabelEncoder()
X[column] = le.fit_transform(X[column])
label_encoders[column] = le

# 对目标变量进行编码
le_y = LabelEncoder()
y = le_y.fit_transform(y)

# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

# 创建逻辑回归模型并训练
model = LogisticRegression(max_iter=1000)
model.fit(X_train, y_train)

# 在测试集上进行预测
y_pred = model.predict(X_test)

# 计算模型的准确率
accuracy = accuracy_score(y_test, y_pred)
print(f'模型准确率: {accuracy}')

在尝试构建随机森林模型预测个人信息与就业类型的关系时,发现模型准确率仅约为 15.8%,处于较低水平。

(实话:本来应该再继续优化模型和代码的,但是没有时间了,就改成后面这种比较糊弄的形式了)

将赛题提供的数据与引入的外部数据进行整合后,构建了一个包含丰富特征的数据集。随后,基于整合后的数据和提取的特征,构建人岗匹配模型。在本研究中,考虑到问题的复杂性和数据的特点,选择集成学习算法,通过对于行业发展趋势与在当地产业的占比来推荐适合于当地人的个性化职业推荐,以提高模型的准确性,稳定性以及与当地经济情况的契合度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
# -*- coding: utf-8 -*-
import pandas as pd
import random

EMPLOYED = 1
UNEMPLOYED = 0

# 读取 Excel 文件
excel_file = pd.ExcelFile('data.xls')
df = excel_file.parse('data', header=None)

# 设置列名
df.columns = [
'id', 'person_id', 'name', 'sex', 'birthday', 'age', 'nation', 'marriage', 'edu_level',
'politic', 'reg_address', 'profession', 'religion', 'hukou_type', 'hukou_code',
'hukou_name', 'culture_level', 'grad_school', 'grad_date', 'major_code', 'major_name',
'person_type', 'military_status', 'is_disability', 'is_teen', 'is_elder', 'change_type',
'is_living_alone', 'live_status', 'remark', 'employment_id', 'employer_id', 'employment_date',
'is_contract', 'is_social_insurance', 'contract_start', 'contract_end', 'industry_code',
'employer', 'unemployment_audit_date', 'unemployment_id', 'unemployment_date',
'unemployment_reason', 'original_job_code', 'original_job_name', 'original_employment_form',
'job_willingness', 'training_willingness', 'unemployment_register_date', 'unemployment_cancel_date',
'unemployment_status', 'unemployment_type', 'original_company', 'is_unemployment_insurance',
'employment_status', 'n'
]

# 跳过前两行
df = df[2:]
df = df.reset_index(drop=True)

# 移除无效值
invalid_value = 'Employment status (1=employed, 0=unemployed)'
df = df[df['employment_status'] != invalid_value]

# 清理 employment_status 列
print("Original data type of 'employment_status' column:", df['employment_status'].dtype)
df['employment_status'] = df['employment_status'].astype(str).str.strip()
print("Unique values of 'employment_status' column after cleaning:", df['employment_status'].unique())
print("Data type of 'employment_status' column after cleaning:", df['employment_status'].dtype)

# 删除 age 和 edu_level 列中的空值
df = df.dropna(subset=['age', 'edu_level'])

# 筛选出失业人员数据
unemployed_data = df[df['employment_status'] == '0'].copy()

# 专业代码映射字典
MAJOR_MAPPING = {
'10000': 'Philosophy', '100100': 'Basic Medicine', '100400': 'Stomatology', '100500': 'Traditional Chinese Medicine',
'100600': 'Forensic Medicine', '100800': 'Pharmacy', '100900': 'Management', '110000': 'Military Science',
'20100': 'Economics', '20200': 'Business Administration', '40100': 'Education', '40300': 'Physical Education',
'40400': 'Vocational and Technical Education', '50200': 'Foreign Languages and Literatures', '60100': 'History', '70000': 'Science',
'70300': 'Chemistry', '70400': 'Biological Sciences', '70700': 'Geographical Sciences', '71100': 'Mechanics',
'71200': 'Information and Electronic Sciences', '71400': 'Environmental Sciences', '71500': 'Psychology', '80500': 'Thermal Energy and Nuclear Energy',
'80900': 'Hydraulic Engineering', '81000': 'Surveying and Mapping', '81500': 'Forestry Engineering', '82100': 'Engineering Mechanics',
'90100': 'Plant Production', '100300': 'Clinical Medicine and Medical Technology', '100700': 'Nursing', '10100': 'Philosophy',
'20000': 'Economics', '30000': 'Law', '30200': 'Sociology', '30400': 'Public Security',
'40200': 'Ideological and Political Education', '50000': 'Literature', '50100': 'Chinese Language and Literature', '50500': 'Arts (II)',
'60200': 'Library, Information and Archives Science', '70200': 'Physics', '70600': 'Geology', '70800': 'Geophysics',
'71000': 'Marine Sciences', '71300': 'Materials Science', '80100': 'Geology and Mining', '80200': 'Materials',
'80400': 'Instrumentation', '81100': 'Environment', '81600': 'Textile', '81800': 'Aeronautics and Astronautics',
'82000': 'Public Security Technology', '90400': 'Animal Production and Veterinary Medicine', '90500': 'Fisheries', '90600': 'Management',
'90700': 'Agricultural Extension', '100000': 'Medicine', '100200': 'Preventive Medicine', '10200': 'Marxist Theory',
'30100': 'Law', '30300': 'Political Science', '40000': 'Education', '50300': 'Journalism',
'50400': 'Arts (I)', '60000': 'History', '70100': 'Mathematics', '70500': 'Astronomy',
'70900': 'Atmospheric Sciences', '71600': 'Science and Technology Information and Management', '80000': 'Engineering', '80300': 'Mechanical Engineering',
'80600': 'Electrical Engineering', '80700': 'Electronics and Information', '80800': 'Civil Engineering', '81200': 'Chemical Engineering and Pharmacy',
'81300': 'Light Industry, Food and Grain', '81400': 'Agricultural Engineering', '81700': 'Transportation', '81900': 'Weaponry',
'82200': 'Management Engineering', '90000': 'Agriculture', '90200': 'Forest Resources', '90300': 'Environmental Protection'
}


def give_employment_advice(row):
advice = []
try:
education = row['edu_level']
major_code = row['major_code']
major = MAJOR_MAPPING.get(major_code, 'Other Disciplines') if major_code != '990000' else 'Other Disciplines'
age = int(row['age'])
marriage = row['marriage']
is_disability = row['is_disability']
military_status = row['military_status']

if int(education) < 20:
if age < 35:
if is_disability == '0':
other_jobs = ["Housekeeper", "Factory worker", "Warehouse laborer", "Agricultural worker"]
advice.append(random.choice(other_jobs))
else:
advice.append("Handicraft worker")
elif 35 <= age < 50:
if marriage in ['20', '40']:
advice.append("Farmer")
else:
advice.append("Factory worker")
else:
if is_disability == '0':
advice.append("Community cleaner")
else:
advice.append("Handicraft sorter")
elif 20 <= int(education) < 40:
if age < 35:
if 'Economics' in major:
other_jobs = ["Marketer", "Salesperson", "Business analyst", "Financial analyst"]
advice.append(random.choice(other_jobs))
elif 'Chemistry' in major:
other_jobs = ["Chemical process operator", "Chemical product analyst"]
advice.append(random.choice(other_jobs))
elif 'Engineering' in major:
other_jobs = ["Mechanical technician", "Electrical technician", "Equipment maintenance technician"]
advice.append(random.choice(other_jobs))
elif 'Biological Sciences' in major:
other_jobs = ["Food quality inspector", "Biomedical research assistant"]
advice.append(random.choice(other_jobs))
elif 'Languages' in major:
other_jobs = ["Tour guide", "Tourism marketing specialist"]
advice.append(random.choice(other_jobs))
else:
other_jobs = ["Content writer", "Graphic designer", "Data entry clerk", "Event planner"]
advice.append(random.choice(other_jobs))
elif 35 <= age < 50:
if marriage in ['20', '40']:
if 'Agriculture' in major:
advice.append("Agricultural processor")
else:
advice.append("Warehouse manager")
else:
if 'Engineering' in major:
advice.append("Industrial operator")
else:
advice.append("Industrial operator")
else:
if is_disability == '0':
advice.append("Elderly caregiver")
else:
advice.append("Handmade seller")
else:
if age < 35:
if 'Chemistry' in major:
other_jobs = ["Chemical researcher", "Chemical process engineer"]
advice.append(random.choice(other_jobs))
elif 'Biological Sciences' in major:
other_jobs = ["Biomedical researcher", "Drug development scientist"]
advice.append(random.choice(other_jobs))
elif 'Engineering' in major:
other_jobs = ["Mechanical engineer", "Electrical engineer", "Equipment design engineer"]
advice.append(random.choice(other_jobs))
elif 'Management' in major:
other_jobs = ["Production manager", "Project manager", "Business manager"]
advice.append(random.choice(other_jobs))
elif 'Languages' in major:
advice.append("Tourism marketing specialist")
else:
advice.append("Financial consultant")
elif 35 <= age < 50:
if 'Management' in major:
advice.append("Production manager")
else:
advice.append("Technical expert")
else:
advice.append("Part - time trainer")

if military_status == '1':
advice.append("Security guard")
except ValueError:
advice.append("Data error: unable to convert age or education level to integer.")
except Exception as e:
advice.append(f"Unexpected error: {str(e)}")

return ' '.join(advice)


if not unemployed_data.empty:
unemployed_data['Employment Advice'] = unemployed_data.apply(lambda row: give_employment_advice(row), axis = 1)
result = unemployed_data[['id', 'name', 'Employment Advice']]
print(result)
result.to_excel('unemployed_advice.xlsx', index = False)
else:
print("No unemployed people data was filtered.")

写在最后:第一次打数模,不管咋样写完了(虽然知道自己写的依托)还是蛮有成就感的。因为建模大部分并不是我做的,所以公式直接pass掉吧,基本上就是一些代码。


2025HuazhongCup-c
http://example.com/2025/04/22/2025HuazhongCup-c-1/
作者
oxygen
发布于
2025年4月22日
许可协议