sabrinas.space –

методология

Этот проект можно разбить на три части: сбор данных, обработка данных и анализ данных.

сбор данных

Я начал с использования сервиса Open.Trends компании SEM Rush, чтобы найти лучшие веб-сайты для каждой страны во всех отраслях. Хотя это можно сделать вручную, я автоматизировал процесс, используя библиотеки Python BeautifulSoup и Selenium-Python (в этом случае вы также можете использовать библиотеку Requests, но у меня уже был импортирован Selenium, лол). Вот некоторый псевдокод, чтобы дать вам представление о том, как это было сделано:

# run a function to get the list of countries Open.Trends has listed on their site
countries = getCountries()

# initialize a dictionary to store the information
d = {
    'country':[],
    'website':[],
    'visits':[]
}

# iterate through that list
for country in countries:
  # follow semrush's URL formatting and plug in the country using a formatted string
  url = f'https://www.semrush.com/trending-websites/{country}/all'

  # navigate to the URL using Selenium Webdriver
  driver.get(url)

  # feed the page information into BeautifulSoup
  soup = BeautifulSoup(driver.page_source, 'html.parser')

  # extract the table data using BeautifulSoup
  results = getTableData(soup)

  # feed the results into the dictionary
  d['country'] = results['country']
  d['website'] = results['website']
  d['visits'] = results['visits']

# save this into some sort of file
df = pandas.DataFrame(d)
df.save_csv('popular_websites.csv', index=False)

ПРИМЕЧАНИЕ: качество этих данных зависит от точности методов SEM Rush. Я не особо вникал в это, потому что их списки были сопоставимы с аналогичными услугами.

Теперь у вас должен быть словарь самых популярных веб-сайтов в каждой стране. Многие из этих веб-сайтов будут содержать порнографию или вредоносное ПО, или и то, и другое. Давайте попробуем отфильтровать некоторые из них с помощью API поиска URL-адресов Cyren. Это сервис, который использует «машинное обучение, эвристику и человеческий анализ» для категоризации веб-сайтов.

Вот еще псевдокод:

# iterate through all the websites we found
for i in range(len(df['website'])):
  # select the website
  url = df.loc[i,'website']
  # call the API on the website
  category = getCategory(url)
  # save the results 
  df.loc[i,'category'] = category

# filter out all the undesireable categories 
undesireable = [...]
df = df.loc[df['category'] in undesireable]

# save this dataframe to avoid needing to do this all over again
df.save_csv('popular_websites_filtered.csv', index=False)

ПРИМЕЧАНИЕ: Cyren URL Lookup API предоставляет 1000 бесплатных запросов в месяц на каждого пользователя.

Read more:  Пенсия Ристера: BGH объявляет статью недействительной - Экономика

СОВЕРШЕННО ОТДЕЛЬНОЕ ПРИМЕЧАНИЕ: Вы можете использовать такие сервисы, как временная почта для создания временных адресов электронной почты.

Теперь пришло время сделать несколько скриншотов веб-сайтов! Если вы хотите делать полностраничные снимки экрана, вам потребуется использовать веб-драйвер Firefox Selenium-Python. Если нет, подойдет любой веб-драйвер. Однако вы, вероятно, не захотите использовать полные снимки экрана, поскольку размеры веб-страниц сильно различаются, и это может сделать ваши конечные результаты менее интерпретируемыми.

def acceptCookies(...):
  # this function will probably consistent of a bunch of try-exception blocks
  # in search of a button that says accept/agree/allow cookies in every language
  # ngl i gave up like 1/3 of the way through 

def notBot(...):
  # some websites will present a captcha before giving you access
  # there are ways to beat that captcha
  # i didn't even try but you should

