Git Product home page Git Product logo

wechatvisualization's Introduction

功能概要

能做什么

用于对微信聊天记录进行可视化。

  • 文本分析
    • 双方聊天词汇的词云图
    • 专属词汇分析(甲常用而乙不常用的词)
    • 共用词汇分析(甲乙都喜欢用的词)
  • 时间信息分析
    • 月度消息数量变化
    • 时均消息数量变化

下面这些图片都可以自动生成:

不能做什么

  • 不能提取微信聊天记录,微信聊天记录需要用另一个工具提取,下面会介绍。
  • 不能完成图片排版与美化,请自行完成(修改配置文件/源码或者使用 PPT 等第三方工具)。

开箱即用/用户指南

提取微信聊天记录

下载安装留痕

使用留痕这款软件,Github已经22.8 k star了,软件也已迭代到了1.1.1版本,是很成熟的软件了,值得信赖。

GitHub地址:LC044/WeChatMsg: 提取微信聊天记录,将其导出成HTML、Word、CSV文档永久保存,对聊天记录进行分析生成年度聊天报告 (github.com)

软件网站:https://memotrace.lc044.love/

下载 exe 然后安装就行了。

手机聊天记录同步到电脑

相信大部分人的聊天记录都在手机里面,电脑的聊天记录不全。所以先把手机的聊天记录同步到电脑上,这个大家在换手机的时候可能有过体验:微信 - 设置 - 聊天 - 聊天记录迁移与备份 - 迁移。等个几分钟吧,等待时间取决于您的聊天记录量有多大。

留痕软件界面操作

解密2:输入个人信息,获取信息。然后解密:开始启动!

然后就可以在好友中导出聊天记录了。为了减少乱码,请勿勾选图片、视频、表情包,导出的不含图片/视频/文件

导出完毕,退出留痕。在软件同一目录下会出现一个 data目录,点进去,data/聊天记录/ 下面会有个 csv 文件。大概长这个样子:

把这个csv文件拷贝到 WechatVisualization 的 input_data/ 目录里面。

注:使用留痕的时候您可能会发现它也集成了导出年度报告这种分析+可视化的功能,但仔细看看它制作的年度报告就会发现太粗糙了,词云图的词语乱七八糟,没有做数据清洗,这也是我为什么要自己动手开发的原因。不过,如果您觉得留痕制作的报告已经很好了,那我下面的内容您也不用看了。

安装python第三方库

使用者需要具备基本的 Python 知识(如何运行代码),电脑上已经安装了 Anaconda 或者 Python(版本>=3.7)。如果用 Anaconda,最好新建一个环境。

依次安装必要的第三方库

第三方库 功能
pandas 表格处理
matplotlib 绘图条形图
pyyaml 读取配置文件
jieba 中文分词
tqdm 打印进度条
pyecharts 绘制词云

一键安装方法:

pip install -r requirements.txt

安装方法不是本篇重点,基本上都是 pip install ,如果遇到问题请自行上网搜索解决方法,在此不赘。

修改配置文件

配置文件为 config.yml,用记事本就可以打开了,当然用代码编辑器更好,因为可以语法高亮。

里面可以自行设置的内容有

# 输入数据
# 下面这些文件都放在input_data目录下
# 聊天记录
msg_file: msg.csv
 # 微信表情中英文对照表
emoji_file: emoji.txt
# 停用词表,一般是没有实际意义的词,不想让被分析到的词都放在这里
stopword_file: stopwords_hit_modified.txt
# 词语转换表,用于合并意义相近的词,比如把“看到”、“看见”、“看看”都转换为“看”
transform_file: transformDict.txt
# 用户自定义词典,用于添加大部分字典没有的、但自己觉得不能分开的词,如i人、e人、腾讯会议
user_dict_file: userDict.txt

# 名字
# name1是自己的名字
name1: person 1
# name2是对方的名字
name2: person 2
# name_both是双方共同的名字
name_both: both

# 局部参数
# top_k是绘制前多少个词
# 如果词或表情的出现频次低于word_min_count或emoji_min_count,就不会被分析
# figsize是绘图图窗尺寸,第一个是宽度,第二个是高度
word_specificity:
  top_k: 25
  word_min_count: 2
  figsize:
  - 10
  - 12

