主要讲以下两种方法:
方法一:当数据出现严重倾斜的时候,我们可以采取降采样的方式
方法二:在训练模型中添加参数class_weight='balanced'
下面给个实际的例子:
第一步:读数据 (我们把数据放在了txt中)
def read_data(path):
data = []
with open(path) as f:
lines = f.readlines()
for line in lines:
line = line.strip().split(',')
data.append(line)
data = np.array(data).astype(np.float)
return data
if __name__ == '__main__':
path = './data/data_multivar_imbalance.txt'
data = read_data(path)
print(data)
print(data.shape)
print(data[data[:, -1] == 1].shape[0]) # 数据为1000
print(data[data[:, -1] == 0].shape[0]) # 数据为200
查看数据:
第一方法:降采样+支持向量机
从上面的输出我们可以看到标签为1的数据有1000条,标签为0的数据有200. 数据出现了严重的倾斜。我们用降采样的方式+支持向量机进行模型的建立
def model(X, y):
classifier = SVC(kernel='rbf', probability=True)
classifier.fit(X, y)
print('准确率:', classifier.score(X, y))
if __name__ == '__main__':
path = './data/data_multivar_imbalance.txt'
data = read_data(path)
# 我们可以下采样 从标签为1的样本中抽取200进行训练
label_1 = data[data[:, -1] == 1]
label_1 = label_1[0: 200, :]
label_0 = data[data[:, -1] == 0]
# 然后将这两种标签的数据进行合并
data = np.concatenate((label_1, label_0))
data = shuffle(data) # 将数据进行打乱
X1 = data[:, 0:2]
y2 = data[:, 2]
model(X, y)
降采样就是从1000条标签为1的数据中抽出200条
训练结果:
第二方法:参数class_weight+支持向量机
def model2(X, y):
# params = {'kernel':'rbf', 'class_weight':'auto'}
# 它的作用是统计不用类型的数量,调整权重,让模型不平衡问题不印象分类效果
classifier = SVC(kernel='rbf', class_weight='balanced')
classifier.fit(X, y)
print('准确率:', classifier.score(X, y))
if __name__ == '__main__':
path = './data/data_multivar_imbalance.txt'
data = read_data(path)
X = data[:, 0:2]
y = data[:, 2]
model2(X, y)
输出结果:
综合上述两种情况,看来第一种降采样还是比第二种方法好。。。我只是简单的对比了一下。。后期会在不同的参数下再进行测试。
源代码:
import numpy as np
from sklearn.utils import shuffle # 将样本打乱
from sklearn.svm import SVC
import warnings
warnings.filterwarnings('ignore')
def read_data(path):
data = []
with open(path) as f:
lines = f.readlines()
for line in lines:
line = line.strip().split(',')
data.append(line)
data = np.array(data).astype(np.float)
return data
def model(X, y):
classifier = SVC(kernel='rbf', probability=True)
classifier.fit(X, y)
print('准确率:', classifier.score(X, y))
def model2(X, y):
# params = {'kernel':'rbf', 'class_weight':'auto'}
classifier = SVC(kernel='rbf', class_weight='balanced')
classifier.fit(X, y)
print('准确率:', classifier.score(X, y))
if __name__ == '__main__':
path = './data/data_multivar_imbalance.txt'
data = read_data(path)
X = data[:, 0:2]
y = data[:, 2]
print(data)
print(data.shape)
print(data[data[:, -1] == 1].shape[0]) # 数据为1000
print(data[data[:, -1] == 0].shape[0]) # 数据为200
# 根据上面的输出,我们发现数据出现了严重的倾斜
# 我们可以下采样 从标签为1的样本中抽取200进行训练
label_1 = data[data[:, -1] == 1]
label_1 = label_1[0: 200, :]
label_0 = data[data[:, -1] == 0]
# 然后将这两种标签的数据进行合并
data = np.concatenate((label_1, label_0))
data = shuffle(data) # 将数据进行打乱
X1 = data[:, 0:2]
y2 = data[:, 2]
model(X, y)
# 还有一种方法时给数据不同的权重 就是在模型训练的时候加一个参数class_weight
# 它的作用是统计不用类型的数量,调整权重,让模型不平衡问题不印象分类效果
model2(X, y)