Развертывание анализа настроений с помощью Python и ИИ для анализа доходов компаний

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

Звонок о доходах компании обычно представляет собой телеконференцию или веб-трансляцию, на которой публичная компания обсуждает свои финансовые результаты за определенный отчетный период. На этом мероприятии обсуждается большинство ключевых моментов, по которым мы можем иметь представление о ключевых успехах компании. Следовательно, полезность ИИ для решения такой проблемы анализа настроений может создать фантастический план для любой компании.

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



Проект по анализу настроений о доходах Call of Company:

В этом проекте мы будем использовать скрипты Python, платформу AssemblyAI и фреймворк Streamlit для разработки веб-сайта для развертывания проекта. Мы будем использовать три отдельных файла для этого проекта. В первом файле мы будем хранить наш ключ API конфигурации, полученный с веб-сайта AssemblyAI. Мы создадим второй файл для загрузки и сохранения определенного файла YouTube. Наконец, мы разработаем основной веб-сайт и вычислим анализ настроений в окончательном файле Python.

Конфигурация вашего ключа API:

Для начала работы с проектом я бы рекомендовал ознакомиться с платформой AssemblyAI. Здесь вы можете получить ключ API, с помощью которого мы можем выполнить проект анализа настроений по отчету о доходах компаний. Вы можете пройти простой процесс регистрации, если у вас еще нет учетной записи. Как только вы войдете в систему, вы сможете получить доступ к бесплатному ключу API в правой части своей учетной записи AssemblyAI. Скопируйте это и поместите в файл Python configure.py.

auth_key = "Enter Your API Key Here"

Сохранение аудиоданных:

В следующем файле Python мы сохраним аудиоданные, загруженные с YouTube. В этом разделе мы импортируем библиотеку youtube_dl, которую можно установить с помощью простой команды pip install, если у вас ее еще нет. После импорта библиотеки мы создадим переменную, которая будет содержать все основные параметры. Мы загрузим аудиоданные в формате mp3 и сохраним их в лучшем аудиоформате. Это действие можно выполнить, как показано в блоке кода ниже.

import youtube_dl
ydl_opts = {
   'format': 'bestaudio/best',
   'postprocessors': [{
       'key': 'FFmpegExtractAudio',
       'preferredcodec': 'mp3',
       'preferredquality': '192',
   }],
   'ffmpeg-location': './',
   'outtmpl': "./%(id)s.%(ext)s",
}

После того, как мы объявим необходимые параметры, мы можем приступить к созданию функции, которая поможет нам сохранить желаемое видео YouTube в лучшем формате аудиофайла mp3. Мы получим идею и удалим все пробелы и передадим идентификатор для извлечения информации. Как только видеофайл будет загружен, он будет сохранен в текущем рабочем каталоге. Вы можете изменить пути по своему желанию. Код ниже представляет следующую функцию.

def save_audio(link):
  _id = link.strip()
  def get_vid(_id):
    with youtube_dl.YoutubeDL(ydl_opts) as ydl:
      return ydl.extract_info(_id)
  # download the audio of the YouTube video locally
  meta = get_vid(_id)
  save_location = meta['id'] + ".mp3"
  print('Saved mp3 to', save_location)
  return save_location

Мы можем сохранить этот файл как save_audio.py и продолжить сборку основного приложения из следующего раздела.

Импортируйте необходимые библиотеки:

После создания двух основных файлов Python мы можем приступить к созданию основного файла с именем app.py для разработки интерфейса веб-сайта и соответствующего анализа настроений. Сначала мы импортируем все необходимые требования для нашего проекта, включая два файла Python, которые мы создали ранее.

import streamlit as st
from save_audio import save_audio
from configure import auth_key
import pandas as pd
from time import sleep
import urllib.request
import plotly.express as px
import plotly.graph_objects as go
from urllib.request import urlopen
from bs4 import BeautifulSoup
import json
import requests

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

Настройка всех необходимых элементов:

