文本挖掘从小白到精通(十二)--- 7种简单易行的文本特征提取方法

2020 年 7 月 27 日 AINLP

写在前面:本文是笔者近期带的一位实习生写的实操笔记,特分享给大家,enjoy~

特别推荐|【文本挖掘系列教程】:

文本特征提取是文本挖掘中非常重要的一个环节,无论是聚类、分类还是相似度任务,都需要提取出较好的文本特征,如此才能取得较好的结果。
本文简单介绍下文本挖掘中几类特征提取的方法,主要基于scikit-learn和gensim这两个包来操作,在这里,笔者无意去比较它们的优劣,在合适的场景选择使用它们才是王道。

1 加载数据

这里使用的数据是抽样得到的1,000个的新闻样本数据。文章正文部分业已分词且经过去停用词处理。

import pandas as pddf = pd.read_excel('/home/kesci/input/cluster_dataset8319/1000-samples.xlsx')

2 文本特征提取大集合

2.1 CountVectorizer

CountVectorizer是通过统计词汇出现的次数,并用词汇出现的次数的稀疏矩阵来表示文本的特征。它会统计所有出现的词汇,每个词汇出现了多少次,最后得到的稀疏矩阵的列就是词汇的数量(每个词汇就是一个特征/维度)

from sklearn.feature_extraction.text import CountVectorizerctv = CountVectorizer()

这里的CountVectorizer使用的是默认的参数。

我曾经自己设定过的参数主要是: 

(1)ngram_range=(x,y)。其中,x,y 为数字,即n元语法。 
(2)stop_words = stop_words。其中,stop_words是从停用词文件中读取的list,每行一个停用词。
(3)max_features = n。其中,n为词汇表的数量。表示根据词频大小降序排列后的TOP n词汇数。

关于停用词的使用,现在举个例子:

stop_words = [word for word in open('/home/kesci/input/cluster_dataset8319/chinese_stopwords.txt').readlines()]ctv = CountVectorizer(stop_words = stop_words)

x_ctv = ctv.fit_transform(df['clean_sentence'])print(x_ctv[0])

 (0, 25500) 1
(0, 38430) 1
(0, 39738) 1
(0, 28) 1
(0, 398) 1
(0, 5553) 1
: :
(0, 40208) 1
(0, 39018) 1
(0, 24830) 1
(0, 10489) 1
(0, 25982) 1
(0, 37995) 1
(0, 9814) 1

查看得到的结果。要先明确的是:得到的x_ctv是个稀疏矩阵。如果要得到正常的二维数据稠密表达的矩阵,需要使用x_ctv.toarray()。

注意,稀疏矩阵是不可以进行切片操作,比如x_ctv[1][2]。

vocabulary = ctv.get_feature_names()len(vocabulary)

45809

一共得到了45809个单词作为特征。可以看到返回的这个vocabulary是个list。当比如使用KMeans得到聚类结果之后,可以通过vocabulary看到聚类中心有哪些词语。


2.2 TfidfVectorizer

和CountVectorizer很像,TfidfVectorizer提取的特征是:在一个文本中各个有效词汇对应的TFIDF值是多少,同时,每个文本特征向量会自动进行normalization(归一化)操作。

from sklearn.feature_extraction.text import TfidfVectorizertfv = TfidfVectorizer()

这里的TfidfVectorizer使用的是默认的参数。

我曾经自己设定过的参数主要是(和CountVectorizer很像):

(1)ngram_range=(x,y)。其中,x,y 为数字,即n元语法。 

(2)stop_words = stop_words。其中,stop_words为自己从停用词文件中获取到的。(3)max_features = n。其中,n为词汇表的数量。表示根据词频大小降序排列后的TOP n词汇数。

可以感受到:CountVectorizer和TfidfVectorizer很相似。因为TfidfVectorizer = CountVectorizer + TfidfTransformer。也就是说,CountVectorizer得到的是词频(term frequency)特征,那么TfidfVectorizer就像一个给词频term frequency加权的这么个作用:也就是如果这个词特征在别的样本里经常出现,那么这个词在这个样本中的term frequency的加权就低了。这个加权是利用带默认参数的TfidfTransformer来计算出来的。

特别注意:这里的TfidfVectorizer会自动给文本特征向量进行归一化操作,能起到消除文本长短不一的问题。(其实从这个角度看,我个人觉得CountVectorizer才应该归一化一下~)

