NLP自然语言处理实战(一):利用分词器构建词汇表

在NLP中,分词(tokenization,也称分词)是一种特殊的文档切分(segmentation)过程。而文档切分能够将文本拆分成更小的文本块或片段,其中含有更集中的信息内容。文档切分可以是将文档分成段落,将段落分成句子,将句子分成短语,或将短语分成词条(通常是词)和标点符号。

1.简单分词

1.1split分词

对句子进行切分的最简单方法就是利用字符串中的空白符来作为词的“边界”。在python中可以通过标准库方法split来实现这种操作。

sentence = """Thomas Jefferson began building Monticello at the age of 26."""
print(sentence.split())

Out[1]:[‘Thomas’, ‘Jefferson’, ‘began’, ‘building’, ‘Monticello’, ‘at’, ‘the’, ‘age’, ‘of’, ‘26.’]
正如大家看到的那样,split方法已经对这个简单的句子进行了相当不错的分词处理,仅仅在最后那个词上出现一条“错误”,即将句尾的标点符号也归入词条当中而得到“26.”通常来说,我们都希望句子中的某个词条和周围的标点符号及其他有意义的词条分开。“26.”是浮点数26.0的完美表示结果,但是这样的话,它和出现在语料库句子中的“26”及可能出现在问句句尾的"26?"就完全不是一回事了。一个优秀的分词器应该去掉上面词条中的额外的字符而得到“26”,它是词”26,“”26!“”26?“”26.“的等价类表示结果。此外一个更为精确的分词器应该也将句尾的标点符号作为词条输出,这样句子切分工具或者边界检测工具才能确定句子的结束位置。


1.2独热向量

我们构建每个词的数值向量表示,这些向量称为独热向量(one-hot vector)。这些向量构成的序列能够以向量序列(数字构成的表格)的方式完美捕捉原始文本。

sentence = """Thomas Jefferson began building Monticello at the age of 26."""
import numpy as np
token_sequence = sentence.split()  # split是当前临时应急的分词器
vocab = sorted(set(token_sequence))  # 列举所有想要记录的独立词条(词)
print(','.join(vocab))
num_tokens = len(token_sequence)
vocab_size = len(vocab)
onehot_vectors = np.zeros((num_tokens, vocab_size), int)
for i, word in enumerate(token_sequence):  # 对于句子中的每个词,将词汇表中与该词对应的列标为1
    onehot_vectors[i, vocab.index(word)] = 1
print(onehot_vectors)

Out[1]:26.,Jefferson,Monticello,Thomas,age,at,began,building,of,the
Out[2]:
[
[0 0 0 1 0 0 0 0 0 0]
[0 1 0 0 0 0 0 0 0 0]
[0 0 0 0 0 0 1 0 0 0]
[0 0 0 0 0 0 0 1 0 0]
[0 0 1 0 0 0 0 0 0 0]
[0 0 0 0 0 1 0 0 0 0]
[0 0 0 0 0 0 0 0 0 1]
[0 0 0 0 1 0 0 0 0 0]
[0 0 0 0 0 0 0 0 1 0]
[1 0 0 0 0 0 0 0 0 0]]


为了让结果看起来更加清晰明朗,我们引入行列,并且将0替换成空格

import pandas as pd
df = pd.DataFrame(onehot_vectors, columns=vocab)
df[df == 0] = ''
print(df)

Out[1]:在这里插入图片描述


上述表格的每一行都是一个二值的行向量,这就是该向量称为独热向量的原因:这一行的元素除一个位置之外都是0或者空白,而只有该位置上是”热“的(为1)。我们可以在NLP流水线中使用向量[0,0,0,0,0,0,1,0,0,0]来表示词”began“。


1.3词袋向量

上述基于独热向量的句子表示方法保留了原始句子的所有细节,包括语法和词序。但是,相对于上述的短句子而言的整个表格却很大,对长文档来说这种做法不太现实。如果把所有的独热向量加在一起,而不是一次一次地”回放“它们,我们会得到一个词袋向量。这个向量也被称为词频向量,因为它只计算了词的频率,而不是词的顺序。

