主要讲以下两种方法:

方法一:当数据出现严重倾斜的时候,我们可以采取降采样的方式

方法二:在训练模型中添加参数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)