Анализ текстовых данных и визуализация статей Reuters

машинное обучение глубокое обучение компьютерное зрение NLP

Автор | Манмохан Сингх Компилировать|ВКонтакте Источник | К науке о данных

Что вы делаете, когда я прошу вас интерпретировать текстовые данные? Какие шаги вы предпримете для создания визуализации текста?

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

Информация из текстовых данных поможет нам обнаружить связи между статьями. Он будет обнаруживать тенденции и закономерности. Анализ текстовых данных уберет шум и раскроет ранее неизвестную информацию.

Этот процесс анализа также известен как исследовательский анализ текста (ETA). Эти текстовые данные анализируются с использованием K-средних, Tf-IDF, частоты слов и других методов. Кроме того, ETA полезен в процессе очистки данных.

Мы также визуализировали результаты в виде графиков, облаков слов и графиков, используя библиотеки Matplotlib, seaborn и Plotly.

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

Получить данные из источника данных

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

  1. Набор текстовых данных Twitter от Kaggle.

  2. Наборы данных Reddit и Twitter используют API.

  3. Используйте Beautifulsoup для получения статей с веб-сайтов.

Для статей я буду использовать формат SGML от Reuters. Для простоты анализа я буду использовать библиотеку beauthoulsoup для получения даты, заголовка и тела статьи из файла данных.

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

from bs4 import BeautifulSoup
import pandas as pd
import csv

article_dict = {}
i = 0
list_of_data_num = []

for j in range(0,22):
    if j < 10:
        list_of_data_num.append("00" + str(j))
    else:
        list_of_data_num.append("0" + str(j))

# 循环所有文章以提取日期、标题和文章主体
for num in list_of_data_num:
    try:
        soup = BeautifulSoup(open("data/reut2-" + num + ".sgm"), features='lxml')
    except:
        continue
    print(num)
    data_reuters = soup.find_all('reuters')
    for data in data_reuters:
        article_dict[i] = {}
        for date in data.find_all('date'):
            try:
                article_dict[i]["date"] = str(date.contents[0]).strip()
            except:
                article_dict[i]["date"] = None
            # print(date.contents[0])
        for title in data.find_all('title'):
            article_dict[i]["title"] = str(title.contents[0]).strip()
            # print(title.contents)
        for text in data.find_all('text'):
            try:
                article_dict[i]["text"] = str(text.contents[4]).strip()
            except:
                article_dict[i]["text"] = None
        i += 1


dataframe_article = pd.DataFrame(article_dict).T
dataframe_article.to_csv('articles_data.csv', header=True, index=False, quoting=csv.QUOTE_ALL)
print(dataframe_article)
  1. Также возможно объединить или зациклить все файлы данных, используя Regex и библиотеки ОС.

  2. Текст каждой статьи начинается с , поэтому используйте find_all('reuters').

  3. Вы также можете использовать модуль pickle для сохранения данных вместо CSV.

Чистые данные

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

import pandas as pd import re

articles_data = pd.read_csv(‘articles_data.csv’) print(articles_data.apply(lambda x: sum(x.isnull()))) articles_nonNull = articles_data.dropna(subset=[‘text’]) articles_nonNull.reset_index(inplace=True)

def clean_text(text):

‘’’Make text lowercase, remove text in square brackets,remove \n,remove punctuation and remove words containing numbers.’’’

    text = str(text).lower()
    text = re.sub(‘<.*?>+’, ‘’, text)
    text = re.sub(‘[%s]’ % re.escape(string.punctuation), ‘’, text)
    text = re.sub(‘\n’, ‘’, text)
    text = re.sub(‘\w*\d\w*’, ‘’, text)
    return text

articles_nonNull[‘text_clean’]=articles_nonNull[‘text’]\
                                  .apply(lambda x:clean_text(x))
  • Когда мы удаляем нулевые значения в текстовом столбце, нулевые значения в других столбцах также исчезают.

  • Мы используем метод re для удаления шума из текстовых данных.

Шаги, предпринятые во время очистки данных, могут увеличиваться или уменьшаться в зависимости от текстовых данных. Итак, внимательно изучите свои текстовые данные и соответствующим образом создайте метод clean_text().

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

Начнем с анализа.

1. Длина статьи Reuters

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

articles_nonNull[‘word_length’] = articles_nonNull[‘text’].apply(lambda x: len(str(x).split())) print(articles_nonNull.describe())

articles_word_limit = articles_nonNull[articles_nonNull[‘word_length’] > 60]