emoji_specificity:
  emoji_min_count: 1
  top_k: 5
  figsize:
  - 10
  - 12

word_commonality:
  top_k: 25
  figsize:
  - 10
  - 12
  
emoji_commonality:
  top_k: 5
  figsize:
  - 12
  - 12

time_analysis:
  figsize:
  - 12
  - 8

运行代码

可以在代码编辑器中直接运行 main.py,也可以在命令行中(先激活之前创建的环境)运行 python main.py

成功运行应显示如下信息:

生成的图片可以在当前目录的 figs 文件夹中找到。

修改输入文件

查看生成的图片,可能会有些词不是自己想要的,抑或有些自己想要的词被拆分了,此时到 input_data/ 目录下面修改各文件即可。这是一个不断迭代的过程,也就是数据清洗,比较耗时间。但没办法,如果想要质量比较高的结果,就耐心好好做一下,把数据清洗干净。

  1. emoji.txt 是微信表情的中英文对照。微信表情在聊天记录中是以[捂脸]或者[Facepalm]的形式呈现的。我的聊天记录里面中英文的[xxx]都有,所以建立一个对照表,把所有的英文都替换成中文。如果您发现有的表情文字还是英文,可以在里面添加其中文,以便合并。
  2. stopwords_hit_modified.txt 是停用词表。诸如“现在”、“进行”、“好像”这种(我自认为)没有实际意义的词,不应该被统计,直接把它们剔除。如果你觉得生成的结果里面有你不想看到的词,可以在这里添加。
  3. transformDict.txt 把一些词转换成另一些词。诸如“看到”、“看见”、“看”、“看看”这些同义词可能被分别统计,完全没必要,我们可以把它们合并为一个词“看”。为此,只需在两栏中分别填写原词与转换词即可。注意,两栏用的是制表符(Tab)隔开
  4. usreDict 可以添加传统词典中没有的词,比如 “e人”、“i人”、“腾讯会议”等。如果不自行添加这些词,后果是它们可能会被拆成“e”、“i”、“人”、“腾讯”、“会议”这些词,这不是我们希望看到的。

报错解决

  1. ValueError: shape mismatch: objects cannot be broadcast to a single shape

  2. ValueError: The number of FixedLocator locations (5), usually from a call to set_ticks, does not match the number of ticklabels (1).

可能原因:出现上面两个报错,可能是因为相应位置的top_k或者min_count设置得太大了,而聊天记录量太少,导致没有这么多词可以绘制。

解决方法:考虑到这一点,我在每一小段程序运行时都打印了允许设置的最大参数值。如果打印双横线,代表该段参数设置无误,程序运行成功。您可以检查一下自己在相应位置的参数是否设置得太大了,然后适当减小。

实施细节/开发者指南

项目流程

  1. parse.py 读取 input_data/ 中的文件,执行分词。生成 keywords.csv 放入 temp_files/ ,里面在原数据基础上新增两列,一列是被拆分的词,一列是提取出的微信表情。
  2. word_cloud.py 计算词频,生成 pickle 文件 keyword_count.pkl 放入 temp_files/ ,同时制作词云放入 figs/
  3. 利用上一步计算的词频,计算词语专属性。图片放入 figs/
  4. 计算微信表情出现频次,生成 pickle 文件 emoji_count.pkl 放入 temp_files/ 同时计算表情专属性。图片放入 figs/
  5. 利用词频,计算词语共有性。图片放入 figs/
  6. 利用表情频次,计算表情共有性。图片放入 figs/
  7. 利用微信聊天记录原始文件,进行时间信息分析。图片放入 figs/

计算方法

记自己发送过某个词 $i$ 的次数为 $x_i$,对方发送过某个词 $i$ 的次数为 $y_i$​。

专属性计算

专属性表明自己常说,对方不常说(反之亦然)。我对专属性的考虑是这样的,假如有三个词 A、B、C。

自己频次x 对方频次y
A 4 0
B 100 96
C 1 0

