Это третья из четырех статей, направленных на решение проблемы выявления вспышек заболеваний путем извлечения заголовков новостей из популярных источников новостей.
Эта статья направлена на определение простого способа просмотра кластеров, определенных (во второй статье) в глобальном масштабе и на уровне США. Сначала собирается список больших городов и помещается с соответствующими широтой и долготой в набор данных. Затем создается функция, которая отображает точки кластера на карте с разными цветами для каждого соответствующего кластера. Наконец, функция вызывается для точек в Соединенных Штатах, центров кластеров в Соединенных Штатах, глобальных точек и глобальных центров кластеров.
Ниже показано подробное объяснение того, как это реализовано:
Шаг 1. Составление списка крупнейших городов США.
Сначала название города, широта, долгота и численность населения извлекаются из файла «large_us_cities.csv», содержащего города США с населением более 30 000 человек. Города с населением более 200 000 человек были добавлены в словарь, а Анкоридж и Гонолулу были исключены, поскольку они исказили расположение карты. Затем, используя формулу расстояния гаверсинуса, которая определяет расстояние между парами городов, города, близкие друг к другу, были исключены и использовалась эвристика численности населения, чтобы определить, какой город следует сохранить.
file2 = open('largest_us_cities.csv', 'r') large_cities = file2.readlines() large_city_data = {} for i in range(1, len(large_cities)): large_city_values = large_cities[i].strip().split(';') lat_long = large_city_values[-1].split(',') if ((int(large_city_values[-2]) >= 200000) and (large_city_values[0] != "Anchorage") and (large_city_values[0] != "Honolulu") and (large_city_values[0] != "Greensboro")): large_city_data[large_city_values[0]] = [lat_long[0], lat_long[1], large_city_values[-2]] def haversine(point_a, point_b): lon1, lat1 = point_a[0], point_a[1] lon2, lat2 = point_b[0], point_b[1] lon1, lat1, lon2, lat2 = map(radians, [lon1, lat1, lon2, lat2]) dlon = lon2 - lon1 dlat = lat2 - lat1 a = sin(dlat/2)**2 + cos(lat1) * cos(lat2) * sin(dlon/2)**2 c = 2 * asin(sqrt(a)) r = 6371 return c * r for i in list(large_city_data.keys()): for j in list(large_city_data.keys()): if ((i != j) and haversine((float(large_city_data[i][0]), float(large_city_data[i][1])), (float(large_city_data[j][0]), float(large_city_data[j][1]))) < 80.0): if (large_city_data[j][2] > large_city_data[i][2]): large_city_data[i] = [np.nan, np.nan, large_city_data[i][2]] else: large_city_data[j] = [np.nan, np.nan, large_city_data[j][2]] large_city_data['Chicago'] = [41.8781136, -87.6297982, 2718782]
Этап 2. Построение кластеров и центров кластеров методом К-средних с помощью базовой карты
Сначала создается функция с семью параметрами: df1, num_cluster, typeof, path, size, add_large_city и figsize. Используя библиотеку базовых карт, в зависимости от параметра typeof создаются географические модели США и мира. Кроме того, параметр figsize изменяет размер модели в зависимости от его значения. Создается словарь, в котором ключами являются метки кластера, разделенные по широте и долготе. Значения содержат широту и долготу для каждого заголовка для каждой метки кластера.
Список цветов инициализирован, и каждой метке кластера назначаются определенные цвета. Точки широты и долготы нанесены с использованием этих цветовых значений на географических моделях, сделанных выше. Если параметр add_large_city имеет значение true, на график также будут добавлены самые большие города. Рисунок сохраняется в файл «.png» с использованием параметра пути.
def print_k_means(df1, num_cluster, typeof, path, size, add_large_city, figsize): if (typeof == "US"): map_plotter = Basemap(projection='lcc', lon_0=-95, llcrnrlon=-119, llcrnrlat=22, urcrnrlon=-64, urcrnrlat=49, lat_1=33, lat_2=45) else: map_plotter = Basemap() if (figsize): fig = plt.figure(figsize = (24,16)) else: fig = plt.figure(figsize = (12,8)) coordinates = [] for index in df1.index: coordinates.append([df1['latitude'][index], df1['longitude'][index], df1['cluster_label'][index]]) cluster_vals = {} for i in range(num_cluster): cluster_vals[str(i)+"_long"] = [] cluster_vals[str(i)+"_lat"] = [] for index in df1.index: cluster_vals[str(df1['cluster_label'][index])+'_long'].append(float(df1['longitude'][index])) cluster_vals[str(df1['cluster_label'][index])+'_lat'].append(float(df1['latitude'][index])) num_list = [i for i in range(num_cluster)] color_list = ['rosybrown', 'lightcoral', 'indianred', 'brown', 'maroon', 'red', 'darksalmon', 'sienna', 'chocolate', 'sandybrown', 'peru', 'darkorange', 'burlywood', 'orange', 'tan', 'darkgoldenrod', 'goldenrod', 'gold', 'darkkhaki', 'olive', 'olivedrab', 'yellowgreen', 'darkolivegreen', 'chartreuse', 'darkseagreen', 'forestgreen', 'darkgreen', 'mediumseagreen', 'mediumaquamarine', 'turquoise', 'lightseagreen', 'darkslategrey', 'darkcyan', 'cadetblue', 'deepskyblue', 'lightskyblue', 'steelblue', 'lightslategrey', 'midnightblue', 'mediumblue', 'blue', 'slateblue', 'darkslateblue', 'mediumpurple', 'rebeccapurple', 'thistle', 'plum', 'violet', 'purple', 'fuchsia', 'orchid', 'mediumvioletred', 'deeppink', 'hotpink', 'palevioletred'] colors = [color_list[i] for i in range(num_cluster+1)] for target,color in zip(num_list, colors): map_plotter.scatter(cluster_vals[str(target)+'_long'], cluster_vals[str(target)+'_lat'], latlon=True, s = size, c = color) map_plotter.shadedrelief() if (add_large_city): for index in list(large_city_data.keys()): if (large_city_data[index][1] != np.nan): x, y = map_plotter(large_city_data[index][1], large_city_data[index][0]) plt.plot(x, y, "ok", markersize = 4) plt.text(x, y, index, fontsize = 16) plt.show() fig.savefig(path)
Шаг 3. Запуск функции
Функция print_k_means запускается в кадре данных df_no_us, чтобы построить диаграмму рассеяния широты и долготы для заголовков, относящихся к США. Затем определяется географический центр каждого кластера и сохраняется в другом фрейме данных, называемом df_center_us. Функция print_k_means запускается в фрейме данных df_center_us и добавляет крупные города для определения городов, ближайших к центрам вспышек заболеваний. Кроме того, размер увеличен для облегчения чтения. Аналогичный процесс выполняется для df_no_world. Каждый из фреймов данных хранится в файле «.csv».
print_k_means(df_no_us, us_clusters, "US", "corona_disease_outbreaks_us.png", 50, False, False) df_no_us.to_csv("corona_disease_outbreaks_us.csv") df_center_us = {'latitude': [], 'longitude':[] , 'cluster_label': []} for i in range(us_clusters): df_1 = df_no_us.loc[df_no_us['cluster_label'] == i] df_1 = df_1.reset_index() del df_1['index'] latitude = [] longitude = [] for index in df_1.index: latitude.append(float(df_1['latitude'][index])) longitude.append(float(df_1['longitude'][index])) df_1['latitude'] = latitude df_1['longitude'] = longitude sum_latitude = df_1['latitude'].sum() sum_longitude = df_1['longitude'].sum() if (len(df_1['latitude']) >= 20): df_center_us['latitude'].append(sum_latitude/(len(df_1['latitude']))) df_center_us['cluster_label'].append(i) df_center_us['longitude'].append(sum_longitude/(len(df_1['longitude']))) df_center_us = pd.DataFrame(data = df_center_us) for index in df_center_us.index: df_center_us['cluster_label'][index] = index print_k_means(df_center_us, len(df_center_us['latitude']), "US", "corona_disease_outbreaks_us_centers.png", 500, True, True) df_center_us.to_csv("corona_disease_outbreaks_us_centers.csv") df_center_world = {'latitude': [], 'longitude':[] , 'cluster_label': []} for i in range(world_clusters): df_1 = df_no_world.loc[df_no_world['cluster_label'] == i] df_1 = df_1.reset_index() del df_1['index'] latitude = [] longitude = [] for index in df_1.index: latitude.append(float(df_1['latitude'][index])) longitude.append(float(df_1['longitude'][index])) df_1['latitude'] = latitude df_1['longitude'] = longitude sum_latitude = df_1['latitude'].sum() sum_longitude = df_1['longitude'].sum() if (len(df_1['latitude']) >= 10): df_center_world['latitude'].append(sum_latitude/(len(df_1['latitude']))) df_center_world['cluster_label'].append(i) df_center_world['longitude'].append(sum_longitude/(len(df_1['longitude']))) df_center_world = pd.DataFrame(data = df_center_world) for index in df_center_world.index: df_center_world['cluster_label'][index] = index print_k_means(df_center_world, len(df_center_world['latitude']), "world", "corona_disease_outbreaks_world_centers.png", 500, False, True) df_center_us.to_csv("corona_disease_outbreaks_world_centers.csv")
Щелкните эту ссылку для доступа к репозиторию Github с подробным объяснением кода: Github.