赞
踩
词袋 不关注词的先后顺序---词袋模型(bow--一元模型) bag of words
二元模型
n-gram
- # 创建输出目录 保存训练好的模型
- import os#对文件和目录进行操作
- output_dir = u'output'
- if not os.path.exists(output_dir):
- os.mkdir(output_dir)
- import numpy as np#一个数据分析处理数据的常见的库,它提供的数据结构比 Python 自身的更高效
- import pandas as pd
1.Pandas 是基于 NumPy 的一个开源 Python 库,它被广泛用于快速分析数据,以及数据清洗和准备等工作。它的名字来源是由“ Panel data”(面板数据,一个计量经济学名词)两个单词拼成的。简单地说,你可以把 Pandas 看作是 Python 版的 Excel。
2. Pandas能很好地处理来自各种不同来源的数据,比如 Excel 表格、CSV 文件、SQL 数据库,甚至还能处理存储在网页上的数据。
3. Pandas基于Numpy,常常与Numpy、matplotlib一起使用。
4. Pandas库的两个主要数据结构:
Series:一维
DataFrame:多维
python list 列表保存的是对象的指针,比如 [0,1,2] 需要保存 3 个指针和 3 个整数的对象,这样就很浪费内存了。
Numpy 是储存在一个连续的内存块中,节约了计算资源。
- # 查看训练数据
- train_data = pd.read_csv('sohu_train.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8',error_bad_lines=False, delimiter="\t", names=[u'频道', u'文章'])
- train_data.head()
- # 载入停用词
- stopwords = set()
- with open('stopwords.txt', 'r',encoding='utf8') as infile:
- for line in infile:
- line = line.rstrip('\n')
- if line:
- stopwords.add(line.lower())
- import jieba
- from sklearn.feature_extraction.text import TfidfVectorizer
min_df去掉df值小的词 这样的词一般是非常专业的名词或者是生僻词 是噪音
max_df 去掉df值很大的词 这样词是常用词 去掉不要
- tfidf = TfidfVectorizer(tokenizer=jieba.lcut, stop_words=stopwords, min_df=50, max_df=0.3)#使用TfidfVectorizer实例化
- x = tfidf.fit_transform(train_data[u'文章'])
·输出结果
- Building prefix dict from the default dictionary ...
- Loading model from cache C:\Users\10248\AppData\Local\Temp\jieba.cache
- Loading model cost 0.550 seconds.
- Prefix dict has been built successfully.
- E:\ANACODAN\lib\site-packages\sklearn\feature_extraction\text.py:388: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['&', ',', '.', ';', 'e', 'g', 'nbsp', '—', '\u3000', '傥', '兼', '前', '唷', '啪', '啷', '喔', '始', '漫', '然', '特', '竟', '若果', '莫', '见', '设', '说', '达', '非'] not in stop_words.
- warnings.warn('Your stop_words may be inconsistent with '
print(u'词表大小: {}'.format(len(tfidf.vocabulary_)))
词表大小: 14516
编码目标变量 因为咱们的标签是字符串 sklearn只接受数值
- from sklearn.preprocessing import LabelEncoder#LabelEncoder:将类别数据数字化
- y_encoder = LabelEncoder()
- y = y_encoder.fit_transform(train_data[u'频道'])#将类别转换成0,1,2,3,4,5,6,7,8,9...
- y[:10]
·输出结果
array([3, 3, 3, 3, 3, 3, 3, 3, 3, 3])
编码X变量
x = tfidf.transform(train_data[u'文章'])
- # 划分训练测试数据
- from sklearn.model_selection import train_test_split#分割数据集
- # 根据y分层抽样,测试数据占20%
- #因为现在数据量很大 此时采用对下标进行分割
- train_idx, test_idx = train_test_split(range(len(y)), test_size=0.2, stratify=y)
- train_x = x[train_idx, :]#训练集
- train_y = y[train_idx]
- test_x = x[test_idx, :]#测试集
- test_y = y[test_idx]
训练逻辑回归模型 我们是12分类 属于多分类
常用参数说明
penalty: 正则项类型,l1还是l2
C: 正则项惩罚系数的倒数,越大则惩罚越小
fit_intercept: 是否拟合常数项
max_iter: 最大迭代次数
multi_class: 以何种方式训练多分类模型
ovr = 对每个标签训练二分类模型
multinomial ovo = 直接训练多分类模型,仅当solver={newton-cg, sag, lbfgs}时支持
solver: 用哪种方法求解,可选有{liblinear, newton-cg, sag, lbfgs}
小数据liblinear比较好,大数据量sag更快
多分类问题,liblinear只支持ovr模式,其他支持ovr和multinomial
liblinear支持l1正则,其他只支持l2正则
- from sklearn.linear_model import LogisticRegression#引入逻辑回归
- model = LogisticRegression(multi_class='multinomial', solver='lbfgs')#solver='lbfgs':求解方式
- model.fit(train_x, train_y)
·输出结果
- E:\ANACODAN\lib\site-packages\sklearn\linear_model\_logistic.py:763: ConvergenceWarning: lbfgs failed to converge (status=1):
- STOP: TOTAL NO. of ITERATIONS REACHED LIMIT.
-
- Increase the number of iterations (max_iter) or scale the data as shown in:
- https://scikit-learn.org/stable/modules/preprocessing.html
- Please also refer to the documentation for alternative solver options:
- https://scikit-learn.org/stable/modules/linear_model.html#logistic-regression
- n_iter_i = _check_optimize_result(
LogisticRegression(multi_class='multinomial')
- from sklearn.metrics import confusion_matrix, precision_recall_fscore_support
- # 在测试集上计算模型的表现
- test_y_pred = model.predict(test_x)
- # 计算混淆矩阵
- pd.DataFrame(confusion_matrix(test_y, test_y_pred), columns=y_encoder.classes_, index=y_encoder.classes_)
·输出结果
- 体育 健康 女人 娱乐 房地产 教育 文化 新闻 旅游 汽车 科技 财经
- 体育 193 1 0 1 0 0 3 2 0 0 0 0
- 健康 0 165 9 0 0 4 0 7 3 0 4 8
- 女人 1 5 167 4 0 0 13 5 3 0 1 1
- 娱乐 0 1 9 164 0 5 17 2 0 0 1 1
- 房地产 0 1 4 0 180 0 0 3 0 0 1 11
- 教育 0 0 3 2 0 185 2 6 1 0 1 0
- 文化 0 3 13 17 0 1 153 8 2 1 2 0
- 新闻 1 4 6 5 1 12 4 124 5 2 11 25
- 旅游 0 2 8 0 6 1 8 8 163 0 1 3
- 汽车 1 1 3 0 0 0 0 4 2 182 1 6
- 科技 0 1 0 0 0 2 2 12 5 1 164 13
- 财经 1 4 3 0 12 0 4 19 2 4 11 140
- # 计算各项评价指标
- def eval_model(y_true, y_pred, labels):
- # 计算每个分类的Precision, Recall, f1, support
- p, r, f1, s = precision_recall_fscore_support(y_true, y_pred)
- # 计算总体的平均Precision, Recall, f1, support
- tot_p = np.average(p, weights=s)
- tot_r = np.average(r, weights=s)
- tot_f1 = np.average(f1, weights=s)
- tot_s = np.sum(s)
- res1 = pd.DataFrame({
- u'Label': labels,
- u'Precision': p,
- u'Recall': r,
- u'F1': f1,
- u'Support': s
- })
- res2 = pd.DataFrame({
- u'Label': [u'总体'],
- u'Precision': [tot_p],
- u'Recall': [tot_r],
- u'F1': [tot_f1],
- u'Support': [tot_s]
- })
- res2.index = [999]
- res = pd.concat([res1, res2])
- return res[[u'Label', u'Precision', u'Recall', u'F1', u'Support']]
·输出结果
eval_model(test_y, test_y_pred, y_encoder.classes_)
-
- Label Precision Recall F1 Support
- 0 体育 0.979695 0.965 0.972292 200
- 1 健康 0.877660 0.825 0.850515 200
- 2 女人 0.742222 0.835 0.785882 200
- 3 娱乐 0.849741 0.820 0.834606 200
- 4 房地产 0.904523 0.900 0.902256 200
- 5 教育 0.880952 0.925 0.902439 200
- 6 文化 0.742718 0.765 0.753695 200
- 7 新闻 0.620000 0.620 0.620000 200
- 8 旅游 0.876344 0.815 0.844560 200
- 9 汽车 0.957895 0.910 0.933333 200
- 10 科技 0.828283 0.820 0.824121 200
- 11 财经 0.673077 0.700 0.686275 200
- 999 总体 0.827759 0.825 0.825831 2400
- # 保存模型到文件 pip install dill
- #注意 我们要把tfidf特征提取模型保存 标签转换模型 预测模型
- !pip install dill
- import dill
- import pickle
- model_file = os.path.join(output_dir, u'model.pkl')
- with open(model_file, 'wb') as outfile:
- dill.dump({
- 'y_encoder': y_encoder,
- 'tfidf': tfidf,
- 'lr': model
- }, outfile)
·输出结果
Requirement already satisfied: dill in e:\anacodan\lib\site-packages (0.3.4)
- # 加载新文档数据
- new_data = pd.read_csv('sohu_test.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8',error_bad_lines=False, delimiter="\t", names=[u'频道', u'文章'])
- new_data.head()
- # 加载模型
- import pickle
- model_file = os.path.join(output_dir, u'model.pkl')
- with open(model_file, 'rb') as infile:
- model = pickle.load(infile)
- # 对新文档预测(这里只对前10篇预测)
- # 1. 转化为词袋表示
- new_x = model['tfidf'].transform(new_data[u'文章'][:50])
·输出结果
-
- E:\ANACODAN\lib\site-packages\sklearn\feature_extraction\text.py:388: UserWarning: Your stop_words may be inconsistent with your preprocessing. Tokenizing the stop words generated tokens ['&', ',', '.', ';', 'e', 'g', 'nbsp', '—', '\u3000', '傥', '兼', '前', '唷', '啪', '啷', '喔', '始', '漫', '然', '特', '竟', '若果', '莫', '见', '设', '说', '达', '非'] not in stop_words.
- warnings.warn('Your stop_words may be inconsistent with '
- # 2. 预测类别
- new_y_pred = model['lr'].predict(new_x)
- new_y_pred
·输出结果
- array([3, 0, 3, 3, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
- 3, 3, 3, 3, 3, 3])
- # 3. 解释类别
- pd.DataFrame({u'预测频道': model['y_encoder'].inverse_transform(new_y_pred), u'实际频道': new_data[u'频道'][:50]})
·输出结果
- 预测频道 实际频道
- 0 娱乐 娱乐
- 1 体育 娱乐
- 2 娱乐 娱乐
- 3 娱乐 娱乐
- 4 教育 娱乐
- 5 娱乐 娱乐
- 6 娱乐 娱乐
- 7 娱乐 娱乐
- 8 娱乐 娱乐
- 9 娱乐 娱乐
- 10 娱乐 娱乐
- 11 娱乐 娱乐
- 12 娱乐 娱乐
- 13 娱乐 娱乐
- 14 娱乐 娱乐
- 15 娱乐 娱乐
- 16 娱乐 娱乐
- 17 娱乐 娱乐
- 18 娱乐 娱乐
- 19 娱乐 娱乐
- 20 娱乐 娱乐
- 21 娱乐 娱乐
- 22 娱乐 娱乐
- 23 娱乐 娱乐
- 24 娱乐 娱乐
- 25 娱乐 娱乐
- 26 娱乐 娱乐
- 27 娱乐 娱乐
- 28 娱乐 娱乐
- 29 娱乐 娱乐
- 30 娱乐 娱乐
- 31 娱乐 娱乐
- 32 娱乐 娱乐
- 33 娱乐 娱乐
- 34 娱乐 娱乐
- 35 娱乐 娱乐
- 36 娱乐 娱乐
- 37 娱乐 娱乐
- 38 娱乐 娱乐
- 39 娱乐 娱乐
- 40 娱乐 娱乐
- 41 娱乐 娱乐
- 42 娱乐 娱乐
- 43 娱乐 娱乐
- 44 娱乐 娱乐
- 45 娱乐 娱乐
- 46 娱乐 娱乐
- 47 娱乐 娱乐
- 48 娱乐 娱乐
- 49 娱乐 娱乐
- # 加载模型
- import pickle
- import os
- import numpy as np
- import pandas as pd
-
- output_dir = u'output'
- if not os.path.exists(output_dir):
- os.mkdir(output_dir)
-
- model_file = os.path.join(output_dir, u'model.pkl')
- with open(model_file, 'rb') as infile:
- model = pickle.load(infile)
-
- oo = 1
- while oo == 1:
- f = open('yuce.txt', 'w', encoding='utf8')
- f.write(input())
- f.close()
- new1_data = pd.read_csv('yuce.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8', names=[u'文章'])
- new1_data.head()
- # 加载模型
- import pickle
-
- model_file = os.path.join(output_dir, u'model.pkl')
- with open(model_file, 'rb') as infile:
- model = pickle.load(infile)
- new1_x = model['tfidf'].transform(new1_data[u'文章'])
- # 2. 预测类别
- new1_y_pred = model['lr'].predict(new1_x)
- pd.DataFrame({u'预测频道': model['y_encoder'].inverse_transform(new1_y_pred)})
- print(pd.DataFrame({u'预测频道': model['y_encoder'].inverse_transform(new1_y_pred)}))
- with open(r'yuce.txt', 'a+', encoding='utf-8') as test:
- test.truncate(0)
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。