文本数据分析的基础知识

拆包操作

*** : 放到形参位置就是接收可变单身元素到元组中 放到实参位置就类似元组拆包**

**** : 放到形参位置就是接收可变键值对元素到字典中 放到实参位置就类似字典拆包**

python 复制代码
def demo1(*args, **kwargs):
    print(args)  # (1, 2, 3)
    print(kwargs)  # {'a': 4, 'b': 5, 'c': 6}
if __name__ == '__main__':
    demo1(1, 2, 3, a=4, b=5, c=6)
    a = (1, 2, 3)
    b = {'a': 4, 'b': 5, 'c': 6}
    demo1(*a, **b)
ini 复制代码
(1, 2, 3)
{'a': 4, 'b': 5, 'c': 6}
(1, 2, 3)
{'a': 4, 'b': 5, 'c': 6}

分隔符操作

**分隔符.join(列表): 把列表中的每个元素取出用指定分隔符依次拼接成新字符串**

字符串.split(分隔符): 把字符串根据指定分隔符依次分隔,分隔后元素放到列表中

set(x): 把x转换为set 注意: 默认去重

list(x): 把x转换为list

python 复制代码
def demo2():
    # 列表转为字符串
    name_list = ['苹果', '香蕉', '橘子', '橙子']
    print('-'.join(name_list))  # "苹果-香蕉-橘子-橙子"
    print('======================================')
    # 字符串转为列表
    name_str = "苹果-香蕉-橘子-橙子"
    print(name_str.split('-'))  # ['苹果', '香蕉', '橘子', '橙子']
    print(set(name_str))  # {'橙', '子', '橘', '蕉', '香', '苹', '果', '-'}
    print(list(name_str))  # ['苹', '果', '-', '香', '蕉', '-', '橘', '子', '-', '橙', '子']
    print(list(set(name_str)))  # ['橙', '子', '橘', '蕉', '香', '苹', '果', '-']

列表的拼接

**chain 是一种函数能将两个列表进行拼接,但是拼接形成的结果为生成器,如果直接进行输出,输出的结果为生成器地址,可以使用list 或者set进行生成器的遍历,但是set会自动对生成器内的内容进行去重操作**

python 复制代码
from itertools import chain
def demo3():
    # 已知两个列表
    a = [1, 2, 3, 4, 5]
    b = [6, 7, 8, 9]
    # chain()
    result = chain(a, b)
    print(type(result), result)
    print(next(result))
    print(list(result))  # [1, 2, 3, 4, 5, 6, 7, 8, 9]
    # 序列的+
    c = a + b
    print(c)
    # extend()
    a.extend(b)
    print(a)

各种类型的推导式

基础的推导式内容,都是普通的遍历最终将遍历的内容进行统一输出

python 复制代码
def demo4():
    # 列表推导式方式
    result = [i for i in range(10)]
    print(type(result), result)
    # 集合推导式方式
    result = {i for i in range(10)}
    print(type(result), result)
    # 字典推导式方式
    result = {i: i for i in range(10)}
    print(type(result), result)
    # 生成器推导式方式
    result = (i for i in range(1, 10))
    print(type(result), result)
    print(next(result))
    print(list(result))

zip进行列表合并

这段代码中主要是使用zip进行列表合并,结果为生成器所以第一个结果的输出type类型为zip,zip的合并方式是将上下两个列表一一对应合并的,如果有一个对应不上的不存在的则那个不会有结果

python 复制代码
def demo5():
    # 1.zip()合并多个列表
    # 已知两个列表
    name = ['张三', '李四', '王五', '赵六']
    age = [16, 17, 18, 19, 20]
    result = zip(name, age)
    print(type(result), result)
    print(list(result))

    # 2.先*解包成多个列表,然后zip()合并
    nums = [name, age]
    print(zip(nums))
    print(list(zip(*nums)))  # *只能解1层
    print(list(zip(name, age)))  # 手动

#<class 'zip'> <zip object at 0x00000273FFEA0340>
#[('张三', 16), ('李四', 17), ('王五', 18), ('赵六', 19)]
#<zip object at 0x00000273FFEA0540>
#[('张三', 16), ('李四', 17), ('王五', 18), ('赵六', 19)]
#[('张三', 16), ('李四', 17), ('王五', 18), ('赵六', 19)]

map函数对于lambda表达式的调用

lambda表达式也属于一种遍历方法 前面为获取的值 冒号后面是对值的操作结果

map函数是对于lambda的调用只有这样才能相互配合使用输出结果

