拆包操作
*** : 放到形参位置就是接收可变单身元素到元组中 放到实参位置就类似元组拆包**
**** : 放到形参位置就是接收可变键值对元素到字典中 放到实参位置就类似字典拆包**
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 ```