plt.figure(figsize=(12,6)) 
p1=sns.kdeplot(articles_word_limit[‘word_length’], shade=True, color=”r”).set_title(‘Kernel Distribution of Number Of words’)

  • Я удалил статьи длиной менее 60 слов.

  • Распределение длины слова искажено вправо.

  • Большинство статей составляют около 150 слов.

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

2. Распространенные слова в статьях Reuters

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

Мы удалим стоп-слова из текстовых данных. Поскольку стоп-слова — это шум, они малопригодны для анализа.

1 наиболее часто встречающееся слово из одного слова (N=1)

Давайте нанесем слова-униграммы на гистограмму и облако слов для слов-униграмм.

from gensim.parsing.preprocessing 
import remove_stopwords					   
import genism											      
from wordcloud import WordCloud								   
import numpy as np										   
import random									          

# 从gensim方法导入stopwords到stop_list变量
# 你也可以手动添加stopwords
gensim_stopwords = gensim.parsing.preprocessing.STOPWORDS			   
stopwords_list = list(set(gensim_stopwords))					           
stopwords_update = ["mln", "vs","cts","said","billion","pct","dlrs","dlr"]			          
stopwords = stopwords_list + stopwords_update
articles_word_limit['temp_list'] = articles_word_limit['text_clean'].apply(lambda x:str(x).split())

# 从文章中删除停用词
def remove_stopword(x):
    return [word for word in x if word not in stopwords]
articles_word_limit['temp_list_stopw'] = articles_word_limit['temp_list'].apply(lambda x:remove_stopword(x))

# 生成ngram的单词
def generate_ngrams(text, n_gram=1):
    ngrams = zip(*[text[i:] for i in range(n_gram)])
    return [' '.join(ngram) for ngram in ngrams]
  
  
article_unigrams = defaultdict(int)
for tweet in articles_word_limit['temp_list_stopw']:
    for word in generate_ngrams(tweet):
        article_unigrams[word] += 1
        
article_unigrams_df = pd.DataFrame(sorted(article_unigrams.items(), key=lambda x: x[1])[::-1])
N=50

# 在路透社的文章中前50个常用的unigram
fig, axes = plt.subplots(figsize=(18, 50))
plt.tight_layout()
sns.barplot(y=article_unigrams_df[0].values[:N], x=article_unigrams_df[1].values[:N], color='red')
axes.spines['right'].set_visible(False)
axes.set_xlabel('')
axes.set_ylabel('')
axes.tick_params(axis='x', labelsize=13)
axes.tick_params(axis='y', labelsize=13)
axes.set_title(f'Top {N} most common unigrams in Reuters Articles', fontsize=15)
plt.show()


# 画出词云
def col_func(word, font_size, position, orientation, font_path, random_state):
    colors = ['#b58900', '#cb4b16', '#dc322f', '#d33682', '#6c71c4',
              '#268bd2', '#2aa198', '#859900']
    return random.choice(colors)
fd = {
    'fontsize': '32',
    'fontweight' : 'normal',
    'verticalalignment': 'baseline',
    'horizontalalignment': 'center',
}
wc = WordCloud(width=2000, height=1000, collocations=False,
               background_color="white",
               color_func=col_func,
               max_words=200,
               random_state=np.random.randint(1, 8)) .generate_from_frequencies(article_unigrams)
fig, ax = plt.subplots(figsize=(20,10))
ax.imshow(wc, interpolation='bilinear')
ax.axis("off")
ax.set_title(‘Unigram Words of Reuters Articles’, pad=24, fontdict=fd)
plt.show()

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

Таким образом, мы можем сказать, что большинство статей Reuters относится к категории финансов и капитала.

2. Наиболее распространенные биграммные слова (N=2)

Давайте нарисуем гистограмму и облако слов для слов Biggram.

article_bigrams = defaultdict(int)
for tweet in articles_word_limit[‘temp_list_stopw’]:
    for word in generate_ngrams(tweet, n_gram=2):
        article_bigrams[word] += 1
        
df_article_bigrams=pd.DataFrame(sorted(article_bigrams.items(),
                                key=lambda x: x[1])[::-1])
                                
N=50

# 前50个单词的柱状图
fig, axes = plt.subplots(figsize=(18, 50), dpi=100)
plt.tight_layout()
sns.barplot(y=df_article_bigrams[0].values[:N],
            x=df_article_bigrams[1].values[:N], 
            color=’red’)