python 复制代码
def my_func(x):
    # 功能是接收每个值,然后给这个值加2
    return x + 2

def demo6():
    # 1.直接传入函数名
    result = map(my_func, [1, 2, 3, 4, 5, 6])
    print(type(result), result)
    print(next(result))
    print(list(result))
    # 2.使用lambda表达式(匿名函数)
    result = map(lambda x: x + 2, [1, 2, 3, 4, 5, 6])
    # result = map(lambda x: x - 2, [1, 2, 3, 4, 5, 6])
    # result = map(lambda x: x * 2, [1, 2, 3, 4, 5, 6])
    # result = map(lambda x: x / 2, [1, 2, 3, 4, 5, 6])
    print(next(result))
    print(list(result))

上述核心知识点汇总练习

方式1是传统的for循环方式 方式二是通过lambda表达式和前面学习的拆包操作进行的多层嵌套,代码不易理解但是简洁迅速。

python 复制代码
"""
需求: 已知一个文件中存储了多行文本: 今天天气很好 今天有点热 昨天下雨 明天有可能下雨
要求获取到结巴分词并去重后的词列表
"""
from itertools import chain

import jieba

# 方式1: 原始方式
all_words_list = []
for line in open('data/test1.txt', encoding='utf8').readlines():
    all_words_list.extend(jieba.lcut(line))
print(list(set(all_words_list)))
# 方式2: 一行解决
print(list(set(chain(*map(lambda line: jieba.lcut(line), open('data/test1.txt', encoding='utf8'))))))

文本分析案例

python 复制代码
# todo 1.定义函数, 实现训练集和测试集的 标签分布的 可视化统计
def dm01_label_sns_countplot():
    # 1. 设置538风格 -> 一种具有现代感的可视化风格(不做也行)
    # plt.style.use('fivethirtyeight')

    # 2. 读取训练集 和 测试集.
    # 参1: 文件路径, 参2: 列分隔符(csv文件用, tsv文件用\t)
    train_data = pd.read_csv('./data/train.tsv', sep='\t')
    dev_data = pd.read_csv('./data/dev.tsv', sep='\t')
    # print(f'train_data.head: {train_data.head()}')
    # print(f'dev_data.head: {dev_data.head()}')

    # 3. 统计训练集标签的 0(负) 和 1(正) 的分组数量并可视化, 采用: 计数柱状图(countplot)
    # 参1: x轴标签, 参2: 数据集, 参3: 用于分组的分类变量, 参4: 是否显示图例(默认显示)
    sns.countplot(x='label', data=train_data, hue='label', legend=False)
    plt.title('train_label')
    plt.show()

    # 4. 统计测试集标签的 0(负) 和 1(正) 的分组数量并可视化, 采用: 计数柱状图(countplot)
    sns.countplot(x='label', data=dev_data, hue='label', legend=False)
    plt.title('dev_label')
    plt.show()
