特征表示—动态词典

2018-08-13  本文已影响0人  Silence_Dong

动态词典构造

在动态词典中,文本表示的词并不是像词袋模型那样----根据构建的词表[wd1,wd2,wd3,......],计算全文档集中的词的权重,最后对每一个训练文档进行词对应的权重赋值,构建一个高维的稀疏矩阵[0,0,0.342,0,0,0.1353,0,0,......]等等。

表示为:
[[类别1,类别3,类别2,类别3,.....]
[[词列表1],[词列表2],[词列表3],[词列表4],....]

category_mapping = {u'其他': 0, u'电子商务': 1, u'社交网络': 2}

def get_label_mapping(source):
    """ 载入标签映射表 """
    mapping = {}
    with open(source, 'rb') as f:
        for line in f:
            filename, label = line.decode('utf-8').split()
            mapping[filename] = category_mapping[label]
    return mapping

def get_data_mapping(source, stopwords):
    """ 载入数据隐射表 """
    mapping = {}
    for root, dirs, files in os.walk(source):
        for folder in dirs:
            raw_file = os.path.join(root, folder, 'raw_%s.txt' % folder)
            with open(raw_file, 'rb') as f:
                content = f.read().strip().decode('utf-8')
            mapping['raw_%s.txt' % folder] = cut(content, stopwords)
    return mapping

def get_filename_mapping(label_mapping, data_mapping):
    idx = 0
    idx_label = {}
    idx_data = {}
    for filename, label in label_mapping.iteritems():
        idx_label[idx] = label
        idx_data[idx] = data_mapping[filename]
        idx += 1
    return idx_label, idx_data
def get_vocab(idx_data):
  """ 获取文档列表的总词集
  :param idx_data:
  :return:
  """
  vocab = defaultdict(int)
  for idx, words in idx_data.iteritems():
    for word in words:
        vocab[word] += 1
  return vocab
  1. 首先根据第一步中文档词列表与类别映射表,按照类别,统计每个类别下所有词的词频,即label_dicts;同时,记录各个类别的总数label_counts。
  2. 然后根据第二步中统计出的全文档集中的词(不重复),对每个词应用以下公式计算权重:
wj(wdi) = [ (nj(wdi) + 0.1) / Cj ] / [(N(wdi) - nj(wdi) + 1) / (L - Cj)]  
           其中wj(wdi) —— 总词表中第i个词在类别j下的权重
           nj(wdi) —— 第i个词在类别j中出现的次数
           N(wdi) —— 第i个词在工文档集中出现的次数
           Cj —— 属于类别j的文档数
           L —— 总文档数
def build_dynamic_dict(idx_data, idx_label, vocab):
   '''
   构建动态词典
   :param idx_data: 映射文档词集
                   [[word1,word2,word3],[word3,word4],....]
   :param idx_label: 映射文档分类标签
                   [1,0,2,1,0,....]
   :param vocab:词与词频
               {word1:freq1,Word2:freq2,......}
   :return: 动态词典
           {类别1:{word1:p1,word2:p2,.....},
           类别2:{word1:p1,word2:p2,....},
           类别3:{word1:p1,word2:p2,....}
           }
   '''
   # 构造类别词典
   label_dicts = OrderedDict()
   label_counts = defaultdict(int)
   for idx, label in idx_label.iteritems():
       if not locals().has_key('dict_%d' % label):
           locals()['dict_%d' % label] = defaultdict(int)
           label_dicts[label] = eval('dict_%d' % label)

       label_counts[label] += 1
       for word in idx_data[idx]:
           label_dicts[label][word] += 1

   L = sum([x for _, x in label_counts.iteritems()])
   # 构造动态词典
   dynamic_dicts = OrderedDict()
   for label, label_dict in label_dicts.iteritems():
       if not locals().has_key('dynamic_dict_%d' % label):
           locals()['dynamic_dict_%d' % label] = defaultdict(float)
           dynamic_dicts[label] = eval('dynamic_dict_%d' % label)

       for word, N in vocab.iteritems():
           freq = label_dict.get(word, 0)
           other_freq = N - freq
           dynamic_dicts[label][word] = (
               (freq + 0.1) / label_counts[label]) / ((other_freq + 1) / (L - label_counts[label]))
   return dynamic_dicts
  1. 对于待表示文本,遍历词表与动态词表,生成文本词表对应的词权重,按权重大小倒序排列。并如代码注释,根据权重列表生成6个特征,添加到向量vec中。
  2. 对每一个类别执行上述操作,则vec的长度为6*类别数 = 18(此处类别数为3)
def sentence2vec(sentence, dynamic_dicts):
    """ 使用动态词典将句子转换成特征向量

    每个类别分别生成6个特征:
        - average: 平均强度
        - top_1: 类别强度最高
        - top_3: 类别强度前3之和
        - top_6: 类别强度前6之和
        - top_10: 类别强度前10之和
        - top_15: 类别强度前15之和
    """
    vec = []
    sentence = set(sentence)
    for label, dynamic_dict in dynamic_dicts.iteritems():
        weights = [dynamic_dict.get(word, 0.1) for word in sentence]
        weights = sorted(weights, reverse=True)

        # average
        vec.append(sum(weights) / len(weights))
        # top_1
        vec.append(weights[0])
        # top_3
        vec.append(sum(weights[:3]))
        # top_6
        vec.append(sum(weights[:6]))
        # top_10
        vec.append(sum(weights[:10]))
        # top_15
        vec.append(sum(weights[:15]))

    return vec
上一篇 下一篇

猜你喜欢

热点阅读