x_tfv = tfv.fit_transform(df['clean_sentence'])print(x_tfv[0])

(0, 9814) 0.03644325520745695
(0, 37995) 0.03903038473141272
: :
(0, 5553) 0.01897783467880405
(0, 398) 0.013384132069498216
(0, 28) 0.029201349468525248
(0, 39738) 0.00992908598253803
(0, 38430) 0.024893592049250953
(0, 25500) 0.023539781440642706

验证看看:TfidfVectorizer = CountVectorizer + TfidfTransformer。

注意:使用TfidfTransformer输入为一个numpy.array,形状是(n_samples, n_features)。因为2个方法的输入设定不同,对于CountVectorizer和TfidfVectorizer只要是iterable(可迭代)的就可以了。

根据设定,TfidfTransformer是将CountVectorizer的输出作为输入的。

from sklearn.feature_extraction.text import TfidfTransformertft = TfidfTransformer()x_tft = tft.fit_transform(x_ctv)print(x_tft[0])

 (0, 45273) 0.040193714135109256
(0, 44596) 0.09208048277751922
(0, 44249) 0.05795488832300332
(0, 43855) 0.08323502851073701
(0, 43638) 0.03238523570742493
: :
(0, 396) 0.01940495185481739
(0, 392) 0.055555098696532024
(0, 378) 0.1579043530170612
(0, 372) 0.036443255207456955
(0, 28) 0.02920134946852525

format_x_tfv = ['%.14f' % number for number in x_tfv[0].toarray().flatten()]format_x_tft = ['%.14f' % number for number in x_tft[0].toarray().flatten()]print( (format_x_tfv == format_x_tft) )

True

再随便从0-999中抽取一个来试试看。

format_x_tfv = ['%.14f' % number for number in x_tfv[563].toarray().flatten()]format_x_tft = ['%.14f' % number for number in x_tft[563].toarray().flatten()]print( (format_x_tfv == format_x_tft) )

True

也就是说:TfidfVectorizer是一种包装的比较好的写法罢了。(这里要说明的是上面format中到小数14位是最远的返回True的,我估计是还是有float计算上的误差,所以不能再往后比较了~)

vocabulary = tfv.get_feature_names()len(vocabulary)

45809

那么,这里得到和CountVectorizer一样多的features就一点都不奇怪了。

2.3 HashingVectorizer

说到CountVectorizer和TfidfVectorizer,使得好像要带一笔HashingVectorizer。在我的印象中,HashingVectorizer就是--- CountVectorizer省略了vocabulary这个映射(不管是CountVectorizer还是TfidfVectorizer,都是在内存中有一个word2id的映射。),而直接使用Hash的方式来映射。无论多少个词汇,都可以设定为固定维度,这么做节省了内存,但会有存在冲突的可能了,因为可能存在多个词汇共用一个id的情形。

不过,没有这个vocabulary的缺点也就很明显了,就是不能再倒回来看这个列对应的词是什么。而且,它对于Count 的结果还默认归一化了。(我个人觉得Count的结果是真的可以归一化的,因为如果归一化的目的就是使得不同长度的文本都可以进行互相比较的话,那么对Count的结果归一化是最方便的、最直观的了。)

这里带来了一个特别的好处 --- 可以文件流的形式来输入数据,也就是说,不需要一开始就把文件全部读进来了。因为这里的HashingVectorizer是把word通过hash对应到一个下标上,一开始的n_features如果你自己不指定,它自己也是指定好的,而且它是个Count,只依赖每一行自己的特征的情况,和别人无关;而且它的输出的列的数量又是一定的,也就是每个输出格式一定。这样完全可以文件不在内存中,我就一点点读到内存再处理就好了。

但我没有使用过,无法说常调参的参数是哪些。

从HashingVectorizer的实现上来看,HashingVectorizer主要就是FeatureHasher(当然增加了stop_words、normalization这些了)。此类没有fit这个过程,所以fit_transform和transform等价,效果是一样的。

from sklearn.feature_extraction.text import HashingVectorizerhv = HashingVectorizer()x_hv = hv.transform(df['clean_sentence'])x_hv[0]

