快速入门指南
恭喜您成功安装了Sequenzo! 🎉 现在就可以开始玩转社会序列分析啦。
这个指南会手把手教你分析国家级CO₂排放序列。想了解我们是怎么把原始数据处理成适合做序列分析的格式?详细过程看这里(TODO:SequenzoWebsite网页)。
python新手?没关系!Sequenzo专门为小白设计,界面直观好上手,不管你是编程萌新还是Python老司机,都能快速掌握。
这个教程结束后,你将掌握:
- 安装Sequenzo
- 导入和对数据进行初步探索
- 分析社会序列
- 结果可视化
好了,开始我们的数据分析之旅吧!🐍✨
1. 初步了解数据
python
# 导入必要的库
# 你的调用代码(比如在脚本或notebook中)
from sequenzo import * # 导入包,给它一个简短的别名
import pandas as pd # 数据处理
# 列出Sequenzo中所有可用的数据集
# 现在用别名来调用函数:
print('Sequenzo中的可用数据集: ', list_datasets())
# 加载我们在本教程中要探索的数据
# `df`是`dataframe`的缩写,这是数据集的常用变量名
# df = load_dataset('country_co2_emissions')
df = load_dataset('country_co2_emissions_global_deciles')
# 显示数据框
dfSequenzo中的可用数据集: ['biofam', 'biofam_child_domain', 'biofam_left_domain', 'biofam_married_domain', 'chinese_colonial_territories', 'country_co2_emissions', 'country_co2_emissions_global_deciles', 'country_co2_emissions_global_quintiles', 'country_co2_emissions_local_deciles', 'country_co2_emissions_local_quintiles', 'country_gdp_per_capita', 'polyadic_samplec1', 'polyadic_samplep1', 'polyadic_seqc1', 'polyadic_seqp1']
| country | 1800 | 1801 | 1802 | 1803 | 1804 | 1805 | 1806 | 1807 | 1808 | ... | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | Afghanistan | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | ... | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 |
| 1 | Albania | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | ... | D9 | D9 | D9 | D9 | D9 | D9 | D9 | D9 | D9 | D9 |
| 2 | Algeria | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | ... | D9 | D9 | D9 | D9 | D9 | D9 | D9 | D9 | D9 | D9 |
| 3 | Andorra | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | ... | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) |
| 4 | Angola | D3 | D3 | D3 | D3 | D3 | D3 | D3 | D3 | D3 | ... | D8 | D8 | D8 | D8 | D8 | D8 | D8 | D8 | D8 | D8 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 189 | Venezuela | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | ... | D9 | D9 | D9 | D9 | D9 | D8 | D6 | D8 | D8 | D8 |
| 190 | Vietnam | D3 | D3 | D3 | D3 | D3 | D3 | D3 | D3 | D3 | ... | D8 | D8 | D8 | D8 | D8 | D9 | D9 | D9 | D9 | D9 |
| 191 | Yemen | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | D1 (Very Low) | ... | D8 | D8 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 |
| 192 | Zambia | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | ... | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 |
| 193 | Zimbabwe | D5 | D5 | D5 | D5 | D5 | D5 | D5 | D5 | D5 | ... | D8 | D8 | D8 | D8 | D8 | D8 | D8 | D8 | D8 | D8 |
194 rows × 224 columns
这个分类基于所有年份的人均CO₂排放值:
- 极低(后20%)
- 低(20-40%)
- 中等(40-60%)
- 高(60-80%)
- 极高(前20%)
用社会序列分析的术语来说,每个类别叫做一个状态,状态的序列叫做社会序列。总的来说,这个数据集展示了每个国家每年的人均CO₂排放水平。
以安道尔为例:
python
# 筛选安道尔的数据
andorra_df = df[df['country'] == 'Andorra']
# 显示安道尔的数据框
andorra_df| country | 1800 | 1801 | 1802 | 1803 | 1804 | 1805 | 1806 | 1807 | 1808 | ... | 2013 | 2014 | 2015 | 2016 | 2017 | 2018 | 2019 | 2020 | 2021 | 2022 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3 | Andorra | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | D7 | ... | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) | D10 (Very High) |
1 rows × 224 columns
根据结果(原数据集的一个子集),我们可以看到安道尔的人均CO₂排放在这些年里经历了以下变化:
- 1990-1991: 从"极高"水平开始,说明排放量在所有国家中排前20%
- 1992-1997: 下降到"高"水平(60-80百分位)
- 1998: 短暂回到"极高"水平
- 2000年代至今: 稳定在"高"水平(60-80百分位),并一直保持到2019年
但这就带来了一个问题:如果我们想分析所有国家的序列怎么办? 🤔
这时候Sequenzo就能派上用场!
2. 使用 Sequenzo 分析社会序列
python
# 创建 SequenceData 对象
# 定义时间跨度变量
time_list = list(df.columns)[1:]
# states = ['Very Low', 'Low', 'Middle', 'High', 'Very High']
states = ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9']
# TODO: 编写异常处理逻辑:如果参数不存在,则提示传入正确的参数
# sequence_data = SequenceData(df, time=time, id_col="country", ids=df['country'].values, states=states)
sequence_data = SequenceData(df,
time=time_list,
id_col="country",
states=states,
labels=states)
sequence_data[!] Detected missing values (empty cells) in the sequence data.
→ Automatically added 'Missing' to `states` and `labels` for compatibility.
However, it's strongly recommended to manually include it when defining `states` and `labels`.
For example:
states = ['At Home', 'Left Home', 'Missing']
labels = ['At Home', 'Left Home', 'Missing']
This ensures consistent color mapping and avoids unexpected visualization errors.
[>] SequenceData initialized successfully! Here's a summary:
[>] Number of sequences: 194
[>] Number of time points: 223
[>] Min/Max sequence length: 216 / 223
[>] There are 7 missing values across 1 sequences.
First few missing sequence IDs: ['Panama'] ...
[>] Top sequences with the most missing time points:
(Each row shows a sequence ID and its number of missing values)
Missing Count
Sequence ID
Panama 7
[>] States: ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'Missing']
[>] Labels: ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'Missing']
SequenceData(194 sequences, States: ['D1 (Very Low)', 'D10 (Very High)', 'D2', 'D3', 'D4', 'D5', 'D6', 'D7', 'D8', 'D9', 'Missing'])
数据可视化
在众多可视化方法中,索引图是最常用的。下面我们来看看它的效果。
我们刚才已经成功创建了SequenceData对象,这是Sequenzo分析社会序列的核心工具。
如果只用肉眼看原始数据,我们一次只能关注一个国家的发展轨迹。但有了Sequenzo,我们就能同时分析所有国家的数据!可视化是其中最关键的功能,它能帮我们发现数据中隐藏的规律和趋势。
python
# 绘制索引图
# TODO: 在这里同样处理意外参数的问题。TypeError: plot_sequence_index() 函数收到了意外的关键字参数 'sortv'
plot_sequence_index(sequence_data,
# save_as='index_plot'
)
<Figure size 640x480 with 0 Axes>
还想挖掘更多信息?状态分布图来啦!
python
sequence_data.plot_legend(save_as="legend_plot")
python
plot_most_frequent_sequences(sequence_data, save_as='test', top_n=5)hh
<Figure size 640x480 with 0 Axes>
python
plot_mean_time(sequence_data, save_as='mean_time')
<Figure size 640x480 with 0 Axes>
python
plot_transition_matrix(sequence_data, save_as='transition_matrix')
<Figure size 640x480 with 0 Axes>
python
plot_state_distribution(sequence_data, save_as='state_distribution')
<Figure size 640x480 with 0 Axes>
python
plot_modal_state(sequence_data, save_as='modal_state')
差异性度量
python
# 参数替换选项:用"OM/DHD/HAM"代替"OMspell",用"CONSTANT"代替"TRATE"
om = get_distance_matrix(seqdata=sequence_data,
method='OM',
sm="TRATE",
indel="auto")
om[>] Processing 194 sequences with 11 unique states.
[>] Transition-based substitution-cost matrix (TRATE) initiated...
- Computing transition probabilities for: [D1 (Very Low), D10 (Very High), D2, D3, D4, D5, D6, D7, D8, D9, Missing]
[>] Indel cost generated.
[>] Identified 194 unique sequences.
[>] Starting Optimal Matching(OM)...
[>] Computing all pairwise distances...
[>] Computed Successfully.
| Afghanistan | Albania | Algeria | Andorra | Angola | Antigua and Barbuda | Argentina | Armenia | Australia | Austria | ... | Uganda | Ukraine | Uruguay | Uzbekistan | Vanuatu | Venezuela | Vietnam | Yemen | Zambia | Zimbabwe | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Afghanistan | 0.000000 | 272.363879 | 141.530885 | 405.839693 | 357.116339 | 352.452702 | 369.202821 | 199.747566 | 363.605396 | 367.308098 | ... | 356.188303 | 251.681276 | 391.564474 | 253.570661 | 333.417093 | 193.512323 | 339.495876 | 337.004372 | 405.784131 | 389.419165 |
| Albania | 272.363879 | 0.000000 | 196.640891 | 293.042386 | 360.848766 | 357.623372 | 291.258820 | 190.293293 | 330.065835 | 318.787795 | ... | 301.974406 | 207.816080 | 269.205424 | 205.916577 | 385.871215 | 217.202167 | 355.905637 | 150.343476 | 331.733788 | 324.072412 |
| Algeria | 141.530885 | 196.640891 | 0.000000 | 299.876169 | 360.346243 | 329.826237 | 297.445339 | 131.698913 | 285.521108 | 291.201892 | ... | 386.745755 | 173.060640 | 276.896587 | 145.923477 | 361.337985 | 75.716405 | 348.517376 | 309.997189 | 397.970384 | 368.047516 |
| Andorra | 405.839693 | 293.042386 | 299.876169 | 0.000000 | 356.053656 | 317.797407 | 119.351333 | 288.455080 | 161.034886 | 143.550606 | ... | 442.272407 | 231.894801 | 323.007193 | 256.673631 | 337.870059 | 320.299300 | 305.637267 | 338.668802 | 248.972441 | 316.165089 |
| Angola | 357.116339 | 360.848766 | 360.346243 | 356.053656 | 0.000000 | 291.024809 | 338.252215 | 304.404207 | 333.524614 | 343.035738 | ... | 299.756320 | 323.190476 | 213.309453 | 329.042700 | 223.247060 | 388.304116 | 126.257652 | 324.332208 | 355.987397 | 347.278292 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| Venezuela | 193.512323 | 217.202167 | 75.716405 | 320.299300 | 388.304116 | 332.208197 | 314.154419 | 167.770756 | 307.697612 | 294.576219 | ... | 407.898441 | 178.451252 | 299.052292 | 159.381580 | 393.463182 | 0.000000 | 386.746863 | 338.328445 | 409.781349 | 363.126942 |
| Vietnam | 339.495876 | 355.905637 | 348.517376 | 305.637267 | 126.257652 | 277.169745 | 281.862722 | 262.901696 | 284.480681 | 296.840967 | ... | 250.273278 | 313.199712 | 224.199999 | 317.111338 | 171.558720 | 386.746863 | 0.000000 | 332.362799 | 311.052135 | 313.268987 |
| Yemen | 337.004372 | 150.343476 | 309.997189 | 338.668802 | 324.332208 | 402.822666 | 338.626193 | 287.908848 | 368.726059 | 362.779293 | ... | 210.976531 | 287.655467 | 289.098219 | 284.491015 | 338.798635 | 338.328445 | 332.362799 | 0.000000 | 323.373702 | 353.783341 |
| Zambia | 405.784131 | 331.733788 | 397.970384 | 248.972441 | 355.987397 | 400.131845 | 247.433419 | 362.309280 | 364.953012 | 359.363387 | ... | 442.218057 | 373.720811 | 406.480220 | 371.778073 | 255.268940 | 409.781349 | 311.052135 | 323.373702 | 0.000000 | 304.666582 |
| Zimbabwe | 389.419165 | 324.072412 | 368.047516 | 316.165089 | 347.278292 | 279.071995 | 315.245317 | 292.686113 | 257.977877 | 282.863190 | ... | 372.870754 | 325.264179 | 340.907764 | 320.059748 | 347.484712 | 363.126942 | 313.268987 | 353.783341 | 304.666582 | 0.000000 |
194 rows × 194 columns
python
plot_relative_frequency(seqdata=sequence_data,
distance_matrix=om,
num_groups=12,
dpi=200,
# save_as='relative_frequency_plot'
)
# 可视化主要问题
# 1. 当把横坐标从“严格的分类标签”变成“数值(年份/年龄)”时,刻度有可能跑偏,得手动把 xticks/布局调回来。
# 2. 状态(分类)多了以后,默认 legend 效果会很糟,得自己选位置或分列、扩增画布空间,才能让图例和主体同时都好看、好读。
<Figure size 640x480 with 0 Axes>
聚类分析
python
cluster = Cluster(om, sequence_data.ids, clustering_method='ward')
cluster.plot_dendrogram(xlabel="Countries", ylabel="Distance")[>] Converting DataFrame to NumPy array...

