text classification

一、分词

1、采用jieba分词

安装:全自动安装:pip install jieba / pip3 install jieba

https://blog.csdn.net/flysky1991/article/details/73948971
https://www.jianshu.com/p/e8b5d01ca073
https://www.cnblogs.com/echo-cheng/p/7967221.html
https://www.cnblogs.com/Denise-hzf/p/6612212.html


三种分词模式:
-精确模式:试图将句子最精确地切开,适合文本分析;(选择)
-全模式:把句子中所有的可以成词的词语都扫描出来, 速度非常快,但是不能解决歧义;
-搜索引擎模式:在精确模式的基础上,对长词再次切分,提高召回率,适合用于搜索引擎分词。


主要涉及如下几种算法
(1)基于前缀词典实现高效的词图扫描,生成句子中汉字所有可能成词情况所构成的有向无环图 (DAG);

DAG分词过程:对待分词句子, 根据给定的词典进行查词典操作, 生成几种可能的句子切分。dag记录的是句子中某个词的开始位置, 从0到n-1(n为句子的长度), 每个开始位置作为字典的键, value是个list, 其中保存了可能的词语的结束位置(通过查字典得到词, 开始位置+词语的长度得到结束位置)。
例如:{0:[1,2,3]} 这样一个简单的DAG, 就是表示0位置开始, 在1,2,3位置都是词, 就是说0~1, 02,03这三个起始位置之间的字符, 在dict.txt中是词语。
比如 sentence 是 "国庆节我在研究结巴分词",对应生成的DAG是这样的:{0: [0, 1, 2], 1: [1], 2: [2], 3: [3], 4: [4], 5: [5, 6], 6: [6], 7: [7, 8], 8: [8], 9: [9, 10], 10: [10]} 其中的数字表示每个汉字在sentence中的位置,所以0:[0,1,2] 表示 在trie 树中,"国"开头的词语中对应于该 sentence 有三种匹配情况:国,国庆,国庆节。

(2)采用了动态规划查找最大概率路径, 找出基于词频的最大切分组合;

(3)对于未登录词,采用了基于汉字成词能力的 HMM 模型,采用Viterbi 算法(动态规划)进行计算==>HMM五元组中(观察值(句子),状态转移矩阵(BMES 4X4),发射矩阵(4Xn(好多汉字)),初始状态值(BMES))求解状态值(BMES),根据状态值分词
https://blog.csdn.net/riverflowrand/article/details/50057323

(4)基于Viterbi算法做词性标注;(计算概率)


http://www.cnblogs.com/bottlebox/archive/2011/11/21/2256644.html
(5)基于tf-idf和textrank模型抽取关键词;
textrank与tf-idf不同,不再依赖语料环境(通过语料环境求idf)
textrank公式:

其中,d是阻尼系数,防止结果为0,一般取0.85

程序步骤:
1、文章分词: 对每一篇文章进行分词,分词系统主要由坤雁分词系统、ansj分词,结巴分词等。
2、分词结果数据清洗: 主要包括去停用词、去除符号字母数字等。
3、构建候选关键词图: 根据设定的词语选择窗口截取文本的分词结果,将每个词语作为候选关键词图的节点,截取的每一段文本中的词语作为相邻的边,以此构建候选关键词图。
4、关键词提取: 利用pagerank思想循环迭代候选关键词图, 每个节点的权重初始化化为1.0f,通过设定的迭代次数达到稳定后,对节点权重进行倒序排序,从而得到最重要的num个单词,作为候选关键词。
程序主要包含两大部分,第一部分为候选关键词图构件。第二部分为关键词提取

1.依赖语料
tf-idf的idf值依赖于语料环境,这给他带来了统计上的优势,即它能够预先知道一个词的重要程度.这是它优于textrank的地方。
而textrank只依赖文章本身,它认为一开始每个词的重要程度是一样的。
2.词语的互相关联性
tf-idf是纯粹用词频的思想(无论是tf还是idf都是)来计算一个词的得分,最终来提取关键词,完全没有用到词之间的关联性。
而textrank用到了词之间的关联性(将相邻的词链接起来),这是其优于tf-idf的地方。
https://blog.csdn.net/u013041398/article/details/52473994
https://blog.csdn.net/gzt940726/article/details/80256011