(0, 9819) 0.0323254091917618
(0, 28307) 0.0323254091917618
(0, 46014) 0.09697622757528539
(0, 49628) 0.0646508183835236
(0, 60743) 0.0323254091917618
(0, 61902) 0.0323254091917618
: :
(0, 1008494) -0.0646508183835236
(0, 1012037) -0.0646508183835236
(0, 1048038) 0.2586032735340944

为了对比和CountVectorizer的关系,把norm设定为None。

hv = HashingVectorizer(norm = None)x_hv = hv.transform(df['clean_sentence'])print(x_hv[0])

(0, 9819) 1.0
(0, 28307) 1.0
(0, 46014) 3.0
(0, 49628) 2.0
(0, 60743) 1.0
(0, 61902) 1.0
(0, 73561) -1.0
(0, 91501) 1.0
(0, 97738) -2.0
: :
(0, 959451) -1.0
(0, 975414) -1.0
(0, 1004860) -1.0
(0, 1008494) -2.0
(0, 1012037) -2.0
(0, 1048038) 8.0

x_hv[0]

<1x1048576 sparse matrix of type '<class 'numpy.float64'>'
with 131 stored elements in Compressed Sparse Row format>

x_ctv[0]

<1x45809 sparse matrix of type '<class 'numpy.int64'>'
with 131 stored elements in Compressed Sparse Row format>

x_hv_pos = [abs(x) for x in x_hv[456].toarray().flatten()]x_ctv_value = [int(x) for x in x_ctv[456].toarray().flatten() if x != 0]x_hv_value = [int(x) for x in x_hv_pos if x != 0]x_ctv_value = x_ctv_value.sort()x_hv_value = x_hv_value.sort()x_ctv_value == x_hv_value

True

通过上面2个方面可以大致确定HashingVectorizer和CountVectorizer功能一致。(当然由于HashingVectorizer会有冲突的现象产生,有不一致的也有可能的。)一个是每一个样本的稀疏矩阵中有值的特征的数量一致。另一个就是随机找出一个样本来做对比,看是否非零的值都相等。(由于HashingVectorizer有可能会有相反数,也就是负值,所以我把负值都先abs转化了正的。)

想想这里还是挺有意思的,就是随机给count值赋予正负号。应该是和哈希冲突的处理相关,但我没大懂。

2.4 Word2Vec + Mean

这里使用到的方法是先使用Word2Vec得到抽取的作为特征的词语的向量。然后,针对每一个样本中包含的特征,特征对应的向量相加,再求平均值,得到这个样本的向量表示。当然,由于这里求得是一个平均值,想要直接倒回去看比如最后得到的聚类中心是什么,就不行了。

from gensim.models import Word2Vecclean_words = [word.split() for word in df['clean_sentence']]
wv_model = Word2Vec(clean_words, min_count = 3, workers = 8, window = 5)print(wv_model)

Word2Vec(vocab=15942, size=100, alpha=0.025)

我会可以考虑自己设置的参数: 

min_count:总出现次数少于多少次就不把这个单词作为vocabulary了。(这里注意:说明并不是所有的词都会在vocabulary中的。) 

workers:并行处理,即使用多少个worker threads来并行同时训练模型。

iter:对于有的语料,在神经网络上训练多少轮。(就相当于神经网络上的epoch参数。)可以通过增加iter来对小数据(即:样本总数量少的时候)多进行几次训练。 

window:在一个句子中,当前词语和预测的词语之间的最大距离可以多大。如果你的语料多,就可以设置的大一点。

这里的结果表示:有15942个词被列入到vocabulary中,每一个特征是一个100个维度的向量来表示。

def get_wv_mean(one_sample, model, size): result = np.zeros(size).reshape(1, size) count = 0 for word in one_sample: try: result = result + model.wv[word] count = count + 1 except: pass if count != 0: result = result / count return result
size = 100x_wv_mean = get_wv_mean(clean_words[0], wv_model, size)for i in range(1, len(clean_words)): x_wv_mean = np.concatenate((x_wv_mean, get_wv_mean(clean_words[i], wv_model, size)), axis = 0)

x_wv_mean.shape

(1000, 100)

2.5 Word2Vec + Similarity

