个性化阅读
专注于IT技术分析

使用Scikit-learn的朴素贝叶斯分类

本文概述

假设你是产品经理, 则希望将客户评论分为正面和负面类别。或作为贷款经理, 你想确定哪些贷款申请人是安全或有风险的?作为一名医疗保健分析师, 你想预测哪些患者可能患有糖尿病。所有示例都存在相同的问题, 无法对评论, 贷款申请人和患者进行分类。

朴素贝叶斯是最直接, 最快速的分类算法, 适用于大量数据。朴素贝叶斯分类器已成功用于各种应用程序, 例如垃圾邮件过滤, 文本分类, 情感分析和推荐系统。它使用概率的贝叶斯定理预测未知类别。

在本教程中, 你将学习以下所有内容:

  • 分类工作流程
  • 什么是朴素贝叶斯分类器?
  • 朴素贝叶斯分类器如何工作?
  • Scikit-learn中的分类器构建
  • 零概率问题
  • 它的优缺点
使用Scikit-learn的朴素贝叶斯分类1

分类工作流程

每当执行分类时, 第一步就是了解问题并确定潜在功能和标签。特征是那些会影响标签结果的特征或属性。例如, 在发放贷款的情况下, 银行经理可以识别客户的职业, 收入, 年龄, 位置, 以前的贷款历史, 交易历史和信用评分。这些特征被称为有助于模型对客户进行分类的特征。

分类分为两个阶段, 学习阶段和评估阶段。在学习阶段, 分类器在给定的数据集上训练其模型, 在评估阶段, 它测试分类器的性能。根据各种参数(例如准确性, 错误, 准确性和召回率)评估性能。

使用Scikit-learn的朴素贝叶斯分类2

什么是朴素贝叶斯分类器?

朴素贝叶斯是基于贝叶斯定理的统计分类技术。它是最简单的监督学习算法之一。朴素贝叶斯分类器是快速, 准确和可靠的算法。朴素贝叶斯分类器在大型数据集上具有较高的准确性和速度。

朴素贝叶斯分类器假定类中特定功能的效果独立于其他功能。例如, 根据他/她的收入, 以前的贷款和交易历史, 年龄和位置, 是否需要贷款申请人。即使这些功能是相互依存的, 也仍然可以独立考虑这些功能。这个假设简化了计算, 这就是为什么它被认为是幼稚的原因。此假设称为类条件独立性。

使用Scikit-learn的朴素贝叶斯分类3
  • P(h):假设h为真的概率(与数据无关)。这称为h的先验概率。
  • P(D):数据的概率(与假设无关)。这称为先验概率。
  • P(h | D):给定数据D的假设h的概率。这称为后验概率。
  • P(D | h):在假设h为真的情况下数据d的概率。这称为后验概率。

朴素贝叶斯分类器如何工作?

让我们通过一个示例来了解朴素贝叶斯的工作方式。举例说明天气状况和参加体育运动。你需要计算参加体育运动的可能性。现在, 你需要根据天气情况对玩家是否参加比赛进行分类。

第一种方法(如果有单个功能)

朴素贝叶斯分类器通过以下步骤计算事件的概率:

  • 步骤1:计算给定类别标签的先验概率
  • 步骤2:找出每个类别的每个属性的可能性概率
  • 步骤3:将这些值放入贝叶斯公式并计算后验概率。
  • 步骤4:鉴于输入属于较高概率类别, 请查看哪个类别具有较高概率。

为了简化先验概率和后验概率计算, 你可以使用两个表频率和似然度表。这两个表都将帮助你计算先验概率和后验概率。频率表包含所有功能标签的出现。有两个似然表。可能性表1显示了标签的先验概率, 可能性表2显示了后验概率。

使用Scikit-learn的朴素贝叶斯分类4

现在假设你要计算天气阴天时的上场概率。

玩的可能性:

P(是|阴)= P(阴|是)P(是)/ P(阴)…………………(1)

  1. 计算先验概率:

    P(阴)= 4/14 = 0.29

    P(是)= 9/14 = 0.64

  1. 计算后验概率:

    P(阴暗|是)= 4/9 = 0.44

  1. 将先验和后验概率放在等式(1)中

    P(是|阴)= 0.44 * 0.64 / 0.29 = 0.98(更高)

同样, 你可以计算不玩的可能性:

