#!/usr/bin/env python # coding: utf-8 # # Майнор по Анализу Данных, Группа ИАД-2 # ## 26/04/2017 Алгоритмы кластеризации # In[1]: import pandas as pd import numpy as np import matplotlib.pyplot as plt get_ipython().run_line_magic('matplotlib', 'inline') plt.style.use('ggplot') plt.rcParams['figure.figsize'] = (12,5) # Для кириллицы на графиках font = {'family': 'Verdana', 'weight': 'normal'} plt.rc('font', **font) try: from ipywidgets import interact, IntSlider, fixed, FloatSlider except ImportError: print u'Так надо' # # Пищевая ценность продуктов # Загрузите файл `food.txt`. В нем содержится информация о пищевой ценности разных продуктов # "Name" is the name of the item. # # "Energy" is the number of calories. # # "Protein" is the amount of protein in grams. # # "Fat" is the amount of fat in grams. # # "Calcium" is the amount of calcium in milligrams. # # "Iron" is the amount of iron in milligrams. # * Подготовте данные к кластеризации - выполните нормализацию признаков # * Сделайте иерарническую кластеризацию этого набора данных. # * Изобразите дендрограмму # * Выверите число кластеров и интерпретируйте их # # Почему перед применением кластеризации признки необходимо нормализовать? # In[5]: from scipy.cluster.hierarchy import dendrogram, fcluster, linkage # In[6]: df = pd.read_csv('food.txt', sep=' ') # In[7]: df.head() # In[ ]: # ## K-means, метод "локтя" и меры качества кластеризации # * Загрузите данные по ирисам # * Определите количество кластеров для метода k-means с помощью метода "локтя" # * Выполните кластеризацию и получите вектор с метками кластеров # * Оцените качество кластеризации с помощью # * ARI # * Силуэта # In[1]: from sklearn.datasets import load_iris from sklearn.metrics import adjusted_rand_score, silhouette_samples, silhouette_score from sklearn.cluster import KMeans # In[ ]: # ## Применение K-means на профилях с интересами # Загрузите [данные](https://github.com/brenden17/sklearnlab/blob/master/facebook/snsdata.csv) в которых содержится описание интересов профилей учеников старшей школы США. # In[ ]: df_sns = pd.read_csv('snsdata.csv', sep=',') df_sns.head() # Данные устроены так: # * Год выпуска # * Пол # * Возраст # * Количество друзей # * 36 ключевых слов, которые встречаются в профилe facebook (интересы, сообщества, встречи) # * Удалите все признаки кроме 36 ключевых слов. # * Нормализуйте данные - из каждого столбца вычтите его среднее значение и поделите на стандартное отклонение. # * Используйте метод k-means чтобы выделить 9 кластеров # * Интерпретируйте каждый кластер проанализировав полученные центройды # In[ ]: from sklearn.cluster import KMeans from sklearn.feature_extraction.text import TfidfTransformer # In[ ]: ## Your Code Here # # Геоданные # Загрузите геоданные из `geo_data.txt` (uid, timestamp, lat, lon, location_id). # # Будем пытаться кластеризовать данные с помощью DBSCAN и меры [haversine](https://en.wikipedia.org/wiki/Haversine_formula) # In[ ]: import mpl_toolkits.basemap as bm from sklearn.cluster import DBSCAN from sklearn.neighbors import NearestNeighbors # In[ ]: df_geo = pd.read_csv('geo_data.txt', sep='\t', header=None, names=['lat', 'lon'])/10000 # In[ ]: df_geo.head() # In[ ]: def plot_geo(lat, lon, labels=None): try: lllat, lllon = lat.min()-1, lon.max()+1 urlat, urlon = lat.max()+1, lon.min()-1 plt.figure(figsize=(10, 10)) m = bm.Basemap( llcrnrlon=lllon, llcrnrlat=lllat, urcrnrlon=urlon, urcrnrlat=urlat, projection='merc', resolution='h' ) m.drawcoastlines(linewidth=0.5) m.drawmapboundary(fill_color='#47A4C9', zorder=1) m.fillcontinents(color='#EBC4D8',lake_color='#47A4C9', zorder=2) parallels = np.linspace(lllat, urlat, 10) m.drawparallels(parallels,labels=[1,0,0,0],fontsize=10) # draw meridians meridians = np.linspace(urlon, lllon, 10) m.drawmeridians(meridians,labels=[0,0,0,1],fontsize=10) m.scatter(lon, lat, latlon=True, cmap=plt.cm.jet, zorder=3, lw=0, c=labels) except: print 'что-то пошло не так' plt.scatter(x=lon, y=lat, c=labels, cmap=plt.cm.jet) plt.axis('equal') # Для начала нарисуем все точки на карте # In[ ]: plot_geo(df_geo.lat.values, df_geo.lon.values) # Мы будем использовать расстояние haversine - на входе требуются координаты в **радианах**. Выход тоже будет в радианах. Чтобы перейти от градусов в радианты мы можем вспомнить тригонометрию, а можем воспользоваться функцией `np.radians`. # # Для кого, чтобы не терять связь с реальностью, будем иметь ввиду, что расстояние в 1 радиан на земном шаре равно примерно 6371.0088 километрам. # # Создайте матрицу X с координатами в радианах # In[ ]: km_in_radian = 6371.0088 X = ... # Как же определить, какие параметры для DBSCAN выставлять? Наибольшую проблемы представляет параметр eps. # # Будем считать, что MinPts нам дан свыше (например MinPts = 20). Воспользуемся эвристикой, схожей с методом локтя для оценки eps: # # * Расчитайте среднее расстояние до k=MinPts ближайших соседей каждой точки (класс `NearestNeighbors` и метод `kneighbors`) # * Отсортируйте полученный массив и выведите его на график # * Выберите такое расстояние, где будет наблюдаться "перегиб" # In[ ]: nn = NearestNeighbors(n_neighbors=20, algorithm='ball_tree', metric='haversine') nn.fit(X) # In[ ]: ## Your Code Here # Определим eps мы можем начать кластеризацию # # * Создайте экземпляр класса DBSCAN, кластеризуйте данные # * Выведите полученные метки кластеров и их частоты # * Изобразите координаты точек, не попавших в кластер выбросов (метка -1) # In[ ]: dbscan = DBSCAN(...) ## Your Code Here