目标值分布不均衡

目标值分布不均衡,处理方法如下图所示。
处理方法

本文首先使用smogn对数据集进行过采样

SMOTER生成数据

## load libraries
import smogn
import pandas as pd

data = pd.read_csv('E:/Myjupyter/data/butter_lowpass_data.csv')
features = data.drop(['target','name'],axis = 1)
target = data['target']

k = 5  # 例如,选择5个最近邻
relevance_threshold = 0.5  # 相关性阈值,可以根据数据集进行调整

# 调用smogn的smoter函数进行数据增强
# smoter函数将返回一个新的DataFrame,其中包含了增强后的数据
augmented_data = smogn.smoter(data, y='target', k=k)

# 查看增强后的数据
print(augmented_data.head())
augmented_data.to_csv('E:/Myjupyter/data/augmented_data.csv')

SMOTER数据质量判断

SMOTER数据质量判断的方法:
1.检查数据分布,检查SMOTER生成的合成样本是否与原始少数类样本在统计分布上保持一致,可以通过绘制合成样本和原始样本的直方图或核密度估计图进行比较。
2.比较生成的数据和原始数据的特征分布,检查合成样本的特征是否在原始数据的范围内,以及是否与原始样本具有相似的统计特性,确保生成的数据在特征空间中与原始数据保持一致。
3.分析合成样本是否合理,例如,它们是否位于原始数据的边界附近,并且没有产生异常值或离群点。
4.使用统计测试(使用如t-SNE、PCA等降维技术来查看样本在低维空间的分布情况,或者使用ANOVA等统计测试来比较组间差异。
5.检查生成的数据中是否存在异常值。异常值可能会影响模型的性能,因此需要确保生成的数据不包含异常值。
6.评估所使用的SMOTER参数(如邻居数量k、相关性阈值等)是否合理,以及是否需要根据数据集特性进行调整。

异常值检测

X = data.drop(['name','target'], axis=1)

# 创建LOF模型
lof = LocalOutlierFactor(n_neighbors=20, contamination=0.05)

# 拟合模型并预测离群点
y_pred = lof.fit_predict(X)
result = []
# 打印每个数据点的LOF得分和离群点预测结果,并绘制散点图
for i, (score, pred) in enumerate(zip(lof.negative_outlier_factor_, y_pred)):
    # print(f"数据点{i} - LOF得分: {score:.2f}, 预测结果: {'离群点' if pred == -1 else '正常点'}")
    if pred == -1:
        result.append(i)
# 打印离群点的索引
print("离群点的索引:", result)

检查数据分布

#检查数据分布
original_data = data.iloc[130:180] # 原始样本数据
synthetic_data = data.iloc[0:74]  # SMOTER生成的合成样本数据

# 选择一个特征进行可视化,例如第一个特征
feature_index = 'Amp_14.0'

# 绘制原始样本和合成样本的直方图
plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
sns.histplot(original_data[feature_index], kde=False, color='blue', label='Original')
plt.title('Original Data')

plt.subplot(1, 2, 2)
sns.histplot(synthetic_data[feature_index], kde=False, color='orange', label='Synthetic')
plt.title('Synthetic Data')

plt.show()

# 绘制原始样本和合成样本的核密度估计图
plt.figure(figsize=(10, 6))
plt.subplot(1, 2, 1)
sns.kdeplot(original_data[feature_index], color='blue', label='Original')
plt.title('Original Data KDE')

plt.subplot(1, 2, 2)
sns.kdeplot(synthetic_data[feature_index], color='orange', label='Synthetic')
plt.title('Synthetic Data KDE')

plt.show()

合成样本特征的直方图或核密度估计图并不需要与原始数据集的特征分布完全一致。SMOTER算法生成的合成样本是为了增加数据集中少数类的样本数量,改善类别不平衡问题,而不是为了复制原始数据的分布。以下是几个关于合成样本分布的关键点:

  1. 分布差异:合成样本可能会在某些特征上展现出与原始样本不同的分布特性,这是由于SMOTER算法通过在少数类样本之间进行插值来生成新样本 。

  2. 统计一致性:尽管合成样本的分布可能与原始样本不同,但它们应保持统计上的一致性,即合成样本的统计特性(如均值、方差)应与原始样本相似 。

  3. 评估方法:评估合成样本的有效性不应仅依赖于分布的相似性,还应考虑模型性能的提升。例如,使用合成样本训练的模型在测试集上的表现是否有所提高 。

  4. 多样性:合成样本的引入增加了数据集的多样性,有助于提高模型的泛化能力,但也可能引入一定的噪声 。

  5. 模型适应性:不同的学习器可能对合成样本的适应性不同,某些模型可能从合成样本中受益更多,而另一些模型可能对原始样本分布的保持更为敏感 。

  6. 改进算法:为了解决SMOTER可能带来的问题,如合成样本质量问题、模糊类边界问题等,研究者们提出了多种改进算法,这些算法通过调整合成样本的生成方式来提高其与原始数据集的一致性 。

  7. 高维数据考虑:在高维数据集中,SMOTER的效果可能受到限制,因此在使用SMOTER之前,可能需要对数据进行降维处理,以保持合成样本与原始样本在特征空间中的一致性 。

总之,合成样本的分布不必与原始数据集完全一致,但应保持统计特性的相似性,并有助于提高模型对少数类的识别能力。在实际应用中,应根据具体情况选择合适的SMOTER参数和改进算法,以达到最佳的数据处理效果。

分析合成样本是否合理

分析合成样本是否合理,例如,它们是否位于原始数据的边界附近,并且没有产生异常值或离群点。使用散点图、箱线图等可视化手段来观察。

# 假设 data 是包含原始数据和合成样本的 DataFrame
# 选择几个关键特征
features = data[['feature1', 'feature2']]

# 绘制特征1和特征2之间的散点图
plt.figure(figsize=(10, 6))
plt.scatter(selected_features['feature1'], selected_features['feature2'], alpha=0.5)
plt.title('Scatter Plot of Feature1 vs Feature2')
plt.xlabel('Feature1')
plt.ylabel('Feature2')
plt.show()

# 使用 Seaborn 绘制箱线图
import seaborn as sns

# 绘制选定特征的箱线图
plt.figure(figsize=(12, 6))
sns.boxplot(data=selected_features)
plt.title('Boxplot of Selected Features')
plt.xticks(rotation=45)
plt.show()

连续的标签空间的测试误差分布与标签密度分布的Pearson correlation

根据这个文章https://cloud.tencent.com/developer/article/2047093计算连续的标签空间的测试误差分布与标签密度分布的Pearson correlation。

在机器学习中,“标签密度”(Label Density)通常不是一个标准术语,但我们可以将其理解为与标签分布相关的一个概念。标签密度可以指:
1.标签频率:每个类别在数据集中出现的频率,即每个类别的样本数与总样本数的比例。

标签分布的均匀性:数据集中各个类别的样本分布是否均匀,如果某个类别的样本数远多于其他类别,则该类别的密度较高。

连续标签的密集度:对于连续标签空间,标签值在某个区间内出现的密集程度。

# 假设 y_test 是测试集的连续标签值数组,test_errors 是相应的误差值数组
# 请确保 y_test 和 test_errors 已经被正确计算并赋值
# 计算测试集连续标签值的箱宽和箱边界
bin_width_labels = (np.max(y_test) - np.min(y_test)) / 20
bins_labels = np.arange(np.min(y_test), np.max(y_test) + bin_width_labels, bin_width_labels)

test_errors = np.abs(test_errors)

# 计算测试集误差值的箱宽和箱边界
bin_width_errors = (np.max(test_errors) - np.min(test_errors)) / 20
bins_errors = np.arange(np.min(test_errors), np.max(test_errors) + bin_width_errors, bin_width_errors)

# 指定中文支持的字体路径,例如使用Windows系统中的'SimHei'字体
chinese_font_path = 'SimHei.ttf'
chinese_font = FontProperties(fname=chinese_font_path)

# 设置matplotlib的默认字体
plt.rcParams['font.family'] = 'SimHei'
plt.rcParams['font.sans-serif'] = ['SimHei']
# 创建图形和子图
fig, axs = plt.subplots(2, 1, figsize=(10, 8))  # 2行1列的子图布局

# 绘制测试集连续标签值的直方图
axs[0].hist(y_test, bins=bins_labels, alpha=0.7, color='blue', edgecolor='black')
axs[0].set_title('测试集连续标签值的直方图')
axs[0].set_xlabel('连续标签值')
axs[0].set_ylabel('个数')

# 绘制测试集误差值的直方图
axs[1].hist(test_errors, bins=bins_errors, alpha=0.7, color='green', edgecolor='black')
axs[1].set_title('测试集误差值的直方图')
axs[1].set_xlabel('误差值')
axs[1].set_ylabel('个数')

# 调整子图间距
plt.tight_layout()

# 显示图表
plt.show()

# 计算Pearson相关系数
# 假设连续标签值已经包含在 y_true 中,我们直接使用它们
corr_coefficient, _ = pearsonr(y_test, np.sqrt(test_errors))  # 取误差的平方根作为示例

print(f"Pearson相关系数: {corr_coefficient}")
print(f"P-Value: {_}")
# 如果你想分析误差与原始连续标签值的关系,也可以计算
corr_coefficient_original, _ = pearsonr(y_test, test_errors)

print(f"原始误差与连续标签的Pearson相关系数: {corr_coefficient_original}")
print(f"P-Value: {_}")

参考资料:
https://www.jianshu.com/p/b21ed1141883
https://www.cnblogs.com/ljwgis/p/15471550.html
https://www.zhihu.com/question/66408862
https://cloud.tencent.com/developer/article/2047093
https://neptune.ai/blog/how-to-deal-with-imbalanced-classification-and-regression-data

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
对于目标值是连续数值的回归模型,可以使用基于重采样的方法来实现目标值分布上的平衡。其中一种常用的方法是SMOTE算法。 SMOTE算法通过合成新的少数类样本来平衡不同类别之间的样本数量。具体地,它通过在少数类样本之间进行插值来生成新的合成样本。这些新的样本是通过对少数类样本的随机选择,以及在少数类样本之间随机选择的近邻点之间进行线性插值而生成的。 下面是一个使用SMOTE算法对目标值分布进行平衡的Python实现代码示例: ``` python from imblearn.over_sampling import SMOTE from sklearn.model_selection import train_test_split from sklearn.linear_model import LinearRegression # 加载数据 X, y = load_data() # 划分训练集和测试集 X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42) # 使用SMOTE算法对训练集进行过采样 smote = SMOTE(random_state=42) X_train_resampled, y_train_resampled = smote.fit_resample(X_train, y_train) # 训练线性回归模型 model = LinearRegression() model.fit(X_train_resampled, y_train_resampled) # 在测试集上进行预测 y_pred = model.predict(X_test) # 计算模型性能指标 performance = calculate_performance(y_test, y_pred) ``` 上述代码中,使用了imblearn库中的SMOTE类对训练集进行过采样,并使用sklearn库中的LinearRegression类构建线性回归模型,最后计算了模型在测试集上的性能指标。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值