В этом разделе мы настроим все необходимые требования, которые потребуются для просмотра различных графиков для анализа тональности, включая инициализацию нужных переменных. Во-первых, давайте создадим конечные точки и соответствующим образом инициализируем заголовки. Конечная точка расшифровки содержит расположение платформы AssemblyAI, где доступна расшифровка аудиоданных. Точно так же у нас также есть конечная точка загрузки и назначение заголовков с ключом API авторизации AssemblyAI.

## AssemblyAI endpoints and headers
transcript_endpoint = "https://api.assemblyai.com/v2/transcript"
upload_endpoint = 'https://api.assemblyai.com/v2/upload'
headers_auth_only = {'authorization': auth_key}
headers = {
   "authorization": auth_key,
   "content-type": "application/json"
}

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

## App explanation
st.title('Sentiment analysis of earning calls')
st.caption('With this app you can analyse the sentiment of earnings calls by providing a YouTube link to its recording.')
st.subheader('Submit a video link or choose one of the pre-determined ones to analyse.')
st.subheader('Submit a video link or choose one of the pre-determined ones to analyse.')

На следующем шаге мы создадим панель ввода текста, в которой пользователь может ввести конкретную ссылку, относящуюся к отчету о доходах конкретной компании. Данные предоставленной ссылки (обычно видео с YouTube) будут загружены в лучшем аудиоформате и сохранены локально в рабочем каталоге. Как только данные будут загружены, мы загрузим данные в виде фрагментов на веб-сайт AssemblyAI и получим загруженный URL-адрес аудио. Мы также указали ссылку по умолчанию, которая предоставляет нам доступ к одному из вызовов доходов Amazon.

# Get link from user
video_url = st.text_input(label='Earnings call link', value="https://www.youtube.com/watch?v=UA-ISgpgGsk")
# Save audio locally
save_location = save_audio(video_url)
## Upload audio to AssemblyAI
CHUNK_SIZE = 5242880
def read_file(filename):
 with open(filename, 'rb') as _file:
  while True:
   data = _file.read(CHUNK_SIZE)
   if not data:
    break
   yield data
upload_response = requests.post(
 upload_endpoint,
 headers=headers_auth_only, data=read_file(save_location)
)
audio_url = upload_response.json()['upload_url']
print('Uploaded to', audio_url)

Теперь, когда мы закончили загрузку наших аудиоданных на веб-сайт AssemblyAI, мы можем начать транскрипцию аудиофайла. Мы предоставим загруженный URL-адрес аудио и укажем условие анализа тональности как True. Когда эти параметры установлены, мы можем перейти к получению ответа расшифровки и идентификатора расшифровки. Наконец, настройте конечную точку опроса для выполнения транскрипции.

## Start transcription job of audio file
data = {
 'audio_url': audio_url,
 'sentiment_analysis': 'True',
}
transcript_response = requests.post(transcript_endpoint, json=data, headers=headers)
print(transcript_response)
transcript_id = transcript_response.json()['id']
polling_endpoint = transcript_endpoint + "/" + transcript_id
print("Transcribing at", polling_endpoint)

Мы можем проверить статус завершения программы и дождаться завершения процесса транскрипции с помощью цикла While. После завершения процесса транскрипции мы можем получить стенограмму, которую мы можем отобразить для просмотра пользователем. Но для этого шага мы просто сохраним текст полученного ответа расшифровки.

## Waiting for transcription to be done
status = 'submitted'
while status != 'completed':
 print('not ready yet')
 sleep(1)
 polling_response = requests.get(polling_endpoint, headers=headers)
 transcript = polling_response.json()['text']
 status = polling_response.json()['status']

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

Анализ многочисленных компонентов посредством визуализации:

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

# Display transcript
print('creating transcript')
st.sidebar.header('Transcript of the earnings call')
st.sidebar.markdown(transcript)
print(json.dumps(polling_response.json(), indent=4, sort_keys=True))
## Sentiment analysis response 
sar = polling_response.json()['sentiment_analysis_results']
## Save to a dataframe for ease of visualization
sen_df = pd.DataFrame(sar)
print(sen_df.head())

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

