词表征

·词表征就是如何用向量的方式来表示一个词的特征,让计算机能够对词进行处理,常用的两种词表征的方法:

·词袋模型:一个词也可以理解为是一篇最简单的文档,所以它可以用词袋来表示他的特征,这个时候的词袋就是一个独热编码。

独热编码举例:

·词向量模型:

词向量:又叫词嵌入,这种方法可以解决词袋模型的稀核心思想是:每一个词映射到一个多维空间中,成为空间中的一个向量,一般这个多维空间的维数不会太高,在几百个的量级,这几百维的特征向量是稠密的,向量中的每一个成员都是非零的。

由于词向量由几百个维度构成,所以也被称为分布式表征。词向量模型是通过对原始文本建模训练学习得到的。

由于词向量把每一个词映射到了一个高维空间中,并用向量表示,响亮的生成是基于词与词之间的相关性得来,可以理解为相关的词在空间中的位置比较靠近,所以词向量有一个非常有趣的特征,那就是类比。

·中心词:就是每一个待分析的词

·邻居词:在文档语料中,出现在中心词,周围某个小窗口内的关联词

·窗口大小c:就是指寻找邻居词的时候需要观察中心词的前后c个词

举例说明:“我家/猫/是/我/养/的/第一/只/宠物”这句话中,如果把“猫”当成当前正在分析的中心词,如果窗口大小c=3,那么,“猫”的邻居词是:我家,是,我,养。

词向量模型的核心原理就是用邻居词的概率分布来作为中心词的向量表示。

1.基于邻居词共现矩阵分解法

 2.神经网络训练:通过构建两种类型的预测模型,然后使用网络的隐藏层输出作为词向量表征,这两种预测模型是

CBOW:利用中心词和邻居词预测中心词

Skip-gram:利用中心词来预测邻居词

不管是哪种类型的神经网络,它的本质都是希望发现中心词和邻居词之间的相关关系,词向量就是隐藏在这个相关关系中的隐特征。

从上图的示例中可以看到:输入是中心词(或者是邻居词),输出是邻居词(或者中心词)。神经网络中间有一个隐藏层,他的神经元个数要显著小于词的个数(一般就只有几百个),通过预测模型的训练学习,我们会得到网络的连接权重,例如”drink“这个词会和隐藏层的所有神经元都有连接权重,依据这个权重就可以得到drink这个词的词向量,向量的长度就是隐藏层的神经元个数,向量的数值就是神经元之间的连接权重。再看图的右边,与drink连接权重较高的神经元,他的右边又连接了一些词,这些词可以理解为就是drink的邻居词,例如juice,milk之类的词。

词向量只是对词的特征表征,如果要对一篇文档进行特征表征,有以下几种方法

·直接使用文档中所有词的词向量的平均值

·使用文档中每个词的TF-IDF值做为权重,与每个词的词向量进行加权平均

·根据文档中每个词的词向量对文档进行聚类,使用聚类后包含词最多的那个类的中心点作为文档特征向量

·使用doc2vec模型,这是个类似word2vec的模型,不过他是直接对doc来建模

以下为训练word2vec的代码及一些参数的讲解

创建输出目录 用来保存训练好的词向量

output_dir='output_word2vec'
import os
if not os.path.exists(output_dir):os.mkdir(output_dir)

导入数据

import numpy as np
import pandas as pd

查看训练数据


train_data=pd.read_csv('sohu_train.txt',sep='\t',header=None,dtype=np.str_,encoding='utf8',names=['频道','文章'])
train_data.info()

·输出结果

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 12000 entries, 0 to 11999
Data columns (total 2 columns):#   Column  Non-Null Count  Dtype
---  ------  --------------  ----- 0   频道      12000 non-null  object1   文章      12000 non-null  object
dtypes: object(2)
memory usage: 187.6+ KB

载入停用词

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
article_words=[]
# 遍历每篇文章
for article in train_data[u'文章']:curr_words=[]# 遍历文章中的每个词for word in jieba.cut(article):# 去除停用词if word not in stopwords:curr_words.append(word)article_words.append(curr_words)

·输出结果

Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\10248\AppData\Local\Temp\jieba.cache
Loading model cost 0.530 seconds.
Prefix dict has been built successfully.

分词结果存储到文件

seg_word_file=os.path.join(output_dir,'seg_words.txt')
with open(seg_word_file,'wb') as outfile:for words in article_words:outfile.write(u' '.join(words).encode('utf8') + b'\n')
print('分词结果保存到文件:{}'.format(seg_word_file))

·输出结果

分词结果保存到文件:output_word2vec\seg_words.txt

预训练word2vec模型

from gensim.models import Word2Vec
from gensim.models.word2vec import LineSentence
from gensim.models import KeyedVectors

