精华内容
下载资源
问答
  • 今天我们来分享一下word怎么组织架构图,那么,什么是组织架构图呢?它是表现雇员、职称和群体关系的一种图表,形象的反映了组织内各机构、岗位和上下左右相互之间的关系。一个架构图就能一目了然各个部门之间的...

    今天我们来分享一下word怎么做组织架构图,那么,什么是组织架构图呢?它是表现雇员、职称和群体关系的一种图表,形象的反映了组织内各机构、岗位和上下左右相互之间的关系。一个架构图就能一目了然各个部门之间的相互关系,下面我们来看看SmartArt秒做组织架构图的操作。在这里插入图片描述
    首先要明确各部门之间的层级关系,如下图例子,总经理是最高领导是第一级,所以在【总经理】三个字前面按Tab键一次即可。三位副总由总经理所管理,层级仅次于他,所以是二级,都按Tab键两次。生产部和研发部都由生产副总所管理,所以这两个部门是他的下级,即是第三级,都按Tab键三下,以此类推。在这里插入图片描述
    把职位等级分好了之后呢,接着全选后按Ctrl+X 剪切内容,再点击插入,找到SmartArt这个按键(在WPS中叫做智能图形)。然后选择层次结构,点击插入,再单击左侧的小箭头,在弹出的编辑框中,按ctrl+v粘贴内容。在这里插入图片描述在这里插入图片描述
    这样组织架构图就做好啦,如果你还想换样式的话,点击右键,会出现样式、颜色、布局的选择栏,按你的喜好来设定就可以了。在这里插入图片描述
    看了以上操作,是不是很简单呢,你学会了吗?如果能帮助到你的话,赶快关注我吧,与你分享更多office小技巧。

    展开全文
  • 系统有个相应的模板,模板让用户填写内容最后生成相应的文件。我需要这个框架很灵活,因为我需要让用户填写意见,意见有编号,个数不定的。
  • 如何使用 word2vec 来推荐系统

    千次阅读 2019-08-09 18:00:00
    点击上方“AI派”,选择“设为星标”最新分享,第一时间送达!译者 | Arno来源 | Analytics Vidhy这篇文章主要介绍了如何使用word2vec构建推荐系...
        
    点击上方“AI派”,选择“设为星标
    最新分享,第一时间送达!640?wx_fmt=gif

    640?wx_fmt=png

    译者 | Arno

    来源 | Analytics Vidhy


    这篇文章主要介绍了如何使用word2vec构建推荐系统。

    概览

    完整的代码可以从这里下载:

    https://github.com/prateekjoshi565/recommendation_system/blob/master/recommender_2.ipynb

     介绍

    老实说,你在亚马逊上有注意到网站为你推荐的内容吗(Recommended for you部分)? 自从几年前我发现机器学习可以增强这部分内容以来,我就迷上了它。每次登录Amazon时,我都会密切关注该部分。

    Netflix、谷歌、亚马逊、Flipkart等公司花费数百万美元完善他们的推荐引擎是有原因的,因为这是一个强大的信息获取渠道并且提高了消费者的体验。

    让我用一个最近的例子来说明这种作用。我去了一个很受欢迎的网上市场购买一把躺椅,那里有各种各样的躺椅,我喜欢其中的大多数并点击了查看了一把人造革手动躺椅。

    640?wx_fmt=png

    请注意页面上显示的不同类型的信息,图片的左半部分包含了不同角度的商品图片。右半部分包含有关商品的一些详细信息和部分类似的商品。

    而这是我最喜欢的部分,该网站正在向我推荐类似的商品,这为我节省了手动浏览类似躺椅的时间。

    在本文中,我们将构建自己的推荐系统。但是我们将从一个独特的视角来处理这个问题。我们将使用一个NLP概念--Word2vec,向用户推荐商品。如果你觉得这个教程让你有点小期待,那就让我们开始吧!

    在文中,我会提及一些概念。我建议可以看一下以下这两篇文章来快速复习一下

    理解神经网络: https://www.analyticsvidhya.com/blog/2017/05/neural-network-from-scratch-in-python-and-r/?utm_source=blog&    utm_medium=how-to-build-recommendation-system-word2vec-python
    构建推荐引擎的综合指南:
    https://www.analyticsvidhya.com/blog/2018/06/comprehensive-guide-recommendation-engine-python/?utm_source=blog&utm_medium=how-to-build-recommendation-system-word2vec-python

    word2vec - 词的向量表示

    我们知道机器很难处理原始文本数据。事实上,除了数值型数据,机器几乎不可能处理其他类型的数据。因此,以向量的形式表示文本几乎一直是所有NLP任务中最重要的步骤。

    在这个方向上,最重要的步骤之一就是使用 word2vec embeddings,它是在2013年引入NLP社区的并彻底改变了NLP的整个发展。

    事实证明,这些 embeddings在单词类比和单词相似性等任务中是最先进的。word2vec embeddings还能够实现像 King - man +woman ~= Queen之类的任务,这是一个非常神奇的结果。

    有两种⁠word2vec模型——Continuous Bag of Words模型和Skip-Gram模型。在本文中,我们将使用Skip-Gram模型。

    首先让我们了解word2vec向量或者说embeddings是怎么计算的。

    如何获得word2vec embeddings?

    word2vec模型是一个简单的神经网络模型,其只有一个隐含层,该模型的任务是预测句子中每个词的近义词。然而,我们的目标与这项任务无关。我们想要的是一旦模型被训练好,通过模型的隐含层学习到的权重。然后可以将这些权重用作单词的embeddings。

    让我举个例子来说明word2vec模型是如何工作的。请看下面这句话:

    640?wx_fmt=png

    假设单词“teleport”(用黄色高亮显示)是我们的输入单词。它有一个大小为2的上下文窗口。这意味着我们只考虑输入单词两边相邻的两个单词作为邻近的单词。

    注意:上下文窗口的大小不是固定的,可以根据我们的需要进行更改。

    现在,任务是逐个选择邻近的单词(上下文窗口中的单词),并给出词汇表中每个单词成为选中的邻近单词的概率。这听起来应该挺直观的吧?

    让我们再举一个例子来详细了解整个过程。

    准备训练数据

    我们需要一个标记数据集来训练神经网络模型。这意味着数据集应该有一组输入和对应输入的输出。在这一点上,你可能有一些问题,像:

    等等。

    然而我要告诉你的是:我们可以轻松地创建自己的标记数据来训练word2vec模型。下面我将演示如何从任何文本生成此数据集。让我们使用一个句子并从中创建训练数据。

    第一步: 黄色高亮显示的单词将作为输入,绿色高亮显示的单词将作为输出单词。我们将使用2个单词的窗口大小。让我们从第一个单词作为输入单词开始。

    640?wx_fmt=png

    所以,关于这个输入词的训练样本如下:

    640?wx_fmt=png

    第二步: 接下来,我们将第二个单词作为输入单词。上下文窗口也会随之移动。现在,邻近的单词是“we”、“become”和“what”。

    640?wx_fmt=png

    新的训练样本将会被添加到之前的训练样本中,如下所示:

    640?wx_fmt=png

    我们将重复这些步骤,直到最后一个单词。最后,这句话的完整训练数据如下:

    640?wx_fmt=png

    640?wx_fmt=png

    我们从一个句子中抽取了27个训练样本,这是我喜欢处理非结构化数据的许多方面之一——凭空创建了一个标记数据集。

    获得 word2vec Embeddings

    现在,假设我们有一堆句子,我们用同样的方法从这些句子中提取训练样本。我们最终将获得相当大的训练数据。

    假设这个数据集中有5000个惟一的单词,我们希望为每个单词创建大小为100维的向量。然后,对于下面给出的word2vec架构:

    640?wx_fmt=png


    输入将是一个热编码向量,而输出层将给出词汇表中每个单词都在其附近的概率

    一旦对该模型进行训练,我们就可以很容易地提取学习到的权值矩阵 640?wx_fmt=pngx N,并用它来提取单词向量:

    640?wx_fmt=png

    正如你在上面看到的,权重矩阵的形状为5000 x 100。这个矩阵的第一行对应于词汇表中的第一个单词,第二个对应于第二个单词,以此类推。

    640?wx_fmt=png

    这就是我们如何通过word2vec得到固定大小的词向量或embeddings。这个数据集中相似的单词会有相似的向量,即指向相同方向的向量。例如,单词“car”和“jeep”有类似的向量:

    640?wx_fmt=png

    这是对word2vec如何在NLP中使用的高级概述。

    在我们开始构建推荐系统之前,让我问你一个问题。如何将word2vec用于非nlp任务,如商品推荐?我相信自从你读了这篇文章的标题后,你就一直在想这个问题。让我们一起解出这个谜题。

    在非文本数据上应用word2vec模型

    你能猜到word2vec用来创建文本向量表示的自然语言的基本特性吗?

    文本的顺序性。每个句子或短语都有一个单词序列。如果没有这个顺序,我们将很难理解文本。试着解释下面这句话:

    “these most been languages deciphered written of have already”

    这个句子没有顺序,我们很难理解它,这就是为什么在任何自然语言中,单词的顺序是如此重要。正是这个特性让我想到了其他不像文本具有顺序性质的数据。

    其中一类数据是消费者在电子商务网站的购买行为。大多数时候,消费者的购买行为都有一个模式,例如,一个从事体育相关活动的人可能有一个类似的在线购买模式:

    640?wx_fmt=png

    如果我们可以用向量表示每一个商品,那么我们可以很容易地找到相似的商品。因此,如果用户在网上查看一个商品,那么我们可以通过使用商品之间的向量相似性评分轻松地推荐类似商品。

    但是我们如何得到这些商品的向量表示呢?我们可以用word2vec模型来得到这些向量吗?

    答案当然是可以的! 把消费者的购买历史想象成一句话,而把商品想象成这句话的单词:

    640?wx_fmt=png

    更进一步,让我们研究在线零售数据,并使用word2vec构建一个推荐系统。

    案例研究:使用Python中的word2vec进行在线商品推荐

    现在让我们再一次确定我们的问题和需求:

    我们被要求创建一个系统,根据消费者过去的购买行为,自动向电子商务网站的消费者推荐一定数量的商品。

    我们将使用一个在线零售数据集,你可以从这个链接下载:

    https://archive.ics.uci.edu/ml/machine-learning-databases/00352/

    让我们启动Jupyter Notebook,快速导入所需的库并加载数据集。

    import pandas as pdimport numpy as npimport randomfrom tqdm import tqdmfrom gensim.models import Word2Vec import matplotlib.pyplot as plt%matplotlib inlineimport warnings;warnings.filterwarnings('ignore')as pd
    import numpy as np
    import random
    from tqdm import tqdm
    from gensim.models import Word2Vec 
    import matplotlib.pyplot as plt
    %matplotlib inline
    import warnings;
    warnings.filterwarnings('ignore')
    df = pd.read_excel('Online Retail.xlsx')df.head()
    df.head()
    640?wx_fmt=png

    以下是该数据集中字段的描述:

    df.shape
    Output: (541909, 8)

    数据集包含541,909个记录,这对于我们建立模型来说相当不错。

    处理缺失数据

    # 检查缺失值数据df.isnull().sum()
    df.isnull().sum()
    640?wx_fmt=jpeg

    由于我们有足够的数据,我们将删除所有缺少值的行。

    # 删除缺失值所在行df.dropna(inplace=True)
    df.dropna(inplace=True)

    准备数据

    让我们将StockCode转换为string数据类型:

    df['StockCode']= df['StockCode'].astype(str)'StockCode'].astype(str)

    让我们来看看我们的数据集中消费者的数量:

    customers = df["CustomerID"].unique().tolist()len(customers)
    len(customers)
    Output: 4372

    在我们的数据集中有4,372个消费者,对于这些消费者,我们将提取他们的购买历史。换句话说,我们可以有4372个购买序列。

    留出数据集的一小部分用于验证是一个很好的方法。因此,我将使用90%消费者的数据来创建word2vec embeddings。让我们开始分割数据。

    # 打乱消费者idrandom.shuffle(customers)# 提取90%的消费者customers_train = [customers[i] for i in range(round(0.9*len(customers)))]# 分为训练集和验证集train_df = df[df['CustomerID'].isin(customers_train)]validation_df = df[~df['CustomerID'].isin(customers_train)]
    random.shuffle(customers)
    # 提取90%的消费者
    customers_train = [customers[i] for i in range(round(0.9*len(customers)))]
    # 分为训练集和验证集
    train_df = df[df['CustomerID'].isin(customers_train)]
    validation_df = df[~df['CustomerID'].isin(customers_train)]

    我们将在数据集中为训练集和验证集创建消费者购买的序列。

    # 存储消费者的购买历史purchases_train = []# 用商品代码填充列表for i in tqdm(customers_train):    temp = train_df[train_df["CustomerID"] == i]["StockCode"].tolist()    purchases_train.append(temp)
    purchases_train = []
    # 用商品代码填充列表
    for i in tqdm(customers_train):
        temp = train_df[train_df["CustomerID"] == i]["StockCode"].tolist()
        purchases_train.append(temp)
    # 存储消费者的购买历史purchases_val = []# 用商品代码填充列表for i in tqdm(validation_df['CustomerID'].unique()):    temp = validation_df[validation_df["CustomerID"] == i]["StockCode"].tolist()    purchases_val.append(temp)
    purchases_val = []
    # 用商品代码填充列表
    for i in tqdm(validation_df['CustomerID'].unique()):
        temp = validation_df[validation_df["CustomerID"] == i]["StockCode"].tolist()
        purchases_val.append(temp)

    为商品构建word2vec Embeddings

    # 训练word2vec模型model = Word2Vec(window = 10, sg = 1, hs = 0,negative = 10, # for negative samplingalpha=0.03, min_alpha=0.0007,seed = 14)model.build_vocab(purchases_train, progress_per=200)model.train(purchases_train, total_examples = model.corpus_count, epochs=10, report_delay=1)
    model = Word2Vec(window = 10, sg = 1, hs = 0,
    negative = 10# for negative sampling
    alpha=0.03, min_alpha=0.0007,
    seed = 14)
    model.build_vocab(purchases_train, progress_per=200)
    model.train(purchases_train, total_examples = model.corpus_count, 
    epochs=10, report_delay=1)

    因为我们不打算进一步训练模型,所以我们在这里调用init_sims()。这将使模型的内存效率更高:

    model.init_sims(replace=True)

    让我们来看看“model”的相关参数:

    print(model)
    Output: Word2Vec(vocab=3151, size=100, alpha=0.03)

    我们的模型有3151个唯一的单词,每个单词的向量大小为100维。接下来,我们将提取词汇表中所有单词的向量,并将其存储在一个地方,以便于访问。

    # 提取向量X = model[model.wv.vocab]X.shape
    X = model[model.wv.vocab]
    X.shape
    Output: (3151, 100)

    可视化word2vec Embeddings

    可视化你所创建的embeddings是很有帮助的。在这里,我们有100维的Embeddings。我们甚至无法可视化4维空间,更不用说100维了,那么我们怎么做呢?

    我们将使用UMAP算法将商品Embeddings的维数从100降到2,UMAP算法通常用于降维。

    import umapcluster_embedding = umap.UMAP(n_neighbors=30, min_dist=0.0,n_components=2, random_state=42).fit_transform(X)plt.figure(figsize=(10,9))plt.scatter(cluster_embedding[:, 0], cluster_embedding[:, 1], s=3, cmap='Spectral')
    cluster_embedding = umap.UMAP(n_neighbors=30, min_dist=0.0,
    n_components=2, random_state=42).fit_transform(X)
    plt.figure(figsize=(10,9))
    plt.scatter(cluster_embedding[:, 0], cluster_embedding[:, 1], s=3, cmap='Spectral')
    640?wx_fmt=png

    这个图中的每个点都是一个商品。如你所见,这些数据点有几个很小的集群。这些是相似商品的组。

    开始推荐商品

    恭喜你!我们终于准备好我们的在线零售数据集中每个商品的word2vec embeddings 。现在,我们的下一步是为某个商品或某个商品的向量推荐类似的商品。

    让我们首先创建一个商品id和商品描述的字典,以便轻松地将商品的描述映射到其id,反之亦然。

    products = train_df[["StockCode", "Description"]]# 去重products.drop_duplicates(inplace=True, subset='StockCode', keep="last")# 创建一个商品id和商品描述的字典products_dict = products.groupby('StockCode')['Description'].apply(list).to_dict()"Description"]]
    # 去重
    products.drop_duplicates(inplace=True, subset='StockCode', keep="last")
    # 创建一个商品id和商品描述的字典
    products_dict = products.groupby('StockCode')['Description'].apply(list).to_dict()
    # 字典测试products_dict['84029E']
    products_dict['84029E']
    Output: [‘RED WOOLLY HOTTIE WHITE HEART.’] [‘RED WOOLLY HOTTIE WHITE HEART.’]

    我定义了下面的函数。将一个商品的向量(n)作为输入,返回前6个相似的商品:

    def similar_products(v, n = 6):# 为输入向量提取最相似的商品    ms = model.similar_by_vector(v, topn= n+1)[1:]# 提取相似产品的名称和相似度评分    new_ms = []for j in ms:        pair = (products_dict[j[0]][0], j[1])        new_ms.append(pair)return new_ms        
    # 为输入向量提取最相似的商品
        ms = model.similar_by_vector(v, topn= n+1)[1:]
    # 提取相似产品的名称和相似度评分
        new_ms = []
    for j in ms:
            pair = (products_dict[j[0]][0], j[1])
            new_ms.append(pair)
    return new_ms        

    让我们通过传递商品编号为'90019A' (‘SILVER M.O.P ORBIT BRACELET’)的商品:

    similar_products(model['90019A'])
    Output:[(‘SILVER M.O.P ORBIT DROP EARRINGS’, 0.766798734664917),(‘PINK HEART OF GLASS BRACELET’, 0.7607438564300537),(‘AMBER DROP EARRINGS W LONG BEADS’, 0.7573930025100708),(‘GOLD/M.O.P PENDANT ORBIT NECKLACE’, 0.7413625121116638),(‘ANT COPPER RED BOUDICCA BRACELET’, 0.7289256453514099),(‘WHITE VINT ART DECO CRYSTAL NECKLAC’, 0.7265784740447998)]
    [(‘SILVER M.O.P ORBIT DROP EARRINGS’, 0.766798734664917),
    (‘PINK HEART OF GLASS BRACELET’, 0.7607438564300537),
    (‘AMBER DROP EARRINGS W LONG BEADS’, 0.7573930025100708),
    (‘GOLD/M.O.P PENDANT ORBIT NECKLACE’, 0.7413625121116638),
    (‘ANT COPPER RED BOUDICCA BRACELET’, 0.7289256453514099),
    (‘WHITE VINT ART DECO CRYSTAL NECKLAC’, 0.7265784740447998)]

    太酷了!结果还是非常相关,并且与输入商品匹配得很好。然而,这个输出仅基于单个商品的向量。如果我们想根据他或她过去的多次购买来推荐商品呢?

    一个简单的解决方案是取用户迄今为止购买的所有商品的向量的平均值,并使用这个结果向量找到类似的商品。我们将使用下面的函数,它接收一个商品id列表,并返回一个100维的向量,它是输入列表中商品的向量的平均值:

    def aggregate_vectors(products):    product_vec = []for i in products:try:    product_vec.append(model[i])except KeyError:continuereturn np.mean(product_vec, axis=0)
        product_vec = []
    for i in products:
    try:
        product_vec.append(model[i])
    except KeyError:
    continue
    return np.mean(product_vec, axis=0)

    回想一下,为了验证目的,我们已经创建了一个单独的购买序列列表。现在刚好可以利用它。

    len(purchases_val[0])
    Output: 314

    用户购买的第一个商品列表的长度为314。我们将把这个验证集的商品序列传递给aggregate_vectors函数。

    aggregate_vectors(purchases_val[0]).shape
    Output: (100, )

    函数返回了一个100维的数组。这意味着函数运行正常。现在我们可以用这个结果得到最相似的商品:

    similar_products(aggregate_vectors(purchases_val[0]))
    Output:[(‘PARTY BUNTING’, 0.661663293838501),(‘ALARM CLOCK BAKELIKE RED ‘, 0.640213131904602),(‘ALARM CLOCK BAKELIKE IVORY’, 0.6287959814071655),(‘ROSES REGENCY TEACUP AND SAUCER ‘, 0.6286610960960388),(‘SPOTTY BUNTING’, 0.6270893216133118),(‘GREEN REGENCY TEACUP AND SAUCER’, 0.6261675357818604)]0.661663293838501),
    (‘ALARM CLOCK BAKELIKE RED ‘, 0.640213131904602),
    (‘ALARM CLOCK BAKELIKE IVORY’, 0.6287959814071655),
    (‘ROSES REGENCY TEACUP AND SAUCER ‘, 0.6286610960960388),
    (‘SPOTTY BUNTING’, 0.6270893216133118),
    (‘GREEN REGENCY TEACUP AND SAUCER’, 0.6261675357818604)]

    结果,我们的系统根据用户的整个购买历史推荐了6款商品。此外,你也可以根据最近几次购买情况来进行商品推荐。

    下面我只提供了最近购买的10种商品作为输入:

    similar_products(aggregate_vectors(purchases_val[0][-10:]))-10:]))
    Output:[(‘PARISIENNE KEY CABINET ‘, 0.6296610832214355),(‘FRENCH ENAMEL CANDLEHOLDER’, 0.6204789876937866),(‘VINTAGE ZINC WATERING CAN’, 0.5855435729026794),(‘CREAM HANGING HEART T-LIGHT HOLDER’, 0.5839680433273315),(‘ENAMEL FLOWER JUG CREAM’, 0.5806118845939636)]
    [(‘PARISIENNE KEY CABINET ‘, 0.6296610832214355),
    (‘FRENCH ENAMEL CANDLEHOLDER’, 0.6204789876937866),
    (‘VINTAGE ZINC WATERING CAN’, 0.5855435729026794),
    (‘CREAM HANGING HEART T-LIGHT HOLDER’, 0.5839680433273315),
    (‘ENAMEL FLOWER JUG CREAM’, 0.5806118845939636)]

    你可以随意修改这段代码,并尝试从验证集中的更多商品序列进行商品推荐。也可以进一步优化这段代码或使其更好。

    结语

    最后,你可以尝试在类似的非文本序列数据上实现此代码。例如,音乐推荐就是一个很好的用例。

    640?wx_fmt=png


    点下「在看」,给文章盖个戳吧!?
    展开全文
  • SSM框架实现导出Word文档并下载

    千次阅读 2017-03-30 20:23:44
    最近在开发过程中遇到一个SSM框架导出Word文档的问题,我也研究了好久,现在给大家分享一下我的经验,希望可以帮到大家: 第一步,就是制作Word模板,打开需要导出样式的模板,在需要填插数据的地方设置好限定名称...

    最近在开发过程中遇到一个SSM框架导出Word文档的问题,我也研究了好久,现在给大家分享一下我的经验,希望可以帮到大家:
    第一步,就是制作Word模板,打开需要导出样式的模板,在需要填插数据的地方设置好限定名称:如图模板图片
    第二步,把写好的模板文件保存成XML文件形式,如下图:
    转换成XML文件格式
    第三步:把保存好的XML文件利用xml文件处理工具打开,查看进行修改,(我这里运用的是foxe工具具体用法,大家可以百度了解),如下图:文件工具利用软件打开,查看标签是否对照,刚刚Word模板的标签是否分开,如果分开,或者标签不对照,请自行进行修改。然后把修改后的XML文件进行另存为.ftl文件格式:如下图:
    修改文件为ftl格式在这里提醒一下文件名不要用中文哦。
    第四步:上面的工作完成,模板的准备就完成了,下面就是把处理好的ftl文件和Word模板放到工程下:如下图
    模板所放位置
    下一步就是需要编写工程代码,实现导出的控制层与业务逻辑层,前台美工就不说了,一个超链接搞定,后面的业务逻辑就是取数据,并对Word模板里的限定好的字段进行数据的填充如下图:
    控制层代码
    在控制层里我建立了一个map集合对数据进行存取,注意你要存储的字段必须和Word模板里的限定字段一样,否则就会出错。,我是创建可一个createword函数,进行导出word文件,wordutils文件代码如下:
    构造函数createword
    createword函数里面调用了createDoc函数,createword函数主要是创建word文件的下载流,而createDoc函数是给word模板里字段赋值,主要代码入下:填充word模板的值
    以上就是SSM框架导出word的全过程,代码就上上面的那样,大家可以根据具体用处不同,可以在代码少做修改,但是原理不变,以上就是我的处理,希望可以帮到大家,谁有啥不懂的,可以私聊。。。。

    展开全文
  • 不懂word2vec,还敢说自己是NLP?

    千次阅读 2018-07-27 19:30:02
    由于最近正在一个相关的NLP项目,所以抽时间总结一下word2vec的相关知识点。   文章结构: 1、词的独热表示 2、词的分布式表示 3、词嵌入 4、两种训练模式 5、两种加速方法 6、word2vec和wor...

    如今,深度学习炙手可热,deep learning在图像处理领域已经取得了长足的进展。随着Google发布word2vec,深度学习在自然语言处理领域也掀起了一阵狂潮。由于最近正在做一个相关的NLP项目,所以抽时间总结一下word2vec的相关知识点。

     

    文章结构:

    1、词的独热表示

    2、词的分布式表示

    3、词嵌入

    4、两种训练模式

    5、两种加速方法

    6、word2vec和word embedding的区别 

    7、小结

     

    1、词的独热表示

    到目前为止最常用的词表示方法是 One-hot Representation,这种方法把每个词表示为一个很长的向量。这个向量的维度是词表大小,其中绝大多数元素为 0,只有一个维度的值为 1,这个向量就代表了当前的词。

     

    “可爱”表示为 [0 0 0 1 0 0 0 0 0 0 0 0 0 0 0 0 ...] 

    “面包”表示为 [0 0 0 0 0 0 0 0 1 0 0 0 0 0 0 0 ...]

     

    每个词都是茫茫 0 海中的一个 1。这种 One-hot Representation 如果采用稀疏方式存储,会是非常的简洁:也就是给每个词分配一个数字 ID。比如刚才的例子中,可爱记为 3,面包记为 8(假设从 0 开始记)。

     

    缺点分析: 

    1、向量的维度会随着句子的词的数量类型增大而增大; 

    2、任意两个词之间都是孤立的,无法表示语义层面上词汇之间的相关信息,而这一点是致命的。

     

    2、词的分布式表示

    传统的独热表示仅仅将词符号化,不包含任何语义信息。如何将语义融入到词表示中?Harris 在 1954 年提出的“分布假说”为这一设想提供了理论基础:上下文相似的词,其语义也相似。Firth 在 1957年对分布假说进行了进一步阐述和明确:词的语义由其上下文决定

     

    以(CBOW)为例,如果有一个句子“the cat sits one the mat”,在训练的时候,将“the cat sits one the”作为输入,预测出最后一个词是“mat”。 

     

    图1

     

    分布式表示的较大优点在于它具有非常强大的表征能力,比如n维向量每维k个值,可以表征k的n次方个概念。下图的神经网络语言模型(NNLM)采用的就是文本分布式表示。而词向量(word embedding)是训练该语言模型的一个附加产物,即图中的Matrix C。

     

    图2

     

    所以我们可以将我们的任务拆解成两部分: 

    一、选择一种方式描述上下文; 

    二、选择一种“模型”刻画某个词(即“目标词”)与其上下文之间的关系。

     

    3、词嵌入

    基于神经网络的分布表示一般称为词向量、词嵌入( word embedding)或分布式表示( distributed representation)。核心依然是上下文的表示以及上下文与目标词之间的关系的建模。

     

    上面了解到独热编码的维度过大的缺点。对此进行如下改进:

     

    1、将vector每一个元素由整形改为浮点型,变为整个实数范围的表示; 

    2、将原来稀疏的巨大维度压缩嵌入到一个更小维度的空间。如图所示: 

     

    图3

     

    “词嵌入”也由此得名。

     

    本质词向量是训练神经网络时候的隐藏层参数或者说矩阵。

     

    图4

     

    4、两种训练模式

    CBOW (Continuous Bag-of-Words Model)

    Skip-gram (Continuous Skip-gram Model)

     

    CBOW:上下文来预测当前词

    图5

     

    Skip-gram:当前词预测上下文

     

    图6

     

    5、两种加速方法

    Negative Sample

    Hierarchical Softmax

    大家都知道哈夫曼树是带权路径最短的树,一般神经网络语言模型在预测的时候,输出的是预测目标词的概率(每一次预测都要基于全部的数据集进行计算,很大的时间开销)。

     

    Hierarchical Softmax是一种对输出层进行优化的策略,输出层从原始模型的利用softmax计算概率值改为了利用Huffman树计算概率值。一开始我们可以用以词表中的全部词作为叶子节点,词频作为节点的权,构建Huffman树,作为输出。从根节点出发,到达指定叶子节点的路径是的。Hierarchical Softmax正是利用这条路径来计算指定词的概率,而非用softmax来计算。 

    即Hierarchical Softmax:把 N 分类问题变成 log(N)次二分类

     

    Negative Sampling(简写NEG,负采样),这是Noise-Contrastive Estimation(简写NCE,噪声对比估计)的简化版本:把语料中的一个词串的中心词替换为别的词,构造语料 D 中不存在的词串作为负样本。在这种策略下,优化目标变为了:较大化正样本的概率,同时最小化负样本的概率。这样说大家可能已经糊涂了,我们省去繁琐的数学推倒,这里举一个例子:

     

    假设有一个句子为:“The quick brown fox jumps over the lazy dog.“ 

    如果我们用skip-gram model ,貌似这是一个很大的网络。 

    图7

     

    注意:比如像“the”这种常见的词,我们会遇到两个问题: 

    1. 比如(fox,the)其实没有传递我们关于 fox的信息。‘the‘出现得太多了。 

    2. 我们有太多 (‘the’,…)的样本,多于我们实际需要的。 

    所以word2vec采用了降采样的策略。对于每个我们在训练样本中遇到的词,我们有一个概率去删除它。这个概率与单词出现的频率相关。

     

    如果我们采用window size = 10,同时我们删除‘the’: 

    1. 当我们再去训练剩下的词,我们就不会再遇到‘the’了; 

    2. 我们减少了10个包含‘the’的样本 

    这其实就是‘NEG’的核心思想。

     

    6、word2vec和word embedding的区别 

    简言之,word embedding 是一个将词向量化的概念,中文译名为"词嵌入"。 

    word2vec是谷歌提出的一种word embedding的具体手段,采用了两种模型(CBOW与skip-gram模型)与两种方法(负采样与层次softmax方法)的组合,比较常见的组合为 skip-gram+负采样方法。

     

    Word embedding的训练方法大致可以分为两类:

    (1)无监督或弱监督的预训练 

    优点:不需要大量的人工标记样本就可以得到质量还不错的embedding向量 

    缺点:准确率有待提高 

    解决办法:得到预训练的embedding向量后,用少量人工标注的样本再去优化整个模型 

    典型代表:word2vec和auto-encoder 

    (这里解释一下AutoEncoder,AutoEncoder也可以用于训练词向量,先将one hot映射成一个hidden state,再映射回原来的维度,令输入等于输出,取中间的hidden vector作为词向量,在不损耗原表达能力的前提下压缩向量维度,得到一个压缩的向量表达形式。) 

     

    (2)端对端(end to end)的有监督训练。 

    优点:学习到的embedding向量也往往更加准确 

    缺点:模型在结构上往往更加复杂 

    应用:通过一个embedding层和若干个卷积层连接而成的深度神经网络以实现对句子的情感分类,可以学习到语义更丰富的词向量表达。

     

    word2vec不关心后续的应用场景,其学习到的是就是根据共现信息得到的单词的表达,用n-gram信息来监督,在不同的子task间都会有一定效果。而end2end训练的embedding其和具体子task的学习目标紧密相关,直接迁移到另一个子task的能力非常弱

     

    常用的word embedding分为dense和sparse两种形式: 

    常见的sparse就比如 co-occurence 或者one-hot的形式;对sparse embedding进行一些降维运算比如SVD、PCA就可以得到dense。

     

    小结

    通过阅读这篇文章,大家应该对word2ec有了一个基本的了解,如果想更加深入透彻的了解此工具,可以从数学原理入手并且阅读word2vec的源码,这里附上我参考的带有完整注释的源码地址,感兴趣的可以参考一下。 

    带完整注释的word2vec源码:

    https://github.com/peklixuedong/RepresentationLearning

     

    Word Embedding模型: 词、短语及它们的组合的分布式表示

    摘要

      最近引入的连续Skip-gram模型是学习可以高质量分布式向量表示的有效方法,而这种分布式向量表示可以刻画大量精确的句法和语义关系。本文我们介绍了Skip-gram模型的多种扩展,它们可以提升向量的质量和训练速度。通过对频繁词进行重复采样我们可以极大地提升学习速度,学习到更有规律的单词表示。我们还描述了一种分层softmax的简单代替方案称作负抽样。
      单词表示的内在局限是它们对单词顺序的无差异化以及不能表示惯用短语。例如,在单词表示中,难以简单地将“Canada”和“Air”结合得到“Air Canada”。受此例所激发,我们给出了一种找到文本中的短语的简单方法,并且表明为百万级的短语学习到好的向量表示是可能的。

    引言

      在自然语言处理任务中,向量空间中单词的分布式表示通过对相似的词分类可以帮助学习算法取得更好的效果。单词表示的最早使用可以追溯到1986年[Rumelhart, Hinton and Williams]。此后该思想便被应用于统计语言模型中,获得了极大的成功。后续的工作包括将其应用到自动语音辨识,机器翻译以及大量的自然语言处理任务中。
      最近,Mikolov等人引入了Skip-gram模型[8],这是一种从大量分结构化的文本数据中学习高质量的向量表示的有效方法。与之前大量使用的用神经网络结构学习单词向量的架构不同,训练Skip-gram模型(如图1)不涉及密集的矩阵乘法。这就使得训练非常有效:经过优化的单机训练可以在一天训练1000亿个单词。
      使用神经网络计算得到的单词表示非常有趣,因为学习到的向量可以显式编码很多语言规律和模式。有点惊人的是,很多这些模式可以表示成linear translations(线性变换)。例如,vec(‘‘Madrid")−vec(‘‘Spain")+vec(‘‘France")

    的向量计算比任何词向量都更接近于‘‘vec("Paris")。
      本文我们给出了原始Skip-gram模型的若干扩展。我们的研究表明在模型训练时对频繁词进行子抽样可以极大提升训练速度(2-10倍),并且提升了欠频繁词的表示精度。此外,我们介绍了用Noise Contrastive Estimation(噪音对比估计)的简单变体来训练Skip-gram模型,实验表明我们的方法相比于之前工作中使用的更加复杂的分层softmax方法,可以得到更好的频繁词的向量表示,训练速度更快。
      单词表示受限于它们不能表示惯用语,惯用语不是单个词的简单组合。例如波士顿环球报是一家报纸,但它不是波士顿和环球两个单词组合在一起的意思。因此,使用向量来表示整个短语使得Skip-gram模型更具有表达力。其它的通过构成词向量来表示句子意思的技术也可以受益于短语向量而不是词向量。
      将基于词的模型扩展到基于短语的模型相当简单。首先我们使用数据驱动的方法识别大量的短语,然后在训练阶段我们将短语视作单个符号。为了评价短语向量的质量,我们生成了包含单词和短语的类比推理任务的测试集。我们测试集中一个典型的类比对是蒙特利尔:蒙特利尔加拿大人队,多伦多:多伦多枫叶队(二者都是北美冰球联盟的俱乐部)。因此如果vec(Montreal Canadiens)-vec(Montreal)+vec(Toronto)的最近表示为vec(Toronto Maple Leafs),那么我们就认为是一个正确的短语表示。

    Skip-gram模型

      Skip-gram模型的训练目标是发现可以用于预测句子或者文档中附近的词(surrounding words)的单词表示。更正式地讲,给定一个训练词w1,w2,w3,⋯,wT

    序列,Skip-gram模型的目标是最大化平均对数概率
      

    1T∑t=1T∑−c≤j≤c,j≠0logp(wt+j|wt)


    其中c是训练环境的规模(可以是中心词center wordwt的函数)。大c会得到更多的训练样本从而能得到更高的精度,当然也会有着更多的训练时间。基本的Skip-gram模型使用下面的softmax函数定义p(wt+j|wt):

    p(wO|wI)=exp(v′⊤wOvwI)∑Ww=1exp(v′⊤wvwI)


    其中vw和v′w是w的输入和输出的向量表示,W是词典中的单词个数。这种方式不太实际,因为计算∇logp(wO|wI)正比于W,而W通常非常大(105−107)。

     

    分层Softmax

      完全softmax的有效近似计算是分层Softmax。在神经网络语言模型环境中,首先由Morin和Bengio引入。主要优势在于在神经网络中不需要评估W个输出节点而是log2(W)

    个节点来得到概率分布。
      分层Softmax使用一种输出层的二元树表示(有W个词)作为它的叶子节点,而且对于每个节点,显式地表示它的子节点的相关概率。这些定义了一个将概率分配到单词的随机游走模型。
      更精确的是,我们可以通过一个从树根的合适路径到达每个单词w。令n(w,j)为从根到w的路径上的第j个节点,令L(w)为这条路径的长度,所以n(w,1)=root且n(w,L(w))=w。此外,对于任何内部节点n,令ch(n)为n的一个任意固定的子代,若x为真令[x]为1,否则为-1。那么用分层softmax定义的p(wO|wI)

    如下:

    p(w|wI)=∏j=1L(w)−1σ([n(w,j+1)=ch(n(w,j))]⋅v′⊤n(w,j)vwI)


    其中σ(x)=1/(1+exp(−x))。可以证明∑Ww=1p(w|wI)=1。这表明计算logp(wO|wI)和∇logp(wO|wI)的成本正比于L(wO),一般来说不大于logW。此外,不像标准的softmax形式化的Skip-gram对每个单词w分配两个表示vw和v′w,分层softmax对每个单词w有一个表示vw,对二元树上的每个内节点n有一个表示v′n。
      分层softmax使用的树结构对结果又很大影响。Mnih和Hinton探究了很多方法来构建树结构及其对训练时间和模型精度的影响。在我们的工作中,我们用了一个二元Huffman树,由于它对频繁词分配了短代码,因而可以得到更快的训练速度。之前有观测发现,按照频率将单词分组可以加速基于语言模型的神经网络的训练速度。

     

    负抽样

      一种对分层Softmax的替代方案是Noise Contrastive Estimation(NCE),这种方法由Gutmann和Hyvarimen引入,并被Mnih和Teh应用于语言模型中。NCE指出一个好的模型应该可以通过逻辑回归从噪音中区分数据。这类似于Collobert和Weston使用的Hinge loss,他们在训练模型时将数据排在噪音前面。
       尽管NCE可以近似最大化softmax的对数概率,但是Skip-gram模型只关心学习到高质量的向量表示,所以我们可以任意地简化NCE只要向量表示可以保持它们的质量。我们用下面的目标函数来定义负抽样(NEG):

    logσ(v′⊤wOvwI)+∑i=1kEwi∼Pn(w)[logσ(−v′⊤wivwI)]


    该目标函数用来替换Skip-gram目标函数中的每个logP(wO|wI)。因此任务就是利用逻辑回归从噪音分布Pn(w)抽取的分布中区分目标词wO,对每个数据样本有k个负样本。我们的实验表明对于小的训练数据集k的取值范围大概在5-20之间,而对于大型数据集k约为2-5。负抽样和NCE之间的主要区别在于NCE既需要样本还需要噪音分布的数值概率,而负抽样仅仅使用样本即可。此外尽管NCE近似最大化softmax的对数概率,但是这个性质对于我们的应用不重要。
      NCE和NEG都将噪音分布Pn(w)作为一个自由参数。对于NCE和NEG在每个任务上的表现,我们研究了Pn(w)的选择,发现一元分布U(w)的3/4次幂(也就是U(w)3/4/Z)显著优于一元分布和均匀分布。

     

    频繁词的子抽样

      在非常大的语料库中,最频繁的词可能会出现上亿次(如in,the,a等)。这类词相比于那些较少出现的词通常提供较少的信息。例如,尽管Skip-gram模型可以从法国和巴黎的共现中发现模式,但是从同样频繁出现的法国和the中得到较少的信息,因为几乎每个词都会与the共现。这一思想也可反向应用:即频繁词(in, the, a)的向量表示在经过几百万个样本的训练后也不会有明显变化。
      为了考虑稀有词和频繁词的不平衡性,我们用一种简单的子抽样方法:训练集中的每个单词被丢弃概率的计算公式如下:
      

    P(wi)=1−tf(wi)−−−−−√


    其中f(wi)是单词wi的频率,t是一个选择的阈值,通常为10−5。我们选择这个子抽样公式因为它既可以抽取那些频率大于t的单词,同时又保证了频率的顺序。虽然这个子抽样公式是一个试探性的方法,但是我们发现在实际中很有效。它可以加速学习,甚至极大地提升了学习到的稀有词的向量的精度。

     

    实验结果

      本节我们验证了分层Softmax(HS),NCE,负抽样和训练词的子抽样方法。我们使用Mikolov等人[8]引入的类比推理任务。该任务由下面的类比如:“德国”:“柏林”::“法国”:?组成,通过求一个向量x

    使得vec(x)接近于vec(Berlin)−vec(Germany)+vec(France),如果x是巴黎那么就认为是正确的。该任务有两大类:句法类比如“quick”: “quickly”::”slow”:”slowly”以及语义类比如国家和首都城市关系。
      为了训练Skip-gram模型,我们使用了由多个新闻文章组成的大型数据集(有10亿单词的谷歌内部数据)。我们去除了训练数据中出现次数不超过5次的单词,得到的词典的规模为692K(也就是词典中有接近70万个单词)。多个Skip-gram模型在单词类比测试集上的效果如表1所示。该表显示:在类比推理任务中负抽样优于分层Softmax方法,甚至略微胜于NCE方法。对频繁词的子抽样提升了训练速度,使得单词表示更加精确。

     

     

    背景简介

    本人是深度学习入门的菜菜菜鸟一枚…
    利用LSTM + word2vec词向量进行文本情感分类/情感分析实验,吸收了网上的资源和代码并尝试转化为自己的东西~

    实验环境

    • win7 64位系统
    • Anaconda 4.3.0 , Python 2.7 version
    • Pycharm开发环境
    • python包:keras,gensim,numpy等

    实验数据

    本文的实验数据是来自网上的中文标注语料,涉及书籍、酒店、计算机、牛奶、手机、热水器六个方面的购物评论数据,具体介绍参见该文:购物评论情感分析

    数据处理

    上面提到的数据在网上见到的次数比较多,原始格式是两个excel文件,如图:
    两个excel

    对,就是这两个…估计来到本文的小伙伴也见过。一些代码就是直接从这两个excel里读取数据、分词、处理…不过我表示自己习惯从txt文本里获取数据,因此本人将数据合并、去重(原数据里有不少重复的评论)、分词(用的是哈工大LTP分词)之后存为一份txt文本,保留的数据情况如下:

    正面评价个数:8680个
    负面评价个数:8000个

    文本如图所示:
    这里写图片描述

    然后人工生成一份【语料类别】文本,用1表示正面评价,用0表示负面评价,与评论数据一一对应。

    生成词语的索引字典、词向量字典

    利用上述文本语料生成词语的索引字典和词向量字典。
    注意:当Word2vec词频阈值设置为5时,词频小于5的词语将不会生成索引,也不会生成词向量数据。

    工具:gensim里的Word2vec,Dictionary

    代码

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
    功能:利用大语料生成词语的索引字典、词向量,然后保存为pkl文件
    时间:2017年3月8日 13:19:40
    """
    
    import pickle
    import logging
    import tkFileDialog
    
    import numpy as np
    np.random.seed(1337)  # For Reproducibility
    
    from Functions.TextSta import TextSta
    from gensim.models.word2vec import Word2Vec
    from gensim.corpora.dictionary import Dictionary
    
    # 创建词语字典,并返回word2vec模型中词语的索引,词向量
    def create_dictionaries(p_model):
        gensim_dict = Dictionary()
        gensim_dict.doc2bow(p_model.vocab.keys(), allow_update=True)
        w2indx = {v: k + 1 for k, v in gensim_dict.items()}  # 词语的索引,从1开始编号
        w2vec = {word: model[word] for word in w2indx.keys()}  # 词语的词向量
        return w2indx, w2vec
    
    # 主程序
    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
    
    print u"请选择大语料的分词文本..."
    T = TextSta(tkFileDialog.askopenfilename(title=u"选择文件"))
    sentences = T.sen()    # 获取句子列表,每个句子又是词汇的列表
    
    print u'训练Word2vec模型(可尝试修改参数)...'
    model = Word2Vec(sentences,
                     size=100,  # 词向量维度
                     min_count=5,  # 词频阈值
                     window=5)  # 窗口大小
    
    model_name = raw_input(u"请输入保存的模型文件名...\n").decode("utf-8")
    model.save(model_name + u'.model')  # 保存模型
    
    # 索引字典、词向量字典
    index_dict, word_vectors= create_dictionaries(model)
    
    # 存储为pkl文件
    pkl_name = raw_input(u"请输入保存的pkl文件名...\n").decode("utf-8")
    output = open(pkl_name + u".pkl", 'wb')
    pickle.dump(index_dict, output)  # 索引字典
    pickle.dump(word_vectors, output)  # 词向量字典
    output.close()
    
    if __name__ == "__main__":
        pass

    其中,

    T = TextSta(tkFileDialog.askopenfilename(title=u"选择文件"))
    sentences = T.sen()    # 获取句子列表,每个句子又是词汇的列表

    TextSta是我自己写的一个类,读取语料文本后,sentences = T.sen()将文本里的每一行生成一个列表,每个列表又是词汇的列表。(这个类原来是用作句子分类的,每行是一个句子;这里每行其实是一个评论若干个句子…我就不改代码变量名了…)

    TextSta类部分代码:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
    功能:一个类,执行文本转换
    输入:分词文本
    输出:句子列表,全文的词汇列表,TF,DF
    时间:2016年5月17日 19:08:34
    """
    
    import codecs
    import re
    import tkFileDialog
    
    
    class TextSta:
        # 定义基本属性,分词文本的全路径
        filename = ""
    
        # 定义构造方法
        def __init__(self, path):    # 参数path,赋给filename
            self.filename = path
    
        def sen(self):    # 获取句子列表
            f1 = codecs.open(self.filename, "r", encoding="utf-8")
            print u"已经打开文本:", self.filename
    
            # 获得句子列表,其中每个句子又是词汇的列表
            sentences_list = []
            for line in f1:
                single_sen_list = line.strip().split(" ")
                while "" in single_sen_list:
                    single_sen_list.remove("")
                sentences_list.append(single_sen_list)
            print u"句子总数:", len(sentences_list)
    
            f1.close()
            return sentences_list
    
    if __name__ == "__main__": 
        pass

    总之,sentences的格式如下:

    [[我, 是, 2月, …], [#, 蒙牛, 百, …], …]

    所有的评论文本存为一个列表,每个评论文本又是词汇的列表。
    sentences列表的长度就是文本的行数:len(sentences) = 16680

    利用Keras + LSTM进行文本分类

    工具:Keras深度学习库

    代码:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
    功能:利用词向量+LSTM进行文本分类
    时间:2017年3月10日 21:18:34
    """
    
    import numpy as np
    
    np.random.seed(1337)  # For Reproducibility
    
    import pickle
    from keras.preprocessing import sequence
    from keras.models import Sequential
    from keras.layers.embeddings import Embedding
    from keras.layers.recurrent import LSTM
    from keras.layers.core import Dense, Dropout, Activation
    
    from sklearn.cross_validation import train_test_split
    
    from Functions import GetLineList
    from Functions.TextSta import TextSta
    
    # 参数设置
    vocab_dim = 100  # 向量维度
    maxlen = 140  # 文本保留的最大长度
    batch_size = 32
    n_epoch = 5
    input_length = 140
    
    
    def text_to_index_array(p_new_dic, p_sen):  # 文本转为索引数字模式
        new_sentences = []
        for sen in p_sen:
            new_sen = []
            for word in sen:
                try:
                    new_sen.append(p_new_dic[word])  # 单词转索引数字
                except:
                    new_sen.append(0)  # 索引字典里没有的词转为数字0
            new_sentences.append(new_sen)
    
        return np.array(new_sentences)
    
    
    # 定义网络结构
    def train_lstm(p_n_symbols, p_embedding_weights, p_X_train, p_y_train, p_X_test, p_y_test):
        print u'创建模型...'
        model = Sequential()
        model.add(Embedding(output_dim=vocab_dim,
                            input_dim=p_n_symbols,
                            mask_zero=True,
                            weights=[p_embedding_weights],
                            input_length=input_length))
    
        model.add(LSTM(output_dim=50,
                       activation='sigmoid',
                       inner_activation='hard_sigmoid'))
        model.add(Dropout(0.5))
        model.add(Dense(1))
        model.add(Activation('sigmoid'))
    
        print u'编译模型...'
        model.compile(loss='binary_crossentropy',
                      optimizer='adam',
                      metrics=['accuracy'])
    
        print u"训练..."
        model.fit(p_X_train, p_y_train, batch_size=batch_size, nb_epoch=n_epoch,
                  validation_data=(p_X_test, p_y_test))
    
        print u"评估..."
        score, acc = model.evaluate(p_X_test, p_y_test, batch_size=batch_size)
        print 'Test score:', score
        print 'Test accuracy:', acc
    
    
    # 读取大语料文本
    f = open(u"评价语料索引及词向量.pkl", 'rb')  # 预先训练好的
    index_dict = pickle.load(f)  # 索引字典,{单词: 索引数字}
    word_vectors = pickle.load(f)  # 词向量, {单词: 词向量(100维长的数组)}
    new_dic = index_dict
    
    print u"Setting up Arrays for Keras Embedding Layer..."
    n_symbols = len(index_dict) + 1  # 索引数字的个数,因为有的词语索引为0,所以+1
    embedding_weights = np.zeros((n_symbols, 100))  # 创建一个n_symbols * 100的0矩阵
    for w, index in index_dict.items():  # 从索引为1的词语开始,用词向量填充矩阵
        embedding_weights[index, :] = word_vectors[w]  # 词向量矩阵,第一行是0向量(没有索引为0的词语,未被填充)
    
    # 读取语料分词文本,转为句子列表(句子为词汇的列表)
    print u"请选择语料的分词文本..."
    T1 = TextSta(u"评价语料_分词后.txt")
    allsentences = T1.sen()
    
    # 读取语料类别标签
    print u"请选择语料的类别文本...(用0,1分别表示消极、积极情感)"
    labels = GetLineList.main()
    
    # 划分训练集和测试集,此时都是list列表
    X_train_l, X_test_l, y_train_l, y_test_l = train_test_split(allsentences, labels, test_size=0.2)
    
    # 转为数字索引形式
    X_train = text_to_index_array(new_dic, X_train_l)
    X_test = text_to_index_array(new_dic, X_test_l)
    print u"训练集shape: ", X_train.shape
    print u"测试集shape: ", X_test.shape
    
    y_train = np.array(y_train_l)  # 转numpy数组
    y_test = np.array(y_test_l)
    
    # 将句子截取相同的长度maxlen,不够的补0
    print('Pad sequences (samples x time)')
    X_train = sequence.pad_sequences(X_train, maxlen=maxlen)
    X_test = sequence.pad_sequences(X_test, maxlen=maxlen)
    print('X_train shape:', X_train.shape)
    print('X_test shape:', X_test.shape)
    
    train_lstm(n_symbols, embedding_weights, X_train, y_train, X_test, y_test)
    
    if __name__ == "__main__":
        pass
    

    其中,

    from Functions import GetLineList

    GetLineList是自定义模块,用于获取文本的类别(存为列表),代码如下:

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    """
    功能:文本转列表,常用于读取词典(停用词,特征词等)
    使用:给定一个文本,将文本按行转换为列表,每行对应列表里的一个元素
    时间:2016年5月15日 22:45:23
    """
    
    import codecs
    import tkFileDialog
    
    
    def main():
        # 打开文件
        file_path = tkFileDialog.askopenfilename(title=u"选择文件")
        f1 = codecs.open(file_path, "r", encoding="utf-8")
        print u"已经打开文本:", file_path
    
        # 转为列表
        line_list = []
        for line in f1:
            line_list.append(line.strip())
        print u"列表里的元素个数:", len(line_list)
    
        f1.close()
        return line_list
    
    if __name__ == "__main__":
        pass

    实验结果

    这里写图片描述

    参考文献:

    http://buptldy.github.io/2016/07/20/2016-07-20-sentiment%20analysis/
    https://github.com/BUPTLdy/Sentiment-Analysis

    展开全文
  • 问题:将word1中的表格复制到word2中,表格出现变形。 解决办法:1.先选中word1中的表格,然后选择复制; 2.在word2中粘贴刚才复制的表格; 3.选中word1中的表格,在选中格式刷; 4.再word2中将表格用格式...
  • LSTM文本生成(基于word2vec)

    千次阅读 2018-09-26 01:15:12
    框架:Keras import os import numpy as np import nltk from keras.models import Sequential from keras.layers import Dense from keras.layers import Dropout from keras.layers import ...
  • 还在用PPT、Word和Excel画企业组织结构吗?对于人力资源的同事来说,画组织结构是一键非常头疼的事情,尤其是对于一些大公司和人员变动较大的公司来说,需要经常更换组织结构,每次变动都要耗费大量的时间和...
  • gensim是基于Python的一个框架,它不但将Python与Word2Vec了整合,还提供了基于LSA、LDA、HDP的主体框架Word2Vec Word2Vec属于一种神经网络架构的概率语言模型 两个重要模型 CBOW模型:CBOW模型是Word2Vec最...
  • 根据实际的业务需要,做出了一个简易的部署及架构设计。... 下展示的报告的基本生成方式:采用配置文件+word模板的方式   下展示的是服务器的数据访问及流向情况: (未完待续)
  • GPU架构“征途之旅”即日起航 GPU架构“征途之旅”即日起航  显卡GPU架构之争永远是DIY玩家最津津乐道的话题之一,而对于众多普通玩家来说经常也就看看热闹而已。大多数玩家在购买显卡的时候其实想的是...
  • [提供源码下载]在大型软件中用Word做报表: 书签的应用(提供一种思路) ——通过知识共享树立个人品牌。 报表基本上在每一个项目中占有很大的比例,报表也是我们开发人员必须过的坎,现在市面上各种类型的报表...
  • php 生成word 网络上方法有3中 其中第一种是用com组件,我印象中过com组件的开发,但是对这种操作潜意识就是觉得麻烦,复杂,而且据网上资料显示这个性能还不好。权衡之下我选择了其他方法。我使用的框架是...
  • office系列以简便、功能强大的特色发展为当今世界上范围最广、用户最多的办公软件,同时也深受码农的喜欢…。MFC项目中嵌入office系列软件也是随处可见的,最早...所以最后选择使用以安装ocx的形式进行使用word文档...
  • Word2Vec总结

    千次阅读 2017-12-16 19:37:43
    最近一段时间,我写了好几篇关于Word2vec的文章,从理论部分到具体实践,现总结如下: 理论部分 轻松理解skip-gram模型 轻松理解CBOW模型 上述两篇博文从理论角度,讲述了Word2Vec两大模型 实践部分 ...
  • 比如下所示的就是在Word文档中输入的某一公司的所有组织,如何使其以层次清晰的结构进行展现? 第一步我们需要的是按照它的层次加其前面按下“TAB”键,每下一级需要多按下一个“TAB”键。 以上为例,...
  • Aspose系列的控件,功能都挺好,之前一直在我的Winform开发框架中用Aspose.Cell来报表输出,可以实现多样化的报表设计及输出,由于一般输出的内容比较正规化或者多数是表格居多,所以一般使用Aspose.Cell来实现我...
  • word2vec

    2019-06-24 09:00:01
    Word2vec是Google实现word embedding的一种具体的方式。因为速度快效果好,而广为人知。 而Word embedding是一个普适的概念或者任务,即用向量来表示字或词,一般也称为词嵌入。 核心公式: 简单来说,Word2Vec...
  • java基于word模板分分钟动态生成word及输出pdf
  • 本人现在在一个word插件,用的是C++的ATL框架,主要功能是辅助web端实现word文件的上传下载,其中界面是加载由VSTO创建生成的Ribbon.xml界面文件(相关技术可以参考...目前按钮的事件是可以相应的,但是我现在想根据...
  • (BOOK_NO, BOOK_NAME, BOOK_CLASSIFY_NO, AUTHOR, PUBLISH, PUBLISH_TIME, PRICE, KEY_WORD, IN_TIME, BORROW_COUNT, INVENTORY_NUMBER, REMOVED, CREATE_TIME, UPDATE_TIME, OPERATE_ID, Id) values (?, ?, ?, ...
  • 在项目中, 一开始是使用java Apache poi 根据word模板生成word报表, 后面发现框架有个低版本的poi 3.0.1, 由于这个版本太低, 新版本poi整合不了旧版本的poi, 所以使用了另外一种方式: 1,先将word文档另存为 : Word ...
  • 图解Word2vec

    千次阅读 多人点赞 2019-04-08 08:58:57
    上述的这种架构被称为连续词袋(CBOW),在一篇关于word2vec的论文中有阐述。 还有另一种架构,它不根据前后文(前后单词)来猜测目标单词,而是推测当前单词可能的前后单词。我们设想一下滑动窗在训练数据时如下所...
  • php生成word文件

    千次阅读 2018-04-17 15:28:07
    需求: 甲方爸爸说“我有一个word文件,里面是关于用户信息的表格,你帮我把系统里面所有用户数据都按照这个文件导出来给我“; 我当时就不乐意了,啪的一拍桌子站起来,愤愤的回了一句“好的,什么时候要”百度查...
  • POI导出word文档模版直接用于下载和html页面展示
  • Java中文分词组件 - word分词

    万次阅读 2019-02-10 16:17:50
    word分词是一个Java实现的分布式的中文分词组件,提供了多种基于词典的分词算法,并利用ngram模型来消除歧义。能准确识别英文、数字,以及日期、时间等数量词,能识别人名、地名、组织机构名等未登录词。能通过...
  • word2vec和word embedding有什么区别?

    千次阅读 2017-12-18 11:26:29
    作者:Scofield链接:...很好,正好可借此机会介绍词向量、word2vec以及DeepNLP整套相关的东西:文章很长,是从CSDN上写好复制过来的,亦可直接跳到博客观看:深度学习(Deep Learning)
  • 如何用python后端写网页-flask框架

    千次阅读 多人点赞 2021-02-21 23:32:34
    如何以python后端写网页-flask框架什么是Flask安装flask模块Hello World更深一步:数据绑定如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右...
  • Aspose系列的控件,功能都挺好,之前一直在我的Winform开发框架中用Aspose.Cell来报表输出,可以实现多样化的报表设计及输出,由于一般输出的内容比较正规化或者多数是表格居多,所以一般使用Aspose.Cell来实现我...
  • 在使用MapReduce框架编写程序时,对于MapReduce的key-value,输入输出数据,只能使用Hadoop提供的数据类型,不能使用Java的基本数据类型,例如long-LongWritable,int-IntWritable,String-Text等。 在节点间的内部通讯...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 82,926
精华内容 33,170
关键字:

word里的框架怎么做