sentences = """Thomas Jefferson began building Monticello at the age of 26.\n"""
sentences += """Construction was done mostly by local masons and carpenters.\n"""
sentences += """He moved into the South Pavilion in 1770.\n"""
sentences += """Turning Monticello into a neoclassical masterpiece was Jefferson's obsession."""
corpus = {}
for i, sent in enumerate(sentences.split('\n')):
    corpus['sent{}'.format(i)] = dict((token, 1) for token in sent.split())
df = pd.DataFrame.from_records(corpus).fillna(0).astype(int).T
print(df)

Out[1]:在这里插入图片描述


2.度量词袋之间的重合度

用点积来判断两个句子的相似度

df = df.T
print(df['sent0'].dot(df['sent1']))
print(df['sent0'].dot(df['sent2']))
print(df['sent0'].dot(df['sent3']))

Out[1]:0
Out[2]:1
Out[3]:1
结果表明有一个词同时出现在sent0和sent2中,同理,某个词同时出现在sent0和sent3中。词之间的重合度可以作为句子相似度的一种度量方法。
下面给出了一种找出sent0和sent3当中那个共享词的方法。

print([(k, v) for (k, v) in (df['sent0'] & (df['sent3'])).items() if v])

Out[1]:[(‘Monticello’, 1)]


3.标点符号的处理

3.1正则表达式

有关正则表达式更多详情请点击。。。

import re
sentence = """Thomas Jefferson began building Monticello at the age of 26."""
pattern = re.compile(r'([-\s.,;!?])+')
tokens = pattern.split(sentence)
print(tokens)
print([x for x in tokens if x and x not in '- \t\n.,;!?'])