<Figure size 640x480 with 0 Axes>
python
# Create a ClusterQuality object to evaluate clustering quality创建一个 ClusterQuality 对象,用于评估聚类质量。
cluster_quality = ClusterQuality(cluster)
cluster_quality.compute_cluster_quality_scores()
cluster_quality.plot_combined_scores(norm='zscore', save_as='combined_scores')
summary_table = cluster_quality.get_metrics_table()
print(summary_table)
Metric Opt. Clusters Opt. Value Z-Score Norm. Min-Max Norm.
0 ASW 6 1.922696 1.922696 1.0
1 ASWw 6 1.922696 1.922696 1.0
2 HG 2 3.235991 3.235991 1.0
3 PBC 20 1.028963 1.028963 1.0
4 CH 8 0.613044 0.613044 1.0
5 R2 20 1.297366 1.297366 1.0
6 HC 20 1.228937 1.228937 1.0
<Figure size 640x480 with 0 Axes>
python
cluster_results = ClusterResults(cluster)
membership_table = cluster_results.get_cluster_memberships(num_clusters=5)
print(membership_table)
distribution = cluster_results.get_cluster_distribution(num_clusters=5)
print(distribution)
cluster_results.plot_cluster_distribution(num_clusters=5, save_as="distribution.png", title=None) Entity ID Cluster
0 Afghanistan 1
1 Albania 1
2 Algeria 1
3 Andorra 3
4 Angola 4
.. ... ...
189 Venezuela 1
190 Vietnam 4
191 Yemen 2
192 Zambia 3
193 Zimbabwe 5
[194 rows x 2 columns]
Cluster Count Percentage
0 1 55 28.35
1 2 30 15.46
2 3 49 25.26
3 4 18 9.28
4 5 42 21.65
/Users/lei/Documents/Sequenzo_all_folders/Sequenzo-main/sequenzo/clustering/hierarchical_clustering.py:598: FutureWarning:
Passing `palette` without assigning `hue` is deprecated and will be removed in v0.14.0. Assign the `x` variable to `hue` and set `legend=False` for the same effect.
ax = sns.barplot(x='Cluster', y='Count', data=distribution, palette='pastel')

<Figure size 640x480 with 0 Axes>
python
mapping_dict = {
1: 'xxx',
2: 'Test',
3: 'The name of the cluster',
4: 'xxxxx',
5: 'whsiaa',
}
membership_table = replace_cluster_id_by_labels(membership_table,
mapping=mapping_dict,
new_cluster_column_name='Cluster',
new_id_column_name='ID')
membership_table| ID | Cluster | |
|---|---|---|
| 0 | Afghanistan | xxx |
| 1 | Albania | xxx |
| 2 | Algeria | xxx |
| 3 | Andorra | The name of the cluster |
| 4 | Angola | xxxxx |
| ... | ... | ... |
| 189 | Venezuela | xxx |
| 190 | Vietnam | xxxxx |
| 191 | Yemen | Test |
| 192 | Zambia | The name of the cluster |
| 193 | Zimbabwe | whsiaa |
194 rows × 2 columns
python
plot_sequence_index(seqdata=sequence_data,
id_group_df=membership_table,
categories='Cluster',
# save_as='cluster_index_plot'
)
python
plot_state_distribution(seqdata=sequence_data,
id_group_df=membership_table,
categories='Cluster',
# save_as='cluster_state_distribution_plot'
)
Regression
python
python
Conclusions
python