## Get the title of this video
with urlopen(video_url) as url:
    s = url.read()
    soup = BeautifulSoup(s)
    title = soup.title.string
st.header(title)
## Visualizations
st.markdown("### Number of sentences: " + str(sen_df.shape[0]))
grouped = pd.DataFrame(sen_df['sentiment'].value_counts()).reset_index()
grouped.columns = ['sentiment','count']
print(grouped)
col1, col2 = st.columns(2)

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

# Display number of positive, negative and neutral sentiments
fig = px.bar(grouped, x='sentiment', y='count', color='sentiment', color_discrete_map={"NEGATIVE":"firebrick","NEUTRAL":"navajowhite","POSITIVE":"darkgreen"})
fig.update_layout(
 showlegend=False,
    autosize=False,
    width=400,
    height=500,
    margin=dict(
        l=50,
        r=50,
        b=50,
        t=50,
        pad=4
    )
)
col1.plotly_chart(fig)

Гистограмма не всегда может отражать истинное восприятие, необходимое для анализа любой проблемы. Следовательно, мы будем использовать индикатор, который будет означать, есть ли у нас больше положительных или отрицательных ответов. Мы рассчитаем оценку тональности, как показано в приведенном ниже блоке кода, и проанализируем индикатор. Стрелка вверх означает положительную индикацию, тогда как отрицательная индикация будет представлена ​​индикатором вниз. Посмотрите на изображение выше для более интуитивного понимания.

## Display sentiment score
pos_perc = grouped[grouped['sentiment']=='POSITIVE']['count'].iloc[0]*100/sen_df.shape[0]
neg_perc = grouped[grouped['sentiment']=='NEGATIVE']['count'].iloc[0]*100/sen_df.shape[0]
neu_perc = grouped[grouped['sentiment']=='NEUTRAL']['count'].iloc[0]*100/sen_df.shape[0]
sentiment_score = neu_perc+pos_perc-neg_perc
fig = go.Figure()
fig.add_trace(go.Indicator(
    mode = "delta",
    value = sentiment_score,
    domain = {'row': 1, 'column': 1}))
fig.update_layout(
 template = {'data' : {'indicator': [{
        'title': {'text': "Sentiment score"},
        'mode' : "number+delta+gauge",
        'delta' : {'reference': 50}}]
                         }},
    autosize=False,
    width=400,
    height=500,
    margin=dict(
        l=20,
        r=50,
        b=50,
        pad=4
    )
)
col2.plotly_chart(fig)

Наконец, мы также создадим точечный график для лучшей визуализации настроений. Эту визуализацию можно создать, как показано в приведенном ниже фрагменте кода.

## Display negative sentence locations
fig = px.scatter(sar, y='sentiment', color='sentiment', size='confidence', hover_data=['text'], color_discrete_map={"NEGATIVE":"firebrick","NEUTRAL":"navajowhite","POSITIVE":"darkgreen"})
fig.update_layout(
 showlegend=False,
    autosize=False,
    width=800,
    height=300,
    margin=dict(
        l=50,
        r=50,
        b=50,
        t=50,
        pad=4
    )
)
st.plotly_chart(fig)

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

Окончательная настройка:

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

Для окончательной настройки я бы рекомендовал проверить следующую ссылку на GitHub, которая охватывает весь код и требования, необходимые для успешного развертывания следующего проекта. Я бы также посоветовал ознакомиться со следующим видеоуроком, который в сжатой форме раскрывает следующую тему, охватывая большинство сложных деталей, связанных с этим проектом.

Заключение:

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

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

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



Если у вас есть какие-либо вопросы, связанные с различными пунктами, изложенными в этой статье, не стесняйтесь, дайте мне знать в комментариях ниже. Я постараюсь вернуться к вам с ответом как можно скорее.

Ознакомьтесь с некоторыми другими моими статьями по теме, затронутой в этой статье, которые, возможно, вам также понравится читать!







Всем спасибо, что дочитали до конца. Надеюсь, всем вам понравилось читать статью. Желаю всем прекрасного дня!