Out[1]:[‘Thomas’, ’ ', ‘Jefferson’, ’ ', ‘began’, ’ ', ‘building’, ’ ', ‘Monticello’, ’ ', ‘at’, ’ ', ‘the’, ’ ', ‘age’, ’ ', ‘of’, ’ ', ‘26’, ‘.’, ‘’]
Out[2]:[‘Thomas’, ‘Jefferson’, ‘began’, ‘building’, ‘Monticello’, ‘at’, ‘the’, ‘age’, ‘of’, ‘26’]


3.2NLTK

from nltk.tokenize import RegexpTokenizer
sentence = """Thomas Jefferson began building Monticello at the age of 26."""
tokenizer = RegexpTokenizer(r'\w+|$[0-9.]+|\S+')
print(tokenizer.tokenize(sentence))

Out[1]:[‘Thomas’, ‘Jefferson’, ‘began’, ‘building’, ‘Monticello’, ‘at’, ‘the’, ‘age’, ‘of’, ‘26’, ‘.’]


一个更好的分词器来自NLTK包中的TreebankWordTokenizer分词器,它内置了多种常见的英语分词规则,例如,它从相邻的词条中将短语结束符号(?!.;,)分开,将包含句号的小数当成单个词条。此外,它还包含一些英语缩略语的规则,例如,”don‘t“会切分成[“do”,“n’t”]。该分词器将有助于NLP流水线的后续步骤,如词干还原。

from nltk.tokenize import TreebankWordTokenizer
sentence = """Monticello wasn't designated as UNESCO World Heritage Site until 1987."""
tokenizer = TreebankWordTokenizer()
print(tokenizer.tokenize(sentence))

Out[1]:[‘Monticello’, ‘was’, “n’t”, ‘designated’, ‘as’, ‘UNESCO’, ‘World’, ‘Heritage’, ‘Site’, ‘until’, ‘1987’, ‘.’]


3.3缩略语

对一些应用来说,例如使用句法树的基于语法的NLP模型,将wasn’t分成was和not很重要,这样可以使句法树分析器能够将与已知语法规则保持一致并且可预测的词条集作为输入。存在大量标准和非标准的缩略词处理方法。通过将缩略语还原为构成它的各个词,只需要对依存树分析器或者句法分析器进行编程以预见各词的不同拼写形式,而不需要面对所有可能的缩略语。
NLTK库中包含一个分词器casual_tokenize,该分词器用于处理来自社交网络的非规范的包含表情符号的短文本。
casual_tokenize函数可以剥离文本中的用户名,也可以减少词条内的重复字符数。

from nltk.tokenize.casual import casual_tokenize
message = """RT @TJMonticello Best day everrrrrrr at Monticello.Awesommmmmmeeeeeeee day :*)"""
print(casual_tokenize(message))
print(casual_tokenize(message, reduce_len=True, strip_handles=True))

Out:在这里插入图片描述


4.将词汇表扩展到n-gram

4.1 n-gram

n-gram是一个最多包含n个元素的序列,这些元素从由它们组成的序列(通常是字符串)中提取而成。例如2-gram可以指的是两个词构成的队,如“ice cream”。
当一个词条列向量化成词袋向量时,它丢失了词序中所包含的很多含义。如果不考虑n-gram,那么单词“not”就会自由漂移,而不会固定在某几个词周围,其否定的含义可能就会与整个句子甚至整篇文档,而不是只与某几个相邻词关联。

from nltk.util import ngrams
sentence = """Thomas Jefferson began building Monticello at the age of 26."""
pattern = re.compile(r'([-\s.,;!?])+')
tokens = pattern.split(sentence)
tokens = [x for x in tokens if x and x not in '- \t\n.,;!?']
two_grams = list(ngrams(tokens, 2))
print([" ".join(x) for x in two_grams])

Out[1]:[‘Thomas Jefferson’, ‘Jefferson began’, ‘began building’, ‘building Monticello’, ‘Monticello at’, ‘at the’, ‘the age’, ‘age of’, ‘of 26’]
如果这些n-gram出现得非常少,它们就不会承载太多其他词的关联信息,而这些关联信息可以用于帮助识别文档的主题,这些主题可以将多篇文档或者多个文档类连接起来。


4.2 停用词

在任何一种语言中,停用词(stop word)指的是那些出现频率非常高的常见词,但是对短语的含义而言,这些词承载的实质性信息内容却少得多。一些常用的停用词如下:

  • a, an
  • the, this
  • and, or
  • of, on
    大家可能会对词汇表大小导致所需的任何训练集的大小表示担心,训练集要足够大以避免对任何具体词或者词的组合造成过拟合。训练集的大小会决定对它的处理量,但是,从20000个词中剔除100个停用词不会显著加快上述处理过程,对2-gram词汇表而言,通过剔除停用词而获得的好处无足轻重。此外,如果不对使用停用词的2-gram频率进行检查就武断地剔除这些停用词的话,可能会丢失很多信息。
    因此,如果我们有足够的内存和处理带宽来运行大规模词汇表下NLP流水线中的所有步骤,那么可能不必为在这里或那里忽略几个不重要的词而忧虑不已。如果担心大规模词汇表与小规模训练集之间发生过拟合的话,那么有比忽略停用词更好的方法来选择词汇表或者降维。

5.词表归一化

5.1 大小写转换

将单词或字符的大小写统一是一种减小词汇表规模的方法(case folding)。但是,单词的大写有时候也包含了一些特定的含义,例如"doctor"和’Doctor"往往具有不同的含义。如果命名实体识别对NLP流水线而言很重要的话,我么就希望能够识别出上面那些不同于其他单词的专有名词。然而,如果词条不进行大小写归一处理,那么词汇表的规模就大约是原来的两倍,需要消耗的内存和处理时间也大约是原来的两倍,这样可能会增加需要标注的训练数据的数量以保证机器学习流水线收敛到精确的通用解。
在python中,利用列表解析式能够很方便地对词条进行大小归一化处理:

tokens = ['House', 'Visitor', 'Center']
normalized_tokens = [x.lower() for x in tokens]
print(normalized_tokens)

Out[1]:[‘house’, ‘visitor’, ‘center’]
不幸的是这种做法处理会将我们希望的那些意义不大的句首大写字母归一化,也会将很多有意义的大小写形式给归一化掉,一个更好的大小写归一化方法是只将句首大写字母转成小写。
即使采用这种小心谨慎的大小写处理方法,也会遇到某些情况下专有名词出现在句首而导致的错误。为了避免可能的信息损失,很多NLP流水线根本不进行大小写归一化处理。在很多应用中,将词汇表规模减小一半带来的效率提升(存储和处理)会大于专有名词的信息损失。拥有真正完善手段的流水线会在选择性地归一化那些出现在句首但明显不是专有名词的词之前。


5.2 词干还原

另一种常用的词汇表归一化技术是消除词的复数形式、所有格的词尾甚至不同的动词形式等带来的意义上的微小差别。例如,housing和houses的公共词干是house。词干还原过程会去掉词的后缀,从而试图将具有相似意义的词归并到其公共词干。不一定要求词干必须是一个拼写正确的词,而只需要是一个能够代表词的多种可能拼写形式的词条或者标签。
词干还原的主要好处之一是,机器中的软件或语言模型所需记录其意义的词的个数得以压缩。它在限制信息或意义损失的同时,会尽可能减小词汇表的规模,这在机器学习中称为降维。它能够帮助泛化语言模型,使模型能够在属于同一词干的词上表现相同。
然而,词干还原可能会大幅度降低搜索引擎的正确率得分,这是因为在返回相关文档的同时可能返回了大量不相关文档,例如在搜索“developing houses in Portland”时,返回的页面或者文档可以同时包含"house",“houses”,甚至"housing",因为这些词都会还原成词干"house",同样,返回的页面除了包含"developing",还可以包含"developer"和"development",因为它们都可以还原成词干"develop"。

from nltk.stem.porter import PorterStemmer
stemmer = PorterStemmer()
print(' '.join([stemmer.stem(w).strip("'") for w in "dish washer's washed dishes".split()]))

Out[1]:dish washer wash dish


5.3 词形归并

如果知道词义之间可以互相关联,那么可能就能将一些词关联起来,即使它们的拼写完全不一样。这种更粗放的将词归一化成语义词根即词元(lemma)的方式称为词形归并(lemmatization)。由于考虑了词义,相对于词干还原和大小写归一化,词形归并是一种潜在的更具有精确性的词的归一化方法。
设想一下如何使用词性信息从而比使用词干还原更好地识别词的"词根"?考虑词better,词干还原工具可能会去掉better词尾的er,从而得到bett或bet。但是这样做会将better和betting、bets和Bet’s混在一起,而一些更相近的词如betterment、best甚至good却被排除在外。
因此,在很多应用中词形归并比词干还原更有效。词干还原工具实际上仅仅用于大规模信息检索应用(关键词搜索)中。如果我们真的希望在信息检索流水线中通过词干还原工具进行降维和提高召回率,那么可能需要在使用词干还原工具之前先使用词形归并工具。由于词元本身是一个有效的英文词,词干还原工具作用于词形归并的输出会很奏效。这种技巧回避单独使用词干还原工具能够更好地降维和提高信息检索的召回率。


6. 情感

无论NLP流水线中使用的是单个词、n-gram、词干还是词元作为词条,每个词条都包含了一些信息。这些信息中的一个重要部分是词的情感,即一个词所唤起的总体感觉或感情。这种度量短语或者文本块的情感的任务称为情感分析(sentiment analysis),是NLP中的一个常见应用。
有两种情感分析的方法,分别是:

  • 基于规则的算法,规则由人来攥写
  • 基于机器学习的模型,模型是机器从数据中学习而得到

第一种情感分析的方法使用用户设计的规则(有时也称为启发式规则)来度量文本的情感。一个常用的基于规则的方法是在文本中寻找关键词,并将每个关键词映射到某部字典或者映射上的数值得分或权重。

第二种基于机器学习的方法利用一系列标注语句或者文档来训练机器学习模型以产生规则。需要大量标注好“正确”情感得分的文本数据。

6.1 VADER:一个基于规则的情感分析器

from vaderSentiment.vaderSentiment import SentimentIntensityAnalyzer
sa = SentimentIntensityAnalyzer()
print([(tok, score) for tok,score in sa.lexicon.items()])

Out[1]:[(‘$:’, -1.5), (‘%)’, -0.4), (‘%-)’, -1.5), (‘&-:’, -0.4), (‘&:’, -0.7), (“( ‘}{’ )”, 1.6), (‘(%’, -0.9), (“('-:”, 2.2)…]
这里的分词其最擅长处理标点符号和表情符号,这样VADER才能更好地工作。

print(sa.polarity_scores(text="Python is very readable and it's great for NLP."))
print(sa.polarity_scores(text="Python is not a bad choice for most applications."))

Out[1]:{‘neg’: 0.0, ‘neu’: 0.661, ‘pos’: 0.339, ‘compound’: 0.6249}
Out[2]:{‘neg’: 0.0, ‘neu’: 0.737, ‘pos’: 0.263, ‘compound’: 0.431}
VADER算法用3个不同的分数(正向、负向和中立)来表达情感极性的强度,然后将它们组合在一起得到一个复合的情感倾向性得分。

corpus = ["Absolutely perfect! Love it! :-) :-) :-)","Horrible!Completely useless. :(","It was OK.Some good and some bad things."]
for doc in corpus:
    scores = sa.polarity_scores(doc)
    print('{:+}:{}'.format(scores['compound'],doc))

在这里插入图片描述
VADER的唯一不足在于,它只关注其词库中的7500个词条,而非文档中的所有词。


6.2朴素贝叶斯

from nlpia.data.loaders import get_data
movies = get_data('hutto_movies')
print(movies.head().round(2))
print(movies.describe().round(2))

在这里插入图片描述

import pandas as pd
pd.set_option('display.width', 75)
from nltk.tokenize import casual_tokenize # 相对于TreebankWordTokenizer分词器或者其它分词器,NLTK的casual_tokenize可以更好地处理表情符号、不寻常的标点符号以及行业术语
bags_of_words = []
from collections import Counter # python内置的Counter的输入是一系列对象,然后对这些对象进行计数,并返回一部字典,其中键是对象本身(这里是词条),值是这些对象计数后得到的整数值
for text in movies.text:
    bags_of_words.append(Counter(casual_tokenize(text)))
df_bows = pd.DataFrame.from_records(bags_of_words) # DataFrame构造器from——records()的输入是一个字典的序列,它为所有键构建列,值被加入合适的列对应的表格中,而缺失值用NaN进行填充
df_bows = df_bows.fillna(0).astype(int) # Numpy和Pandas只能用浮点对象来表示NaN,因此一旦将所有NaN填充为0,可以将DataFrame转换为整数,这样在内存存储和显示上可以紧凑的多
print(df_bows.shape)
print(df_bows.head())

在这里插入图片描述
现在我们拥有了朴素贝叶斯模型所需要的所有数据,利用这些数据可以从自然语言文本中寻找那些预测情感的关键词:

from sklearn.naive_bayes import MultinomialNB
nb = MultinomialNB()
nb = nb.fit(df_bows,movies.sentiment > 0) # 朴素贝叶斯是分类器,因此需要将输出的变量(代表情感的浮点数)转换成离散的标签(整数、字符串或者布尔值)
movies['predicted_sentiment'] = nb.predict(df_bows).astype(int) * 8 - 4# 将二值的分类结果变量(0或1)转换到-4到4之间,从而能够和标准情感得分进行比较。利用np.predict_proba可以得到一个连续值
movies['error'] = (movies.predicted_sentiment - movies.sentiment).abs()
print(round(movies.error.mean(), 1))
movies['sentiment_ispositive'] = (movies.sentiment > 0).astype(int)
movies['predicted_ispositive'] = (movies.predicted_sentiment > 0).astype(int)
print(movies['''sentiment predicted_sentiment sentiment_ispositive predicted_ispositive'''.split()].head(5))
print((movies.predicted_ispositive == movies.sentiment_ispositive).sum() / len(movies))

在这里插入图片描述
平均预测错误绝对值(也称为MAE)是2.4
点赞评级的正确率是93%
另外,朴素贝叶斯模型没有像VADER一样处理否定词。我们必须要将n-gram放到分词器中才能够将否定词(如“not”和“never”)与其修饰的可能要用的正向词关联起来。

博文的 java 实现,可以自动抽取语料库中的词汇,可以作为自然语言处理的第步,准备词典。成词条件互信息左右熵位置成词概率ngram 频率运行方法下载或者gradle distTar打包程序解压dict_build-x.x.x.tar解压之后,进入bin. 运行:./dict_build 你的数据文件的绝对路径结束之后,在数据文件同目录有文件:words_sort.data四列分别为:词,词频,互信息,左右熵,位置成词概率.示例《金瓶梅》抽取结果西门庆  4754    6.727920454563199   2.0315193024276885  0.17472535684926388 月娘    1829    6.491853096329675   2.3714166640957095  0.22135096835144072 敬济    906 9.084808387804362   2.554594603718855   0.14485683987274656 春梅    799 8.134426320220927   2.7880175589451714  0.16484505593416485 玳安    796 8.228818690495881   2.865686193737731   0.11791820110723605 后边    617 6.6293566200796095  4.008365154080131   0.2160373686259245 玉楼    594 7.977279923499917   2.27346284978306    0.27518689925240297 明日    580 6.189824558880018   2.705423396095033   0.1774535638537181 两银子  458 6.129283016944967   2.351100547282295   0.3809078896437581 小厮    454 7.257387842692652   3.945653525477103   0.16666666666666666 打发    444 6.870364719583405   3.694604352707633   0.18409496065046307 如今    410 6.643856189774725   2.1460777430093394  0.1780766096169519 淫妇    382 7.768184324776926   3.277903508489837   0.2555205047318612 桂姐    371 7.584962500721156   2.5922046565140424  0.36255305256284687 老婆    331 6.266786540694902   3.5783015008688523  0.3758007117437722 衣服    309 8.90388184573618    2.786139685416002   0.13284518828451883 丫头    297 7.383704292474053   4.291010086795063   0.21875 潘金莲  288 8.276124405274238   2.4955186567189194  0.35333669524289796 昨日    285 6.857980995127572   2.6387249970833997  0.1774535638537181 王婆    284 7.1799090900149345  2.3129267619188907  0.3758007117437722《西游记》抽取结果八戒    1807    7.88874324889826    2.00952580557629    0.36441586280814575 师父    1632    7.507794640198696   3.745294449785798   0.1371395690812608 大圣    1270    6.599912842187128   2.7790919785432147  0.13128460061010055 唐僧    1003    7.076815597050832   4.350465172292435   0.43277723258096173 菩萨    765 9.471675214392045   3.6013747138664756  0.15910495734948696 妖精    634 7.199672344836364   3.1817261900583627  0.13134411600669268 徒弟    439 8.060695931687555   2.498555429145656   0.15553809897879026 兄弟    284 7.845490050944376   2.93037668783551    0.16085578446909668 宝贝    283 9.319672120946995   2.616164396748633   0.15108220492589827 今日    282 6.714245517666122   2.1303069812971214  0.1774535638537181 取经    263 7.539158811108032   2.663944888382171   0.10181178023912565 如今    259 6.189824558880018   2.056188859866133   0.1780766096169519 认得    223 6.357552004618085   2.9543379335926954  0.2326782564877803 东土    212 8.422064766172811   3.326253983395916   0.14745277618775043 孙大圣  202 6.022367813028454   2.4886576514017107  0.13128460061010055 变作    189 7.554588851677638   3.0713596792578635  0.23452975920036348 玉帝    189 8.912889336229961   2.973106046717708   0.27518689925240297 土地    179 7.499845887083206   3.1206506190132566  0.2819944064037033 欢喜    173 8.861086905995393   2.184918471204895   0.31727272727272726 贫僧    170 7.400879436282184   2.0731236036504477  0.43277723258096173拉勾JD语料抽取结果工作  641962  11.645208082774683  4.083574124851783   0.11247281022865935 开发  348538  14.031184262140844  4.37645153459778    0.18409496065046307 相关  300517  10.477758266443889  5.038915743418073   0.1758213331033888 合作  159688  10.397674632948268  3.9963476653135794  0.19498851077798446 专业  158831  10.712527000439824  3.152041650598071   0.2640750670241287 测试  158179  13.65362883340751   4.464104436545589   0.18344308560677328 互联网   148818  16.106992250086762  3.9556191209604314  0.407386403912951 活动  131099  10.391243589427443  3.9155422678129406  0.20137250696976194 维护  120316  12.681677655209691  3.2400117935377266  0.1960306406685237 问题  112116  9.159871336778389   2.314215135279833   0.20283174185051037 优化  109563  11.324180546618742  4.331660381832997   0.2456782591010779 营销  105845  14.36850646150769   5.097001962525406   0.14961371773129828 平台  100783  9.002815015607053   4.443804901153697   0.2877423571272965 培训  93204   9.041659151637216   3.8898570467819824  0.13345998575160295 资源  90339   8.651051691178928   4.063430372719874   0.14695817490494298 相关专业    87545   8.988684686772165   2.4897196388075598  0.2905199904149232 网站  87182   8.92184093707449    5.465843476701055   0.21266038137095059 独立  86111   9.074141462752506   3.1456261690072957  0.19050261614079594 定  83798   8.335390354693924   2.107303660112154   0.26157299167679793 流程  83165   9.321928094887362   2.5509378861028074  0.2063141084699957 网络  82742   9.087462841250339   4.681429111504988   0.21266038137095059 优秀  74600   9.370687406807217   2.0756995478573135  0.2899855507391353 信息  71009   9.820178962415188   4.2602697278449755  0.18863532864443658 媒体  67533   10.556506054671928  4.615376861300178   0.17976710334788937 编写  64337   7.960001932068081   3.482400585501417   0.265625 思维  62351   8.741466986401146   2.4320664807326646  0.15396736072031514 规划  59733   7.851749041416057   2.936854928368285   0.14166201896263245 移动  59671   10.10459875356437   3.4421932833155653  0.20137250696976194 渠道  59072   9.513727595952437   4.597891463808354   0.23578595317725753 关系  58483   8.348728154231077   2.4369558675502927  0.3170022612253688 积极  57295   9.044394119358454   2.763249521041074   0.1746848469256496 实施  56645   7.781359713524661   4.371966846513886   0.15944453739334113 福利  55732   8.475733430966399   2.4036919305145426  0.20908952728378172 其他  55665   8.434628227636725   2.9614863103296867  0.15943975441289332 功能  55087   7.787902559391432   4.1663586610392755  0.18097560975609756 代码  52431   7.88874324889826    3.876917512626917   0.2135697048449972 微信  49143   8.945443836377912   3.6868130380800643  0.18215857916308253 企业  48799   9.422064766172813   5.568662443510237   0.2905199904149232 提升  48446   8.233619676759702   3.7390647282620666  0.29750778816199375 质量  47918   10.861862340059153  3.391825261582227   0.10921827734437191 人员  47109   7.774787059601174   5.249783964892326   0.13589632038101343 数据库   45445   8.290018846932618   4.123423571610193   0.2640569395017794 商务  44047   8.189824558880018   3.44858516585648    0.12901085044961344 主动  42628   13.815583433851023  2.5049637884195137  0.1968791796700847 创意  41768   14.396470993910388  4.115068825929573   0.30544056771141337 工具  40227   9.927777962082342   2.208874047820781   0.11247281022865935 等相关   39230   11.919608238603255  3.0330398736413557  0.1758213331033888 提出  38741   10.179909090014934  4.46446156782086    0.13053040103492886 各类  38309   8.344295907915816   5.136417986953123   0.3969948596283116 操作  37061   9.06339508128851    4.676836974292029   0.23452975920036348 收集  36600   8.800899899920305   2.797691452951563   0.11388512456999896 过程  36534   8.214319120800766   2.5633950372758565  0.2063141084699957 数据分析    36081   8.442943495848729   3.5589033442862585  0.2640569395017794 标签:dictbuild
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值