机器学习系列:(四)从线性回归到逻辑回归---续篇

欢迎小伙伴们回来继续学习,本篇内容是连着上一篇

“机器学习系列:(四)从线性回归到逻辑回归”文章。

多类分类

现实中有很多问题不只是分成两类,许多问题都需要分成多个类,成为多类分类问题(Multi-class classification)。比如听到一首歌的样曲之后,可以将其归入某一种音乐风格。这类风格就有许多种。scikit-learn用one-vs.-all或one-vs.-the-rest方法实现多类分类,就是把多类中的每个类都作为二元分类处理。分类器预测样本不同类型,将具有最大置信水平的类型作为样本类型。LogisticRegression()通过one-vs.-all策略支持多类分类。下面,我们用它来分析一个多类分类问题。

假设你想看电影,而你又非常讨厌看太次的电影。所以有品位的你可以在看每部电影之前都会看一堆影评,不过你更讨厌看影评。那么下面我们就用好影评来给电影分类。

本例中,我们利用烂番茄(Rotten Tomatoes)网站影评短语数据对电影进行评价。每个影评可以归入下面5个类项:不给力(negative),不太给力(somewhat negative),中等(neutral),有点给力(somewhat positive), 给力(positive)。解释变量不会总是直白的语言,因为影评内容千差万别,有讽刺的,否定的,以及其他语义的表述,语义并不直白,这些都会让分类充满挑战。数据集可以从kaggle上下载。首先,我们还是用Pandas简单探索一下:

import zipfile# 压缩节省空间z = zipfile.ZipFile('mlslpic/train.zip')df = pd.read_csv(z.open(z.namelist()[0]), header=0, delimiter='\t')
df.head()

Out[30]:

PhraseId

SentenceId

Phrase

Sentiment

0

1

1

A series of escapades demonstrating the adage ...

1

1

2

1

A series of escapades demonstrating the adage ...

2

2

3

1

A series

2

3

4

1

A

2

4

5

1

series

2

df.count()

Out[31]:

PhraseId      156060
SentenceId    156060
Phrase        156060
Sentiment     156060
dtype: int64

Sentiment是响应变量,0是不给力(negative),4是给力(positive),其他以此类推。Phrase列是影评的内容。影评中每句话都被分割成一行。我们不需要考虑PhraseId列和SentenceId列。

df.Phrase.head(10)

Out[32]:

0    A series of escapades demonstrating the adage ...
1    A series of escapades demonstrating the adage ...
2                                             A series
3                                                    A
4                                               series
5    of escapades demonstrating the adage that what...
6                                                   of
7    escapades demonstrating the adage that what is...
8                                            escapades
9    demonstrating the adage that what is good for ...
Name: Phrase, dtype: object
df.Sentiment.describe()

Out[33]:

count    156060.000000
mean          2.063578
std           0.893832
min           0.000000
25%           2.000000
50%           2.000000
75%           3.000000
max           4.000000
Name: Sentiment, dtype: float64
df.Sentiment.value_counts()

Out[34]:

2    79582
3    32927
1    27273
4     9206
0     7072
dtype: int64
df.Sentiment.value_counts()/df.Sentiment.count()

Out[35]:

2    0.509945
3    0.210989
1    0.174760
4    0.058990
0    0.045316
dtype: float64

可以看出,近51%都是评价为2中等(neutral)的电影。可见,在这个问题里,准确率不是一个有信息量的评价指标,因为即使很烂的分类器预测出中等水平的结果,其准确率也是51%。3有点给力(somewhat positive)的电影占21%, 4给力(positive)的电影占6%,共占27%。剩下的21%就是不给力(negative),不太给力(somewhat negative)的电影。用scikit-learn来训练分类器:

import pandas as pdfrom sklearn.feature_extraction.text import TfidfVectorizerfrom sklearn.linear_model.logistic import LogisticRegressionfrom sklearn.cross_validation import train_test_splitfrom sklearn.metrics import classification_report, accuracy_score, confusion_matrixfrom sklearn.pipeline import Pipelinefrom sklearn.grid_search import GridSearchCVimport zipfilepipeline = Pipeline([
    ('vect', TfidfVectorizer(stop_words='english')),
    ('clf', LogisticRegression())])parameters = {
    'vect__max_df': (0.25, 0.5),
    'vect__ngram_range': ((1, 1), (1, 2)),
    'vect__use_idf': (True, False),
    'clf__C': (0.1, 1, 10),}z = zipfile.ZipFile('mlslpic/train.zip')df = pd.read_csv(z.open(z.namelist()[0]), header=0, delimiter='\t')X, y = df['Phrase'], df['Sentiment'].as_matrix()X_train, X_test, y_train, y_test = train_test_split(X, y, train_size=0.5)grid_search = GridSearchCV(pipeline, parameters, n_jobs=3, verbose=1, scoring='accuracy')grid_search.fit(X_train, y_train)print('最佳效果:%0.3f' % grid_search.best_score_)print('最优参数组合:')best_parameters = grid_search.best_estimator_.get_params()for param_name in sorted(parameters.keys()):
    print('\t%s: %r' % (param_name, best_parameters[param_name]))