这种方法是偶然不记得在哪里看到的。其实我感觉仿照的是CountVectorizer/TfidfVectorizer。因为CountVectorizer/TfidfVectorizer的思路都是:根据一个整体的所有样本,找到需要的单词作为特征,然后每个样本看在所有的特征上,这个样本和这个整体的特征有什么关系:比如:Count、比如:Tfidf。而这里也是一样,先找到一个整体的语料(其实,如果已知现在的样本是哪个专业领域的话,那应该找这个专业领域的一个比较好的语料库来训练Word2Vec是更好的。这里只能靠自己搜集语料训练模型了。)

训练Word2Vec,假设找到了n个特征,那么对于每一个样本,我都设定一个n维的向量,然后对于向量的每个维度,计算该维度对应的单词和标题中的每个单词的相似度,最后使用那个最大的相似度的值作为这一位的值,计算每一位,得到一个完整的向量。

但这个方法有一点说清楚就是:计算特别慢。我这里使用的是自己写的方法,也许有更好的方法来写。

所以,这里我自己写的只能作为一种写法,真实中很难使用,因为太慢了。

row_length = len(df)col_length = len(wv_model.wv.vocab)matrix = np.zeros([row_length, col_length])
for row in range(0, row_length): for vocab in wv_model.wv.vocab: max_similarity = 0 for col in range(0, len(clean_words[row])): clean_word = clean_words[row][col] similarity = 0 try: similarity = wv_model.wv.similarity(vocab, clean_word) except: pass if similarity > max_similarity: max_similarity = similarity matrix[row][col] = max_similarity


2.6 Doc2Vec

接下来使用Doc2Vec来直接抽取语句特征,不是像之前那样做词汇向量叠加的简单平均,那样会丢失语句词序和句法信息。

Doc2Vec 或者叫做 paragraph2vec, sentence embeddings,是一种非监督式算法,可以获得 sentences/paragraphs/documents 的向量表达,是 word2vec 的拓展。学出来的向量可以通过计算距离来找 sentences/paragraphs/documents 之间的相似性,可以用于文本聚类,对于有标签的数据,还可以用监督学习的方法进行文本分类,例如经典的情感分析问题。

from gensim.models.doc2vec import Doc2Vec, TaggedDocumentclean_words = [word.split() for word in df['clean_sentence']]documents = [TaggedDocument(doc, [i]) for i, doc in enumerate(clean_words)]dv_model = Doc2Vec(documents, vector_size=5, window=2, min_count=1, workers=4)
matrix_dv = []for sentence, _ in documents: matrix_dv.append(dv_model.infer_vector(sentence))

matrix_dv[0]

array([-3.6228316 , -3.269969 , 0.02452112, 3.18907 , 1.8077784 ],
dtype=float32)

Doc2Vec我用过的次数并不多,说一下这里用到的参数: 
documents:注意:这里的输入需要是一个TaggedDocument。
vector_size:表示的是特征的维数。 
window:在一个句子中,当前词语和预测的词语之间的最大距离可以多大。 
min_count : 总出现次数少于多少次就不把这个单词作为vocabulary了。
从结果可以看到ventor_size是定义好的,每个样本都由一个5个特征的向量来表示。

2.7 texts_to_sequences

texts_to_sequence从名字上看虽然和doc2vec挺像的,但texts_to_sequences可比doc2vec做的事情简单多了。说白了就是建立一个word2id的dictionary,然后利用id把句子表示出来。当然也可以不使用id,使用别的东西了,但那个就要自己设置了。

这个操作是深度学习文本预处理的必要操作,比如喂到CNN、RNN神经网络的Embedding层里。

from tensorflow.python.keras.preprocessing import sequencefrom tensorflow.python.keras.preprocessing import text
tokenizer = text.Tokenizer(num_words = 1000)tokenizer.fit_on_texts(df['clean_sentence'])print(len(tokenizer.word_index))
x_seq = tokenizer.texts_to_sequences(df['clean_sentence'])print(x_seq[:1])

46470


[[5, 2, 58, 8, 329, 185, 9, 146, 70, 9, 424, 714, 146, 133, 172, 73, 168, 116, 146, 152, 168, 146, 307, 21, 87, 119, 50, 9, 98, 15, 803, 552, 9, 146, 133, 600, 572, 521, 164, 284, 98, 59, 766, 477, 714, 926, 237, 715, 135, 150, 394, 235, 9, 527, 146, 133, 164, 284, 146, 133, 364, 9, 982, 600, 146, 133, 431, 714, 573, 767, 146, 152, 146, 215, 186, 146, 133, 235, 573, 477, 714, 926, 237, 89, 586, 119, 477, 164, 284, 364, 164, 284, 714, 9, 527, 146, 133, 235, 573, 846, 364, 146, 133, 235, 19, 146, 235, 116, 152, 751, 714, 9, 186, 364, 168, 572, 490, 146, 133, 235, 573, 146, 152, 173, 7, 2, 6, 733, 509]]


