2024年华为杯研赛C题解题思路
C题 数据驱动下磁性元件的磁芯损耗建模
问题1
励磁波形作为影响磁芯性能的核心要素之一,其形态深刻影响着磁芯的损耗特性。励磁波形的独特形状直接塑造了磁芯内部磁通的动态行为,不同的波形轮廓影响了磁通密度随时间的变化速率,导致其损耗特性呈现出显著差异。因此,准确识别出励磁波形,对于深入理解磁芯损耗机制、优化磁芯设计具有至关重要的价值。
励磁波形主要体现在磁通密度随时间变化的分布规律上,不同的励磁波形会导致磁通密度呈现出不同的增长、衰减或波动模式。请利用附件一中磁通密度数据,首先分析磁通密度的分布特征及不同波形的形状特征,提取出反映磁通密度分布及波形的形状特征变量;然后利用这些特征变量建立分类模型,识别出励磁的三种波形,分析分类模型的合理性及有效性;并对附件二中的样本识别出相应波形,把分类结果填入附件四(Excel表格)中第2列,要求:(1)按样本序号填入相应分类结果,只填数字,1表示正弦波,2表示三角波,3表示梯形波,比如:附件二中第1个样品分类结果是三角波,在第2列样本序号为1对应行就填数字2;(2)结果填入附件四后,保留原文件名,以附件材料上传;(3)统计出附件二中三种波形的各自数量,呈现在论文正文中;(4)特别把附件二中样本序号为:1、5、15、25、35、45、55、65、75、80的分类结果,以表格形式呈现在论文正文中。
1.1题目分析
初步分析:
- 数据理解:附件一中包含4种磁芯材料的数据,每种材料下有不同的温度、频率、励磁波形和磁通密度数据。磁通密度数据是1024个采样点,代表一个周期内的波形。
- 波形特征:励磁波形有三种:正弦波、三角波和梯形波。这些波形在形状和频域特征上有所不同。
解题思路:
1. 特征提取:
- 时域特征:计算峰值、均值、方差、峰峰值、偏度、峰度等统计特征。
- 频域特征:对磁通密度数据进行快速傅里叶变换(FFT),提取频谱特征,如主频率、频谱能量等。
2. 特征选择:通过相关性分析或主成分分析(PCA)选择最能区分三种波形的特征。
3. 建立分类模型:
- 选择合适的机器学习算法,如支持向量机(SVM)、随机森林、K近邻(KNN)、神经网络等。
- 使用附件一的数据进行训练,附件二的数据进行预测。
4. 模型评估:通过交叉验证评估模型的准确性。
5. 结果输出:将预测的波形类型填入附件四,并统计各波形的数量。
1.2解题思路
- 数据分析与预处理:
首先,我们需要处理附件一中的数据,主要是从中提取特征变量以区分不同的波形类型。数据包含温度、频率、磁芯损耗和磁通密度的1024个采样点。
预处理步骤:
-
读取附件一的数据,并对不同的波形类型进行标注(1表示正弦波,2表示三角波,3表示梯形波)。
-
对每一行1024个采样点进行标准化处理,去除噪声或异常值。
-
特征提取:
为了有效分类波形,必须提取能够表征波形形状的有效特征。考虑的特征包括时域和频域特征。
时域特征:
频域特征:
- 使用**快速傅里叶变换(FFT)**将时域数据转换为频域,并提取主频率和频谱能量。
- 主频率:定义为傅里叶变换后频谱的最大频率分量。
- 频谱能量:定义为频谱幅值的平方和:
特征选择:
为避免特征冗余和过拟合,需要进行特征选择。我们可以采用以下方法:
•皮尔逊相关系数:计算每个特征与波形标签之间的相关性:
•主成分分析(PCA):通过降维方法减少特征数量,保留信息最多的特征。
模型选择与智能优化算法引入:
通过提取的特征,我们可以选择机器学习模型进行分类。为了优化模型的性能,我们可以引入智能优化算法,如遗传算法(GA)对分类器参数进行调优。
模型选择:
智能优化算法------遗传算法(GA): 遗传算法可以用于优化分类器的超参数,例如SVM 中的惩罚参数C和核函数参数γ。遗传算法的主要步骤包括:
- 初始化种群:随机生成一组超参数的组合。
- 适应度函数:计算每个个体(超参数组合)的适应度值,通常以分类准确率为指标。
- 选择:根据适应度值选择优良个体。
- 交叉:对选中的个体进行交叉操作,生成新一代个体。
- 变异:对部分个体进行随机变异,增加搜索的多样性。
- 终止条件:当分类器的准确率达到某个阈值或达到最大迭代次数时停止。
遗传算法的适应度函数可以定义为:
模型验证与评估:
a 使用交叉验证(如K折交叉验证)来评估模型性能,计算分类的准确率、精确率、召回率和F1分数等指标。
b 优化后的分类器预测结果可以对附件二的数据进行分类,生成三种波形类型的数量统计。
结果输出:
a 根据模型的分类结果,将波形的分类标签(1表示正弦波,2表示三角波,3表示梯形波)填入附件四。
b 输出附件二中波形分类的数量统计结果,特别对指定样本序号的波形结果以表格形式展示。
1.3参考代码
import pandas as pd
import numpy as np
from sklearn.preprocessing import StandardScaler
# 读取数据
data = pd.read_csv('your_data_file.csv')
# 数据预处理:提取磁通密度(1024个采样点),并进行标准化
X_raw = data.iloc[:, 4:] # 第5列到最后是磁通密度数据
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X_raw)
# 提取波形标签 (1: 正弦波, 2: 三角波, 3: 梯形波)
y = data['waveform_label'] # 假设波形标签在 'waveform_label' 列
from scipy.fft import fft
import numpy as np
# 时域特征提取函数
def extract_time_domain_features(X):
features = pd.DataFrame()
features['max'] = np.max(X, axis=1)
features['min'] = np.min(X, axis=1)
features['mean'] = np.mean(X, axis=1)
features['std'] = np.std(X, axis=1)
features['peak_to_peak'] = np.max(X, axis=1) - np.min(X, axis=1)
return features
# 频域特征提取函数
def extract_frequency_domain_features(X):
features = pd.DataFrame()
# 对每一行进行傅里叶变换并提取频域特征
fft_features = fft(X, axis=1)
features['fft_max_freq'] = np.max(np.abs(fft_features), axis=1)
features['fft_energy'] = np.sum(np.abs(fft_features)**2, axis=1)
return features
# 提取特征
time_features = extract_time_domain_features(X_scaled)
freq_features = extract_frequency_domain_features(X_scaled)
# 合并所有特征
X_features = pd.concat([time_features, freq_features], axis=1)
from sklearn.feature_selection import SelectKBest, f_classif
# 使用皮尔逊相关系数选择最佳特征
selector = SelectKBest(f_classif, k=10) # 选择最优的10个特征
X_selected = selector.fit_transform(X_features, y)
# 输出被选择的特征
selected_features = X_features.columns[selector.get_support()]
print(f"Selected features: {selected_features}")
from sklearn.model_selection import train_test_split, cross_val_score
from sklearn.svm import SVC
from deap import base, creator, tools, algorithms
# 划分训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X_selected, y, test_size=0.2, random_state=42)
# 遗传算法用于SVM的超参数优化
# 定义适应度函数
creator.create("FitnessMax", base.Fitness, weights=(1.0,))
creator.create("Individual", list, fitness=creator.FitnessMax)
toolbox = base.Toolbox()
toolbox.register("attr_float", np.random.uniform, 0.1, 10.0)
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, 2) # 两个参数: C, gamma
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
# 适应度函数定义
def evalSVM(individual):
C, gamma = individual
model = SVC(C=C, gamma=gamma)
score = cross_val_score(model, X_train, y_train, cv=5).mean()
return score,
toolbox.register("mate", tools.cxBlend, alpha=0.5)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=0.1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", evalSVM)
# 设置遗传算法参数
population = toolbox.population(n=20)
NGEN = 10
CXPB = 0.7
MUTPB = 0.2
# 运行遗传算法
result, logbook = algorithms.eaSimple(population, toolbox, cxpb=CXPB, mutpb=MUTPB, ngen=NGEN,
verbose=True, stats=None)
# 提取最佳个体
best_individual = tools.selBest(result, 1)[0]
print(f"Best C: {best_individual[0]}, Best Gamma: {best_individual[1]}")
# 使用最佳参数训练SVM模型
best_model = SVC(C=best_individual[0], gamma=best_individual[1])
best_model.fit(X_train, y_train)
from sklearn.metrics import classification_report, confusion_matrix
# 在测试集上评估模型
y_pred = best_model.predict(X_test)
print(classification_report(y_test, y_pred))
# 输出混淆矩阵
conf_matrix = confusion_matrix(y_test, y_pred)
print(conf_matrix)
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay
# 混淆矩阵可视化
ConfusionMatrixDisplay.from_estimator(best_model, X_test, y_test)
plt.title("Confusion Matrix of SVM Model")
plt.show()
# 交叉验证得分图
gen = list(range(1, NGEN + 1))
mean_scores = [log['avg'] for log in logbook]
plt.plot(gen, mean_scores)
plt.xlabel('Generation')
plt.ylabel('Mean Accuracy')
plt.title('Genetic Algorithm Optimization Progress')
plt.grid()
plt.show()
# 将预测结果填入附件四
result_df = pd.DataFrame({'sample_number': X_test.index, 'predicted_waveform': y_pred})
result_df.to_csv('attachment_four_with_results.csv', index=False)
问题2
斯坦麦茨方程(Steinmetz-equation)修正
在传统磁芯损耗模型中,斯坦麦茨方程(Steinmetz-equation)(公式(2))虽作为经典模型被广泛应用,却显著受限于其特定的适用条件,如:该方程主要针对正弦波形设计;对于不同种类的磁芯材料及工作温度的变化,SE方程会造成较大的误差,这在实际工程应用中带来了诸多不便与复杂性。目前已经有针对非正弦波形下磁芯损耗模型进行修正(见公式(7)、(8))。
请通过分析斯坦麦茨方程(公式(2)),在同一种磁芯材料、正弦波形下,对于不同温度变化,磁芯损耗预测效果存在的差异性,构造一种可适用于不同温度变化的磁芯损耗修正方程(即在原斯坦麦茨方程基础上,增加温度这个因素,以适应不同温度变化,使磁芯损耗预测效果更好);并以附件一材料1中正弦波形的数据为例,分析你构造的修正方程与斯坦麦茨方程,他们预测磁芯损耗的效果(误差)哪个更好?
2.1题目分析
初步分析:
- 现有问题:斯坦麦茨方程(SE)在不同温度下预测磁芯损耗的效果不佳,需要修正。
- 温度影响:温度对磁性材料的特性有显著影响,可能改变材料的损耗特性。
解题思路:
- 数据分析:在同一种磁芯材料、正弦波形下,分析不同温度对磁芯损耗的影响。
- 模型修正:在SE 方程中引入温度因子,构建修正方程,例如:
其中,T 是温度,γ是需拟合的温度系数。
-
参数拟合:使用附件一的数据,采用非线性回归方法拟合 k, α, β ,γ 的值。
-
模型比较:比较修正后的方程与原SE 方程在磁芯损耗预测上的误差。
2.2解题思路
1. 数据分析
通过附件中的实验数据,获得不同温度下的磁芯损耗、频率和磁通密度的对应关系。分析这些数据,并将其应用到斯坦麦茨方程中。
2. 现有斯坦麦茨方程的误差分析
应用原始的斯坦麦茨方程对实验数据进行预测,并计算其误差:
其中:
• P实际 为实验测量得到的磁芯损耗
• PSE 为通过斯坦麦茨方程计算得到的磁芯损耗
通过分析不同温度下的误差 ,可以得出温度对磁芯损耗的影响。
3.构建温度修正模型
为了使模型更加准确地预测磁芯损耗,我们在斯坦麦茨方程基础上引入温度修正因子。假设温度的影响为幂函数形式,修正后的斯坦麦茨方程为:
其中:
• T 为温度
• γ为需拟合的温度影响因子
该方程通过引入温度因子 γ ,使模型能够更好地预测不同温度下的磁芯损耗。
4. 拟合模型参数
我们需要通过实验数据来拟合模型中的参数 k, α, β ,γ 。拟合目标是最小化预测损耗与实际测量损耗之间的误差:
其中:
• P实际,i 为第 i 个实验条件下的实际损耗
• P预测,i 为修正斯坦麦茨方程预测的损耗
我们通过优化算法拟合 k, α, β ,γ的最优值。
智能优化算法引入
为了更加高效地拟合模型参数,引入遗传算法(GA)进行优化。遗传算法是一种全局优化算法,能够在多维参数空间中寻找最优解。
遗传算法步骤:
种群初始化:随机生成一组初始解,每个解对应于参数 k, α, β ,γ;
适应度函数:适应度函数为模型的误差,即目标函数:
**选择:**根据适应度值选择表现较好的个体(参数组)。
**交叉与变异:**通过交叉(如单点交叉、均匀交叉)生成新个体,并通过变异引入随机性。
**终止条件:**当适应度函数收敛或者达到最大迭代次数时,算法终止。
遗传算法通过上述步骤逐渐优化参数,使得修正后的斯坦麦茨方程能够更精确地预测磁芯损耗。
模型验证与比较
在完成参数拟合后,使用修正后的斯坦麦茨方程对实验数据进行预测,并计算误差。比较修正模型和原始斯坦麦茨方程的预测效果。
误差比较:
计算修正模型和原始模型的相对误差:
通过计算不同温度下的相对误差,评估修正模型的准确性。
可视化与分析
为了更直观地展示修正后的斯坦麦茨方程的效果,我们可以绘制以下图表:
1. 不同温度下的损耗预测图:展示实际损耗与修正斯坦麦茨方程预测的损耗值之间的差异。
2. 误差分布图:比较原始斯坦麦茨方程和修正模型的误差分布。
2.3参考代码
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
# 读取 Excel 文件中的数据
# 请将 'magnetic_data.xlsx' 替换为你附件的文件名
data = pd.read_excel('magnetic_data.xlsx')
# 假设 Excel 文件的列名与之前一致,包含温度、频率、磁通密度峰值和损耗
# 如果你的数据列名不同,请相应修改列名
# Column: 'Temperature', 'Frequency', 'Magnetic_flux_density_peak', 'Core_loss'
X = data[['Temperature', 'Frequency', 'Magnetic_flux_density_peak']] # 温度、频率、磁通密度
y = data['Core_loss'] # 损耗
# 将数据集划分为训练集和测试集
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 定义斯坦麦茨方程模型
def steinmetz_eq(frequency, flux_density, temperature, k, alpha, beta, gamma):
return k * (frequency ** alpha) * (flux_density ** beta) * (temperature ** gamma)
from scipy.optimize import minimize
# 定义误差函数 (目标是最小化平方误差)
def objective(params, X, y):
k, alpha, beta, gamma = params
frequency = X['Frequency']
flux_density = X['Magnetic_flux_density_peak']
temperature = X['Temperature']
# 计算预测的损耗
y_pred = steinmetz_eq(frequency, flux_density, temperature, k, alpha, beta, gamma)
# 返回均方误差
return np.mean((y - y_pred) ** 2)
# 安装DEAP库: pip install deap
from deap import base, creator, tools, algorithms
# 初始化遗传算法参数
creator.create("FitnessMin", base.Fitness, weights=(-1.0,)) # 我们需要最小化误差
creator.create("Individual", list, fitness=creator.FitnessMin)
toolbox = base.Toolbox()
toolbox.register("attr_float", np.random.uniform, 0.001, 10.0) # 为每个参数生成初始值
toolbox.register("individual", tools.initRepeat, creator.Individual, toolbox.attr_float, 4) # 4个参数
toolbox.register("population", tools.initRepeat, list, toolbox.individual)
# 适应度函数,用于遗传算法
def eval_individual(individual):
k, alpha, beta, gamma = individual
params = [k, alpha, beta, gamma]
return (objective(params, X_train, y_train),) # 返回一个元组
# 遗传算法的交叉、变异、选择函数
toolbox.register("mate", tools.cxBlend, alpha=0.5)
toolbox.register("mutate", tools.mutGaussian, mu=0, sigma=0.1, indpb=0.2)
toolbox.register("select", tools.selTournament, tournsize=3)
toolbox.register("evaluate", eval_individual)
# 初始化种群
population = toolbox.population(n=50)
# 设置遗传算法参数
NGEN = 50 # 迭代次数
CXPB = 0.7 # 交叉概率
MUTPB = 0.2 # 变异概率
# 运行遗传算法
result, logbook = algorithms.eaSimple(population, toolbox, cxpb=CXPB, mutpb=MUTPB, ngen=NGEN,
verbose=True, stats=None)
# 获取最优解
best_individual = tools.selBest(result, 1)[0]
print(f"Optimal parameters: k={best_individual[0]}, alpha={best_individual[1]}, beta={best_individual[2]}, gamma={best_individual[3]}")
# 使用最优参数预测
k_opt, alpha_opt, beta_opt, gamma_opt = best_individual
y_pred_train = steinmetz_eq(X_train['Frequency'], X_train['Magnetic_flux_density_peak'], X_train['Temperature'],
k_opt, alpha_opt, beta_opt, gamma_opt)
y_pred_test = steinmetz_eq(X_test['Frequency'], X_test['Magnetic_flux_density_peak'], X_test['Temperature'],
k_opt, alpha_opt, beta_opt, gamma_opt)
# 计算误差
from sklearn.metrics import mean_squared_error
mse_train = mean_squared_error(y_train, y_pred_train)
mse_test = mean_squared_error(y_test, y_pred_test)
print(f"Train MSE: {mse_train}")
print(f"Test MSE: {mse_test}")
import matplotlib.pyplot as plt
# 实际值与预测值的对比
plt.figure(figsize=(10,6))
plt.scatter(range(len(y_test)), y_test, label='Actual Core Loss', color='blue')
plt.scatter(range(len(y_pred_test)), y_pred_test, label='Predicted Core Loss', color='red')
plt.title('Actual vs Predicted Core Loss')
plt.xlabel('Sample Index')
plt.ylabel('Core Loss')
plt.legend()
plt.grid(True)
plt.show()
# 残差图
residuals = y_test - y_pred_test
plt.figure(figsize=(10,6))
plt.scatter(range(len(residuals)), residuals, color='purple')
plt.title('Residuals (Actual - Predicted)')
plt.xlabel('Sample Index')
plt.ylabel('Residual')
plt.grid(True)
plt.show()