不玩的可能性:

P(否|阴)= P(阴|否)P(否)/ P(阴)…………………(2)

  1. 计算先验概率:

    P(阴)= 4/14 = 0.29

    P(否)= 5/14 = 0.36

  1. 计算后验概率:

    P(阴|否)= 0/9 = 0

  1. 将先验和后验概率放在等式(2)中

    P(否|阴)= 0 * 0.36 / 0.29 = 0

回答”是”的可能性更高。因此, 你可以在此处确定天气是否阴天, 而不是运动员参加这项运动。

第二种方法(如果有多个功能)

使用Scikit-learn的朴素贝叶斯分类5

现在假设你要计算天气阴天和温度适中时的比赛概率。

玩的可能性:

P(播放=是|天气=阴, 温度=轻度)= P(天气=阴, 温度=轻度|播放=是)P(播放=是)…..(1)

P(天气=阴, 温度=轻微|播放=是)= P(阴|是)P(轻微|是)………..(2)

  1. 计算先验概率:P(是)= 9/14 = 0.64
  2. 计算后验概率:P(阴|是)= 4/9 = 0.44 P(轻度|是)= 4/9 = 0.44
  3. 将后验概率放在等式(2)中P(天气=阴, 温度=轻度|播放=是)= 0.44 * 0.44 = 0.1936(更高)
  4. 将先验概率和后验概率放在等式(1)中P(播放=是|天气=阴, 温度=轻度)= 0.1936 * 0.64 = 0.124

同样, 你可以计算不玩的可能性:

不玩的可能性:

P(播放=否|天气=阴, 温度=轻微)= P(天气=阴, 温度=轻微|播放=否)P(播放=否)…..(3)

P(天气=阴, 温度=轻微|播放=否)= P(天气=阴|播放=否)P(温度=轻微|播放=否)………..(4)

  1. 计算先验概率:P(No)= 5/14 = 0.36
  2. 计算后验概率:P(天气=阴|玩=否)= 0/9 = 0 0 P(临时=轻度|玩=否)= 2/5 = 0.4
  3. 将后验概率放在等式(4)中P(天气=阴, 温度=轻微|播放=否)= 0 * 0.4 = 0
  4. 将先验概率和后验概率放在等式(3)中P(播放=否|天气=阴, 温度=轻微)= 0 * 0.36 = 0

回答”是”的可能性更高。因此, 你可以在这里说, 如果天气阴天, 则运动员将参加这项运动。

Scikit-learn中的分类器构建

朴素贝叶斯分类器

定义数据集

在此示例中, 可以将虚拟数据集与三列一起使用:天气, 温度和游戏。前两个是要素(天气, 温度), 另一个是标签。

# Assigning features and label variables
weather=['Sunny', 'Sunny', 'Overcast', 'Rainy', 'Rainy', 'Rainy', 'Overcast', 'Sunny', 'Sunny', 'Rainy', 'Sunny', 'Overcast', 'Overcast', 'Rainy']
temp=['Hot', 'Hot', 'Hot', 'Mild', 'Cool', 'Cool', 'Cool', 'Mild', 'Cool', 'Mild', 'Mild', 'Mild', 'Hot', 'Mild']

play=['No', 'No', 'Yes', 'Yes', 'Yes', 'No', 'Yes', 'No', 'Yes', 'Yes', 'Yes', 'Yes', 'Yes', 'No']

编码功能

首先, 你需要将这些字符串标签转换为数字。例如:” Overcast”, ” Rainy”, ” Sunny”分别为0、1、2。这称为标签编码。 Scikit-learn提供LabelEncoder库, 用于对标签进行编码, 该标签的值比离散类的数量小0到1。

# Import LabelEncoder
from sklearn import preprocessing
#creating labelEncoder
le = preprocessing.LabelEncoder()
# Converting string labels into numbers.
wheather_encoded=le.fit_transform(wheather)
print wheather_encoded
[2 2 0 1 1 1 0 2 2 1 2 0 0 1]

同样, 你也可以编码temp和play列。

# Converting string labels into numbers
temp_encoded=le.fit_transform(temp)
label=le.fit_transform(play)
print "Temp:", temp_encoded
print "Play:", label
Temp: [1 1 1 2 0 0 0 2 0 2 2 2 1 2]
Play: [0 0 1 1 1 0 1 0 1 1 1 1 1 0]

