Обмен технологиями

[Обработка естественного языка] Приложения социальных вычислений для борьбы с COVID-19

2024-07-12

한어Русский языкEnglishFrançaisIndonesianSanskrit日本語DeutschPortuguêsΕλληνικάespañolItalianoSuomalainenLatina

Приложения социальных вычислений для борьбы с COVID-19

1 цель миссии

1.1 Введение в дело

Эпидемия COVID-19 затрагивает сердца каждого из нас. В этом случае мы попытаемся использовать методы социальных вычислений для анализа новостей и слухов, связанных с эпидемией, чтобы помочь.Эпидемическая информация Исследовать. Это задание является открытым. Мы предоставляем социальные данные во время эпидемии и призываем студентов анализировать социальные тенденции на основе новостей, слухов и юридических документов. (Совет: для анализа данных используйте методы, изученные на уроке, такие как анализ настроений, извлечение информации, понимание прочитанного и т. д.)

1.2 Описание данных

https://covid19.thunlp.org/ предоставляет социальные данные, связанные с новой эпидемией коронавируса, включая слухи, связанные с эпидемией, CSDC-Rumor, китайские новости, связанные с эпидемией, CSDC-News и юридические документы, связанные с эпидемией, CSDC-Legal.

Слухи об эпидемии CSDC-Слухи

В этой части набора данных собрано:

(1) Начиная с 22 января 2020 г.Ложная информация WeiboДанные включают содержание сообщений Weibo, которые считаются ложной информацией, издателей, информаторов, время судебного разбирательства, результаты и другую информацию. По состоянию на 1 марта 2020 года в общей сложности имеется 324 оригинальных текста Weibo, 31 284 пересылки и 7 912 комментариев. , используемый, чтобы помочь исследователям анализировать и изучать распространение ложной информации во время эпидемии;

(2) Платформа проверки слухов Tencent и ложные информационные данные Dingxiangyuan с 18 января 2020 года, включая такую ​​информацию, как содержание слуха, который считается правильным или ложным, время и основание для определения того, является ли это слухом, по состоянию на На 1 марта 2020 года имеется 507 фрагментов слуховых данных, в том числе 124 фрагмента фактических данных. Распределение данных следующее: отрицательные случаи: 420, положительные случаи: 33 и неопределенные: 54.

Китайские новости об эпидемии CSDC-News

Эта часть набора данных собирает данные новостей, начиная с 1 января 2020 года, включая название, содержание, ключевые слова и другую информацию новостей. По состоянию на 16 марта 2020 года было собрано в общей сложности 148 960 новостей и 1 653 086 соответствующих комментариев. Используется, чтобы помочь исследователям анализировать и изучать новостные данные во время эпидемии.

Юридические документы, связанные с эпидемией CSDC-Legal

Эти данные взяты из КЕЙЛ В общей сложности из собранных анонимных данных юридических документов было отобрано 1203 части исторических данных, связанных с эпидемией. Каждая часть данных включает название документа, номер дела и полный текст документа, которые могут быть использованы исследователями для проведения исследований. по актуальным правовым вопросам во время эпидемии.

1.3 Справочные идеи

  1. Обнаружение слухов. Как точно и быстро идентифицировать слухи в социальных сетях, является важным вопросом в области социальных вычислений. На основе предоставляемого нами набора данных о слухах, связанных с эпидемией, учащиеся могут попробовать различные методы обнаружения слухов, например, методы на основе функций[1]. ] , методы на основе нейронных сетей [2, 3] или методы на основе моделей распространения [4], обзор [5] суммирует соответствующие технологии обнаружения слухов.
  2. Анализ настроений в новостях. Обращаясь к нашему домашнему заданию по анализу настроений, вы можете провести анализ настроений в китайских новостях, связанных с эпидемией, с помощью распознавания ключевых слов [6] и других технологий, а также выяснить социологические причины эмоций.
  3. http://weibo.com/n/%E6%B8%85%E5%8D%8E%E8%87%AA%E7%84%B6%E8%AF%AD%E8%A8%80%E5%A4%84%E7%90%86 Лаборатория обработки естественного языка Цинхуа Weibo предоставляет несколько примеров визуализации. Студенты также могут использовать статистические и лингвистические методы для анализа и визуализации текста.

1.4 Критерии оценки

Это задание открытое, мы начнем с

  1. Рациональность и новизна выбора темы.
  2. Рациональность и техническое содержание принятых методов
  3. Завершение работ и объем проекта
  4. Полнота и глубина отчетности и социологического анализа

Оценивание заданий по другим аспектам.

1.5 Ссылки

[1] Достоверность информации в Twitter. в Трудах WWW, 2011.

[2] Обнаружение слухов в микроблогах с помощью рекуррентных нейронных сетей. Труды IJCAI, 2016.

[3] Сверточный подход к идентификации дезинформации. в Трудах IJCAI, 2017.

[4] Распространение правдивых и ложных новостей в Интернете. Наука, 2018.

[5] Ложная информация в Интернете и социальных сетях: исследование. Препринт arXiv, 2018.

[6] Характеристика аффективных норм английских слов по дискретным эмоциональным категориям. Методы исследования поведения, 2007.

2 Анализ данных слухов об эпидемии

Этот эксперимент предоставляет набор данных о слухах, связанных с эпидемией, CSDC-Rumor. Анализируя содержимое набора данных, мы решили сначала выполнить количественный статистический анализ набора данных, затем использовать кластеризацию для реализации семантического анализа слухов и, наконец, разработать набор данных. система обнаружения слухов.