创建一个句子迭代器,一行为一个句子,词和词之间用空格分开
这里我们把一篇文章当作一个句子

sentences=LineSentence(seg_word_file)

预训练word2vec模型
参数说明:
 sentences: 包含句子的list,或迭代器
size: 词向量的维数,size越大需要越多的训练数据,同时能得到更好的模型
alpha: 初始学习速率,随着训练过程递减,最后降到 min_alpha
window: 上下文窗口大小,即预测当前这个词的时候最多使用距离为window大小的词
max_vocab_size: 词表大小,如果实际词的数量超过了这个值,过滤那些频率低的
workers: 并行度
iter: 训练轮数
min_count: 忽略出现次数小于该值的词

model=Word2Vec(sentences=sentences,min_count=20)

保存模型

model_file = os.path.join(output_dir, 'model.w2v')
model.save(model_file)

测试预训练模型

读取模型

model_file = os.path.join(output_dir, 'model.w2v')
model2=Word2Vec.load(model_file)

查找语义相近的词

def invest_similar(*args,**kwargs):res=model2.wv.most_similar(*args,**kwargs)print('\n'.join(['{}:{}'.format(x[0],x[1]) for x in res]))invest_similar(u'摄影', topn=5)

·输出结果

刘晓科:0.7663402557373047
刘建东:0.7626208066940308
评语:0.7005037069320679
作曲:0.6986984014511108
璇:0.67718505859375

女人 + 先生 - 男人 = 女士
先生 - 女士 = 男人 - 女人,这个向量的方向就代表了性别!

invest_similar(positive=[u'女人', u'先生'], negative=[u'男人'], topn=1)

·输出结果

蔡:0.6899486184120178

计算两个词的相似度

model2.wv.similarity('摄影','摄像')

·输出结果

0.6245521

查询某个词的词向量

model2.wv[u'摄影'].shape

·输出结果

(100,)
model2.wv[u'摄影']

·输出结果

array([ 1.12402821e+00, -1.43426090e-01,  1.27216709e+00, -1.03221321e+00,-1.87992001e+00,  5.13237119e-01, -1.13613218e-01,  4.65803176e-01,2.23834977e-01, -5.68113267e-01, -1.13676023e+00,  6.05148017e-01,1.92878091e+00,  1.35197982e-01,  4.71386909e-01,  3.13203558e-02,-4.88490194e-01, -5.21153510e-01, -3.16076130e-01, -4.14293671e+00,-1.09550381e+00,  2.31205606e+00,  3.80034757e+00, -8.64517391e-01,8.61354887e-01, -4.89337295e-01, -3.63620043e-01,  2.25580406e+00,-9.07084405e-01,  7.68696427e-01,  8.44246987e-03, -4.67379779e-01,2.23277569e+00, -1.60536277e+00, -1.76252687e+00,  2.04124570e+00,-5.92672646e-01, -1.79212022e+00, -8.45354021e-01,  1.63020134e-01,-4.94004756e-01,  7.84639716e-02,  2.46292621e-01,  3.91405135e-01,2.69702244e+00,  1.12125501e-01, -3.00367903e-02,  3.96094732e-02,-7.09702730e-01,  2.72683471e-01,  1.63493916e-01,  3.45271856e-01,-7.32331157e-01, -1.10088050e+00,  7.25350261e-01,  1.89776182e-01,-1.67757552e-03, -1.81457877e+00, -2.36800209e-01,  5.88630319e-01,-1.17891036e-01,  1.70819044e+00, -2.11411715e-01,  4.82740730e-01,2.90950954e-01, -6.00913882e-01,  6.11816823e-01,  3.15804314e-03,-9.11727548e-01,  1.11618125e+00,  5.53577483e-01,  9.87007380e-01,1.19754769e-01, -4.53332961e-02,  1.14017117e+00,  5.29826954e-02,-6.54554486e-01, -1.82963490e+00,  1.63241223e-01, -6.50338531e-01,1.28191340e+00,  1.39220166e+00, -3.26665908e-01,  7.38676339e-02,-2.12200940e-01,  6.16843961e-02, -1.28452039e+00, -1.28339744e+00,-1.09384215e+00, -1.32426918e+00,  1.16123927e+00, -3.39918613e-01,1.30219662e+00,  3.30029815e-01,  1.47671258e+00,  4.75448519e-01,6.79319859e-01, -2.00764275e+00,  8.49902809e-01, -4.79526490e-01],dtype=float32)

完整训练word2vec模型

创建输出目录

import os
output_dir = u'output_w2v'
if not os.path.exists(output_dir):os.mkdir(output_dir)

加载数据

import numpy as np
import pandas as pd

查看训练数据

train_data = pd.read_csv('sohu_train.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8', 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())

计算每个文章的词向量

加载训练好的Word2Vec模型
需要预训练的执行结果