print(df['clean_sentence'][:1])

4377 制图 蔡华伟 本报 北京 月 日电 记者 赵贝佳 日前 国家气象中心 单位 编制 2017 ...
Name: clean_sentence, dtype: object

print(len(tokenizer.word_index))

print(type(tokenizer.word_index))print(tokenizer.word_index)

46470

<class 'dict'>

{'中国': 1, '月': 2, '问题': 3, '企业': 4, '北京': 5, '责编': 6, '2018': 7, '记者': 8,...}


我一般只设定num_words这个参数,保留n个词汇特征。 

但是这里要注意:虽然设定了num_words,但是word_index是所有的单词都会被记录到这个dictionary中去(所以如果你看word_index的长度会是46470而非设定的1000)。但在使用word_index来表示样本的时候,才会真正使用到这个num_words,即仅仅使用num_words个最开头的单词来表示样本(可以从上面的check_set中表示出来)。(个人觉得这个设置浪费空间啊。)

还有一点需要注意:word_index是从1开始的,而非从0开始。

由于这里实际上就是word2id而已,那么不同的样本长度不一,得到的向量的长度就会不同的。可以通过word_index找到每个单词对应的id。所以为了之后的操作方便,需要把不同的向量的统一为一个长度。比如:这里可以找出sequence中最长的那一个,然后padding为这个长度。

max_len = np.max([len(s) for s in x_seq])print('max_train_len: ', max_len)x_seq = sequence.pad_sequences(x_seq, maxlen = max_len)print(x_seq[0])print(len(x_seq[0]))

max_train_len: 676

[ 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
    ...
0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0 0 0 0 0 0 0 5 2 58 8 329 185 9 146 70 9 424
714 146 133 172 73 168 116 146 152 168 146 307 21 87 119 50 9 98
15 803 552 9 146 133 600 572 521 164 284 98 59 766 477 714 926 237
715 135 150 394 235 9 527 146 133 164 284 146 133 364 9 982 600 146
133 431 714 573 767 146 152 146 215 186 146 133 235 573 477 714 926 237
89 586 119 477 164 284 364 164 284 714 9 527 146 133 235 573 846 364
146 133 235 19 146 235 116 152 751 714 9 186 364 168 572 490 146 133
235 573 146 152 173 7 2 6 733 509]
676

可以看到前面补充的位置都设为了0。


结语

本文算是近段时间对于文本特征提取方法的实操总结,更为先进的文本特征提取方法,比如ELMO、BERT等还未学习到,后面有余力去学习。当然,针对不同的文版数据和应用场景去选择合适的特征提取方法,我还需要不断的增加实操经验和理论学习,下一篇会写一写文本特征降维的话题,敬请期待~


推荐阅读

这个NLP工具,玩得根本停不下来

征稿启示| 200元稿费+5000DBC(价值20个小时GPU算力)

完结撒花!李宏毅老师深度学习与人类语言处理课程视频及课件(附下载)

从数据到模型,你可能需要1篇详实的pytorch踩坑指南

如何让Bert在finetune小数据集时更“稳”一点

模型压缩实践系列之——bert-of-theseus,一个非常亲民的bert压缩方法

文本自动摘要任务的“不完全”心得总结番外篇——submodular函数优化

Node2Vec 论文+代码笔记

模型压缩实践收尾篇——模型蒸馏以及其他一些技巧实践小结

中文命名实体识别工具(NER)哪家强?

学自然语言处理,其实更应该学好英语

斯坦福大学NLP组Python深度学习自然语言处理工具Stanza试用

关于AINLP

AINLP 是一个有趣有AI的自然语言处理社区,专注于 AI、NLP、机器学习、深度学习、推荐算法等相关技术的分享,主题包括文本摘要、智能问答、聊天机器人、机器翻译、自动生成、知识图谱、预训练模型、推荐系统、计算广告、招聘信息、求职经验分享等,欢迎关注!加技术交流群请添加AINLPer(id:ainlper),备注工作/研究方向+加群目的。


