程序设计一:分词和词云

程序设计一:分词和词云

功能一

功能:将数据读入,再使用jieba库对文件中的弹幕内容进行分词处理,并将所有分词存入列表。

使用函数GetText实现这一功能,代码如下:

def GetText(filepath):
    '''
    读入文档并分词
    :param filepath: 字符串型文件地址,读入格式为csv文件
    :return: 列表类型,采用 jieba 分词后的结果
    '''
    all_words = []
    with open(filepath, encoding='utf-8')as f: # 编码方式 utf-8
        reader = csv.reader(f)
        headers = next(reader)                 # 读入标题行
        Row = namedtuple('Row', headers)       # 构建行结构
        for each_row in reader:
            row = Row(*each_row)               # 将每一行数据转换成行结构
            row_text = row.content
            row_words = jieba.lcut(row_text)   # 采用jieba库来分词
            all_words.extend(row_words)        # 分词结果存入列表
    return  all_words

功能二

功能:统计词频,读入停用词表,并过滤掉停用词。

使用StatWord函数实现这一功能,代码如下:

def StatWord(all_words):
    '''
    统计词频,并过滤停用词
    :param all_words: 列表类型,包含分词
    :return: 字典类型,值为非停用词的词频
    '''
    counts = {}
    #载入停用词
    stopwords = [line.strip() for line in open('stopwords_list.txt', 'r',encoding='utf-8').readlines()]
    #统计非停用词的词频
    for word in all_words:
        if word not in stopwords and word != ' ':    
            counts[word] = counts.get(word, 0) + 1
    return  counts

在主函数中调用该函数实现功能运行程序,统计结果如下(部分截图):
词频排序运行结果

功能三

采用WordFiltrate函数筛选掉低频词,并得到非低频词;

然后采用GetCharacters函数从非低频词中提取出特征集

def WordFiltrate(counts):
    '''
    将所有词按照词频排序,并去除低频词
    :param counts:字典类型,分词极其词频
    :return: 元组列表,词和频率,按照词频从高到低排列
    '''
    items = list(counts.items())                 # 转换为元组列表
    items.sort(key = lambda x:x[1],reverse=True) # 按照元组的第二个元素(词频)排序
    for i in range(len(items)):                  # 筛选非低频词
        if items[i][1] <= 5:
            items = items[:i-1]
            break
    return items

def GetCharacters(items):
    '''
    提取特征词
    :param items: 元组列表,特征词和词频
    :return: 列表,特征词集
    '''
    characters = []
    for item in items:
        characters.append(item[0])
    return characters

在主函数中采取运行上述函数,实现本题功能,可以得到特征集和相应的词频,该部分结果不在展示(因为只去掉了低频词,所以高频词的结果呈现和上一题相同)。

功能四

采用TextVector函数分析相应文本,得到该文本中所有句子的特征向量以及所有特征词的词频。其中,每次迭代调用GetVector函数得到每个句子的特征向量。

def GetVector1(sentence, characters, word_freq):
    '''
    提取句子的特征向量
    :param sentence: 字符,待分析的句子
    :param characters: 列表,特征集
    :param word_freq: 一维列表,所有特征词的词频
    :return: 句子的特征向量
    '''
    words = jieba.lcut(sentence)
    vector = [0] * len(characters)
    for i in range(len(characters)):
        for word in words:
            if word == characters[i]:
                vector[i] = 1
        word_freq[i] += vector[i]
    return vector

def GetVector2(sentence, characters):
    '''
    提取句子的特征向量
    :param sentence: 字符,待分析的句子
    :param characters: 列表,特征集
    :return: 句子的特征向量
    '''
    words = jieba.lcut(sentence)
    vector = [0] * len(characters)
    for i in range(len(characters)):
        for word in words:
            if word == characters[i]:
                vector[i] = 1
    return vector

def TextVector(filepath, characters):
    '''
    读入待分析文本,调用 GetVector 函数统计每个句子的特征向量,并返回待分析文本的相关信息
    :param filepath: 待分析文本路径
    :param characters: 特征词集
    :return: text_vector: 二维列表,存储的是整篇文章所有句子的特征向量
             word_freq: 一维列表,所有特征词的词频(每个特征词共在多少个句子中出现)
             num_sentence: 整数,总共有多少个句子
    '''
    text_vector = []
    word_freq = [0] * len(characters)
    with open(filepath, encoding='utf-8') as f:  # 编码方式
        reader = csv.reader(f)
        headers = next(reader)
        Row = namedtuple('Row', headers)
        num_sentence = 0
        for each_row in reader:
            num_sentence += 1
            row = Row(*each_row)
            row_text = row.content
            if len(row_text) > 5:
                vector = GetVector1(row_text, characters, word_freq)
                text_vector.append([row_text, vector])
    return text_vector, word_freq, num_sentence