现在, 将两个要素(天气和温度)组合到一个变量(元组列表)中。

#Combinig weather and temp into single listof tuples
features=zip(weather_encoded, temp_encoded)
print features
[(2, 1), (2, 1), (0, 1), (1, 2), (1, 0), (1, 0), (0, 0), (2, 2), (2, 0), (1, 2), (2, 2), (0, 2), (0, 1), (1, 2)]

产生模型

在以下步骤中使用朴素贝叶斯分类器生成模型:

  • 创建朴素贝叶斯分类器
  • 在分类器上拟合数据集
  • 执行预测
#Import Gaussian Naive Bayes model
from sklearn.naive_bayes import GaussianNB

#Create a Gaussian Classifier
model = GaussianNB()

# Train the model using the training sets
model.fit(features, label)

#Predict Output
predicted= model.predict([[0, 2]]) # 0:Overcast, 2:Mild
print "Predicted Value:", predicted
Predicted Value: [1]

在这里, 1表示玩家可以”玩”。

具有多个标签的朴素贝叶斯

到目前为止, 你已经了解了带有二进制标签的朴素贝叶斯分类。现在, 你将了解朴素贝叶斯中的多个类别分类。这被称为多项朴素贝叶斯分类。例如, 如果你想对有关技术, 娱乐, 政治或体育的新闻文章进行分类。

在模型构建部分, 你可以使用Wine数据集, 这是一个非常著名的多类别分类问题。 “该数据集是对意大利同一地区但来自三个不同品种的葡萄酒进行化学分析的结果。” (加州大学尔湾分校)

数据集包含13个特征(酒精, 苹果酸, 灰分, alcalinity_of_ash, 镁, 总酚, 黄酮类, 非黄酮酚, 原花青素, 颜色强度, 色调, od280 / od315_of_diluted_wines, 脯氨酸)和葡萄酒品种的类型。该数据具有三种类型的葡萄酒:Class_0, Class_1和Class_3。在这里, 你可以建立模型来对葡萄酒类型进行分类。

该数据集在scikit-learn库中可用。

加载数据中

让我们首先从scikit-learn数据集中加载所需的wine数据集。

#Import scikit-learn dataset library
from sklearn import datasets

#Load dataset
wine = datasets.load_wine()

探索数据

你可以打印目标名称和特征名称, 以确保你拥有正确的数据集, 例如:

# print the names of the 13 features
print "Features: ", wine.feature_names

# print the label type of wine(class_0, class_1, class_2)
print "Labels: ", wine.target_names
Features:  ['alcohol', 'malic_acid', 'ash', 'alcalinity_of_ash', 'magnesium', 'total_phenols', 'flavanoids', 'nonflavanoid_phenols', 'proanthocyanins', 'color_intensity', 'hue', 'od280/od315_of_diluted_wines', 'proline']
Labels:  ['class_0' 'class_1' 'class_2']

经常浏览一下数据是个好主意, 这样你就知道自己在使用什么。在这里, 你可以看到打印了数据集的前五行, 以及整个数据集的目标变量。

# print data(feature)shape
wine.data.shape
(178L, 13L)
# print the wine data features (top 5 records)
print wine.data[0:5]
[[  1.42300000e+01   1.71000000e+00   2.43000000e+00   1.56000000e+01
    1.27000000e+02   2.80000000e+00   3.06000000e+00   2.80000000e-01
    2.29000000e+00   5.64000000e+00   1.04000000e+00   3.92000000e+00
    1.06500000e+03]
 [  1.32000000e+01   1.78000000e+00   2.14000000e+00   1.12000000e+01
    1.00000000e+02   2.65000000e+00   2.76000000e+00   2.60000000e-01
    1.28000000e+00   4.38000000e+00   1.05000000e+00   3.40000000e+00
    1.05000000e+03]
 [  1.31600000e+01   2.36000000e+00   2.67000000e+00   1.86000000e+01
    1.01000000e+02   2.80000000e+00   3.24000000e+00   3.00000000e-01
    2.81000000e+00   5.68000000e+00   1.03000000e+00   3.17000000e+00
    1.18500000e+03]
 [  1.43700000e+01   1.95000000e+00   2.50000000e+00   1.68000000e+01
    1.13000000e+02   3.85000000e+00   3.49000000e+00   2.40000000e-01
    2.18000000e+00   7.80000000e+00   8.60000000e-01   3.45000000e+00
    1.48000000e+03]
 [  1.32400000e+01   2.59000000e+00   2.87000000e+00   2.10000000e+01
    1.18000000e+02   2.80000000e+00   2.69000000e+00   3.90000000e-01
    1.82000000e+00   4.32000000e+00   1.04000000e+00   2.93000000e+00
    7.35000000e+02]]
