1

对于一个良好的模型的选择与训练首先要有良好的数据来源与数据选择。
本周在观看并了解项目数据挖掘报告后,着重了解并复现了数据清洗以及特征选择部分。

1. 数据清洗

  1. 对重复值的检测和处理
    使用了Pandas工具中的去重函数进行检测和删除。
drop_duplicates():删除 DataFrame 中的重复行。
duplicated():返回一个布尔型 Series,指示每行是否为重复行。
dropna():删除缺失值。

pandas常用函数

  1. 噪声过滤
    箱型图分析法:
    简单示例:
import matplotlib.pyplot as plt
# 设置中文和负号正常显示
plt.rcParams['font.sans-serif'] = 'Microsoft YaHei'
plt.rcParams['axes.unicode_minus'] = False
# 设置图形的显示风格
plt.style.use('ggplot')
# 绘图:daily_Ionset_r_c1_predicted的箱线图

# 数据
x = [1200, 1300, 1400, 500,1500, 1600, 1700, 1800, 1900, 2000, 2100,4000]

# 画图
plt.boxplot(x=x,
            patch_artist=True, # 箱体颜色
            showmeans=True, # 均值
            boxprops = {'color':'black', 'facecolor':'#9999ff'}, # 设置箱体属性,填充色和边框色
            flierprops = {'marker':'o','markerfacecolor':'red','color':'black'}, # 设置异常值属性,点的形状、填充色和边框色
            meanprops = {'marker':'D','markerfacecolor':'indianred'}, # 设置均值点的属性,点的形状、填充色
            medianprops = {'linestyle':'--','color':'orange'}) # 设置中位数线的属性,线的类型和颜色
# 设置y轴范围
plt.ylim(0, 5000)
# 显示
plt.show()

image.png

利用三标准差原则去噪

import numpy as np
 
def remove_outliers(data, m=3):
    data = np.array(data)
    d = data - np.mean(data)
    mdev = np.mean(np.abs(d))
    s = d/mdev if mdev else 0
    return data[np.abs(s) < m]
 
# 示例数据
data = np.concatenate([np.random.normal(0, 1, 100), np.random.normal(2, 1, 10)])
# 去噪后的数据
data_cleaned = remove_outliers(data)
 
print(data_cleaned)

对实际项目数据处理如下所示:
处理前:
image.png
处理后:
image.png

基于时间序列的滑动窗口计算窗口均值,进而进行数据清洗

# 示例数据  
data = {  
    'timestamp': pd.date_range(start='2023-01-01', periods=10, freq='D'),  
    'value': [10, 15, 12, 18, 20, 17, 19, 22, 21, 23]  
}  
df = pd.DataFrame(data)  
df.set_index('timestamp', inplace=True)

# 计算3天的滑动窗口平均值  
df['moving_average_3d'] = df['value'].rolling(window=3).mean()  
  
# 如果你想要从第二个窗口开始(即排除窗口开始时的NaN值),可以添加dropna()  
df['moving_average_3d_dropna'] = df['value'].rolling(window=3).mean().dropna()

效果:
image.png
目前DataFrame 包含了一个名为'moving_average'的新列,其中包含每个时间点的3天滑动窗口平均值
基于滑动窗口平均值,我们可以定义一些规则来识别和处理异常值。例如,我们可以将那些远离其滑动窗口平均值的点视为异常值,并选择删除、替换或插值它们。

滑动窗口大小的选择取决于你的具体数据和业务需求。较小的窗口可以更快地响应数据中的变化,但也可能对数据中的噪音更敏感;而较大的窗口则可以更好地平滑数据,但可能无法捕捉到短期内的变化。

对于当前项目来说,这种数据清洗方式可能更适合于当前项目中的特征数据采集需求。

  1. 数据筛选
    根据实际情况进行人工的数据筛选,拿当前项目来说,同一深度在不同时刻采样了近2000条记录,但都对应同一个深度的相对距离真实值,采用了平均值、中位数以及众数等统计指标来进行数据转化,并结合实际测试效果,选择其一进行模型的输入。

2. 数据变换

  1. 数据格式转换
    本次测试使用Pandas工具将excel表格加载进来并转换为DataFrame结构进而方便后续计算处理。
  2. 数据类型转换
    本次测试将加载后的数据全部转换为了float浮点数类型,进而保证在后续运算中不会损失数据原始精度
  3. 数据标准化(归一化)
    归一化的目的就是使得预处理的数据被限定在一定的范围内,避免大量量纲不统一的数据

3. 特征选择

  1. 过滤式
    Pearson相关系数
import pandas as pd  
  
# 假设df是你的DataFrame,其中'target'是目标变量  
df = pd.read_csv('your_data.csv')  # 替换为你的数据文件路径  
  
# 计算特征与目标变量的相关系数  
correlations = df.corr()['target'].abs()  
  
# 设置一个阈值,比如0.3  
threshold = 0.3  
  
# 过滤出相关系数大于阈值的特征  
selected_features = correlations[correlations > threshold].index.tolist()  
  
