文本向量化——方法1:基于高频词的向量化方式(包含python代码)

文本向量化——方法1:基于高频词的向量化方式(包含python代码)

点这里,下一篇——基于TF-IDF词袋模型文本向量化
对大文本进行处理和运用,最关键的一步就是如何将文本向量化,我最近学习和琢磨出了几种方法,这里跟大家分享,我这里以我上一篇博文爬取微博关于“线上教学”的评论作为例子。

一、构造思维
1、将文本转化为向量是处理文本的关键,而使得文本特征表现在对应向量上又是向量化的关键,简单来说就是为了将文本和向量一一对应,并且具有“相似的两个文本转化为相近的两个向量”这个性质。

2、想要获得最理想的特征向量,一个简单粗暴的方式就是将所有文字都取不同的值,按照文本文字顺序构造向量即可,如:
假定 我-1,喜-2,欢-3,吃-4,蛋-5,糕-6,西-7,瓜-8………
那么下面两句话的向量值:
我喜欢吃蛋糕
1 2 3 4 5 6
我喜欢吃西瓜
1 2 3 4 7 8

这样一来,不同的文本的向量必定不一样,并且相近的文本会得到相近的向量(如123456 123478 对于六维向量来说,是接近的,还原成文本以后都表示爱好吃xx的语句)

3、如果完全利用2中的方式,唯一的缺点就是维数问题。例如我提取的微博评论中一共超过3万字,那么就要构造3万维的特征向量,毫无疑问 这是一个维数灾难。三万条评论 需要三万维的向量表示,是没有意义的,计算负担和分析难度也可想而知。

4、对于2中的方法进行三步改进
第一:中文中词语才能表示意义,单个文字的特征表述远小于词语;故将词语作为特征提取对象,不仅赋予了向量一定意义上的语义,还缩小了向量维数,一个词语(两个字以上)仅用一个维数表示
第二:文本中大部分文字是无用的(比如啊、哦、的、了、呢……),称呼停用词,我们仅需要研究停用词之外具有表述意义的词语
第三,对大文本的研究,为了减轻计算负担,仅仅靠以上两步还是不够的,因为维数还是太大,为了减少维数,还需要去除大多数词语。那么除去哪些词语合适呢? 换另一种思维,除去哪些词其实等效于留下哪些词。 这里用地一个方法是,将所有文本中频率最高地那部分词语提出来作为特征词,因为高频词往往表达了百分之五十以上的总体信息;并且,我们可以控制维数,想要控制成N维,就提取最频繁出现的前N个词。一个文本集中的文本长度不一样,但是向量化后的维数是一样的,这也是大多数情况下我们所需要的。

5、例如,我在这里提取了三万多条评论的50个高频词作为特征对象,然后再对每一条评论进行如下方法的向量化:
将50个词按一定顺序排列,如果一条评论中出现某个高频词,相应的位子为1,否则为0,例如
假如 喜欢是高频词,排在第5位,那么“我爱吃蛋糕”和“我爱吃西瓜”的向量是一样的,即:只要第5位子是1,其他都是0的50维向量。这表明这两句话有一定关系,都是指表达爱好的语句。

二、下面是对三万条评论进行向量化的python代码(除去注释也就40行)

# coding:utf-8
import jieba
import matplotlib.pyplot as plt

# 导入评论(我分两次各提取了一万多条关于“线上教学”的评论分别保存在下面连两个文件中)
f1=open('weibocomment.txt','r',encoding='utf-8')
page1=f1.readlines()
f1.close()
f2=open('weibocomment1.txt','r',encoding='utf-8')
page2=f2.readlines()
f2.close()

page=page1+page2 # 合并评论

# 导入停用词库
# 停用词是没用特征的词语,包含标点符号 的 了 呢 啊 哦 …………
f3=open('stopwords1.txt','r',encoding='gbk')
stopwords=f3.readlines()
f3.close()


# 文件都是Txt,最后面都有一个换行,删去换行并将评论放在一个List中
words=[]
for line in page:
    words.append(line.strip('\n'))
stopword=[]
for sw in stopwords:
    stopword.append(sw.strip('\n'))

# 结巴分词,将str类型自动分词,所以要把所有list先转成str
word=jieba.lcut(str(words))
# 分词之后是一个list

# 下面是用字典法对分词得到的list 进行计数,即计算出现频率
word_tf={}
for w in word:
    if w not in word_tf.keys():
        word_tf[w]=1
    else:
        word_tf[w]+=1

# 除去停用词
for sw in stopword:
    if sw in word_tf.keys():
        word_tf.pop(sw) # 字典.pop() 把括号里面的key从子弹中删去

word_tf.pop(' ')  # 由于停用词中没用空格 这里添加删去空格
# print(word_tf)  # 可以打印出来看看

# 下面是让字典按照频率排序
Zip=zip(word_tf.values(),word_tf.keys())
order=list(Zip)
order.sort(reverse=True)
# 排序之后是一个list,元素是tuple(词,频数),可以打印出来看看
#print(order)

# 按照顺序将词和对应频数加入两个list,我提取前50个出现最高的词(可以按照文本大小和需求进行调优)
word_name=[]
word_num=[]
for i in range(50):
    word_name.append(order[i][1])
    word_num.append(order[i][0])

# 下面是作出词语的频数柱状图
plt.figure(figsize=(13,5))
plt.bar(range(50),word_num)
plt.xticks(range(50),word_name,rotation=90)  # 将x轴变量变成词名
plt.rcParams['font.sans-serif']=['SimHei']  # 为了让x轴显示中文的需要加这条(不然就会显示乱码)
plt.savefig('tfwords.jpg') # 保存图片


# 下面是构造每一条评论的特征向量,向量维数和选取的高频词50个对应,即为50维

LINE_VEC=[] # 接收每一个评论和对应向量
for line in page:
    lines=jieba.lcut(line)  # 对单条评论进行分词
    vec=[0]*50 # 初始化向量

    # 如果分词结果出现这50个高频词,则对应的位子为1 否则不变为0
    for word in lines:
        if word in word_name:
            vec[word_name.index(word)]=1

    line_vec=line.strip('\n')+' '+str(vec)+'\n'  # 将其变为 str 方便存入txt 中
    LINE_VEC.append(line_vec)

# 以下是打印出评论和其对应向量 并保存于txt文件中

f=open('line_vec.txt','w',encoding='utf-8')
for line in LINE_VEC:
    print(line)
    f.write(line)
f.close()

三、展示一些结果:

向量化:
文本向量化——方法1:基于高频词的向量化方式(包含python代码)_第1张图片
高频词汇的频数柱状图:
文本向量化——方法1:基于高频词的向量化方式(包含python代码)_第2张图片
这样得到整齐维数的特征向量就可以用于机器学习或者深度学习啦
下一篇将介绍TF-IDF 文本矩阵化方法

你可能感兴趣的:(python,数据分析,自然语言处理,机器学习,人工智能)