对于自己来说,显然A的专属性应该是最高的。B词的话,两个人虽然也是差了4次,但是基数比较大,差了4次其实无明显对比。C的话,基数太小,要说C是自己专属的词汇,可靠性不高。

记专属性度量为 $\alpha$。我看到网上有人专属性计算用的是 $$ \alpha_i=\dfrac{x_i-y_i}{x_i+y_i} $$ 这么算下来,A词和C词的专属性是一致的。不合理!

如果乘上基数呢?基数就是总次数 $x+y$,那就是 $\alpha_i=x_i-y_i$。这样算下来,A词和B词就是一样了。也不合理。

所以在我的实施中,没有乘以词频之和,而是乘以词频的最大值,即 $$ \alpha_i=\dfrac{x_i-y_i}{x_i+y_i}\cdot\mathrm{max}(x_i,y_i) $$ 这样可以确保 A 词的专属性是最高的。

共有性计算

共用性表明两个人都常说某个词。所以首先排除那些有一方从来没说过的词。为此,首先对双方说过的词取交集

现在我们还是假设有三个词 A、B、C。

自己频次x 对方频次y
A 50 50
B 1000 1
C 1 1

B词被自己说过的次数比对方多得多,共有性显然很低。C词虽然双方说过的次数差不多,但基数太小,不能得出可靠结论。所以A词共有性最高。那怎么算呢?

共有性是专属性的反面,那我们能不能用专属性的倒数呢?我觉得不好,一方面因为分母是 $x-y$,容易出现零值;另一方面对于A词(50,50)和C词(1,1)不能做很好地区分。

为此,我使用了调和平均值: $$ \beta=\dfrac{2}{1/x+1/y} $$ 为什么这里使用调和平均值而不使用其他平均值呢,因为调和平均值是四大平均值中最偏向较小数的那个,“共有性”就是强调两个人都要经常说,不能光一个人说另一个人不说,也即一方说得再多,对于共有性的影响也很小,比如B词(1000,1)。

用调和平均值可以确保A词具有最大的共有性。

言未尽处,请看源码。

未来展望

本项目没有集成留痕的功能,如果把留痕的提取数据功能加进来,可以实现更简单的流程化操作。然而囿于作者的能力和时间限制,这一想法目前无法实践。对于其他功能不足、可改进的地方,也欢迎大家在GitHub或公众号后台留言。欢迎志同道合之士加入开发者团队,我们一起开发更好的 WechatVisualization!

wechatvisualization's People

Contributors

jasmine969 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar

Forkers

tymsx

wechatvisualization's Issues

使用问题

我理解支持的是A与B的聊天记录,比如我提取了全部的聊天记录,这里是没有区别的。
能否增加功能,在全部聊天记录里先筛选出目标聊天人,我看提取出来的messages里面有Remark、NickName这种字段,应该可以实现的。比如我用的是全部聊天记录,只筛选出与name1、name2有关的记录进行分析

使用反馈

您好,感谢您的开源项目,使用后发现生成的图片中,两人的个人专属词条和表情,除颜色,方向外其他均相同,不知是否为操作问题,再次感谢!

indexerror

File "c:\Users\xueli\baidu\BaiduSyncdisk\python_file\normal_coding\WechatVisualization-master\main.py", line 28, in main
parse(msg_file, emoji_file, stopword_file, transform_file, user_dict_file, process_rows)
File "c:\Users\xueli\baidu\BaiduSyncdisk\python_file\normal_coding\WechatVisualization-master\parse.py", line 55, in parse
if result[ind2 - 2] != '[':
IndexError: list index out of range
Uploading 屏幕截图 2024-03-21 105556.png…

ValueError

after i analyse three times, it show this error.

>python main.py
开始分词
Building prefix dict from the default dictionary ...
Loading model from cache C:\Users\30969\AppData\Local\Temp\jieba.cache
Loading model cost 0.407 seconds.
Prefix dict has been built successfully.
  0%|                                                                                            | 0/3 [00:00<?, ?it/s]F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\parse.py:73: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '[, 呲, 牙, ]' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.
  records.loc[i, 'keywords'] = ', '.join(result)
