【火炉炼AI】机器学习009-用逻辑回归分类器解决多分类问题

【火炉炼AI】机器学习009-用逻辑回归分类器解决多分类问题

(本文所使用的Python库和版本号: Python 3.5, Numpy 1.14, scikit-learn 0.19, matplotlib 2.2 )git

前面的【火炉炼AI】机器学习008已经讲解了用简单线性分类器解决二分类问题,可是对于多分类问题,咱们该怎么办了?github

此处介绍一种用于解决多分类问题的分类器:逻辑回归。虽然名称中含有回归二字,但逻辑回归不只能够用来作回归分析,也能够用来作分类问题。逻辑回归是机器学习领域比较经常使用的算法,用于估计样本所属类别的可能性,关于逻辑回归的更深层次的公式推导,能够参看https://blog.csdn.net/devotion987/article/details/78343834。算法


1. 准备数据集

此处咱们本身构建了一些简单的数据样本做为数据集,首先咱们要分析该数据集,作到对数据集的特性了然如胸。数组

# 首先准备数据集
# 特征向量
X =np.array([[4, 7], [3.5, 8], [3.1, 6.2], [0.5, 1], [1, 2],
             [1.2, 1.9], [6, 2], [5.7, 1.5], [5.4, 2.2]]) # 自定义的数据集
# 标记
y = np.array([0, 0, 0, 1, 1, 1, 2, 2, 2]) # 三个类别

# 按照类别将数据点画到散点图中
class_0=np.array([feature for (feature,label) in zip(X,y) if label==0])
# print(class_0) # 确保没有问题
class_1=np.array([feature for (feature,label) in zip(X,y) if label==1])
# print(class_1)
class_2=np.array([feature for (feature,label) in zip(X,y) if label==2])
# print(class_2)

# 绘图
plt.figure()
plt.scatter(class_0[:,0],class_0[:,1],marker='s',label='class_0')
plt.scatter(class_1[:,0],class_1[:,1],marker='x',label='class_1')
plt.scatter(class_2[:,0],class_2[:,1],marker='o',label='class_2')
plt.legend()
复制代码

简单数据集的分布状况

########################小**********结###############################dom

1,经过将数据集的y label能够看出,整个数据集有三个类别,每一个类别的数据点都汇集到一块,这个能够从散点图中看出,故而此处是典型的多分类问题。机器学习

2,此处数据集的样本数比较少(每一个类别三个样本),且特征向量只有两个,而且从散点图中能够看出,数据集各个类别都区分的比较开,故而相对比较容易分类。函数

#################################################################post


2. 构建逻辑回归分类器

逻辑回归分类器的构建很是简单,以下代码所示,首先咱们用该分类器的默认参数作一下分类试试。学习

# 构建逻辑回归分类器
from sklearn.linear_model import LogisticRegression
classifier = LogisticRegression(random_state=37) # 先用默认的参数
classifier.fit(X, y) # 对国际回归分类器进行训练
复制代码

虽然此处咱们构建了逻辑回归分类器, 而且用咱们的数据集进行了训练,但训练的效果该怎么查看了?此时咱们也没有测试集,因此暂时的,咱们将该分类器在训练集上的分类效果画到图中,给出一个直观的分类效果。为了在图中看到分类效果,须要定义一个专门绘制分类器效果展现的函数,以下。测试

# 将分类器绘制到图中
def plot_classifier(classifier, X, y):
    x_min, x_max = min(X[:, 0]) - 1.0, max(X[:, 0]) + 1.0 # 计算图中坐标的范围
    y_min, y_max = min(X[:, 1]) - 1.0, max(X[:, 1]) + 1.0
    step_size = 0.01 # 设置step size
    x_values, y_values = np.meshgrid(np.arange(x_min, x_max, step_size), np.arange(y_min, y_max, step_size))
    # 构建网格数据
    mesh_output = classifier.predict(np.c_[x_values.ravel(), y_values.ravel()])
    mesh_output = mesh_output.reshape(x_values.shape) 
    plt.figure()
    plt.pcolormesh(x_values, y_values, mesh_output, cmap=plt.cm.gray)
    plt.scatter(X[:, 0], X[:, 1], c=y, s=80, edgecolors='black', linewidth=1, cmap=plt.cm.Paired)
    # specify the boundaries of the figure
    plt.xlim(x_values.min(), x_values.max())
    plt.ylim(y_values.min(), y_values.max())

    # specify the ticks on the X and Y axes
    plt.xticks((np.arange(int(min(X[:, 0])-1), int(max(X[:, 0])+1), 1.0)))
    plt.yticks((np.arange(int(min(X[:, 1])-1), int(max(X[:, 1])+1), 1.0)))

    plt.show()
复制代码

而后直接调用该绘图函数,查看该逻辑回归分类器在训练集上的分类效果。

plot_classifier(classifier, X, y)
复制代码

逻辑回归分类器的分类效果

########################小**********结###############################

1,使用sklearn模块中的LogisticRegression函数能够轻松的定义和训练一个逻辑回归分类器模型。

2,因为此处采用分类器的默认参数,而不是最适合参数,故而获得的分类效果并非最佳,好比从图中能够看出,虽然该分类模型可以将三个类别区分开来,可是其模型明显还能够继续优化。

#################################################################


3. 对分类模型的优化

逻辑回归分类器有两个最重要的参数:solver和C,其中参数solver用于设置求解系统方程的算法类型,参数C表示对分类错误的惩罚值,故而C越大,代表该模型对分类错误的惩罚越大,即越不能接受分类发生错误。

此处,做为抛砖引玉,能够优化C值对分类效果的影响,以下,咱们随机选择几种C值,而后将分类结果图画出来,凭借直观感觉来判断哪个比较好。固然,更科学的作法是,使用测试集结合各类评估指标来综合评价那个参数组合下的模型最好。

# 优化模型中的参数C
for c in [1,5,20,50,100,200,500]:
    classifier = LogisticRegression(C=c,random_state=37)
    classifier.fit(X, y)
    plot_classifier(classifier, X, y)
# 貌似C越多,分类的效果越好。
复制代码

C=5时逻辑回归分类器的分类效果

C=100时逻辑回归分类器的分类效果

C=500时逻辑回归分类器的分类效果

########################小**********结###############################

1,对模型进行优化是一项体力活,也是最能考验机器学习技术功底的工做,此处做为抛砖引玉,咱们仅仅优化了逻辑回归分类器的一个参数。

2,逻辑回归分类器的C值越大,获得的分类器模型就越在两个数据集中间区分开来,这也符合咱们的预期,那么,是否有必要在一开始时就设置很是大的C值?

#################################################################


注:本部分代码已经所有上传到(个人github)上,欢迎下载。

参考资料:

1, Python机器学习经典实例,Prateek Joshi著,陶俊杰,陈小莉译

相关文章
相关标签/搜索