[Parallel(n_jobs=3)]: Done   1 jobs       | elapsed:    4.6s
[Parallel(n_jobs=3)]: Done  50 jobs       | elapsed:  1.8min
[Parallel(n_jobs=3)]: Done  68 out of  72 | elapsed:  3.0min remaining:   10.6s
[Parallel(n_jobs=3)]: Done  72 out of  72 | elapsed:  3.3min finished
Fitting 3 folds for each of 24 candidates, totalling 72 fits
最佳效果:0.620
最优参数组合:
	clf__C: 10
	vect__max_df: 0.25
	vect__ngram_range: (1, 2)
	vect__use_idf: False

多类分类效果评估

二元分类里,混淆矩阵可以用来可视化不同分类错误的数据。每种类型的精确率,召回率和综合评价指标(F1 score)可以计算,所有预测的准确率也可以计算。

predictions = grid_search.predict(X_test)print('准确率:', accuracy_score(y_test, predictions))print('混淆矩阵:', confusion_matrix(y_test, predictions))print('分类报告:', classification_report(y_test, predictions))
准确率: 0.635024990388
混淆矩阵: [[ 1178  1701   616    71     4]
 [  990  5993  6030   563    30]
 [  227  3231 32668  3520   143]
 [   37   401  6642  8089  1305]
 [    7    30   534  2397  1623]]
分类报告:              precision    recall  f1-score   support

          0       0.48      0.33      0.39      3570
          1       0.53      0.44      0.48     13606
          2       0.70      0.82      0.76     39789
          3       0.55      0.49      0.52     16474
          4       0.52      0.35      0.42      4591

avg / total       0.62      0.64      0.62     78030

我们通过网格搜索获得了最佳参数组合,最终的分类器是通过对开始的分类器不断优化得到的。

多标签分类和问题转换

前面我们讨论了二元分类,多类分类,还有一种分类问题是多标签分类(multi-label classification)。每个样本可以拥有全部类型的一部分类型。这样的例子太普遍了,比如统计班上同学一周7天里哪天有空。每个同学都会在周一到周日这7天里,根据自己的情况分别打勾。再比如常见的博客文章分类标签,一篇文章一般都有好几个标签等等。多标签分类问题一般有两种解决方法。

问题转化方法(Problem transformation)可以将多标签问题转化成单标签问题。 第一种转换方法是训练集里面每个样本通过幂运算转换成单标签。比如下面数据里面每篇文章都带有若干标签。

转换方法就是用幂运算将多个类合并成一个类,比如样本1有LocalUS类,新建一个标签为Local^US类,这样多标签就变成单标签了。

这样原来5个标签现在变成了7个标签。这种幂运算虽然直观,但是并不实用,因为这样做多出来的标签只有一小部分样本会用到。而且,这些标签只能在训练集里面学习这些类似,在测试集中依然无法使用。

另外一种问题转换方法就是每个标签都用二元分类处理。每个标签的分类器都预测样本是否属于该标签。我们的例子中需要5个二元分类器,第一个分类器预测样本是否应该被归入Local类,第二个分类器预测样本是否应该被归入US类,以此类推。预测最后一步就是把这些分类结果求并集,如下图所示。这个问题确保了单标签问题和多标签问题有同样的训练集,只是忽略了标签之间的关联关系。

多标签分类效果评估

多标签分类效果评估与多标签分类效果评估方式不同。最常用的手段是汉明损失函数(Hamming loss)和杰卡德相似度(Jaccard similarity)。汉明损失函数表示错误标签的平均比例,是一个函数,当预测全部正确,即没有错误标签时,值为0。杰卡德相似度或杰卡德相指数(Jaccard index),是预测标签和真实标签的交集数量除以预测标签和真实标签的并集数量。其值在{0,1}之间,公式如下:

import numpy as npfrom sklearn.metrics import hamming_loss, jaccard_similarity_scoreprint(hamming_loss(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[0.0, 1.0], [1.0, 1.0]])))print(hamming_loss(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [1.0, 1.0]])))print(hamming_loss(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [0.0, 1.0]])))print(jaccard_similarity_score(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[0.0, 1.0], [1.0, 1.0]])))print(jaccard_similarity_score(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [1.0, 1.0]])))print(jaccard_similarity_score(np.array([[0.0, 1.0], [1.0, 1.0]]), np.array([[1.0, 1.0], [0.0, 1.0]])))
0.0
0.25
0.5
1.0
0.75
0.5