F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\parse.py:74: FutureWarning: Setting an item of incompatible dtype is deprecated and will raise an error in a future version of pandas. Value '' has dtype incompatible with float64, please explicitly cast to a compatible dtype first.
  records.loc[i, 'emoji'] = ', '.join(emoji_res)
100%|███████████████████████████████████████████████████████████████████████████████████| 3/3 [00:00<00:00, 998.96it/s]
F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\parse.py:82: FutureWarning: Downcasting behavior in `replace` is deprecated and will be removed in a future version. To retain the old behavior, explicitly call `result.infer_objects(copy=False)`. To opt-in to the future behavior, set `pd.set_option('future.no_silent_downcasting', True)`
  records.replace('', float('nan'), inplace=True)  # 方便后面dropna
====================
计算词频并制作词云
====================
计算word_specificity
word_min_count应不超过1
top_k应不超过3
====================
计算emoji_specificity
emoji_min_count应不超过2
top_k应不超过1
Traceback (most recent call last):
  File "F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\main.py", line 41, in <module>
    main(
  File "F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\main.py", line 31, in main
    emoji_specificity(name1, name2, **p_emoji_specificity)
  File "F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\emoji_specificity.py", line 33, in emoji_specificity
    plt.yticks(y, all_df.iloc[:top_k, 0].tolist())
  File "D:\py\lib\site-packages\matplotlib\pyplot.py", line 2139, in yticks
    labels_out = ax.set_yticklabels(labels, minor=minor, **kwargs)
  File "D:\py\lib\site-packages\matplotlib\axes\_base.py", line 73, in wrapper
    return get_method(self)(*args, **kwargs)
  File "D:\py\lib\site-packages\matplotlib\_api\deprecation.py", line 297, in wrapper
    return func(*args, **kwargs)
  File "D:\py\lib\site-packages\matplotlib\axis.py", line 2025, in set_ticklabels
    raise ValueError(
ValueError: The number of FixedLocator locations (3), usually from a call to set_ticks, does not match the number of labels (1).

and it seems have bug? the date seems just one day?

时域处理
第一天:2021-06-03
最后一天:2021-06-03
共计1天

maybe it wasnot error,but when i check the html and png, it seems dont have lots of data.

type error

>python main.py
Traceback (most recent call last):
  File "F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\main.py", line 3, in <module>
    from word_specificity import word_specificity
  File "F:\wechat_visulization\WechatVisualization-master\WechatVisualization-master\word_specificity.py", line 1, in <module>
    from matplotlib import pyplot as plt
  File "D:\py\lib\site-packages\matplotlib\pyplot.py", line 2230, in <module>
    switch_backend(rcParams["backend"])
  File "D:\py\lib\site-packages\matplotlib\__init__.py", line 672, in __getitem__
    plt.switch_backend(rcsetup._auto_backend_sentinel)
  File "D:\py\lib\site-packages\matplotlib\pyplot.py", line 247, in switch_backend
    switch_backend(candidate)
  File "D:\py\lib\site-packages\matplotlib\pyplot.py", line 267, in switch_backend
    class backend_mod(matplotlib.backend_bases._Backend):
  File "D:\py\lib\site-packages\matplotlib\pyplot.py", line 268, in backend_mod
    locals().update(vars(importlib.import_module(backend_name)))
  File "D:\py\lib\importlib\__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "D:\py\lib\site-packages\matplotlib\backends\backend_qtagg.py", line 12, in <module>
    from .backend_qt import (
  File "D:\py\lib\site-packages\matplotlib\backends\backend_qt.py", line 73, in <module>
    _MODIFIER_KEYS = [
  File "D:\py\lib\site-packages\matplotlib\backends\backend_qt.py", line 74, in <listcomp>
    (_to_int(getattr(_enum("QtCore.Qt.KeyboardModifier"), mod)),
TypeError: int() argument must be a string, a bytes-like object or a real number, not 'KeyboardModifier'

数据问题

请问我报错ValueError: shape mismatch: objects cannot be broadcast to a single shape. Mismatch is between arg 2 with shape (0,) and arg 3 with
shape (10,).这样应该如何去修改数值才对 自己研究了好久都没弄清楚麻烦大佬可以解决一下

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.