例子:

# encoding=utf-8
import jieba

seg_list = jieba.cut("沧州渤海新区金龙渤海新城三期B幢401号英泰丽斯科技发展有限公司2015年11月16日", cut_all=True)
print("Full Mode: " + "/ ".join(seg_list))  # 全模式
Full Mode: 沧州/ 渤海/ 新区/ 金/ 龙/ 渤海/ 新城/ 三期/ B/ 幢/ 401/ 号/ 英/ 泰/ 丽斯/ 科技/ 发展/ 有限/ 有限公司/ 公司/ 2015/ 年/ 11/ 月/ 16/ 日

seg_list = jieba.cut("沧州渤海新区金龙渤海新城三期B幢401号英泰丽斯科技发展有限公司2015年11月16日", cut_all=False)  #cut_all=False可以不写
print("Default Mode: " + "/ ".join(seg_list))  # 精确模式 默认
Default Mode: 沧州/ 渤海/ 新区/ 金龙/ 渤海/ 新城/ 三期/ B/ 幢/ 401/ 号/ 英泰/ 丽斯/ 科技/ 发展/ 有限公司/ 2015/ 年/ 11/ 月/ 16/ 日

seg_list = jieba.cut_for_search("沧州渤海新区金龙渤海新城三期B幢401号英泰丽斯科技发展有限公司2015年11月16日")  # 搜索引擎模式
print("Search Mode: ".join(seg_list))
Search Mode: 沧州/ 渤海/ 新区/ 金龙/ 渤海/ 新城/ 三期/ B/ 幢/ 401/ 号/ 英泰/ 丽斯/ 科技/ 发展/ 有限/ 公司/ 有限公司/ 2015/ 年/ 11/ 月/ 16/ 日

二、建立自己字典

分词后,针对自己当前的分类目的需要对自己的数据集建立词典(word_dict),通常train.txt,test.txt,val.txt(能得到的所有文件)都用来建立字典,字典就是一个word_dict.txt文件,里面存有所有出现过的词。
在应用的时候,每一个词会对应一个index,可以通过文本中单词顺序定义为0,1,2...也可以根据建词典时的词频降序标为0,1,2,3...

full_feature_set = set([key for key in full_feature_set])

# ensure <unk> is 0
word_dict = {v:(k+1) for (k,v) in enumerate(full_feature_set - set(['<unk>']))}
word_dict['<unk>'] = 0

word_dict得到字典key:word, value:index

对于一个输入的句子,每一个词通过word_dict对应一个index,最后会得到一个列表作为网络输入,例如,你好:1,世界:2,则句子"你好 世界"对应网络输入[1, 2]

out of vocabulary未登录词:如果对于测试集出现了word_dict中没有的词,则可以用<unk>代替,或者更新word_dict(在数据量较大生成word_dict时频率小于5的词一般不计入)

三、embedding layer

https://www.zhihu.com/question/45027109?sort=created
embedding layer是网络的第一层,经过该层可以产生词向量
词汇是语料库的基本元素, 所以, 使用embedding layer来学习词嵌入, 将一个词映射成为固定维度的稠密向量. 有了这一步, 才能构造矩阵, 实现神经网络的前向传播.

如何使用?

  • 从头训练
    就像word2vec一样, 这一层是可学习的, 用随机数initialize , 通过BP去调整.
  • pre-trained + fine tuning
    用其他网络(如 word2vec、glove) 训练好的现成的词向量, 作为初始化参数, 然后继续学习.
  • pre-trained + static
    用其他网络(如 word2vec、glove) 训练好的现成的词向量, 作为初始化参数, 并且这些参数保持固定, 不参与网络的学习.

keras 的 Embedding

Embedding(Layer) 类.

  • 将索引映射为固定维度的稠密的向量.
    eg. [[4], [20]] -> [[0.25, 0.1], [0.6, -0.2]]
    This layer can only be used as the first layer in a model.

