機器學習-樸素貝葉斯文本分類Python實現
一 樸素貝葉斯必須瞭解的概率
條件概率
聯合概率(乘法公式)
全概率公式
樸素貝葉斯公式
以上詳解請看 概率基礎
樸素貝葉斯文本分類最通俗易懂講解 樸素貝葉斯通俗易懂講解
二 樸素貝葉斯介紹
前面提到的K最近鄰算法和決策樹算法,數據實例最終被明確的劃分到某個分類中,下面介紹
樸素貝葉斯是一種運用概率給對象進行分類,而不是完全確定實例應該分到哪個類;K近鄰算法和決策樹,對象被明確劃分到了某個類。
樸素貝葉斯模型被廣泛應用於海量互聯網文本分類任務。由於其較強的特徵條件獨立假設,使得模型預測所需要估計的參數規模從冪指數量級向線性量級減少,極大的節約了內存消耗和計算時間。到那時,也正是受這種強假設的限制,模型訓練時無法將各個特徵之間的聯繫考量在內,使得該模型在其他數據特徵關聯性較強的分類任務上的性能表現不佳
優點:在數據較少的情況下仍然有效,可以處理多類別問題
缺點:要求數據相互獨立,往往數據並不是完全獨立的
適用數據類型:標稱型數據。
三 樸素貝葉斯案例介紹
3.1 案例背景介紹
公司發展部給到了20萬多家公司信息,包括公司名稱和公司經營範圍介紹;其中大約有2/3 的公司已經標註了屬於哪個行業,其他公司沒有標註行業信息,需要對沒有行業分類的公司進行行業分類。
3.2 樸素貝葉斯過程
樸素貝葉斯的一般過程
收集數據:可以使用任何方式
準備數據:中文分詞—構建詞向量—TF-IDF
分類數據:分類器分類
優化:訓練集數據校驗測試集數據,評價模型,改進模型
3.3 數據及代碼目錄結構
暫時還沒有時間,數據和代碼目錄還沒有上傳
3.4 代碼
# 模型調優max_df和alpha
# -*- coding: utf-8 -*-
# @Time : 2019/7/22 上午8:05
# @Author : Einstein Yang!!
# @Nickname : 穿着開襠褲上大學
# @FileName: bayes_formal.py
# @Software: PyCharm
# @PythonVersion: python3.5
# @Blog :https://blog.csdn.net/weixin_41734687
import pandas as pd
pd.set_option('display.max_columns', None)
pd.set_option('display.max_rows', None)
from sklearn.datasets import base
from utilstool import *
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import MultinomialNB # 導入多項式貝葉斯算法
from sklearn import metrics
class BayesTextType(object):
def __init__(self):
self.bunch = base.Bunch(target_name=[], label=[], id=[], contents=[], tdm=[], vocabulary={})
self.pd_re = pd.DataFrame(columns=['id', 'manage_scope', 'company_name', 'industry'])
self.mysql = UtilsMysql(host="localhost", port=3306, user="crawl", passwd="123456tt", db="yhouse_dev",
charset="utf8mb4")
@staticmethod
def _readfile(path):
with open(path, "r", encoding="utf-8") as fp:
content = fp.read()
return content
def vector_space(self):
stopword_path = "./hlt_stop_words.txt"
# 停用詞
stpwrdlst = BayesTextType._readfile(stopword_path).splitlines()
# max_df 單詞在文檔中最高出現率,如max_df=0.5,表示一個單詞在50%的文檔中都出現了,那麼它只攜帶了非常少的信息,因
# 此不作爲分詞統計,一般很少設置 min_df,因爲 min_df 通常都會很小
# sublinear_tf:boolean, optional,應用線性縮放TF,例如,使用1 + log(tf)覆蓋tf
vectorizer = TfidfVectorizer(stop_words=stpwrdlst, sublinear_tf=True, max_df=0.6)
# 計算每個單詞在每個文檔中的TF-IDF值,向量裏的順序是按照詞語的id順序來的
self.bunch.tdm = vectorizer.fit_transform(self.bunch.contents)
# 輸出每個單詞對應的id值
self.bunch.vocabulary = vectorizer.vocabulary_
# print(self.bunch.vocabulary)
def metrics_result(self):
x_train, x_test, y_train, y_test = train_test_split(self.bunch.tdm, self.bunch.label, test_size=0.25)
# 訓練分類器:輸入詞袋向量和分類標籤,alpha:0.001 alpha越小,迭代次數越多,精度越高;如果詞列表總數多alpha越小,
# 精度越高,但是如果詞頻列表總數少,alphada一點精度更高(詞太少,根本無法在把詞劃分)
clf = MultinomialNB(alpha=1).fit(x_train, y_train)
# 預測分類結果
predicted = clf.predict(x_test)
for flabel, expct_cate, content in zip(y_test, predicted, x_test):
if flabel != expct_cate:
print( ": 實際類別:", flabel, " -->預測類別:", expct_cate)
print("預測完畢!!!")
# 計算分類精度:
print('精度:{0:.3f}'.format(metrics.precision_score(y_test, predicted, average='weighted')))
print('召回:{0:0.3f}'.format(metrics.recall_score(y_test, predicted, average='weighted')))
print('f1-score:{0:.3f}'.format(metrics.f1_score(y_test, predicted, average='weighted')))
def bayes_text_type(self):
# 目標分類是已經確定的
target_name = ["房地產業", "旅行社", "餐飲業", "美容美髮服務"]
self.bunch.target_name = target_name
select_sql = 'select id, manage_scope, company_name, industry from china_product_info where industry in ("房地產業", "旅行社", "餐飲業", "美容美髮服務") ;'
se_re = list(self.mysql.select_sql(select_sql))
self.pd_re = pd.DataFrame(se_re, columns=['id', 'manage_scope', 'company_name', 'industry'])
# 先分詞,停用詞在tfidf處處理
self.pd_re["contents"] = (self.pd_re["manage_scope"] +","+ self.pd_re["company_name"]).apply(lambda x: " ".join(jieba.cut(x)))
self.bunch.label = self.pd_re['industry']
self.bunch.contents = self.pd_re["contents"]
# print(self.pd_re.head(10))
# print(self.bunch.contents)
self.vector_space()
self.metrics_result()
if __name__ == '__main__':
bayes_text_type = BayesTextType()
bayes_text_type.bayes_text_type()