# print the wine labels (0:Class_0, 1:class_2, 2:class_2)
print wine.target
[0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1
 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2
 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2]

分割数据

首先, 将列分为因变量和自变量(或功能和标签)。然后将这些变量拆分为训练集和测试集。

使用Scikit-learn的朴素贝叶斯分类6
# Import train_test_split function
from sklearn.cross_validation import train_test_split

# Split dataset into training set and test set
X_train, X_test, y_train, y_test = train_test_split(wine.data, wine.target, test_size=0.3, random_state=109) # 70% training and 30% test

模型生成

分割后, 你将在训练集上生成随机森林模型, 并对测试集特征执行预测。

#Import Gaussian Naive Bayes model
from sklearn.naive_bayes import GaussianNB

#Create a Gaussian Classifier
gnb = GaussianNB()

#Train the model using the training sets
gnb.fit(X_train, y_train)

#Predict the response for test dataset
y_pred = gnb.predict(X_test)

评估模型

生成模型后, 使用实际值和预测值检查准确性。

#Import scikit-learn metrics module for accuracy calculation
from sklearn import metrics

# Model Accuracy, how often is the classifier correct?
print("Accuracy:", metrics.accuracy_score(y_test, y_pred))
('Accuracy:', 0.90740740740740744)

零概率问题

假设数据集中没有元组用于风险贷款, 在这种情况下, 后验概率将为零, 并且该模型无法进行预测。这个问题被称为零概率, 因为特定类的出现为零。

解决此问题的方法是拉普拉斯校正或拉普拉斯变换。拉普拉斯校正是平滑技术之一。在这里, 你可以假设数据集足够大, 以至于每个类别添加一行都不会对估计的概率产生影响。这将克服将概率值设为零的问题。

例如:假设对于有贷款风险的类, 数据库中有1000个训练元组。在此数据库中, “收入”列具有低收入的0个元组, 中等收入的990个元组和高收入的10个元组。如果不使用Laplacian校正, 则这些事件的概率分别为0、0.990(从990/1000起)和0.010(从10/1000起)

现在, 在给定的数据集上应用拉普拉斯校正。让我们为每个收入值对再增加1个元组。这些事件的可能性:

使用Scikit-learn的朴素贝叶斯分类7

优点

  • 它不仅是一种简单的方法, 而且还是一种快速而准确的预测方法。
  • 朴素贝叶斯的计算成本非常低。
  • 它可以有效地处理大型数据集。
  • 与连续变量相比, 它在离散响应变量的情况下表现良好。
  • 它可以与多个类别预测问题一起使用。
  • 在文本分析问题的情况下, 它也表现良好。
  • 当独立性的假设成立时, 朴素贝叶斯分类器比其他模型(如逻辑回归)表现更好。

缺点

  • 独立功能的假设。实际上, 模型几乎不可能获得一组完全独立的预测变量。
  • 如果没有特定类别的训练元组, 则后验概率为零。在这种情况下, 模型无法做出预测。此问题称为零概率/频率问题。

总结

恭喜, 你已完成本教程的结尾!

在本教程中, 你了解了朴素贝叶斯算法, 它的工作原理, 朴素贝叶斯假设, 问题, 实现, 优缺点。在这条路上, 你还通过scikit-learn学习了二进制和多项式类的模型构建和评估。

朴素贝叶斯是最简单, 最有效的算法。尽管最近几年机器学习取得了长足的进步, 但它已经证明了它的价值。它已经成功地部署在从文本分析到推荐引擎的许多应用程序中。

我期待听到任何反馈或问题。你可以通过发表评论来提出问题, 我会尽力回答。

如果你想了解有关使用Python的scikit-learn的更多信息, 请参加srcmini的scikit-learn监督学习课程。

赞(0)
未经允许不得转载:srcmini » 使用Scikit-learn的朴素贝叶斯分类

评论 抢沙发

评论前必须登录!