from gensim.models import Word2Vec
w2v = Word2Vec.load('output_word2vec/model.w2v')

使用文章中所有词的平均词向量作为文章的向量

import jieba
def compute_doc_vec_single(article):vec = np.zeros((w2v.layer1_size,), dtype=np.float32)n = 0for word in jieba.cut(article):if word in w2v.wv:vec += w2v.wv[word]#求所有词向量的和n += 1#计算词的个数return vec / n#求平均值def compute_doc_vec(articles):return np.row_stack([compute_doc_vec_single(x) for x in articles])x = compute_doc_vec(train_data[u'文章'])

训练分类器

编码目标变量

from sklearn.preprocessing import LabelEncoder
y_encoder = LabelEncoder()
y = y_encoder.fit_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]

训练逻辑回归模型

常用参数说明
penalty: 正则项类型,l1还是l2
C: 正则项惩罚系数的倒数,越大则惩罚越小
fit_intercept: 是否拟合常数项
max_iter: 最大迭代次数
multi_class: 以何种方式训练多分类模型
    ovr = 对每个标签训练二分类模型
    multinomial = 直接训练多分类模型,仅当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')
model.fit(train_x, train_y)

模型效果评估

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_)

·输出结果

 体育  健康  女人  娱乐  房地产 教育  文化  新闻  旅游  汽车  科技  财经
体育  184 0   2   0   0   3   1   4   6   0   0   0
健康  0   158 11  0   0   3   3   11  2   1   2   9
女人  1   5   149 13  0   0   16  4   6   2   4   0
娱乐  1   0   18  145 2   2   26  1   2   1   2   0
房地产 0   0   1   1   173 0   1   8   4   3   1   8
教育  0   2   5   1   1   169 5   9   3   0   3   2
文化  2   3   12  35  2   1   118 14  9   0   4   0
新闻  6   8   4   3   4   9   4   134 7   3   6   12
旅游  1   2   8   0   4   0   9   7   158 1   3   7
汽车  1   3   1   0   0   1   0   1   3   185 3   2
科技  0   5   3   0   2   4   1   5   2   3   162 13
财经  1   2   4   0   12  0   1   13  1   7   19  140

计算各项评价指标

def eval_model(y_true, y_pred, labels):# 计算每个分类的Precision, Recall, f1, supportp, r, f1, s = precision_recall_fscore_support(y_true, y_pred)# 计算总体的平均Precision, Recall, f1, supporttot_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_)

·输出结果

0    体育  0.934010    0.92000 0.926952    200
1   健康  0.840426    0.79000 0.814433    200
2   女人  0.683486    0.74500 0.712919    200
3   娱乐  0.732323    0.72500 0.728643    200
4   房地产 0.865000    0.86500 0.865000    200
5   教育  0.880208    0.84500 0.862245    200
6   文化  0.637838    0.59000 0.612987    200
7   新闻  0.635071    0.67000 0.652068    200
8   旅游  0.778325    0.79000 0.784119    200
9   汽车  0.898058    0.92500 0.911330    200
10  科技  0.775120    0.81000 0.792176    200
11  财经  0.725389    0.70000 0.712468    200
999 总体  0.782105    0.78125 0.781278    2400

模型保存

# 保存模型到文件
import dill
import pickle
model_file = os.path.join(output_dir, u'model.pkl')
with open(model_file, 'wb') as outfile:pickle.dump({'y_encoder': y_encoder,'lr': model}, outfile)

对新文档预测

from gensim.models import Word2Vec
import dill
import pickle
import jieba

把预测相关的逻辑封装在一个类中,使用这个类的实例来对新文档进行分类预测

class Predictor(object):def __init__(self, w2v_model_file, lr_model_file):self.w2v = Word2Vec.load(w2v_model_file)with open(lr_model_file, 'rb') as infile:self.model = pickle.load(infile)def predict(self, articles):x = self._compute_doc_vec(articles)y = self.model['lr'].predict(x)y_label = self.model['y_encoder'].inverse_transform(y)return y_labeldef _compute_doc_vec(self, articles):return np.row_stack([compute_doc_vec_single(x) for x in articles])def _compute_doc_vec_single(self, article):vec = np.zeros((w2v.layer1_size,), dtype=np.float32)n = 0for word in jieba.cut(article):if word in w2v:vec += w2v[word]n += 1return vec / n

加载新文档数据

new_data = pd.read_csv('sohu_test.txt', sep='\t', header=None, dtype=np.str_, encoding='utf8', names=[u'频道', u'文章'])
new_data.head()

加载模型

predictor = Predictor('output_word2vec/model.w2v', model_file)

预测前10000篇的分类

new_y_pred = predictor.predict(new_data[u'文章'][:10000])

对比预测

pd.DataFrame({u'预测频道': new_y_pred, u'实际频道': new_data[u'频道'][:10000]})