# 打印选中的特征  
print("Selected features:", selected_features)  
  
# 如果你想要基于这些特征创建一个新的DataFrame  
df_selected = df[selected_features + ['target']]

对当前项目进行筛选即可选出如下结果:第2、5、8、14、16、19、20列影响较大,即"0.Z"、"1.Z"、"2.Z"、"方位角"、"温度"、"磁场幅值","北向方位"相对影响较大,选取这些特征进行训练。
image.png

互信息检验

# -*- coding: utf-8 -*-

import numpy as np
import pandas as pd
from sklearn.feature_selection import mutual_info_regression
# 假设df是你的DataFrame,其中'target'是目标变量
df = pd.read_excel('data/22_feature.xlsx', header=None)  # 替换为你的数据文件路径
# 假设df是一个Pandas DataFrame,其中包含特征和目标变量
features = df.drop(22, axis=1)  # 特征列
target = df[22]  # 目标列

# 计算互信息值
mi = mutual_info_regression(features, target)

# 对互信息值进行排序,并获取对应的特征名称
sorted_features = np.argsort(mi)[::-1]
top_features = features.columns[sorted_features]

# 选择前k个特征
k = 6  # 例如,选择前6个最重要的特征
selected_features = top_features[:k]
print selected_features

可得到如下结果:
image.png
即——"方位角","温度","相对方位","磁场幅值","北向方位","高边方位"

  1. 包裹式
    递归特征消除(Recursive Feature Elimination,RFE)
# -*- coding: utf-8 -*-
# -*- coding: utf-8 -*-
import pandas as pd
from sklearn.feature_selection import RFE
from sklearn.linear_model import LinearRegression

# 读取Excel文件
data = pd.read_excel('data/22_feature.xlsx', header=None)

# 假设最后一列是目标变量,其余列是特征
X = data.iloc[:, :-1]  # 特征数据
y = data.iloc[:, -1]  # 目标变量

# 定义模型,由于目标变量是连续的,我们使用线性回归模型
model = LinearRegression()

# 定义要选择的特征数量
n_features_to_select = 5

# 创建RFE实例
rfe = RFE(estimator=model, n_features_to_select=n_features_to_select)

# 使用RFE拟合数据并选择特征
rfe.fit(X, y)

# 打印选择的特征
print("Selected features:", rfe.support_)
print("Feature ranking:", rfe.ranking_)

# 根据RFE的结果选择重要的特征
selected_features = X.columns[rfe.support_]
print("Selected feature names:", selected_features)

# 可以使用选择的特征来训练最终的模型
X_selected = rfe.transform(X)
# print X_selected
# model.fit(X_selected, y)  # 用于训练模型的代码(可选)

image.png
由此所选出的特征为 重力Z、倾斜角、温度、磁倾角、磁场幅值
通过包裹式方法的特征选择,可以更加精确地选择出对于模型性能最为关键的特征。

  1. 嵌入式
    树模型和集成算法(如随机森林和梯度提升树)通常具有内置的特征重要性评估机制,可以通过分析树的分裂过程或特征在树中的使用情况来得到特征的重要性。
    这里以树模型为例
# -*- coding: utf-8 -*-

import pandas as pd
from sklearn.ensemble import RandomForestRegressor

# 读取Excel数据
data = pd.read_excel('data/22_feature.xlsx', header=None)  # 替换为你的数据文件路径

# 分离特征和目标变量
X = data.drop(22, axis=1)  # 替换'target_column_name'为目标列的名称
y = data[22]

# 初始化随机森林模型(这里以分类为例)
rf = RandomForestRegressor(n_estimators=100, random_state=42)

# 训练模型
rf.fit(X, y)

# 获取特征重要性
importances = rf.feature_importances_

# 将特征重要性和特征名称结合起来
feature_importances = pd.DataFrame({'feature': X.columns, 'importance': importances})

# 对特征按重要性进行排序
feature_importances = feature_importances.sort_values(by='importance', ascending=False)

# 输出选择的特征(这里选择重要性大于某个阈值的特征,或选择前N个特征)
selected_features = feature_importances[feature_importances['importance'] > 0.01]  # 设置你自己的阈值
# 或者选择前N个特征:selected_features = feature_importances.head(N)

print(selected_features)

可得到如下结果
image.png
可看到14、19列重要度明显较高,所以我们可选择方位角和磁场幅值作为选择的特征。

4. mlp模型实践

此外本周也对mlp模型进行了了解并根据特征数据进行了实际运行。
mlp模型的训练主要包括了——mlp各层定义以及各层间的传播路径、数据加载和预处理、定义损失函数和优化器、训练模型、通过均方误差(MSE)、平均绝对误差(MAE)评估模型。
收敛结果:
image.png
image.png

5. 总结

本周突然被抽到了毕业论文抽检,要送去校外审核,往年并没有抽检这一事项,是今年新增的环节,所以老师们也比较重视,花了较长时间进行整改。计划下周继续复现项目中的模型,争取快速参与算法的调优和创新中来。


李明
441 声望18 粉丝