__init__(self, input_dim, output_dim,input_length,...)

  • 构造函数,三个参数分别代表vocab_size、vector_dimension、fixed_word_number.
  • 继承自父类的weights、trainable参数.
    如一个语料库, 词汇量为20万, word representation vector is 200d, 文章的截断长度为250个单词, 那么
    embedding_layer=Embedding(input_dim=20E4,output_dim=200,input_length=250,weights=embedding_matrix,trainable=is_trainable)

实现过程

输入是word2index得到的第一个句子列表[1, 33, 55, 3]四个词,第二个句子[33, 56]两个词,对于每一个句子要设置成相同的维数,不够补零,大于截断
pad_sequence 函数
对于word2vec得到的.bin文件,他的主要作用是用来对embedding layer进行初始化,因为随机初始化训练时间较长,将训练集中的词在.bin文件中查找,如果存在就得到它的词向量。

pretrain_embed = 'path'
pre_vocab = 'path1'
pretrain_embedding = loadPretrain(pretrain_embed)
vocab = loadVocab(pre_vocab)  # all word in embedding word2index
word_embeds = np.random.uniform(-np.sqrt(0.01), np.sqrt(0.01), (len(word_dict), emb_dim))
n = 0
for w in word_dict:
    if w in vocab:
        word_embeds[word_dict[w]] = pretrain_embeding[vocab[w]]
        n +=1
    else:
        print(w)

其中pre_vocab和pretrain_embed是由.bin文件得到的,得到的方式:
pip install torchwordemb
import torchwordemb
torchwordemb.load_word2vec_bin(path)
read word2vec binary-format model from path.
return(vocab, vec)

  • vocab is a dict mapping a word to its index
  • vec is a torch.FloatTensor of size V x D, which V is teh vocabulary size and D is the dimension of wordd2vec.
vocab, vec = torchwordemb.load_word2vec_bin("***.bin")
print(vrc.size())
print(vec[w2v.vocab["apple"]])

torchwordemb.load_word2vec_text(path)
read word2vec text-format model from path.
torchwordemb.load_glove_text(path)
read glove text-format model from path.
其实就是One hot representation => Distributed representation

四、神经网络

embedding层后就开始接神经网络,CNN/RNN/LSTM/RCNN
以RNN为例:

self.loss_val = self.loss()  # -->self.loss_nce()
self.train_op = self.train()
self.predictions = tf.argmax(self.logits, axis=1, name="predictions")  # shape:[None,]
correct_prediction = tf.equal(tf.cast(self.predictions, tf.int32), self.input_y)  # tf.argmax(self.logits, 1)-->[batch_size]
self.accuracy = tf.reduce_mean(tf.cast(correct_prediction, tf.float32), name="Accuracy")  # shape=()

loss ==> 交叉熵损失+l2损失
(可选:nce_loss ==> nce_loss + l2损失)
学习率:
通过tf.train.exponential_decay函数实现指数衰减学习率。
步骤:
1.首先使用较大学习率(目的:为快速得到一个比较优的解);
2.然后通过迭代逐步减小学习率(目的:为使模型在训练后期更加稳定);

tf.train.exponential_decay(learning_rate, global_step, decay_steps, decay_rate, staircase=True/False)

公式:decayed_learning_rate=learining_rate*decay_rate^(global_step/decay_steps)

  • decayed_learning_rate为每一轮优化时使用的学习率;
  • learning_rate为事先设定的初始学习率;
  • decay_rate为衰减系数;
  • decay_steps为衰减速度。
  • tf.train.exponential_decay函数则可以通过staircase(默认值为False,当为True时,(global_step/decay_steps)则被转化为整数) ,选择不同的衰减方式。

初始的学习速率是learining_rate,如果staircase=True,那就表明每decay_steps次计算学习速率变化,更新原始学习速率,如果是False,那就是每一步都更新学习速率。学习速率第一次训练开始变化,global_steps每次自动加1。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,496评论 6 501
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,407评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,632评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,180评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,198评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,165评论 1 299
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,052评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,910评论 0 274
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,324评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,542评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,711评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,424评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,017评论 3 326
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,668评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,823评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,722评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,611评论 2 353