总结

本章我们介绍了广义线性模型,是对普通线性回归中解释变量非正态分布情况的扩展。广义线性回归模型通过联接方程将解释变量和响应变量联接起来,和普通线性回归不同,这个方程可能是非线性的。我们重点介绍了逻辑联接方程,其图象是一种S曲线,对任意实数的返回值都在在{0,1}之间,如群体生长曲线。

之后,我们介绍了逻辑回归,一种通过逻辑联接方程联接解释变量与呈伯努力分布的响应变量的关系。逻辑回归可用于解决二元分类问题,我们用它研究了典型的垃圾短信分类问题。紧接着我们介绍了多类分类问题,其类型空间超过两个,每个样本都有且仅有一种类型,我们用one-vs.-all策略研究了通过影评对电影分类的问题。最后,我们介绍了多标签分类,其类型空间超过两个,每个样本都有至少一种标签。介绍完广义线性模型的回归和分类问题,下一章我们就来介绍非线性模型的回归和分类问题——决策树。

博主简介:风雪夜归子(英文名: Allen),机器学习算法攻城狮,喜爱钻研Machine Learning的黑科技,对Deep Learning和Artificial Intelligence充满兴趣,经常关注kaggle数据挖掘竞赛平台,对数据、Machine Learning和Artificial Intelligence有兴趣的各位童鞋可以一起探讨哦

原文发布于微信公众号 - PPV课数据科学社区(ppvke123)

原文发表时间:2016-07-20

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏机器之心

四天速成!香港科技大学 PyTorch 课件分享

机器之心整理 参与:黄小天、蒋思源 前天,香港科技大学计算机系教授 Sung Kim 在 Google Drive 分享了一个 3 天速成的 TensorFlo...

449100
来自专栏AI研习社

谷歌工程师:聊一聊深度学习的weight initialization

编者按:本文作者夏飞,清华大学计算机软件学士,卡内基梅隆大学人工智能硕士。现为谷歌软件工程师。作者授权雷锋网 AI 研习社发布。 ? █ TLDR (or th...

32750
来自专栏大数据挖掘DT机器学习

R语言与点估计学习笔记(EM算法与Bootstrap法)

众所周知,R语言是个不错的统计软件。今天分享一下利用R语言做点估计的内容。主要有:矩估计、极大似然估计、EM算法、最小二乘估计、刀切法(Jackknife)、自...

406100
来自专栏素质云笔记

DBSCAN聚类︱scikit-learn中一种基于密度的聚类方式

一、DBSCAN聚类概述 基于密度的方法的特点是不依赖于距离,而是依赖于密度,从而克服基于距离的算法只能发现“球形”聚簇的缺点。 DBSCAN的核心思想是从...

80980
来自专栏AI2ML人工智能to机器学习

最小二乘法的6个假设 (中篇)

继续 上篇 里面讨论了最小二乘法的2个最基本假设:参数线性,矩阵满秩有解(多重共线性)。 下面继续讨论其余4个假设。

18430
来自专栏AI2ML人工智能to机器学习

矩阵分解 (乘法篇)

前面我们在矩阵分解 (加法篇)里面分析的加法下的矩阵分解。 这里我们来看看乘法下矩阵分解的要点。

16510
来自专栏IT派

【无监督学习】DBSCAN聚类算法原理介绍,以及代码实现

主要包括:K-means、DBSCAN、Density Peaks聚类(局部密度聚类)、层次聚类、谱聚类。

18840
来自专栏机器之心

教程 | 无监督学习中的两个非概率模型:稀疏编码与自编码器

机器之心整理 作者:Ruslan Salakhutdinov 参与:Smith 「无监督学习」(Unsupervised Learning)现在已经成为深度学习...

35970
来自专栏AI研习社

如何使用 Keras 实现无监督聚类

由于深度学习算法在表达非线性表征上的卓越能力,它非常适合完成输入到有标签的数据集输出的映射。这种任务叫做分类。它需要有人对数据进行标注。无论是对 X 光图像还是...

60620
来自专栏程序生活

CS224n 笔记2-词向量表示:Word2vec1. 单词含义的表示2. Word2Vec的主要思路3. 更多Word2Vec细节4 .梯度的推导5. 损失/目标函数相关推荐阅读

1. 单词含义的表示 我们如何表示一个单词的意思 下面是意思的定义: 用词语,语句表示的想法或观点 人们使用词汇,符号来表达的想法 在一篇文章和艺术品表达的观点...

45180

扫码关注云+社区

领取腾讯云代金券