阅读至此了,分享、点赞、在看三选一吧🙏

登录查看更多
2

相关内容

【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
85+阅读 · 2020年6月28日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
最新《自动微分手册》77页pdf
专知会员服务
97+阅读 · 2020年6月6日
【实用书】Python数据科学从零开始,330页pdf
专知会员服务
139+阅读 · 2020年5月19日
【经典书】Python数据数据分析第二版,541页pdf
专知会员服务
189+阅读 · 2020年3月12日
【经典书】精通机器学习特征工程,中文版,178页pdf
专知会员服务
347+阅读 · 2020年2月15日
NLP基础任务:文本分类近年发展汇总,68页超详细解析
专知会员服务
57+阅读 · 2020年1月3日
文本分析与可视化
Python程序员
8+阅读 · 2019年2月28日
文本挖掘中特征选择(附python实现)
七月在线实验室
4+阅读 · 2018年5月22日
【干货】--基于Python的文本情感分类
R语言中文社区
5+阅读 · 2018年1月5日
自然语言处理(4)之中文文本挖掘流程详解(小白入门必读)
机器学习算法与Python学习
5+阅读 · 2017年12月22日
文本分析 | 常用距离/相似度 一览
数说工作室
26+阅读 · 2017年10月12日
文本挖掘之特征选择(python 实现)
数据挖掘入门与实战
4+阅读 · 2017年7月19日
【宁波站】网络爬虫与文本挖掘
数萃大数据
4+阅读 · 2017年7月19日
Tutorial on NLP-Inspired Network Embedding
Arxiv
7+阅读 · 2019年10月16日
Simplifying Graph Convolutional Networks
Arxiv
7+阅读 · 2019年6月20日
Phase-aware Speech Enhancement with Deep Complex U-Net
Attend More Times for Image Captioning
Arxiv
6+阅读 · 2018年12月8日
Arxiv
6+阅读 · 2018年8月27日
Arxiv
3+阅读 · 2018年6月19日
Arxiv
3+阅读 · 2017年8月15日
VIP会员
相关VIP内容
【2020新书】从Excel中学习数据挖掘,223页pdf
专知会员服务
85+阅读 · 2020年6月28日
一份简明有趣的Python学习教程,42页pdf
专知会员服务
76+阅读 · 2020年6月22日
最新《自动微分手册》77页pdf
专知会员服务
97+阅读 · 2020年6月6日
【实用书】Python数据科学从零开始,330页pdf
专知会员服务
139+阅读 · 2020年5月19日
【经典书】Python数据数据分析第二版,541页pdf
专知会员服务
189+阅读 · 2020年3月12日
【经典书】精通机器学习特征工程,中文版,178页pdf
专知会员服务
347+阅读 · 2020年2月15日
NLP基础任务:文本分类近年发展汇总,68页超详细解析
专知会员服务
57+阅读 · 2020年1月3日
相关资讯
文本分析与可视化
Python程序员
8+阅读 · 2019年2月28日
文本挖掘中特征选择(附python实现)
七月在线实验室
4+阅读 · 2018年5月22日
【干货】--基于Python的文本情感分类
R语言中文社区
5+阅读 · 2018年1月5日
自然语言处理(4)之中文文本挖掘流程详解(小白入门必读)
机器学习算法与Python学习
5+阅读 · 2017年12月22日
文本分析 | 常用距离/相似度 一览
数说工作室
26+阅读 · 2017年10月12日
文本挖掘之特征选择(python 实现)
数据挖掘入门与实战
4+阅读 · 2017年7月19日
【宁波站】网络爬虫与文本挖掘
数萃大数据
4+阅读 · 2017年7月19日
相关论文
Tutorial on NLP-Inspired Network Embedding
Arxiv
7+阅读 · 2019年10月16日
Simplifying Graph Convolutional Networks
Arxiv
7+阅读 · 2019年6月20日
Phase-aware Speech Enhancement with Deep Complex U-Net
Attend More Times for Image Captioning
Arxiv
6+阅读 · 2018年12月8日
Arxiv
6+阅读 · 2018年8月27日
Arxiv
3+阅读 · 2018年6月19日
Arxiv
3+阅读 · 2017年8月15日
Top
微信扫码咨询专知VIP会员