<jupyter_start><jupyter_text>TF-IDFtf-idf（英语：term frequency–inverse document frequency）是一种用于信息检索与文本挖掘的常用加权技术。tf-idf是一种统计方法，用以评估一字词对于一个文件集或一个语料库中的其中一份文件的重要程度。字词的重要性随着它在文件中出现的次数成正比增加，但同时会随着它在语料库中出现的频率成反比下降。<jupyter_code>import pandas as pd
import jieba
import time
import numpy as np
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn import metrics
from sklearn.externals import joblib
from sklearn.utils import shuffle
def chinese_word_cut(s):
    # 中文分词（jieba）
    return ' '.join(jieba.cut(s))


def train_and_predict(train_x, train_y, test_x, test_y):
    # 使用多项分布朴素贝叶斯分类器进行训练
    clf = MultinomialNB().fit(train_x, train_y)
    # 在本地保存 model 参数
    joblib.dump(clf, 'model.pkl')
    # 预测 test_x 中的结果
    predicted = clf.predict(test_x)
    # 打印报表
    print(metrics.classification_report(test_y, predicted))
    print('accuracy_score: {}'.format(metrics.accuracy_score(test_y, predicted)))


def read_vocab(path):
    # 读取 path 下文本的内容，返回 list https://github.com/goto456/stopwords
    f = open(path, 'r', encoding='utf8')
    res = f.readlines()
    f.close()
    return res<jupyter_output><empty_output><jupyter_text>加载训练集以及测试集<jupyter_code>train_data = pd.read_csv('cnews.train.txt', sep='\t', names=['label', 'content'])
test_data = pd.read_csv('cnews.test.txt', sep='\t', names=['label', 'content'])
# shuffle 一下
shuffle(train_data)
shuffle(test_data)<jupyter_output><empty_output><jupyter_text>对于数据集中每一个句子进行中文分词<jupyter_code>train_data['content'] = train_data['content'].apply(chinese_word_cut)
test_data['content'] = test_data['content'].apply(chinese_word_cut)<jupyter_output><empty_output><jupyter_text>根据词袋向量统计TF-IDF定义 TfidfVectorizer，将 train_data 以及 test_data 转换为词向量并计算 TF-IDF<jupyter_code># 可以直接在 TfidfVectorizer 中传入停用词，设置词汇维度最大为 max_features
tfidf = TfidfVectorizer(max_features=100000, stop_words=read_vocab('stop_word.txt'))
# 拼接 train_data 以及 test_data 的作用是为了获得同一空间中的词汇向量（但实际中还是提前使用训练集做个映射表比较好，因为测试集中可能某些词汇在训练集中没有出现过）
# 为了偷懒一起做方便很多
x = tfidf.fit_transform(train_data['content'].append(test_data['content']))
train_x = x[:len(train_data)]
test_x = x[len(train_data):]
train_y = train_data['label']
test_y = test_data['label']<jupyter_output>C:\Anaconda3\envs\mLearning\lib\site-packages\sklearn\feature_extraction\text.py:300: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['一些', '一何', '一切', '一则', '一方面', '一旦', '一来', '一样', '一般', '一转眼', '万一', '上下', '不仅', '不但', '不光', '不单', '不只', '不外乎', '不如', '不妨', '不尽', '不尽然', '不得', '不怕', '不惟', '不成', '不拘', '不料', '不是', '不比', '不然', '不特', '不独', '不管', '不至于', '不若', '不论', '不过', '不问', '与其', '与其说', '与否', '与此同时', '且不说', '且说', '两者', '个别', '为了', '为什么', '为何', '为止', '为此', '为着', '乃至', '乃至于', '之一', '之所以', '之类', '乌乎', '也好', '也罢', '二来', '于是', '于是乎', '云云', '云尔', '人们', '人家', '什么', '什么样', '介于', '仍旧', '从此', '从而', '他人', '他们', '以上', '以为', '以便', '以免', '以及', '以故', '以期', '以来', '以至', '以至于', '以致', '任何', '任凭', '似的', '但凡', '但是', '何以', '何况', '何处', '何时', '余外', '作为', '你们', '使得', '例如', '依据', '依照', '便于', '俺们', '倘使', '倘或', '倘然', '倘若', '假使', '假如', '假若', '傥然', '先不先', '光是', '全体', '全部', '关于', '其一', '其中', '其二', '其他', '其余', '其它', '其次', '具体地说', '具体说来', '兼之', '再其次', '[...]<jupyter_text>测试文章中词语的 TF-IDF 权重与文章类别之间的关系抽取 5 条数据分别计算其中词语的 TF-IDF 权重并降序输出前 10 个关键词，并与其真实类别对比tfidf.get_feature_names 可以获取当前模型中所有的词语，最大数量为 max_features<jupyter_code>word = tfidf.get_feature_names()
for i in np.random.randint(train_x.shape[0], size=5):
    print('label: ', train_y[i])
    arg_sort = np.argsort(-train_x[i].toarray()[0])[:10]
    for j in arg_sort:
        print(word[j], '\t', train_x[i].toarray()[0][j])
    print('--------------------------------')<jupyter_output>label:  房产
流动人口 	 0.4082248955538784
计划生育 	 0.34829150970183487
改革 	 0.34125189927858635
深化 	 0.19670126794087855
资本金 	 0.19556879143230255
推进 	 0.1890876174017774
项目 	 0.15657100082162545
条例 	 0.1437456888734804
会议 	 0.13021221269175748
投资 	 0.12625010914409945
--------------------------------
label:  娱乐
激浪 	 0.4316732046209529
青春 	 0.3830683472008551
黄轩 	 0.3179488217376342
黄晓明 	 0.2286114607959972
龙舟 	 0.18052996401984894
陈乔恩 	 0.17527095996307465
梁柏坚 	 0.13644213118630136
车震 	 0.13438219859039577
法宝 	 0.1238574067351264
青春片 	 0.12252506778901526
--------------------------------
label:  教育
雅思考试 	 0.5728694476032157
考生 	 0.2701400489157494
史哲明 	 0.24672257560968106
雅思 	 0.22926765074731068
文化教育 	 0.17088583079652214
大使馆 	 0.15683943946480075
院校 	 0.1563748289754174
超过 	 0.14911140474311899
认可 	 0.14811921410744747
英国 	 0.12173639512952922
--------------------------------
label:  房产
农村 	 0.4475497399879565
吕祖善 	 0.35359914278201837
农民 	 0.3179448351651087
改造 	 0.26207820762374934
住房 	[...]<jupyter_text>训练并预测<jupyter_code>train_and_predict(train_x, train_y, test_x, test_y)<jupyter_output>precision    recall  f1-score   support

          体育       1.00      1.00      1.00      1000
          娱乐       0.93      0.99      0.96      1000
          家居       0.97      0.38      0.55      1000
          房产       0.62      0.92      0.74      1000
          教育       0.91      0.94      0.93      1000
          时尚       0.97      0.97      0.97      1000
          时政       0.95      0.91      0.93      1000
          游戏       0.98      0.97      0.97      1000
          科技       0.95      0.99      0.97      1000
          财经       0.95      0.99      0.97      1000

    accuracy                           0.91     10000
   macro avg       0.92      0.91      0.90     10000
weighted avg       0.92      0.91      0.90     10000

accuracy_score: 0.906