Word2Vec对新闻进行分类相关推荐

  1. 使用word2vec分析新闻标题并预测文章流行度

    文章标题的嵌入可以预测受欢迎程度吗? 我们可以从中了解情绪与股票之间的关系? word2vec可以帮助我们回答这些问题. Word嵌入是表示单词内容以及文档(单词集合)中包含的潜在信息的有效方式. 使 ...

  2. python人工智能——机器学习——分类算法-朴素贝叶斯算法对新闻进行分类案例

    朴素贝叶斯案例流程 1.加载20类新闻数据,并进行分割 2.生成文章特征词 3.朴素贝叶斯estimator流程进行预估 代码 from sklearn.datasets import fetch_2 ...

  3. 利用朴素贝叶斯分类算法对搜狐新闻进行分类(python)

    数据来源  https://www.sogou.com/labs/resource/cs.php 介绍:来自搜狐新闻2012年6月-7月期间国内,国际,体育,社会,娱乐等18个频道的新闻数据,提供UR ...

  4. gensim词向量Word2Vec安装及《庆余年》中文短文本相似度计算 | CSDN博文精选

    作者 | Eastmount 来源 | CSDN博文精选 (*点击阅读原文,查看作者更多精彩文章) 本篇文章将分享gensim词向量Word2Vec安装.基础用法,并实现<庆余年>中文短文 ...

  5. 新闻行业中,自然语言理解技术该如何应用?

    在信息爆炸时代下,要想快速获取有价值的内容非常困难,这一点在新闻行业中尤为明显,而本文提到的自然语言理解技术将会是一个不错的解决建议. 自然语言理解技术在新闻行业中的应用 现如今,人类生活在一个信息大 ...

  6. 机器学习实战:朴素贝叶斯算法在新闻文本数据上的分类表现

    https://www.toutiao.com/a6647102437532369421/ 2019-01-17 08:01:00 大家好,今天跟大家学习一下通过sklearn的朴素贝叶斯模型实战.前 ...

  7. 小白看Word2Vec的正确打开姿势|全部理解和应用

    有个用心的读者最近做了一篇论文,想知道Word2Vec的相关理论和应用方法,作为一个有强迫症的我,去翻查了大量的文献资料,决定从Word2Vec的上下文来温习一下这个NLP的基础以及做相关的知识体系的 ...

  8. 数学之美 系列 12 - 余弦定理和新闻的分类

    数学之美 系列 12 - 余弦定理和新闻的分类 余弦定理和新闻的分类似乎是两件八杆子打不着的事,但是它们确有紧密的联系.具体说,新闻的分类很大程度上依靠余弦定理. Google 的新闻是自动分类和整理 ...

  9. 利用word2vec训练词向量

    利用word2vec训练词向量 这里的代码是在pycharm上运行的,文件列表如下: 一.数据预处理 我选用的数据集是新闻数据集一共有五千条新闻数据,一共有四个维度 数据集:https://pan.b ...

最新文章

  1. CodeForces - 960F[动态开点线段树优化dp]详解
  2. POJ 3468 A Simple Problem with Integers
  3. Unity C#基础之 反射反射,程序员的快乐
  4. BOOST内存管理(一) --- boost::object_pool
  5. Cannot find package module @sap/cds/common
  6. Android之抓取adb logcat全日志后怎么过滤掉只包含当前app进程的日志(一般抓启动app奔溃日志)
  7. centos8 安装mysql8.0
  8. tree命令的使用(过滤文件夹)
  9. C语言和设计模式(享元模式)
  10. servlet处理多个请求 笔记
  11. word任意带圈数字
  12. subli快速度创建html,Shortcut to comment out a block of code with subli
  13. 【数理统计】一题了解假设检验
  14. java jar apktool,apktool下载
  15. 安装运行太极框架Android搞机操作root
  16. HTML+CSS实现百度网盘首页
  17. 微信小程序实现朋友圈图片展现形式
  18. android逆向分析so,Android逆向——so反编译分析由浅入深(回帖奖励)
  19. 思科认证介绍(各种证书)
  20. 关于android的webview打开淘宝天猫链接问题

热门文章

  1. 如何把流程图转换为软件设计(初稿)
  2. 路由器重温——RIP路由
  3. 连续信号、离散信号、模拟信号与数字信号区别
  4. CCF大会腾源会专场即将召开,聚焦基础软件与开发语言未来发展
  5. 扫码报修开启校园报修管理系统新时代
  6. 使用Python画小猪佩奇(turtle库)
  7. Python 打印的中英文字体如何对齐?
  8. 欧拉函数φ(x)简要介绍及c++实现
  9. 原生应用,混合应用,H5应用区别
  10. springboot 中favicon.ico 图标不显示问题,后台日志报错找不到favicon.ico 文件问题 解决