1、问题:
在做分类问题时,经常遇到样本不均衡的问题,例如:A类样本100个,B类样本只有30个。写文章投稿时,经常会被审稿人指出这个问题。而SMOTE算法则可以通过过采样来生成B类样本,增加B类样本的数量。
2、原理:
大家自己百度查原理,帖子很多。
3、代码:
数据都存储在excel表格中,代码如下:
import pandas as pd
import numpy as np
from imblearn.over_sampling import SMOTE
from numpy import shape, mean, nonzero, isnan
io = r'./data.xlsx'
data = pd.read_excel(io)
X = data.iloc[:, 2:].values # 自变量
y = data.iloc[:, 1].values # 因变量
# 获取特征维度
numFeat = shape(X)[1]
rows, columns = shape(X)
#遍历数据集每一个维度
for i in range(rows):
# 利用该维度所有非NaN特征求取均值
# nonzero返回非空元素的索引
# isnan和~isnan返回数组元素是否对应为空的True or False数组
a = X[i, :]
b = ~isnan(X[i, :])
nonzero(~isnan(X[i, :]))
meanVal = mean(X[i, nonzero(~isnan(X[i, :]))[0]])
# 将该维度中所有NaN特征全部用均值替换
# .A将matrix转化为ndarray,然后~isnan()获得对应bool数组
# 再通过nonzero()得到所有不为nan数据的索引数组
# 也即第i个特征不为nan的所有元素的索引,最后通过mean对这些元素求出平均值
X[i, nonzero(isnan(X[i, :]))[0]] = meanVal
# 最后再用计算出来的平均值填充空值
X_resampled, y_resampled = SMOTE(sampling_strategy="auto").fit_resample(X, y)
# X_resampled, y_resampled = SMOTE().fit_sample(X, y)
# 合并数据
data_resampled = np.zeros([len(X_resampled[:, 0]), len(X_resampled[1, :]) + 1])
data_resampled[:, 1:] = X_resampled
data_resampled[:, 0] = y_resampled
data_resampled2 = pd.DataFrame(data_resampled)
writer = pd.ExcelWriter(r'./new_data.xlsx') #创建数据存放路径
data_resampled2.to_excel(writer)
writer.save()#文件保存
writer.close()#文件关闭