为方便展示,定义函数来保存结果,代码如下

def WriteTextVector(text_vector):
    with open('vectors_save.csv', 'w', encoding='utf-8', newline='') as fp:
        writer = csv.writer(fp)
        header = ['text', 'vector']
        writer.writerow(header)           # 设置第一行属性名
        writer.writerows(text_vector)     # 将数据写入文件

在主函数中调用这些函数实现上述功能,截图如下(部分):

每一个句子的特征向量

功能五

定义SIMILARITY类,采用两种方法计算句子之间的相似度

其中,方法Cos_dis计算余弦相似度,方法Euc_dis计算欧几里得相似度

class SIMILARITY(object):
    def __init__(self, sentence_1, sentence_2, characters):
        self.sentence_1 = sentence_1
        self.sentence_2 = sentence_2
        self.characters = characters
        self.vector_1 = GetVector2(self.sentence_1, self.characters)
        self.vector_2 = GetVector2(self.sentence_2, self.characters)

    def Cos_dis(self):
        v1 = np.array(self.vector_1)
        v2 = np.array(self.vector_2)
        v1_norm = np.linalg.norm(v1)
        v2_norm = np.linalg.norm(v2)
        self.cos_dis = np.dot(v1, v2) / (v1_norm * v2_norm)
        return self.cos_dis

    def Euc_dis(self):
        self.euc_dis = math.sqrt(sum([(a - b) ** 2 for (a, b) in zip(self.vector_1, self.vector_2)]))
        return self.euc_dis

在主函数中,以两条弹幕为例子,分别调用上述两种方法计算距离,代码如下

# 计算距离
sentence_1 = '哈哈哈哈好吃'
sentence_2 = '还不错哈哈哈哈'
dis = SIMILARITY(sentence_1,sentence_2,characters)
cos_dis = dis.Cos_dis()
euc_dis = dis.Euc_dis()
print("cos_dis = {},euc_dis = {}".format(cos_dis,euc_dis))

功能六

使用WordCloud包绘制词云图,定义WordsCloud函数实现该功能,函数定义代码如下:

def WordsCloud(items):
    '''
    绘制词云图
    :param items: 元组列表,特征词和词频
    :return:
    '''
    frequency = {}                                           # 词云所用词汇和词频
    for i in range(50):
        frequency[items[i][0]] = items[i][1]
    font = "C:\Windows\Fonts\STXINGKA.TTF"                   # 字体路径
    wc = WordCloud(font_path=font,background_color="white")  # 可以增加 mask=mask_image 设置
    wc.fit_words(frequency)                   # 基于前面的词频统计
    plt.imshow(wc)
    plt.axis("off")
    plt.show()

在主函数中调用,结果如下:
词云图

功能七

使用 TF-IDF 的方法构建特征词集,在之前第四题中,已经利用函数TextVector统计了每个词语在多少的句子中出现,并记录了句子的数量。本题定义了TfIdfValue函数,计算每个词的Tf*Idf值,并依据该值来排序。

def TfIdfValue(items, word_freq, num_sentence):
    '''
    按照TF-IDF方法,筛选特征词,构造特征词集
    :param items: 元组列表,所有词语极其词频
    :param word_freq: 一维列表,每个词在多少句子中出现
    :param num_sentence: 整数,句子总数量
    :return: 字典,按照 Tf*Idf 由大到小排序的特征词和值
    '''
    # 计算每个词的TF值
    word_tf = {}      # 存储每个词的tf值
    sum_fenq = 0
    for item in items:
        sum_fenq += int(item[1])
    for item in items:
        word_tf[item[0]] = item[1] / sum_fenq
    # 计算每个词的IDF值
    word_idf = {}      # 存储每个词的idf值
    for i in range(len(items)):
        word_idf[items[i][0]] = math.log(num_sentence / (word_freq[i] + 1))
    # 计算每个词的TF*IDF的值
    word_tf_idf = {}   # 存储每个词的 tf*idf 值
    for item in items:
        word_tf_idf[item[0]] = word_tf[item[0]] * word_idf[item[0]]
    # 对字典按值由大到小排序
    tf_idf_list = sorted(word_tf_idf.items(), key=operator.itemgetter(1), reverse=True)
    return tf_idf_list

在主函数中调用该功能并运行,使用部分样例的结果如下:

Tf-Idf值排序结果

和词频统计的方式相对照,排序结果大致相同,个别词略有差异,在前十个高频词中,”蒜“,”加油“等词的排序不太一样。
综合两种方法来看,第二种计算方法更能反映每个分词的重要程度。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值