上次去深圳招行面试。被问到了这个。中间讨论了几个关于贝叶斯的问题。可能我并不偏向知识图谱。然后就没有下文了。

结合李航的《统计学》和几篇博客,还有在凤凰网某位仁兄贡献新闻分类的源码。给自己复习一下。

 

为什么叫朴素贝叶斯和大学课本里的贝叶斯有什么不同?

朴素一词来源于==>假设各特征之间相互独立。这一假设使得朴素贝叶斯算法变得简单,但有时会牺牲一定的分类准确率。

招行的那位小姐姐有先验。说的就是这个。

大学里面的贝叶斯

朴素贝叶斯原理和应用

算法使用的朴素贝叶斯(怎么我感觉叫条件特征独立贝叶斯更好呢):

条件独立假设:

朴素贝叶斯原理和应用

就是说分类特征在类确定的条件下都是独立的。

朴素贝叶斯分类时,对于给定输出的x,通过学习得到的模型计算后验概率分布p(Y=ck|X=x),将后验概率最大的类作为x的类输出,后验概率计算根据贝叶斯定理进行:

朴素贝叶斯原理和应用

把特征独立条件带入上面公式:

朴素贝叶斯原理和应用

 

 所以贝叶斯分类器可以表示为:

朴素贝叶斯原理和应用

因为分母对于所有的K都是相同的,公式可以简化为

朴素贝叶斯原理和应用

 

朴素贝叶斯法的参数估计

学习就意味着估计,使用极大似然估计法估计相应的概率。

朴素贝叶斯原理和应用

先验概率的极大似然估计是

 朴素贝叶斯原理和应用

条件概率的极大似然估计是

朴素贝叶斯原理和应用

 

 朴素贝叶斯原理和应用

 

朴素贝叶斯的优缺点

优点:

  (1) 算法逻辑简单,易于实现(算法思路很简单,只要使用贝叶斯公式转化即可!)
(2)分类过程中时空开销小(假设特征相互独立,只会涉及到二维存储)
缺点:
      朴素贝叶斯假设属性之间相互独立,这种假设在实际过程中往往是不成立的。在属性之间相关性越大,分类误差也就越大。

朴素贝叶斯实战

    sklearn中有3种不同类型的朴素贝叶斯:

  高斯分布型:用于classification问题,假定属性/特征服从正态分布的。
  多项式型:用于离散值模型里。比如文本分类问题里面我们提到过,我们不光看词语是否在文本中出现,也得看出现次数。如果总词数为n,出现词数为m的话,有点像掷骰子n次出现m次这个词的场景。
  伯努利型:最后得到的特征只有0(没出现)和1(出现过)。


莺尾花Demo

 https://scikit-learn.org/stable/modules/generated/sklearn.model_selection.cross_val_score.html 

 

from sklearn.naive_bayes import GaussianNB
from sklearn.model_selection import cross_val_score
from sklearn import datasets
iris = datasets.load_iris()
gnb = GaussianNB()
scores=cross_val_score(gnb, iris.data, iris.target, cv=10)

print(scores)
[ 0.93333333  0.93333333  1.          0.93333333  0.93333333  0.93333333
  0.86666667  1.          1.          1.        ]
kaggle比赛中旧金山犯罪

1.数据观察
import pandas as pd  
import numpy as np  
from sklearn import preprocessing  
from sklearn.metrics import log_loss  
from sklearn.cross_validation import train_test_split
train = pd.read_csv('train.csv', parse_dates = ['Dates'])  
test = pd.read_csv('test.csv', parse_dates = ['Dates'])
train

特征为

Date: 日期
Category: 犯罪类型,比如 Larceny/盗窃罪 等.
Descript: 对于犯罪更详细的描述
DayOfWeek: 星期几
PdDistrict: 所属警区
Resolution: 处理结果『逮捕』『逃了』
Address: 发生街区位置
X and Y: GPS坐标
朴素贝叶斯原理和应用

 

2.特征处理

sklearn.preprocessing模块中的 LabelEncoder函数可以对类别做编号,我们用它对犯罪类型做编号;

pandas中的get_dummies( )可以将变量进行二值化01向量,我们用它对”街区“、”星期几“、”时间点“进行因子化。

#对犯罪类别:Category; 用LabelEncoder进行编号  
leCrime = preprocessing.LabelEncoder()  
crime = leCrime.fit_transform(train.Category)   #39种犯罪类型  
#用get_dummies因子化星期几、街区、小时等特征  
days=pd.get_dummies(train.DayOfWeek)  
district = pd.get_dummies(train.PdDistrict)  
hour = train.Dates.dt.hour  
hour = pd.get_dummies(hour)  
#组合特征  
trainData = pd.concat([hour, days, district], axis = 1)  #将特征进行横向组合  
trainData['crime'] = crime   #追加'crime'列  
days = pd.get_dummies(test.DayOfWeek)  
district = pd.get_dummies(test.PdDistrict)  
hour = test.Dates.dt.hour  
hour = pd.get_dummies(hour)  
testData = pd.concat([hour, days, district], axis=1)  
trainData

 朴素贝叶斯原理和应用

 

3.建立贝叶斯模型

