[实例笔记]NLP文本处理——公司名称分类(一)

整个项目的最终目标是要通过公司名称和其他特征,来对公司来进行行业分类;
目前大致的思路是:
1、对公司名称进行处理:包括提取关键字、通过名称来找公司之间的相似
2、引入其他特征,来对公司进行分类问题;

这里会记录我处理的整个过程

Day1
整体思路在思考,如果才能从公司名称提取到关键字,思考之后大致的思路是:
1、通过对公司名称分词之后,对每个词进行计算词频,来一个建立企业名称相关词频库;
2、定义一个阈值,将高于阈值的词作为停用词表;
3、对公司名称进行分词后,历遍停用词表,将频率高的词过滤替换;
4、最后剩下词为公司名称里频率最低的关键词

Day2
因为最后目标是要对公司进行归一化,所以主要不需要只剩关键字,将思路改成:
1、不对公司名称分词完的结果进行过滤;
2、采用信息熵的值,来对分词按熵值进行排序;
3、最后将公司分词的结果,转换成计算两个公司分词组成的两个点的距离;

Day3
按以上思路,从GP数据库中提取出11万左右的公司名称,进行建立总分词结果,以及各词的熵值;
取近1万的公司名称进行计算试运行;

#write by xyz
#-*- coding:utf-8 -*-

import pandas as pd
import numpy as np
import sklearn as sk
import time
import collections
import json
from scipy.spatial.distance import pdist
import jieba.analyse
import sys
reload(sys)
sys.setdefaultencoding('utf-8')

def word_cut_count(content,stop_words):
    import collections
    words_count = collections.defaultdict(lambda: 0)
    company_key_word=[]
    for w in content:
        text = jieba.lcut(w, cut_all=False)
        key_word=[]
        # print text
        for word in text:
            if word not in stop_words and word != ' ':
                words_count[word] += 1
                key_word.append(word)
        company_key_word.append(key_word)
    return words_count,company_key_word

def word_freq(content,stop_words):
    import collections
    words_count,company_key_word=word_cut_count(content,stop_words)
    new_words={}
    count=float(sum(words_count.values()))
    for key,value in words_count.items():
        v = -np.log(value/count)
        new_words[key]=v
    new_words = collections.OrderedDict(sorted(new_words.items(), key=lambda x: x[1], reverse=True))
    return new_words,new_words.keys(),new_words.values()

总共得到8万左右词的熵值
在这里插入图片描述
两两公司分词后的词进行合并去重,在对应的词上采用熵值作为维度坐标,转为词向量,计算向量之间的夹角cos,并计算相似度;

def company_key(company_key_word,word_freq):
    company_key =[]
    
    for i in company_key_word:
        word_k={}
        for j in i :
            word_k[j] = float(word_freq[word_freq['word']== j]['freq'].values)
        words_k = collections.OrderedDict(sorted(word_k.items(), key=lambda x: x[1], reverse=True))
        company_key.append(words_k)
    return company_key

def distinct(origin,obj_distinct):
    '''将obj_distinct中与origin相同内容去除'''
    t = []
    for x in obj_distinct:
        if x not in origin:
            t.append(x)
    return t


def word_vec(key_sum,key,entropy):
    '''生成词向量'''
    shape=len(key_sum)
    vec = np.zeros(shape)
    # print v1
    for index in range(shape):
        if key_sum[index] in key:
            vec[index] = entropy[key_sum[index]]
    return vec


result = pd.DataFrame(columns=('company_name', 'company_name_similar', 'similar_point'))
for index in range(new_data.shape[0]):
    entropy = new_data.loc[index,'entropy']
    key=entropy.keys()

    for index1 in range(new_data.shape[0]):
        if index1 != index:
            entropy_p = new_data.loc[index1, 'entropy']
            key_p=entropy_p.keys()
            key_d = distinct(key,key_p)
            key_sum = key+key_d
            v1=word_vec(key_sum,key,entropy)
            v2=word_vec(key_sum,key_p,entropy_p)
            #计算词向量之间相似度
            vv = np.vstack([v1,v2])
            p1 = float(1 - pdist(vv, 'cosine')) #cos夹角相似度
            # p1 = float(pdist(vv,'jaccard')) #默认欧式距离

            # p1 = np.corrcoef(vv)[0][1]
            if p1>0.5:
                content={'company_name':new_data.loc[index,'company_name'],
                         'company_name_similar':new_data.loc[index1,'company_name'],
                         'cos_p':float(p1)}
                print json.dumps((new_data.loc[index,'company_name'],new_data.loc[index1,'company_name'],p1)).decode("unicode-escape")

各公司分词后得到各词的熵值,并按熵值的value进行排序;
在这里插入图片描述

结果:因为熵值较低,导致量向量减仅有一个词(如‘有限公司’)相同,计算出来的相似度都高于90%;
对熵值进行调整,直接采用频率值,为了减小频率差距,对频率采取加log底,平缓频率幅度;计算出来的结果为:
在这里插入图片描述
到这里发现了几个问题:
1.相似度高的公司,可以看出来,基本还是可以认为结果是可以的,但是相似度较低的公司,可以发现,其实两个公司没有任何联系,只是在数字上恰好频率相同,如:
在这里插入图片描述
2.这里两两去比较计算,非常消耗资源,且两两会重复进行计算,最后只是通过数字进行计算,并没有从字来先判断,进行筛选;

Day4
加入筛选过程,引入树(字典);
从频率值高到低进行筛选,并且进行分类叶子节点,存储方式为字典的形式;

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值