axes.spines[‘right’].set_visible(False)
axes.set_xlabel(‘’)
axes.set_ylabel(‘’)
axes.tick_params(axis=’x’, labelsize=13)
axes.tick_params(axis=’y’, labelsize=13)
axes.set_title(f’Top {N} most common Bigrams in Reuters Articles’,
               fontsize=15)
plt.show()

#词云
wc = WordCloud(width=2000, height=1000, collocations=False,
               background_color=”white”,
               color_func=col_func,
               max_words=200,
               random_state=np.random.randint(1,8))\
               .generate_from_frequencies(article_bigrams)
               
fig, ax = plt.subplots(figsize=(20,10))
ax.imshow(wc, interpolation=’bilinear’)
ax.axis(“off”)
ax.set_title(‘Trigram Words of Reuters Articles’, pad=24,
             fontdict=fd)
plt.show()

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

3. Наиболее распространенные триграммные слова

Давайте нарисуем гистограмму и облако слов для слов тригмы.

article_trigrams = defaultdict(int)
for tweet in articles_word_limit[‘temp_list_stopw’]:
    for word in generate_ngrams(tweet, n_gram=3):
        article_trigrams[word] += 1
df_article_trigrams = pd.DataFrame(sorted(article_trigrams.items(),
                                   key=lambda x: x[1])[::-1])
                                   
N=50

# 柱状图的前50个trigram 
fig, axes = plt.subplots(figsize=(18, 50), dpi=100)
plt.tight_layout()
sns.barplot(y=df_article_trigrams[0].values[:N],
            x=df_article_trigrams[1].values[:N], 
            color=’red’)
axes.spines[‘right’].set_visible(False)
axes.set_xlabel(‘’)
axes.set_ylabel(‘’)
axes.tick_params(axis=’x’, labelsize=13)
axes.tick_params(axis=’y’, labelsize=13)
axes.set_title(f’Top {N} most common Trigrams in Reuters articles’,
               fontsize=15)
plt.show()

# 词云
wc = WordCloud(width=2000, height=1000, collocations=False,
background_color=”white”,
color_func=col_func,
max_words=200,
random_state=np.random.randint(1,8)).generate_from_frequencies(article_trigrams)
fig, ax = plt.subplots(figsize=(20,10))
ax.imshow(wc, interpolation=’bilinear’)
ax.axis(“off”)
ax.set_title(‘Trigrams Words of Reuters Articles’, pad=24,
             fontdict=fd)
plt.show()

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

3. Маркировка именованных объектов (NER) для текстовых данных

NER — это процесс извлечения определенной информации из текстовых данных. С помощью NER мы извлекаем из текста местоположение, имя человека, дату, количество и организационные единицы. Узнайте больше о NER здесь. Для этого мы используем библиотеку Spacy Python.

import spacy	
from matplotlib import cm
from matplotlib.pyplot import plt

nlp = spacy.load('en_core_web_sm')
ner_collection = {"Location":[],"Person":[],"Date":[],"Quantity":[],"Organisation":[]}
location = []
person = []
date = []
quantity = []
organisation = []
def ner_text(text):
    doc = nlp(text)
    ner_collection = {"Location":[],"Person":[],"Date":[],"Quantity":[],"Organisation":[]}
    for ent in doc.ents:
        if str(ent.label_) == "GPE":
            ner_collection['Location'].append(ent.text)
            location.append(ent.text)
        elif str(ent.label_) == "DATE":
            ner_collection['Date'].append(ent.text)
            person.append(ent.text)
        elif str(ent.label_) == "PERSON":
            ner_collection['Person'].append(ent.text)
            date.append(ent.text)
        elif str(ent.label_) == "ORG":
            ner_collection['Organisation'].append(ent.text)
            quantity.append(ent.text)
        elif str(ent.label_) == "QUANTITY":
            ner_collection['Quantity'].append(ent.text)
            organisation.append(ent.text)
        else:
            continue
    return ner_collection
   articles_word_limit['ner_data'] = articles_word_limit['text'].map(lambda x: ner_text(x))
    
location_name = []
location_count = []
for i in location_counts.most_common()[:10]:
    location_name.append(i[0].upper())
    location_count.append(i[1])


fig, ax = plt.subplots(figsize=(15, 8), dpi=100)
ax.barh(location_name, location_count, alpha=0.7,
         # width = 0.5,
        color=cm.Blues([i / 0.00525 for i in [ 0.00208, 0.00235, 0.00281, 0.00317, 0.00362,
                                              0.00371, 0.00525, 0.00679, 0.00761, 0.00833]])
        )