python 复制代码
# todo 2.定义函数, 实现训练集和测试集的 句子长度分布的 可视化统计
def dm02_len_sns_countplot_distplot():
    # 1. 读取训练集 和 测试集.
    # 参1: 文件路径, 参2: 列分隔符(csv文件用, tsv文件用\t)
    train_data = pd.read_csv('./data/train.tsv', sep='\t')
    dev_data = pd.read_csv('./data/dev.tsv', sep='\t')

    # 2. 计算训练集的 (每个句子的)长度.
    train_data['sentence_length'] = list(map(lambda x: len(x), train_data['sentence']))
    # 下述代码效果同上, 两种思路均可
    # train_data['sentence_length2'] = train_data['sentence'].apply(lambda x: len(x))
    # print(train_data.iloc[:, 2:])

    # 3. 绘制训练集的 句子长度分布.
    # 图1: 计数柱状图
    sns.countplot(x='sentence_length', data=train_data)
    plt.title('训练集句子长度分布_计数柱状图')
    plt.xticks([])  # 隐藏x轴刻度值
    plt.show()

    # 图2: 密度曲线图
    # distplot() 函数已过时, 可以用, 会报警告, 但是不会报错.
    # sns.distplot(x=train_data['sentence_length'], kde=True)           # seaborn: 3.9.1及其以下写法.
    # sns.distplot(x='sentence_length', data=train_data, kde=True)      # matplotlib: 3.10及其以上写法.

    # histplot(): 直方图
    sns.histplot(x='sentence_length', data=train_data, kde=True)
    # sns.histplot(x=train_data['sentence_length'], kde=True)  # 效果同上.
    plt.title('训练集句子长度分布_密度直方图')
    plt.show()

    # 4. 绘制测试集的 句子长度分布.
    # 4.1 计算测试集的 (每个句子的)长度.
    dev_data['sentence_length'] = list(map(lambda x: len(x), dev_data['sentence']))

    # 4.2 绘制测试集的 句子长度分布 -> 计数柱状图, 密度曲线图
    # 图1: 计数柱状图
    sns.countplot(x='sentence_length', data=dev_data)
    plt.title('测试集句子长度分布_计数柱状图')
    plt.xticks([])  # 隐藏x轴刻度值
    plt.show()

    # 图2: 直方图
    sns.histplot(x=dev_data['sentence_length'], kde=True)  # 效果同上.
    plt.title('测试集句子长度分布_密度直方图')
    plt.show(
python 复制代码
# todo 3.定义函数, 实现训练集和测试集的 正负样本长度散点分布
def dm03_sns_stripplot():
    # 1. 读取训练集 和 测试集.
    train_data = pd.read_csv('./data/train.tsv', sep='\t')
    dev_data = pd.read_csv('./data/dev.tsv', sep='\t')

    # 2. 获取数据长度列
    # 训练集
    train_data['sentence_length'] = list(map(lambda x: len(x), train_data['sentence']))
    # train_data['sentence_length'] = train_data['sentence'].apply(lambda x: len(x))    # 效果同上.

    # 测试集
    dev_data['sentence_length'] = list(map(lambda x: len(x), dev_data['sentence']))

    # 3. 统计正负样本长度散点分布:
    # 训练集
    sns.stripplot(x='label', y='sentence_length', data=train_data)
    plt.title('训练集正负样本长度散点分布')
    plt.show()

    # 测试集
    sns.stripplot(x='label', y='sentence_length', data=dev_data)
    plt.title('测试集正负样本长度散点分布')
    plt.show()
python 复制代码
# todo 4.定义函数, 实现训练集和测试集的 词频统计(即: 获取不同词汇总数统计)
def dm04_word_count_wordcloud():
    # 1. 读取训练集 和 测试集.
    train_data = pd.read_csv('./data/train.tsv', sep='\t')
    dev_data = pd.read_csv('./data/dev.tsv', sep='\t')

    # 2. 统计训练集的词汇总数.
    train_vocab = set(chain(*map(lambda x: jieba.lcut(x), train_data['sentence'])))

    # 3. 统计测试集的词汇总数.
    dev_vocab = set(chain(*map(lambda x: jieba.lcut(x), dev_data['sentence'])))

    # 4. 打印结果.
    print(f'训练集不同词汇总数: {len(train_vocab)}')
    print(f'测试集不同词汇总数: {len(dev_vocab)}')
python 复制代码
# todo 5.定义函数, 实现训练集和测试集的 高频形容词词云
# todo 5.1 定义函数, 获取文本中的形容词列表.
def get_a_list(text):  # 形容词用a表示
    # 1. 定义空列表, 用于存储: 文本中的形容词.
    a_list = []

    # 2. 使用jieba的词性标注功能, 切分文本, 遍历整个切分动作.
    for value in pseg.lcut(text):
        # print(f'value: {value}')        # 词 词性
        # print(f'value: {value.word}')   # 词
        # print(f'value: {value.flag}')   # 词性
        # 3. 判断词性, 是否是形容词, 如果是形容词, 则添加到列表中.
        if value.flag == 'a':
            a_list.append(value.word)
    # 4. 返回结果
    return a_list


# todo 5.2 定义函数, 根据词云列表产生词云
def get_word_cloud(keywords_list):
    # 1. 实例化词云生成器, 设置字体路径, 最大显示数, 背景色...
    # 参1: 字体路径, 参2: 最大显示数, 参3: 背景色
    wordcloud = WordCloud(font_path='./data/SimHei.ttf', max_words=100, background_color='white')
    # 2. 将关键词列表 -> 转换为 空格分割的字符串, 适配词云输入格式.
    keywords_str = ' '.join(keywords_list)
    # 3. 根据关键字字符串, 生成词云.
    wordcloud.generate(keywords_str)
    # 4. 配置并显示词云图像.
    # 4.1 创建新的绘图窗口
    plt.figure()
    # 4.2 生成图云(绘制图像)
    # 参1: 生成词云图像的数据, 参2: 设置图像插值方法为 -> 双线性插值
    plt.imshow(wordcloud, interpolation='bilinear')
    # 4.3 隐藏坐标轴
    plt.axis('off')
    # 4.4 显示图像
    plt.show()


# todo 5.3 定义函数, 实现训练集和测试集的 高频形容词词云
def dm05_word_cloud():
    # 场景1: 处理训练集.
    # 1. 读取训练集
    train_data = pd.read_csv('./data/train.tsv', sep='\t')
    # 2. 处理 训练集 正样本(label=1) -> 生成词云.
    # 2.1 筛选label=1的样本, 并提取句子(sentence)列
    p_train_data = train_data[train_data['label'] == 1]['sentence']
    # print(p_train_data)
    # 2.2 对每个正样本句子, 提取形容词, 并用chain合并所有的形容词. (chain: 链式操作)
    p_a_train_vocab = chain(*map(lambda x: get_a_list(x), p_train_data))
    # 2.3 调用词云函数, 根据形容词列表, 生成词云.
    get_word_cloud(p_a_train_vocab)

    # 3. 分隔符.
    print('-' * 60)

    # 4. 处理 训练集 负样本(label=0) -> 生成词云.
    # 4.1 筛选label=1的样本, 并提取句子(sentence)列
    p_train_data = train_data[train_data['label'] == 0]['sentence']
    # print(p_train_data)
    # 4.2 对每个正样本句子, 提取形容词, 并用chain合并所有的形容词. (chain: 链式操作)
    p_a_train_vocab = chain(*map(lambda x: get_a_list(x), p_train_data))
    # 4.3 调用词云函数, 根据形容词列表, 生成词云.
    get_word_cloud(p_a_train_vocab)

手动实现提取n-gram特征

**给定一段文本序列, 其中n个词或字的相邻共现特征即n-gram特征, 常用的n-gram特征是bi-gram和tri-gram特征, 分别对应n为2和3. 它必须要相邻且共现才为n-gram特征**

且这个n不宜过大 这个特征主要是为了丰富词表,让一些本在一起的却被分开的词语重现,且增加数据集的样本数量。

python 复制代码
def get_n_gram(data, n):
    """
    思考: 如何提取?
    分别获取a和b后,直接zip合并去重即可
    a = [1, 2, 3, 4, 5, 1, 2, 8, 9]
    b = [2, 3, 4, 5, 1, 2, 8, 9]
    """
    # 方式1: 原生方式
    # a = data[0:]
    # b = data[1:]
    # print(set(zip(a, b)))
    # 方式2: 一步到位
    print(set(zip(*[data[i:] for i in range(n)])))

指定文本长度提取训练样本

这个属于是文本规范的方式:

一般模型的输入需要等尺寸大小的矩阵, 因此在进入模型前需要对每条文本数值映射后的长度进行规范, 此时将根据句子长度分布分析出覆盖绝大多数文本的合理长度, 对超长文本进行截断, 对不足文本进行补齐(一般使用数字0), 这个过程就是文本长度规范.

直接调用函数实现文本规范

```python def trans_sequence_len1(data, length): # 填充 new_data = sequence.pad_sequences(sequences=data, maxlen=length, padding='post', value=0, truncating='post') return new_data ```

手动定义函数实现文本规范

相关推荐
xzl042 小时前
当使用 AutoTokenizer 加载百川(Baichuan)模型时出现 BaiChuanTokenizer 相关报错
人工智能·pytorch·python
前端程序猿之路2 小时前
简易版AI知识助手项目 - 构建个人文档智能问答系统
前端·人工智能·python·ai·语言模型·deepseek·rag agent
Chukai1232 小时前
第3章:基于LlamaIndex+Ollama+ChromaDB搭建本地简单RAG问答系统
开发语言·人工智能·python·rag·rag问答系统
私人珍藏库2 小时前
[吾爱大神原创工具] PythonEnvManager - Python 环境管理工具 [更新自定义扫描路径]
开发语言·python
前端程序猿之路2 小时前
AI大模型应用开发之Prompt 工程
人工智能·python·深度学习·机器学习·prompt·ai编程·提示词
呆萌很2 小时前
PyCharm 中使用 Anaconda
python
superman超哥2 小时前
仓颉代码内联策略深度解析
c语言·开发语言·c++·python·仓颉
写代码的【黑咖啡】2 小时前
Python中的文件操作详解
java·前端·python
q_30238195562 小时前
秒级筛查+94.7%精准!华为Atlas 200 DK边缘设备解锁糖尿病视网膜病变检测新范式
人工智能·python·深度学习·智能体