<jupyter_start><jupyter_text>Открытый курс по машинному обучениюАвтор материала: <NAME> – @nonna  Python R Collaboration life hacking Не знаю как вы, но я постоянно встречаю сравнение R и Python в задачах работы с данными и машинного обучения. Я бы даже сказала, их противопоставление и выяснение, какой же лучше? Вы можете найти массу исследований, рассматривающих практически все аспекты работы с тем и другим, но вряд ли где-то есть ответ: "Используй один из двух и все будет OK вообще всегда!" Скорее вы встретите что-то вроде: "Для этой конкретной задачи лучше использовать R, а для той, конечно, Python" - и тут не только в самой задаче дело. Очевидно, что все зависит от конечной цели. Нужно глубокое научное исследование? Бери R, там есть все для этого. Хочешь, чтоб работало быстро и в продакшене? Возьми лучше Python, потом спасибо скажешь! И так до бесконечности...Предположим, у нас все написано на R либо Python: все хорошо работает и проблем не приносит. Но вдруг возникла гениальная мысль, которую хочется срочно проверить, а подходящего пакета нет?!Для этого существуют пакеты несколько способов взять все лучшее из Python и R и собрать своего Франкинштейна. Данный туториал будет об одном из таких способов решения самых тривиальных задач, с которыми вы сталкивались или обязательно повстречаетесь в будущем:>- Как определить число кластеров и не ошибиться?>- Как представить в 2D на данные с большим количеством признаков и не потерять суть?Прежде чем начать работу:1 способ: Если вы не используете докер:    - поставьте R под вашу систему (OS X, Win, Ubu): https://www.r-project.org     - поставьте rpy2: conda install rpy2    - остальные R пакеты потренируемся ставить из jupyter notebook       2 способ: Если вы используете докер-контейнер:    - придется поставить R в контейнер и собрать образ снова (т.к. лозунг этого туториала "по-быстренькому", если вы новичок, который ранее не собирал контейнеры, следуйте первому варианту)<jupyter_code>import pandas as pd
import rpy2.interactive as r
import rpy2.interactive.packages
from rpy2.robjects import pandas2ri
from sklearn import datasets

pandas2ri.activate()
%load_ext rpy2.ipython

rlib = r.packages.packages
r.packages.importr("utils")<jupyter_output><empty_output><jupyter_text>Лафхак 1: подбираем число кластеров Предположим, что мы исследуем вопрос об оптимальном количестве кластеров для какого-либо датасета. Общеизвестное правило локтя покажет нам такую картину:  По такому графику сложно сказать уверенно, какое же количество кластеров будет лучшим. Кто-то скажет 2, кто-то 4 - крайне субъективная оценка... И тут на помощь приходит мудрость толпы - устроим голосование!Для этого используем 30 показателей оптимального количества кластеров R пакета NbClust: https://cran.r-project.org/web/packages/NbClust/NbClust.pdf<jupyter_code># Для примера возьмем всем хорошо знакомый датасет Iris

iris = datasets.load_iris()
df = pd.DataFrame(data = iris.data, columns = iris.feature_names)

features = df.columns
df['target'] = iris.target
import seaborn as sns

%pylab inline

sns.pairplot(df[features]);<jupyter_output><empty_output><jupyter_text>Визуально можно выделить два класса, но мы подозреваем, что их больше, так сколько же?<jupyter_code># преобразуем его в R-пригодный вид
r_df = pandas2ri.py2ri(df[features])

# и отправим в R
%Rpush r_df

# теперь пришло время поставить в R пакет NbClust, сделать это можно так
rlib.utils.install_packages("NbClust");
# а теперь начинается магия!

# подключаем библиотеку
%R library(NbClust)

# сид для воспроизводимости
%R set.seed(1234)

# и указываем диапазон от 2 до 10 кластеров
%R Nnc <- NbClust(r_df, distance = "euclidean", min.nc = 2, max.nc = 10, method = "complete", index = "all")<jupyter_output><empty_output><jupyter_text>Цитируя Conclusion: ...the best number of clusters is  3!<jupyter_code># интересно посмотреть как распределились голоса
%R table(Nnc$Best.n[1,])
%R barplot(table(Nnc$Best.n[1,]), xlab="Number of Clusters", ylab="Number of Criteria", main="Number of Clusters Chosen by 30 Criteria");<jupyter_output><empty_output><jupyter_text>Выглядит очень убедительно, давайте посмотрим на данные в привычном виде - нет ли явных противоречий?<jupyter_code>sns.pairplot(df, hue = 'target');<jupyter_output><empty_output><jupyter_text>Очевидно, что данные вполне хорошо разделимы на три кластера, как и выяснилось с помощью NbClust.На самом деле, из этого пакета можно вытащить намного больше полезной информации, особенно это может быть полезно в Research работах.  Лафхак 2: организуем самоорганизующуюся карту Кохонена за 5 мин В двух словах, самоорганизующиеся карты Кохонена славятся тем, что делают 2D представление из многомерного(и даже очень) представления с минимумом потерь смысла, а еще они самообучаются. R-пакет kohonen обладает массой полезных инструментов, например, heatmaps и разрезы по каждому признаку. А также это очень красиво!https://cran.r-project.org/web/packages/kohonen/kohonen.pdfВ данном примере возьмем датасет побольше: Boston data (недвижимость). В данном случае, мы не решаем задачу кластеризации, но хотим использовать аггрегирование данных как дополнительную feature.<jupyter_code>boston = datasets.load_boston()
b_df = pd.DataFrame(data = boston.data, columns = boston.feature_names)

br_df = pandas2ri.py2ri(b_df)
sns.pairplot(b_df);
# поставим в R пакет kohonen
rlib.utils.install_packages("kohonen")
%Rpush br_df

%R library(kohonen)
%R set.seed(1234)

# данные нужно отдать в виде матрицы
%R b_matrix <- as.matrix(br_df)
%R som_grid <- somgrid(xdim = 20, ydim=20, topo="hexagonal")

# и организовать карту
%R bos.som <- som(b_matrix, som_grid, rlen=100, alpha=c(0.05,0.01));
# теперь определим количество кластеров уже известным нам трюком
%R codes <- getCodes(bos.som)
%R b_Nnc <- NbClust(codes, min.nc=2, max.nc=15, method="kmeans");
# и посмотрим на некоторые визуализации
%R plot(bos.som, type="dist.neighbours")
%R plot(bos.som, type="changes",main="Training Progress")
# в конечном итоге, вот так выглядит в двумерном пространстве весь датасет
%R som_cluster <- cutree(hclust(dist(codes)), 3)
%R pretty_palette <- c('#7DBD00', '#62C2CC', '#FF5B00', '#f1bc41')
%R plot(bos.som, type='mapping', bgcol = pretty_palette[som_cluster], main = "Clusters")<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.08282796042132141, 'fraction_numerical': 0.011330992658793488, 'mean_word_length': 5.69551282051282, 'pattern_counts': {'":': 0, '<': 34, '<?xml version=': 0, '>': 28, 'https://': 3, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '6', 'dir': 'jupyter-structured-clean-dedup', 'id': '447654', 'license': 'Unlicense', 'n_tokens_mistral': 2569, 'n_tokens_neox': 2851, 'n_words': 725, 'path': 'jupyter_russian/tutorials/Python_R_Collab_shakhova.ipynb', 'repo_name': 'salman394/AI-ml--course', 'size': '6272'}