plt.rcParams.update({'font.size': 10})
rects = ax.patches
for i, label in enumerate(location_count):
    ax.text(label+100 , i, str(label), size=10, ha='center', va='center')
ax.text(0, 1.02, 'Count of Location name Extracted from Reuters Articles', 
        transform=ax.transAxes, size=12, weight=600, color='#777777')
ax.xaxis.set_ticks_position('bottom')
ax.tick_params(axis='y', colors='black', labelsize=12)
ax.set_axisbelow(True)
ax.text(0, 1.08, 'TOP 10 Location Mention in Reuters Articles',
        transform=ax.transAxes, size=22, weight=600, ha='left')
ax.text(0, -0.1, 'Source: http://kdd.ics.uci.edu/databases/reuters21578/reuters21578.html',
        transform=ax.transAxes, size=12, weight=600, color='#777777')
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
ax.spines['left'].set_visible(False)
ax.spines['bottom'].set_visible(False)
plt.tick_params(axis='y',which='both', left=False, top=False, labelbottom=False)
ax.set_xticks([])
plt.show()

  • По этому графику можно сказать, что большинство статей содержат новости из США, Японии, Канады, Лондона и Китая.

  • Высокий рейтинг США свидетельствует о том, что агентство Reuters сфокусировано на работе в США.

  • Переменная person представляет, кто был знаменитостью в 1987 году. Эта информация помогает нам понять этих людей.

  • Переменная организация содержит наиболее упоминаемые организации в мире.

4. Уникальные слова в текстовых данных

Мы найдем уникальную лексику в статьях, использующих TF-IDF. Частота терминов (TF) — это количество слов в статье. Inverse Document Frequency (IDF) одновременно учитывает все упомянутые статьи и измеряет важность слов.

Слова с высокими баллами TF-IDF имеют большое количество в одной статье и редко или отсутствуют в других статьях.

Давайте посчитаем оценку TF-IDF и найдем уникальные слова.

from sklearn.feature_extraction.text import TfidfVectorizer

tfidf_vectorizer = TfidfVectorizer(use_idf=True)
tfidf_vectorizer_vectors=tfidf_vectorizer.fit_transform(articles_word_limit[‘text_clean’])
tfidf = tfidf_vectorizer_vectors.todense()
tfidf[tfidf == 0] = np.nan

# 使用numpy的nanmean,在计算均值时忽略nan
means = np.nanmean(tfidf, axis=0)

# 将其转换为一个字典,以便以后查找
Means_words = dict(zip(tfidf_vectorizer.get_feature_names(),
                       means.tolist()[0]))
unique_words=sorted(means_words.items(),
                    key=lambda x: x[1],
                    reverse=True)
print(unique_words)

5. Кластер статей с K-средними

K-Means — это неконтролируемый алгоритм машинного обучения. Это помогает нам собирать статьи одного типа в группу. Мы можем определить количество групп или кластеров, инициализировав значение k. Узнайте больше о K-Means и о том, как выбрать значение K здесь. Для справки я выбираю k=4.

from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.cluster import KMeans
from sklearn.metrics import adjusted_rand_score

vectorizer = TfidfVectorizer(stop_words=’english’,use_idf=True)
X = vectorizer.fit_transform(articles_word_limit[‘text_clean’])
k = 4
model = KMeans(n_clusters=k, init=’k-means++’,
               max_iter=100, n_init=1)
model.fit(X)
order_centroids = model.cluster_centers_.argsort()[:, ::-1]
terms = vectorizer.get_feature_names()
clusters = model.labels_.tolist()
articles_word_limit.index = clusters
for i in range(k):
    print(“Cluster %d words:” % i, end=’’)

for title in articles_word_limit.ix[i
                    [[‘text_clean’,’index’]].values.tolist():
    print(‘ %s,’ % title, end=’’)

Это помогает нам классифицировать статьи по разным группам, таким как спорт, валюта, финансы и т. д. Точность K-Means обычно низкая.

в заключении

NER и K-Means — мои любимые методы анализа. Другим может понравиться подход с N-граммами и уникальными словами. В этой статье я представляю самые известные и неизвестные методы визуализации и анализа текста. Все эти методы в этой статье уникальны и могут помочь вам с визуализацией и анализом.

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

Оригинальная ссылка:к data science.com/analysis-press…

Добро пожаловать на сайт блога Panchuang AI:panchuang.net/

sklearn машинное обучение китайские официальные документы:sklearn123.com/

Добро пожаловать на станцию ​​сводки ресурсов блога Panchuang:docs.panchuang.net/