from sklearn.naive_bayes import BernoulliNB
import time
features=['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday', 'BAYVIEW', 'CENTRAL', 'INGLESIDE', 'MISSION',  
 'NORTHERN', 'PARK', 'RICHMOND', 'SOUTHERN', 'TARAVAL', 'TENDERLOIN']  
X_train, X_test, y_train, y_test = train_test_split(trainData[features], trainData['crime'], train_size=0.6)  
NB = BernoulliNB()  
nbStart = time.time()  
NB.fit(X_train, y_train)  
nbCostTime = time.time() - nbStart  
print(X_test.shape)  
propa = NB.predict_proba(X_test)   #X_test为263415*17; 那么该行就是将263415分到39种犯罪类型中,每个样本被分到每一种的概率  
print("朴素贝叶斯建模%.2f秒"%(nbCostTime))  
predicted = np.array(propa)  
logLoss=log_loss(y_test, predicted)  
print("朴素贝叶斯的log损失为:%.6f"%logLoss) 
输出:
(351220, 17)
朴素贝叶斯建模0.87秒
朴素贝叶斯的log损失为:2.615733




凤凰新闻的文章


package com.ifeng.classify.Util;

import java.io.Serializable;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class NativeBayes implements Serializable {
    
   /**
    * 序列化ID
    */
    private static final long serialVersionUID = -5809782578272943999L;
    
     /**
     * 默认频率
     */
    private double defaultFreq = 0.1;

    /**
     * 训练数据的比例
     */
    private Double trainingPercent = 0.8;

    private Map<String, List<String>> files_all = new HashMap<String, List<String>>();

    private Map<String, List<String>> files_train = new HashMap<String, List<String>>();

    private Map<String, List<String>> files_test = new HashMap<String, List<String>>();

    public NativeBayes() {

    }

    /**
     * 每个分类的频数
     */
    private Map<String, Integer> classFreq = new HashMap<String, Integer>();

    /**
     * 每个分类所占的百分比     先验概率 p(yi)
     */
    private Map<String, Double> ClassProb = new HashMap<String, Double>();

    /**
     * 特征总数
     */
    private Set<String> WordDict = new HashSet<String>();

    /**
     * 每个分类中每个特征的频数
     */
    private Map<String, Map<String, Integer>> classFeaFreq = new HashMap<String, Map<String, Integer>>();

    /**
     * 每个分类中每个特征的概率    p(xi/yi)
     */
    private Map<String, Map<String, Double>> ClassFeaProb = new HashMap<String, Map<String, Double>>();

    /**
     * 每个分类默认的概率
     */
    private Map<String, Double> ClassDefaultProb = new HashMap<String, Double>();
    
    
    public double getDefaultFreq() {
        return defaultFreq;
    }

    public void setDefaultFreq(double defaultFreq) {
        this.defaultFreq = defaultFreq;
    }

    public Double getTrainingPercent() {
        return trainingPercent;
    }

    public void setTrainingPercent(Double trainingPercent) {
        this.trainingPercent = trainingPercent;
    }

    public Map<String, List<String>> getFiles_all() {
        return files_all;
    }

    public void setFiles_all(Map<String, List<String>> files_all) {
        this.files_all = files_all;
    }

    public Map<String, List<String>> getFiles_train() {
        return files_train;
    }

    public void setFiles_train(Map<String, List<String>> files_train) {
        this.files_train = files_train;
    }

    public Map<String, List<String>> getFiles_test() {
        return files_test;
    }

    public void setFiles_test(Map<String, List<String>> files_test) {
        this.files_test = files_test;
    }

    public Map<String, Integer> getClassFreq() {
        return classFreq;
    }

    public void setClassFreq(Map<String, Integer> classFreq) {
        this.classFreq = classFreq;
    }

    public Map<String, Double> getClassProb() {
        return ClassProb;
    }

    public void setClassProb(Map<String, Double> classProb) {
        ClassProb = classProb;
    }

    public Set<String> getWordDict() {
        return WordDict;
    }

    public void setWordDict(Set<String> wordDict) {
        WordDict = wordDict;
    }

    public Map<String, Map<String, Integer>> getClassFeaFreq() {
        return classFeaFreq;
    }

    public void setClassFeaFreq(Map<String, Map<String, Integer>> classFeaFreq) {
        this.classFeaFreq = classFeaFreq;
    }

    public Map<String, Map<String, Double>> getClassFeaProb() {
        return ClassFeaProb;
    }

    public void setClassFeaProb(Map<String, Map<String, Double>> classFeaProb) {
        ClassFeaProb = classFeaProb;
    }

    public Map<String, Double> getClassDefaultProb() {
        return ClassDefaultProb;
    }

    public void setClassDefaultProb(Map<String, Double> classDefaultProb) {
        ClassDefaultProb = classDefaultProb;
    }
}
util

相关文章:

  • 2021-07-22
  • 2021-08-21
  • 2021-10-15
  • 2021-12-18
  • 2022-01-23
  • 2020-03-30
  • 2021-12-01
猜你喜欢
  • 2021-09-30
  • 2021-05-26
  • 2021-08-29
  • 2021-05-20
  • 2021-12-30
  • 2021-12-29
  • 2021-04-11
相关资源
相似解决方案