# iterate through websites
for i in range(len(df['website'])):
  url = df.loc[i,'website]
  driver.get(url)

  # wait for the page to load
  # you shouldn't really use static sleep calls but i did
  sleep(5)
  notBot(driver)
  sleep(2)
  acceptCoookies(driver)
  sleep(2)

  # take screenshots
  driver.save_screenshot(f'homepage_{country.upper()}_{url}.png')

  # this call only exists for firefox webdrivers
  driver.save_full_page_screenshot(f'homepage_{country.upper()}_{url}.png')

ПРИМЕЧАНИЕ: При этом вы можете использовать VPN для перехода в соответствующую страну/регион, чтобы повысить вероятность просмотра местной веб-страницы.

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

я в основном следил этот урок Григорий Серебряков на LearnOpenCV. Он использует реализацию модели ResNet для извлечения характеристик изображения. Вы можете взять код из его сообщения в блоге, но нам нужно загружать изображения по-другому. Мы можем использовать этот метод Эндрюджонга (источник). Нам нужно сохранить пути к файлам изображений для использования в нашей окончательной визуализации.

class ImageFolderWithPaths(datasets.ImageFolder):
    """Custom dataset that includes image file paths. Extends
    torchvision.datasets.ImageFolder
    """

    # override the __getitem__ method. this is the method that dataloader calls
    def __getitem__(self, index):
        # this is what ImageFolder normally returns 
        original_tuple = super(ImageFolderWithPaths, self).__getitem__(index)
        # the image file path
        path = self.imgs[index][0]
        # make a new tuple that includes original and the path
        tuple_with_path = (original_tuple + (path,))
        return tuple_with_path

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

# identify the path containing all your images
# if you want them to be labeled by country, you will need to sort them into folders

root_path="..."

# transform the data so they are identical shapes
transform = transforms.Compose([transforms.Resize((255, 255)),
                                 transforms.ToTensor()])
dataset = ImageFolderWithPaths(root, transform=transform)

# load the data
dataloader = torch.utils.data.DataLoader(dataset, batch_size=32, shuffle=True)

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

# initialize model
model = ResNet101(pretrained=True)
model.eval()
model.to(device)

# initialize variables to store results
features = None
labels = []
image_paths = []

# run the model
for batch in tqdm(dataloader, desc="Running the model inference"):

  images = batch[0].to('cpu')
  labels += batch[1]
  image_paths += batch[2]

  output = model.forward(images)
  # convert from tensor to numpy array
  current_features = output.detach().numpy()

  if features is not None:
      features = np.concatenate((features, current_features))
  else:
      features = current_features

# return labels too their string interpretations
labels = [dataset.classes[e] for e in labels]

# save the data
np.save('images.npy', images)
np.save('features.npy', features)
with open('labels.pkl', 'wb') as f:
  pickle.dump(labels, f)
with open('image_paths.pkl', 'wb') as f:
  pickle.dump(image_paths, f)

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

Read more:  Военные мобилизованы, поскольку зимняя буря вызывает «катастрофические» холода, миллионы людей предупреждены, что обморожения могут случиться менее чем за пять минут: обновления в реальном времени

анализ данных

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

# the s in t-SNE stands for stochastic (random) 
# let's set a seed for reproducible results
seed = 10
random.seed(seed)
torch.manual_seed(seed)
np.random.seed(seed)

# run tsne
n_components = 2
tsne = TSNE(n_components)
tsne_result = tsne.fit_transform(features)

# scale and move the coordinates so they fit [0; 1] range
tx = scale_to_01_range(tsne_result[:,0])
ty = scale_to_01_range(tsne_result[:,1)

# plot the images
for image_path, image, x, y in zip(image_paths, images, tx, ty):
  # read the image
  image = cv2.imread(image_path)

  # resize the image
  image = cv2.resize(image, (150,100))

  # compute the dimensions of the image based on its tsne co-ordinates
  tlx, tly, brx, bry = compute_plot_coordinates(image, x, y)

  # put the image to its t-SNE coordinates using numpy sub-array indices
  tsne_plot[tl_y:br_y, tl_x:br_x, :] = image

cv2.imshow('t-SNE', tsne_plot)
cv2.waitKey()

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

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

Вот базовое описание того, как я использовал эти новые данные анализа.

analysis_data = # import data

# initialize a list to capture a parallel set of labels
# so instead of the country, we can label our data through writing system, etc.
new_labels = []

# iterate through our pre-existing labels and use it to inform our new_labels
for label in labels:
  # select the new_label based on the old label (the country name)
  new_label = analysis_data['country' == label]
  new_labels.append(new_label)

# use the new_labels to colour a scatterplot with our tsne_results
tsne_df = pd.DataFrame({'tsne_1': tx, 'tsne_2': ty, 'label': new_labels})
sns.scatterplot(x='tsne_1', y='tsne_2', data=tsne_df, hue="label")

ПРИМЕЧАНИЕ: В технологическом аргументе использован более качественный метод, и он здесь не рассматривается.

Read more:  Достаточно ли целевой выбросов Австралии достаточно хорошей?

мы можем увидеть результаты этих сравнений в разделах выше.

tsne-реализация сравнения популярных веб-сайтов в Японии и США.

ответ в разработке проекта

2026-02-23 14:28:00


1771860887
#sabrinas.space

Продолжение темы

Leave a Comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.