提交 4e0b4dea 编写于 作者: W wizardforcel

6.20

上级 f960cfdb
......@@ -951,4 +951,199 @@ avg / total 0.66 0.62 0.59 3728
```py
>>> (ll_0 > ll_1).mean()
0.15588673621460505
```
\ No newline at end of file
```
## 4.9 使用随机梯度下降来分类
我们在第二章中讨论过,随机梯度下降是个用于训练分类模型的基本技巧。这两种技巧之间有一些自然联系,因为名称就暗示了这一点。
### 准备
在回归中,我们最小化了损失函数,它用于惩罚连续刻度上的不良选择。但是对于分类,我们会最小化损失函数,它用于乘法两个或更多情况。
### 操作步骤
首先,让我们创建一些基本数据:
```py
>>> from sklearn import datasets
>>> X, y = datasets.make_classification()
```
然后创建`SGDClassifier`实例:
```py
>>> from sklearn import linear_model
>>> sgd_clf = linear_model.SGDClassifier()
```
像往常一样,我们训练模型:
```py
>>> sgd_clf.fit(X, y)
SGDClassifier(alpha=0.0001, class_weight=None, epsilon=0.1, eta0=0.0,
fit_intercept=True, l1_ratio=0.15,
learning_rate='optimal', loss='hinge', n_iter=5,
n_jobs=1, penalty='l2', power_t=0.5,
random_state=None,
shuffle=False, verbose=0, warm_start=False)
```
我们可以设置`class_weight`参数来统计数据集中不平衡的变化总数。
Hinge 损失函数定义为:
```
max(0, 1 - ty)
```
这里,`t`是真正分类,+1 为一种情况,-1 为另一种情况。系数向量记为`y`,因为它是从模型中拟合出来的。`x`是感兴趣的值。这也是一种很好的度量方式。以另外一种形式表述:
```
t ∈ -1, 1
y = βx + b
```
## 4.10 使用朴素贝叶斯来分类数据
朴素分页四是个非常有意思的模型。它类似于 KNN,做了一些假设来简化事实,但是仍然在许多情况下都很好。
### 准备
这个秘籍中,我们会使用朴素贝叶斯来分类文档。我拥有个人经验的一个示例就是,使用会计学中的组成账户描述符的单词,例如应付账款,来判断它属于利润表、现金流转表、还是资产负债表。
基本理念是使用来自带标签的测试语料库中的词频,来学习文档的分类。之后,我们可以将其用在训练集上来尝试预测标签。
我们使用 Sklearn 中的`newgroups `数据集来玩转朴素贝叶斯模型。这是有价值的一组数据,所以我们抓取它而不是加载它。我们也将分类限制为`rec.autos ``rec.motorcycles`
```py
>>> from sklearn.datasets import fetch_20newsgroups
>>> categories = ["rec.autos", "rec.motorcycles"]
>>> newgroups = fetch_20newsgroups(categories=categories)
#take a look
>>> print "\n".join(newgroups.data[:1])
From: gregl@zimmer.CSUFresno.EDU (Greg Lewis)
Subject: Re: WARNING.....(please read)...
Keywords: BRICK, TRUCK, DANGER
Nntp-Posting-Host: zimmer.csufresno.edu
Organization: CSU Fresno
Lines: 33
[]
>>> newgroups.target_names[newgroups.target[:1]]
'rec.autos'
```
既然我们拥有了`newgroups`,我们需要将每个文档表示为词频向量。这个表示就是朴素贝叶斯名称的来历。模型是“朴素”的,不按照任何文档间的单词协方差,来对文档进行分类。这可以认为是可以缺陷,但是朴素贝叶斯已经被证实相当可靠。
我们需要将数据处理为词频矩阵。这是个稀疏矩阵,当某个单词出现在文档中时,这个单词就有条目。这个矩阵可能非常大,就像这样:
```py
>>> from sklearn.feature_extraction.text import CountVectorizer
>>> count_vec = CountVectorizer()
>>> bow = count_vec.fit_transform(newgroups.data
```
这个矩阵是个稀疏矩阵,它的长度是文档数量乘以不同单词的数量。它的值是每个文档中每个单词的频率。
```py
>>> bow <1192x19177 sparse matrix of type '<type 'numpy.int64'>'
with 164296 stored elements in Compressed Sparse Row format>
```
我们实际上需要将矩阵表示为密集数组,用于朴素贝叶斯对象。所以,让我们将其转换回来。
```py
>>> bow = np.array(bow.todense())
```
显然,多数元素都是 0,但是我们可能打算重构文档的统计,作为合理性检查。
```py
>>> words = np.array(count_vec.get_feature_names())
>>> words[bow[0] > 0][:5]
array([u'10pm', u'1qh336innfl5', u'33', u'93740',
u'___________________________________________________________________'],
dtype='<U79')
```
现在,这些就是第一个文档的示例了?让我们使用下面的命令:
```py
>>> '10pm' in newgroups.data[0].lower()
True
>>> '1qh336innfl5' in newgroups.data[0].lower()
True
```
### 操作步骤
好的,所以需要比平常更多的时间来准备数据,因为我们处理的文本数据,并不是能够像之前的矩阵那样快速表示。
但是,既然我们准备好了,我们启动分类器来训练我们的模型。
```py
>>> from sklearn import naive_bayes
>>> clf = naive_bayes.GaussianNB()
```
在我们训练模型之前,让我们将数据集划分为训练集和测试集。
```py
>>> mask = np.random.choice([True, False], len(bow))
>>> clf.fit(bow[mask], newgroups.target[mask])
>>> predictions = clf.predict(bow[~mask])
```
既然我们在训练集训练了模型,之后预测测试集来尝试判断文章属于哪个分类,让我们获取准确率。
```py
>>> np.mean(predictions == newgroups.target[~mask])
0.92446043165467628
```
### 工作原理
朴素贝叶斯的基本原理,就是我们可以根据特征向量,来估计数据点属于分类的概率(`P(Ci|X)`)。
这可以使用贝叶斯定期来变形,来变成特征向量的后验概率(`P(X|Ci)`)。如果特征向量的概率最大,那么后延估计就选择这个分类。
### 更多
我们也可以将朴素贝叶斯扩展来执行多类分类。我们不适用高斯可能性,而是使用多项式可能性。
首先,让我们获取第三个分类:
```py
>>> from sklearn.datasets import fetch_20newsgroups
>>> mn_categories = ["rec.autos", "rec.motorcycles",
"talk.politics.guns"]
>>> mn_newgroups = fetch_20newsgroups(categories=mn_categories)
```
我们需要将这些东西向量化。
```py
>>> mn_bow = count_vec.fit_transform(mn_newgroups.data)
>>> mn_bow = np.array(mn_bow.todense())
```
让我们创建为训练集和测试集创建一个屏蔽数组。
```py
>>> mn_mask = np.random.choice([True, False], len(mn_newgroups.data))
>>> multinom = naive_bayes.MultinomialNB()
>>> multinom.fit(mn_bow[mn_mask], mn_newgroups.target[mn_mask])
>>> mn_predict = multinom.predict(mn_bow[~mn_mask])
>>> np.mean(mn_predict == mn_newgroups.target[~mn_mask]) 0.96594778660612934
```
我们做的很好,完全不会惊讶。我们在两个分类的情况下表现不错,由于`talk.politics.guns`分类和其它两个正交,我们应该也表现不错。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册