2.1 Обработка данных

  1. Формат данных

    Этот эксперимент предоставляет набор данных о слухах, связанных с эпидемией, CSDC-Rumor, который собирает данные ложной информации Weibo и данные, опровергающие слухи. Набор данных содержит следующее.

    rumor
    │  fact.json
    │
    ├─rumor_forward_comment
    │      2020-01-22_K1CaS7Qxd76ol.json
    │      2020-01-23_K1CaS7Q1c768i.json
    ...
    │      2020-03-03_K1CaS8wxh6agf.json
    └─rumor_weibo
            2020-01-22_K1CaS7Qth660h.json
            2020-01-22_K1CaS7Qxd76ol.json
            ...
            2020-03-03_K1CaS8wxh6agf.json
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    Ложная информация Weiboсоответственно rumor_weibo иrumor_forward_comment двое с одинаковыми именамиjson описано в файле.rumor_weibo серединаjson Конкретные поля следующие:

    • rumorCode: уникальный код слуха, с помощью которого можно получить прямой доступ к странице сообщения о слухах.
    • title: Заголовок сообщения о слухе.
    • informerName: имя репортера в Weibo.
    • informerUrl: ссылка репортера на Weibo.
    • rumormongerName: имя Weibo человека, опубликовавшего слух.
    • rumormongerUr: ссылка на Weibo человека, разместившего слух.
    • rumorText: Содержание слухов.
    • visitTimes: Сколько раз был посещен этот слух.
    • result: Результаты обзора слухов.
    • publishTime: Время, когда распространился слух.
    • related_url: Ссылки на доказательства, правила и т. д., связанные с этим слухом.

    rumor_forward_comment серединаjson Конкретные поля следующие:

    • uid: Опубликовать идентификатор пользователя.
    • text: Прокомментируйте или перешлите постскриптум.
    • date: время выпуска.
    • comment_or_forward: двоичный, либо comment, или forward, указывающий, является ли сообщение комментарием или пересылаемым постскриптумом.

    Tencent и Lilac Garden ложная информацияФормат контента:

    • date: время
    • explain: Тип слуха
    • tag:тег слухов
    • abstract: Контент, используемый для проверки слухов.
    • rumor: Слух
  2. Предварительная обработка данных

    проходить json.load() Извлеките данные слухов Weibo отдельноweibo_data Комментарий о пересылке данных со слухамиforward_comment_data , а затем преобразуйте его в формат DataFrame. Два файла с одинаковым именем, статья Weibo и пересылка комментариев Weibo соответствуют друг другу. При обработке данных в папке слух_форвард_коммент добавьте слухкод для последующего сопоставления.

    # 文件路径
    weibo_dir = 'data/rumor/rumor_weibo'
    forward_comment_dir = 'data/rumor/rumor_forward_comment'
    
    # 初始化数据列表
    weibo_data = []
    forward_comment_data = []
    
    # 处理rumor_weibo文件夹中的数据
    for filename in os.listdir(weibo_dir):
        if filename.endswith('.json'):
            filepath = os.path.join(weibo_dir, filename)
            with open(filepath, 'r', encoding='utf-8') as file:
                data = json.load(file)
                weibo_data.append(data)
    
    # 处理rumor_forward_comment文件夹中的数据
    for filename in os.listdir(forward_comment_dir):
        if filename.endswith('.json'):
            filepath = os.path.join(forward_comment_dir, filename)
            with open(filepath, 'r', encoding='utf-8') as file:
                data = json.load(file)
                # 提取rumorCode
                rumor_code = filename.split('_')[1].split('.')[0]
                for comment in data:
                    comment['rumorCode'] = rumor_code  # 添加rumorCode以便后续匹配
                    forward_comment_data.append(comment)
    
    # 转换为DataFrame
    weibo_df = pd.DataFrame(weibo_data)
    forward_comment_df = pd.DataFrame(forward_comment_data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31

2.2 Количественный статистический анализ слухов

​ В этом разделе используется количественный статистический анализ, чтобы получить конкретное представление о распространении слухов об эпидемиях по данным Weibo.

  1. Статистика количества посещений слухов

    статистика weibo_df['visitTimes'] Распределение времен доступа и построение соответствующей гистограммы. Результаты следующие.

    изображение-20240708173948337

    Судя по количеству посещений Weibo, большинство слухов об эпидемиях посещались на Weibo менее 500 раз, причем наибольшая доля приходится на 10-50 раз. Однако на Weibo также ходят слухи, к которым обращались более 5000 раз, что вызвало серьезные последствия и по закону считается «серьезным».

  2. Статистика появления распространителей слухов и информаторов

    по статистике weibo_df['rumormongerName'] иweibo_df['informerName'] Получены следующие данные о количестве слухов, опубликованных каждым издателем слухов, и количестве слухов, о которых сообщил каждый репортер.

    изображение-20240708175825599

    Видно, что количество слухов, опубликованных создателями слухов, не сосредоточено на нескольких людях, а относительно равномерно. Аккаунт, на котором опубликовано больше всего слухов, опубликовал три сообщения со слухами на Weibo. Каждый из 10 крупнейших информаторов сообщил как минимум о 3 слуховых статьях. Среди них количество слухов, о которых сообщили информаторы на Weibo, было значительно выше, чем у других пользователей, и достигло 37 статей.

    Основываясь на приведенных выше данных, аудитория может сосредоточиться на сообщениях об аккаунтах с большим количеством слухов, чтобы облегчить обнаружение слухов.

  3. Статистика распространения комментариев по слухам

    Подсчитав распределение объема распространения слухов и объема комментариев, получается следующая картина распределения.

    Вставьте сюда описание изображения

    Видно, что количество комментариев и репостов на большинстве слухов Weibo находится в пределах 10 раз, при этом максимальное количество комментариев не превышает 500, а максимальное количество репостов достигает более 10 000. Согласно Закону об управлении Интернетом, если слух распространился более 500 раз, это считается «серьезной» ситуацией.

2.3 Семантический анализ слухов

  1. Кластерный анализ текстов слухов

    Эта часть выполняет предварительную обработку данных текстов слухов Weibo и выполняет кластерный анализ после сегментации слов, чтобы увидеть, где сконцентрированы слухи Weibo.

    • Предварительная обработка данных

      Сначала очистите текст данных слухов, удалите значения по умолчанию и <> Содержимое прилагаемой ссылки.

      # 去除缺失值
      weibo_df_rumorText = weibo_df.dropna(subset=['rumorText'])
      
      def clean_text(text):
          # 定义正则表达式模式,匹配 <>
          pattern = re.compile(r'<.*?>')
          # 使用 sub 方法删除匹配的部分
          cleaned_text = re.sub(pattern, '', text)
          return cleaned_text
      
      weibo_df_rumorText['rumorText'] = weibo_df_rumorText['rumorText'].apply(clean_text)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11

      Затем загрузите стоп-слова на китайском языке и используйте стоп-слова cn_стоп-слова ,использоватьjieba Реализуйте обработку данных сегментацией слов и выполните векторизацию текста.

      # 加载停用词文件
      with open('cn_stopwords.txt', encoding='utf-8') as f:
          stopwords = set(f.read().strip().split('n'))
      
      # 分词和去停用词函数
      def preprocess_text(text):
          words = jieba.lcut(text)
          words = [word for word in words if word not in stopwords and len(word) > 1]
          return ' '.join(words)
      
      # 应用到数据集
      weibo_df_rumorText['processed_text'] = weibo_df_rumorText['rumorText'].apply(preprocess_text)
      
      # 文本向量化
      vectorizer = TfidfVectorizer(max_features=10000)
      X_tfidf = vectorizer.fit_transform(weibo_df_rumorText['processed_text'])
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
    • Определите лучшую кластеризацию

      Используя метод локтя, определяются лучшие кластеры.

      Метод локтя — это метод, используемый для определения оптимального количества кластеров в кластерном анализе. Он основан на взаимосвязи между суммой квадратов ошибок (SSE) и количеством кластеров. SSE — это сумма квадратов евклидовых расстояний от всех точек данных в кластере до центра кластера, которому он принадлежит. Он отражает эффект кластеризации: чем меньше SSE, тем лучше эффект кластеризации.

      # 使用肘部法确定最佳聚类数量
      def plot_elbow_method(X):
          sse = []
          for k in range(1, 21):
              kmeans = KMeans(n_clusters=k, random_state=42, n_init='auto')
              kmeans.fit(X)
              sse.append(kmeans.inertia_)
          plt.plot(range(1, 21), sse, marker='o')
          plt.xlabel('Number of clusters')
          plt.ylabel('SSE')
          plt.title('Elbow Method For Optimal k')
          plt.show()
      
      # 绘制肘部法图
      plot_elbow_method(X_tfidf)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15

      Метод локтя определяет оптимальное количество кластеров путем поиска «локтя», то есть поиска точки на кривой, после которой скорость снижения SSE существенно замедляется. Эта точка похожа на локоть руки, отсюда и локтевой метод. название «Метод локтя». Эту точку обычно считают оптимальным количеством кластеров.

      изображение-20240708184711285

      Из приведенного выше рисунка определено, что значение кластеризации колена равно 11, и построена соответствующая диаграмма рассеяния. Результаты следующие.

      изображение-20240708185243978

      Видно, что большинство постов Weibo, о которых ходят слухи, хорошо сгруппированы: № 3 и № 4, некоторые широко распространены, но не очень хорошо сгруппированы, например № 5 и № 8;

    • Результаты кластеризации

      Чтобы четко показать, какие слухи группируются в каждой категории, для каждой категории нарисована облачная диаграмма. Результаты следующие.

      изображение-20240708185416278

      Распечатайте хорошо сгруппированный контент Weibo по слухам, и результаты будут следующими.

      Cluster 2:
      13    #封城日记#我的城市是湖北最后一个被封城的城市,金庸笔下的襄阳,郭靖黄蓉守城战死的地方。至此...
      17    #襄阳封城#最后一座城被封,自此,湖北封省。在这大年三十夜。春晚正在说,为中国七十年成就喝彩...
      18    #襄阳封城#过会襄阳也要封城了,到O25号0点,湖北省全省封省 ,希望襄阳的疑似患者能尽快确...
      19    截止2020年1月25日00:00时❌湖北最后一个城市襄阳,整个湖北所有城市封城完毕,无公交...
      21    #襄阳封城# 湖北省最后的一个城市于2020年1月25日零点零时零分正式封城至此,湖北省,封...
      Name: rumorText, dtype: object
      
      Cluster 3:
      212    希望就在眼前…我期待着这一天早点到来。一刻都等不及了…西安学校开学时间:高三,初三,3月2日...
      213    学校开学时间:高三,初三,3月2日开学,高一,高二,初一,初二,3月9日开学,小学4一6年级...
      224    #长春爆料#【马上要解放了?真的假的?】长春学校开学时间:高三,初三,3月2日开学,高一,高...
      225    有谁知道这是真的吗??我们这些被困湖北的外地人到底什么时候才能回家啊!(市政府会议精神,3月...
      226    山东邹平市公布小道消息公布~:学校开学时间:高三,初三,3月2日开学,高一,高二,初一,初二...
      Name: rumorText, dtype: object
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
  2. Кластерный анализ результатов проверки слухов

    Кластеризация текстового содержимого слухов может быть не очень хороша для анализа содержания слухов, поэтому мы решили сгруппировать результаты проверки слухов.

    • Определите лучшую кластеризацию

      Используя локтевой график, определите лучшую кластеризацию.

      изображение-20240708192216975

      Из приведенной выше диаграммы колен можно определить два колена: одно — когда кластеризация равна 5, а другое — когда кластеризация равна 20. Я выбираю 20 для кластеризации.

      Диаграмма рассеяния, полученная путем кластеризации 20 категорий, выглядит следующим образом.

      изображение-20240708192500231

      Видно, что большинство из них хорошо кластеризованы, но 7-я и 17-я категории кластеризованы недостаточно хорошо.

    • Результаты кластеризации

      Чтобы четко показать, какие результаты проверки слухов сгруппированы в каждой категории, для каждой категории строится облачная диаграмма. Результаты следующие.

      Вставьте сюда описание изображения

      Распечатайте результаты хорошо сгруппированного обзора слухов. Результаты следующие.

      Cluster 4:
      52    从武汉撤回来的日本人,迎接他们的是每个人一台救护车,206人=206台救护车
      53    从武汉撤回来的日本人,迎接他们的是每个人一台救护车,206人=206台救护车
      54    从武汉撤回来的日本人,迎接他们的是每个人一台救护车,206人=206台救护车
      55    从武汉撤回来的日本人,迎接他们的是每个人一台救护车,206人=206台救护车
      56    从武汉撤回来的日本人,迎接他们的是每个人一台救护车,206人=206台救护车
      Name: result, dtype: object
      
      Cluster 10:
      214    所有被啃噬、机化的肺组织都不会再恢复了,愈后会形成无任何肺功能的瘢痕组织
      215    所有被啃噬、机化的肺组织都不会再恢复了,愈后会形成无任何肺功能的瘢痕组织
      216    所有被啃噬、机化的肺组织都不会再恢复了,愈后会形成无任何肺功能的瘢痕组织
      217    所有被啃噬、机化的肺组织都不会再恢复了,愈后会形成无任何肺功能的瘢痕组织
      218    所有被啃噬、机化的肺组织都不会再恢复了,愈后会形成无任何肺功能的瘢痕组织
      Name: result, dtype: object
      
      Cluster 15:
      7           在福州,里面坐的是周杰伦
      8            周杰伦去福州自备隔离仓
      9            周杰伦去福州自备隔离仓
      10    周杰伦福州演唱会,给自己整了个隔离舱
      12    周杰伦福州演唱会,给自己整了个隔离舱
      Name: result, dtype: object
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
      • 10
      • 11
      • 12
      • 13
      • 14
      • 15
      • 16
      • 17
      • 18
      • 19
      • 20
      • 21
      • 22
      • 23

2.4 Обнаружение слухов

​ Для обнаружения слухов мы решили использовать наборы данных, которые были опровергнуты. fact.json Сравните сходство между опровергнутыми слухами и реальными слухами и выберите опровергнутую статью, имеющую наибольшее сходство со слухом Weibo, в качестве основы для обнаружения слухов.

  1. Загрузка данных Weibo по слухам и наборов данных, опровергающих слухи

    # 定义一个空的列表来存储每个 JSON 对象
    fact_data = []
    
    # 逐行读取 JSON 文件
    with open('data/rumor/fact.json', 'r', encoding='utf-8') as f:
        for line in f:
            fact_data.append(json.loads(line.strip()))
    
    # 创建辟谣数据的 DataFrame
    fact_df = pd.DataFrame(fact_data)
    fact_df = fact_df.dropna(subset=['title'])
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
  2. Используйте предварительно обученные языковые модели для кодирования слухов Weibo и заголовков, опровергающих слухи, во встраиваемые векторы.

    В этом эксперименте использовалось bert-base-chinese В качестве предварительно обученной модели выполните обучение модели. Модель SimCSE используется для улучшения представления и измерения сходства семантики предложений посредством контрастного обучения.

    # 加载SimCSE模型
    model = SentenceTransformer('sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2')
    # 加载到 GPU
    model.to('cuda')
    
    # 加载预训练的NER模型
    ner_pipeline = pipeline('ner', model='bert-base-chinese', aggregation_strategy="simple", device=0)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
  3. Рассчитать сходство

    Чтобы вычислить сходство, для расчета полного сходства используются встраивание предложений и сходство именованных объектов модели SimCSE.

    • extract_entitiesФункция извлекает именованные объекты из текста, используя модель NER.

      # 提取命名实体
      def extract_entities(text):
          entities = ner_pipeline(text)
          return {entity['word'] for entity in entities}
      
      • 1
      • 2
      • 3
      • 4
    • entity_similarityФункция вычисляет сходство именованного объекта между двумя текстами.

      # 计算命名实体相似度
      def entity_similarity(text1, text2):
          entities1 = extract_entities(text1)
          entities2 = extract_entities(text2)
          if not entities1 or not entities2:
              return 0.0
          intersection = entities1.intersection(entities2)
          union = entities1.union(entities2)
          return len(intersection) / len(union)
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    • combined_similarityФункция объединяет встраивание предложений и сходство именованных объектов модели SimCSE для расчета полного сходства.

      # 结合句子嵌入相似度和实体相似度
      def combined_similarity(text1, text2):
          embed_sim = util.pytorch_cos_sim(model.encode([text1]), model.encode([text2])).item()
          entity_sim = entity_similarity(text1, text2)
          return 0.5 * embed_sim + 0.5 * entity_sim
      
      • 1
      • 2
      • 3
      • 4
      • 5
  4. Внедрить обнаружение слухов

    Путем сравнения сходств реализуется механизм обнаружения слухов.

    def debunk_rumor(input_rumor):
        # 计算输入谣言与所有辟谣标题的相似度
        similarity_scores = []
        for fact_text in fact_df['title']:
            similarity_scores.append(combined_similarity(input_rumor, fact_text))
        
        # 找到最相似的辟谣标题
        most_similar_index = np.argmax(similarity_scores)
        most_similar_fact = fact_df.iloc[most_similar_index]
        
        # 输出辟谣判断及依据
        print("微博谣言:", input_rumor)
        print(f"辟谣判断:{most_similar_fact['explain']}")
        print(f"辟谣依据:{most_similar_fact['title']}")
    
    weibo_rumor = "据最新研究发现,此次新型肺炎病毒传播途径是华南海鲜市场进口的豺——一种犬科动物携带的病毒,然后传给附近的狗,狗传狗,狗传人。狗不生病,人生病。人生病后又传给狗,循环传染。"
    debunk_rumor(weibo_rumor)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17

    Вывод следующий:

    微博谣言: 据最新研究发现,此次新型肺炎病毒传播途径是华南海鲜市场进口的豺——一种犬科动物携带的病毒,然后传给附近的狗,狗传狗,狗传人。狗不生病,人生病。人生病后又传给狗,循环传染。
    辟谣判断:尚无定论
    辟谣依据:狗能感染新型冠状病毒
    
    • 1
    • 2
    • 3

    Успешно нашел основания для опровержения слухов и вынес решение об опровержении слухов.

3 Анализ китайских новостных данных, связанных с эпидемией

3.1 Обработка данных

  1. Формат данных

    Этот эксперимент предоставляет набор данных новостей CSDC-News, связанных с эпидемией, который собирает новости и комментарии за первую половину 2020 года. Набор данных содержит следующее.

    news
    │
    ├─comment
    │      01-01.txt
    │      01-02.txt
    ...
    │      03-08.txt
    └─data
            01-01.txt
            01-02.txt
            ...
            08-31.txt
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    Папка данных разделена на три части:data,comment

    data В папке находится несколько файлов, каждый файл соответствует данным на определенную дату, в форматеjson . Содержимое этой части соответствует текстовым данным новости (будет постепенно обновляться с датой), а поля включают:

    • time: Время выхода новостей.
    • title: Название новости.
    • url: Исходный адрес ссылки новости.
    • meta: текстовая информация новости, включающая следующие поля:
      • content: Текстовое содержание новости.
      • description: Краткое описание новости.
      • title: Название новости.
      • keyword: Ключевые слова новостей.
      • type: Тип новости.

    comment В папке находится несколько файлов, каждый файл соответствует данным на определенную дату, в форматеjson . Эта часть контента соответствует данным комментариев новостей (между данными комментариев и текстовыми данными новостей может быть задержка около недели). Поля включают в себя:

    • time: Время выпуска новостей и data Соответствует данным в папке.
    • title: заголовок новости с data Соответствует данным в папке.
    • url: исходный адрес ссылки на новость и data Соответствует данным в папке.
    • comment: Информация о комментариях к новостям. Это поле представляет собой массив. Каждый элемент массива содержит следующую информацию:
      • area: Область рецензента.
      • content:Комментарии.
      • nickname: псевдоним рецензента.
      • reply_to: Объект ответа комментатора. Если его нет, это означает, что это не ответ.
      • time: Время комментариев.
  2. Предварительная обработка данных

    Данные о новостных статьях data При предварительной обработке данных необходимоmeta Содержимое выпускается и сохраняется в формате DataFrame.

    # 加载新闻数据
    def load_news_data(data_dir):
        news_data = []
        files = sorted(os.listdir(data_dir))
        for file in files:
            if file.endswith('.txt'):
                with open(os.path.join(data_dir, file), 'r', encoding='utf-8') as f:
                    daily_news = json.load(f)
                    for news in daily_news:
                        news_entry = {
                            'time': news.get('time', 'NULL'),
                            'title': news.get('title', 'NULL'),
                            'url': news.get('url', 'NULL'),
                            'content': news.get('meta', {}).get('content', 'NULL'),
                            'description': news.get('meta', {}).get('description', 'NULL'),
                            'keyword': news.get('meta', {}).get('keyword', 'NULL'),
                            'meta_title': news.get('meta', {}).get('title', 'NULL'),
                            'type': news.get('meta', {}).get('type', 'NULL')
                        }
                        news_data.append(news_entry)
        return pd.DataFrame(news_data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    В обзорных данных comment При предварительной обработке данных необходимоcomment Содержимое выпускается и сохраняется в формате DataFrame.

    # 加载评论数据
    def load_comment_data(data_dir):
        comment_data = []
        files = sorted(os.listdir(data_dir))
        for file in files:
            if file.endswith('.txt'):
                with open(os.path.join(data_dir, file), 'r', encoding='utf-8') as f:
                    daily_comments = json.load(f)
                    for comment in daily_comments:
                        for com in comment.get('comment', []):
                            comment_entry = {
                                'news_time': comment.get('time', 'NULL'),
                                'news_title': comment.get('title', 'NULL'),
                                'news_url': comment.get('url', 'NULL'),
                                'comment_area': com.get('area', 'NULL'),
                                'comment_content': com.get('content', 'NULL'),
                                'comment_nickname': com.get('nickname', 'NULL'),
                                'comment_reply_to': com.get('reply_to', 'NULL'),
                                'comment_time': com.get('time', 'NULL')
                            }
                            comment_data.append(comment_entry)
        return pd.DataFrame(comment_data)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
  3. Загрузить набор данных

    Загрузите набор данных в соответствии с вышеуказанной функцией предварительной обработки данных.

    # 数据文件夹路径
    news_data_dir = 'data/news/data/'
    comment_data_dir = 'data/news/comment/'
    
    # 加载数据
    news_df = load_news_data(news_data_dir)
    comment_df = load_comment_data(comment_data_dir)
    
    # 展示加载的数据
    print(f"新闻数据长度:{len(news_df)},评论数据:{len(comment_df)}")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    Результат печати показывает, что длина данных новостей: 502550, а длина данных комментариев: 1534616.

3.2 Анализ данных новостного контента

  1. Статистика распределения новостей по времени

    Посчитайте отдельно news_df Количество новостных статей за месяц и количество новостных статей в час представлены гистограммами и линейными диаграммами. Результаты следующие.

    изображение-20240708225549063

    Как видно из приведенного выше рисунка, с началом эпидемии количество новостей увеличивалось из месяца в месяц, достигнув пика в марте с 74 000 новостных статей, а затем постепенно снижалось и стабилизировалось до 60 000 статей в месяц, из которых данные за сентябрь составили 3 статьи в 0:00, могут не включаться в статистику.

    Судя по распределению количества новостей в час, видно, что 10 и 15 часов каждый день являются часами пикового выпуска новостей, в каждом из которых публикуется более 30 000 статей. В 12 часов наступает обеденный перерыв, а количество выпусков новостей достигает пиков и спадов. Количество выпусков новостей наименьшее в период с 0:00 до 5:00 каждый день, причем наименьшее значение составляет 3:00.

  2. Отслеживание горячих точек новостей

    В этом эксперименте предполагается использовать метод извлечения ключевых слов новостей для отслеживания горячих точек новостей за эти восемь месяцев. Подсчитав распределение существующих ключевых слов и построив гистограмму, мы получили следующие результаты.

    изображение-20240709224259364

    Видно, что большинство новостных статей имеют менее трех ключевых слов, а большая часть статей даже не имеет ключевых слов. Поэтому вам необходимо самостоятельно собирать статистику и суммировать ключевые слова для отслеживания хотспотов.На этот раз используйтеjieba.analyse.textrank() для подсчета ключевых слов.

    import jieba
    import jieba.analyse
    
    def extract_keywords(text):
        # 基于jieba的textrank算法实现
        keywords = jieba.analyse.textrank(text,topK=5,withWeight=True)
        return ' '.join([keyword[0] for keyword in keywords])
    
    news_df['keyword_new'] =news_df['content'].map(lambda x: extract_keywords(x))
    keyword_data = news_df[['time','keyword','keyword_new']]
    keyword_data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    Отсчитайте 5 новых ключевых слов, сохраните их в ключевое слово_new, затем объедините с ними ключевые слова и удалите повторяющиеся слова.

    # 合并并去除重复的词
    def merge_keywords(row):
        # 将keyword列和keyword_new列合并
        keywords = set(row['keyword']) | set(row['keyword_new'].split())
        return ' '.join(keywords)
    
    keyword_data['merged_keywords'] = keyword_data.apply(merge_keywords, axis=1)
    keyword_data
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Печать после слияния keyword_data , результаты печати следующие.

    изображение-20240709230056352

    Чтобы отслеживать «горячие точки», подсчитайте частоту появления всех встречающихся слов и подсчитайте keyword_data['rolling_keyword_freq']

    # 按时间排序
    keyword_data = keyword_data.sort_values(by='time')
    
    # 计算滚动频率
    def get_rolling_keyword_freq(df, window=7):
        rolling_keyword_freq = []
        for i in range(len(df)):
            start_time = df.iloc[i]['time'] - timedelta(days=window)
            end_time = df.iloc[i]['time']
            mask = (df['time'] > start_time) & (df['time'] <= end_time)
            recent_data = df.loc[mask]
            keywords = ' '.join(recent_data['merged_keywords']).split()
            keyword_counter = Counter(keywords)
            top_keywords = keyword_counter.most_common(20)
            rolling_keyword_freq.append(dict(top_keywords))
        return rolling_keyword_freq
    
    keyword_data['rolling_keyword_freq'] = get_rolling_keyword_freq(keyword_data)
    
    keyword_df = pd.DataFrame(keyword_data['rolling_keyword_freq'].tolist()).fillna(0)
    keyword_df = keyword_df.astype(int)
    
    # 将原始的时间列合并到新的DataFrame中
    result_df = pd.concat([keyword_data['time'], keyword_df], axis=1)
    
    # 保存为CSV文件
    result_df.to_csv('./data/news/output/keyword_frequency.csv', index=False)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    Затем на основе приведенных выше статистических данных постройте график ежедневного изменения горячих слов.

    # 读取数据
    file_path = './data/news/output/keyword_frequency.csv'
    data = pd.read_csv(file_path, parse_dates=['time'])
    
    # 聚合数据,按日期合并统计
    data['date'] = data['time'].dt.date
    daily_data = data.groupby('date').sum().reset_index()
    
    # 准备颜色列表,确保每个关键词都有不同的颜色
    colors = plt.cm.get_cmap('tab20', len(daily_data.columns[1:])).colors
    color_dict = {keyword: colors[i] for i, keyword in enumerate(daily_data.columns[1:])}
    
    def update(frame):
        plt.clf()
        date = daily_data['date'].iloc[frame]
        day_data = daily_data[daily_data['date'] == date].drop('date', axis=1).T
        day_data.columns = ['count']
        day_data = day_data.sort_values(by='count', ascending=False).head(10)
        
        bars = plt.barh(day_data.index, day_data['count'], color=[color_dict[keyword] for keyword in day_data.index])
        plt.xlabel('Count')
        plt.title(f'Keyword Frequency on {date}')
        for bar in bars:
            plt.text(bar.get_width(), bar.get_y() + bar.get_height()/2, f'{bar.get_width()}', va='center')
        plt.gca().invert_yaxis()
    
    # 创建动画
    fig = plt.figure(figsize=(10, 6))
    anim = FuncAnimation(fig, update, frames=len(daily_data), repeat=False)
    
    # 保存动画
    anim.save('keyword_trend.gif', writer='imagemagick')
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    Наконец, была получена диаграмма изменений ключевых слов в новостях об эпидемиях. Результаты следующие.

    ключевое слово_тенденция

    До вспышки термины «компания» и «Иран» оставались высокими. Видно, что после начала эпидемии количество новостей, связанных с эпидемией, начало расти в феврале. После этого термин «новый коронавирус» резко вырос и продолжал оставаться на первом месте до конца августа. первая волна эпидемии замедлилась и вышла на второе место.

3.3 Анализ данных обзоров новостей

​ В этом разделе сначала проводится количественный статистический анализ комментариев к новостям, а затем анализ настроений по различным комментариям.

  1. Статистика количества комментариев в новостях за день

    Подсчитайте тенденцию количества комментариев к новостям, используйте для ее представления гистограмму и нарисуйте приблизительную кривую. Код выглядит следующим образом.

    # 提取日期和小时信息
    dates = []
    hours = []
    
    for time_str in comment_df['news_time']:
        try:
            time_obj = datetime.strptime('2020-' + time_str, '%Y-%m-%d %H:%M')
            dates.append(time_obj.strftime('%Y-%m-%d')) 
            hours.append(time_obj.hour)
        except ValueError:
            pass
    
    # 统计每日新闻数量
    daily_comment_counts = Counter(dates)
    daily_comment_counts = dict(sorted(daily_comment_counts.items()))
    
    # 统计每小时新闻数量
    hourly_news_count = Counter(hours)
    hourly_news_count = dict(sorted(hourly_news_count.items()))
    
    # 绘制每月新闻数量分布柱状图
    plt.figure(figsize=(14, 6))
    
    days = list(daily_comment_counts.keys())
    comment_counts = list(daily_comment_counts.values())
    bars = plt.bar(days, comment_counts, label='Daily Comment Count')
    plt.xlabel('Date')
    plt.ylabel('Comment Count')
    plt.title('Daily Comment Counts on News')
    plt.xticks(rotation=80, fontsize=10)
    
    # 绘制近似曲线
    x = np.arange(len(days))
    y = comment_counts
    spl = UnivariateSpline(x, y, s=100)
    xs = np.linspace(0, len(days) - 1, 500)
    ys = spl(xs)
    plt.plot(xs, ys, 'r', lw=2, label='Smoothed Curve')
    
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40

    Статистическая диаграмма количества ежедневных комментариев к новостям строится следующим образом.

    изображение-20240710213539847

    Видно, что количество новостных комментариев во время эпидемии колебалось от 10 000 до 40 000, при этом в среднем около 20 000 комментариев в день.

  2. Статистика эпидемических новостей по регионам

    по провинциям comment_df['province'] Подсчитайте количество новостей в каждой провинции и подсчитайте количество комментариев к новостям об эпидемии в каждой провинции.

    Сначала вам нужно пройти comment_df['province'] Извлеките информацию о провинции.

    # 统计包含全国34个省、直辖市、自治区名称的地域数据
    province_name = ['北京', '天津', '上海', '重庆', '河北', '河南', '云南', '辽宁', '黑龙江', '湖南', '安徽', '山东', '新疆',
                     '江苏', '浙江', '江西', '湖北', '广西', '甘肃', '山西', '内蒙古', '陕西', '吉林', '福建', '贵州', '广东',
                     '青海', '西藏', '四川', '宁夏', '海南', '台湾', '香港', '澳门']
    
    # 提取省份信息
    def extract_province(comment_area):
        for province in province_name:
            if province in comment_area:
                return province
        return None
    
    comment_df['province'] = comment_df['comment_area'].apply(extract_province)
    
    # 过滤出省份不为空的行
    comment_df_filtered = comment_df[comment_df['province'].notnull()]
    
    # 统计每个省份的评论数量
    province_counts = comment_df_filtered['province'].value_counts().to_dict()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Затем на основе статистических данных строится круговая диаграмма, показывающая долю комментариев к новостям в каждой провинции.

    # 计算总评论数量
    total_comments = sum(province_counts.values())
    
    # 计算各省份评论数量占比
    provinces = []
    comments = []
    labels = []
    for province, count in province_counts.items():
        if count / total_comments >= 0.02:
            provinces.append(province)
            comments.append(count)
            labels.append(province + f" ({count})")
    
    # 绘制饼图
    plt.figure(figsize=(10, 8))
    plt.pie(comments, labels=labels, autopct='%1.1f%%', startangle=140)
    plt.title('各省疫情新闻评论数量占比')
    plt.axis('equal')  # 保证饼图是圆形
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    Вставьте сюда описание изображения

    В этом эксперименте мы также использовали pyecharts.charts изMap Компонент, отображающий распределение количества комментариев на карте Китая по провинциям.

    from pyecharts.charts import Map
    from pyecharts import options as opts
    
    # 省份简称到全称的映射字典
    province_full_name = {
        '北京': '北京市',
        '天津': '天津市',
        '上海': '上海市',
        '重庆': '重庆市',
        '河北': '河北省',
        '河南': '河南省',
        '云南': '云南省',
        '辽宁': '辽宁省',
        '黑龙江': '黑龙江省',
        '湖南': '湖南省',
        '安徽': '安徽省',
        '山东': '山东省',
        '新疆': '新疆维吾尔自治区',
        '江苏': '江苏省',
        '浙江': '浙江省',
        '江西': '江西省',
        '湖北': '湖北省',
        '广西': '广西壮族自治区',
        '甘肃': '甘肃省',
        '山西': '山西省',
        '内蒙古': '内蒙古自治区',
        '陕西': '陕西省',
        '吉林': '吉林省',
        '福建': '福建省',
        '贵州': '贵州省',
        '广东': '广东省',
        '青海': '青海省',
        '西藏': '西藏自治区',
        '四川': '四川省',
        '宁夏': '宁夏回族自治区',
        '海南': '海南省',
        '台湾': '台湾省',
        '香港': '香港特别行政区',
        '澳门': '澳门特别行政区'
    }
    
    # 将省份名称替换为全称
    full_province_counts = {province_full_name[key]: value for key, value in province_counts.items()}
    
    # 创建中国地图
    map_chart = (
        Map(init_opts=opts.InitOpts(width="1200px", height="800px"))
        .add("评论数量", [list(z) for z in zip(full_province_counts.keys(), full_province_counts.values())], "china")
        .set_global_opts(
            title_opts=opts.TitleOpts(title="中国各省疫情新闻评论数量分布"),
            visualmap_opts=opts.VisualMapOpts(max_=max(full_province_counts.values()))
        )
    )
    
    # 渲染图表为 HTML 文件
    map_chart.render("comment_area_distribution.html")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56

    В полученном HTML распределение количества комментариев к новостям об эпидемии в каждой провинции Китая выглядит следующим образом.

    изображение-20240710010121017

    Видно, что во время эпидемии наибольшая доля комментариев приходилась на Пекин, за ним следовала провинция Гуандун, а количество комментариев в других провинциях было относительно равномерным.

  3. эпидемияОбзор анализа настроений

    В этом эксперименте используется библиотека НЛП для обработки текста на китайском языке. SnowNLP , внедрить анализ настроений на китайском языке, проанализировать каждый комментарий и дать соответствующую оценку.sentiment Значение, значение находится между 0 и 1, чем ближе к 1, тем более положительное, чем ближе к 0, тем более отрицательное.

    from snownlp import SnowNLP
    
    # 定义一个函数来计算情感得分,并处理可能的错误
    def sentiment_analysis(text):
        try:
            s = SnowNLP(text)
            return s.sentiments
        except ZeroDivisionError:
            return None
    
    # 对每条评论内容进行情感分析
    comment_df['sentiment'] = comment_df['comment_content'].apply(sentiment_analysis)
    
    # 删除情感得分为 None 的评论
    comment_df = comment_df[comment_df['sentiment'].notna()]
    
    # 将评论按正向(sentiment > 0.5)和负向(sentiment < 0.5)分类
    comment_df['sentiment_label'] = comment_df['sentiment'].apply(lambda x: 'positive' if x > 0.5 else 'negative')
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    В этом эксперименте в качестве порога используется значение 0,5. Все, что превышает это значение, является положительным комментарием, а все, что меньше этого значения, является отрицательным комментарием. Написав код, нарисуйте диаграмму анализа настроений ежедневных комментариев к новостям и подсчитайте количество положительных комментариев и количество отрицательных комментариев к ежедневным новостям. Количество положительных комментариев — это положительное значение, а количество отрицательных комментариев — отрицательное. ценить.

    # 提取新闻日期
    comment_df['news_date'] = pd.to_datetime('2020-' + comment_df['news_time'].str[:5]).dt.date
    
    # 统计每一天的正向和负向评论数量
    daily_sentiment_counts = comment_df.groupby(['news_date', 'sentiment_label']).size().unstack(fill_value=0)
    
    # 绘制柱状图
    plt.figure(figsize=(14, 8))
    
    # 绘制正向评论数量的柱状图
    plt.bar(daily_sentiment_counts.index, daily_sentiment_counts['positive'], label='Positive', color='green')
    
    # 绘制负向评论数量的柱状图(负数,以使其在 x 轴下方显示)
    plt.bar(daily_sentiment_counts.index, -daily_sentiment_counts['negative'], label='Negative', color='red')
    
    # 添加标签和标题
    plt.xlabel('Date')
    plt.ylabel('Number of Comments')
    plt.title('Daily Sentiment Analysis of Comments')
    plt.legend()
    
    # 设置x轴刻度旋转
    plt.xticks(rotation=45)
    
    # 显示图表
    plt.tight_layout()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27

    изображение-20240710235955284

    Итоговая статистическая картина показана выше. Видно, что положительных комментариев во время эпидемии было немного больше, чем отрицательных. Подсчитав долю положительных комментариев, выяснилось, что доля положительных комментариев составила 58,63%, что указывает на то. что общественность более позитивно отнеслась к эпидемии.

  4. Анализ тональности комментариев по регионам

    Путем подсчета доли положительных комментариев, размещенных в каждой провинции и регионе, был получен график доли положительных комментариев в каждом регионе.

    # 计算各地区的积极评论数量和总评论数量
    area_sentiment_stats = comment_df.groupby('province').agg(
        total_comments=('comment_content', 'count'),
        positive_comments=('sentiment', lambda x: (x > 0.5).sum())
    )
    
    # 计算各地区的积极评论占比
    area_sentiment_stats['positive_ratio'] = area_sentiment_stats['positive_comments'] / area_sentiment_stats['total_comments']
    
    # 绘制柱状图
    plt.figure(figsize=(14, 7))
    plt.bar(area_sentiment_stats.index, area_sentiment_stats['positive_ratio'], color='skyblue')
    plt.xlabel('地区')
    plt.ylabel('积极评论占比')
    plt.title('各地区的积极评论占比')
    plt.xticks(rotation=90)
    plt.tight_layout()
    plt.show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    изображение-20240711000236333

    Как видно из приведенного выше рисунка, доля положительных комментариев в большинстве провинций составляет около 60%. В Гонконге и Макао самая низкая доля положительных комментариев, около 50%, тогда как в Тибете самая высокая доля положительных комментариев, близкая к 70%.

    Из приведенного выше распределения комментариев мы видим, что комментарии в материковом Китае в основном положительные, тогда как количество отрицательных комментариев в Гонконге и Макао значительно возросло. Наибольшее количество положительных комментариев в Тибете может быть связано с ошибкой, вызванной ошибкой. небольшой размер выборки в Тибете.

  5. Комментарии к новостям Рисунок облака слов

    Диаграммы облака слов для всех комментариев, положительных комментариев и отрицательных комментариев учитывались отдельно. На рисунке диаграммы облака слов положительные комментарии были указаны как выше 0,6, а отрицательные комментарии были классифицированы как ниже 0,4. Ниже приводится облако из трех слов. нарисованы схемы.

    изображение-20240711000624576

    Видно, что комментарии большинства людей во время эпидемии относительно простые, например «ха-ха», «хорошо» и т. д. В положительных комментариях можно увидеть ободряющие слова, такие как «Давай, Китай», «Давай, Ухань». и т. д., а в негативных комментариях встречаются критические высказывания типа «Ха-ха» и «Трудно сделать страну богатой».