<jupyter_start><jupyter_text>Открытый курс по машинному обучению. Сессия № 2  Автор материала: <NAME> (slack @ivanlipko)   Индивидуальный проект по анализу данных<jupyter_code>import numpy as np
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline

import json
import seaborn as sns<jupyter_output><empty_output><jupyter_text>Часть 1. Описание набора данных и признаков **1. Описание набора данных и признаков (2 балла)**    (+) Описан процесс сбора данных (если применимо), есть подробное описание решаемой задачи, в чем ее ценность, дано описание целевого и прочих признаков;    (+/-) Сказано, какая задача решается, откуда данные, что есть целевой признак. Даны названия признаков;    (-/+) Сказано, какая задача решается, откуда данные и что есть целевой признак;    (-) Описание отсутствует и дано только название датасета или решаемой задачи, скажем, "прогноз оттока". Данные представляют собой **базу кинофильмов и оценок пользователей** из The Movie Database (TMDb). Данные взяты из Kaggle (https://www.kaggle.com/tmdb/tmdb-movie-metadata).Из описания известно что **данные были введены пользователями вручную**, соответственно могут быть ошибки или не соответствия с официальными источниками (All fields are filled out by users so don't expect them to agree on keywords, genres, ratings, or the like). **Метаданные были скачаны** с использованием парсера используя API TMDb's  (https://gist.github.com/SohierDane/4a84cb96d220fc4791f52562be37968b). Как считается рейтинг (целевая переменная), нашёл вот что: ` Популярной возможностью IMDb являются онлайн-голосования. Любой зарегистрированный посетитель сайта может голосовать за фильмы, выставляя им рейтинг: от 1 («ужасный фильм» ) до 10 («шедевр» ) баллов `Я **решаю задачу предсказания рейтинга фильма** (признак vote_average). **Ценность** заключается в следующем: можно выяснить, как зависит окупаемость фильма, его популярность, делать подбор актёров таким образом, чтобы рейтинг фильма. Хочу понять, возможно ли предсказать рейтинг фильма, зная только его краткое описание, бюджет и другие общедоступные данные.Описание признаков: - budget -- бюджет фильма (доллары) - genres -- жанр фильма - homepage -- сайт фильма - id -- номер фильма в каталоге - keywords -- ключевые слова - original_language -- оригинальный язык фильма - original_title -- оригинальное название - overview -- краткая аннотация-описание - popularity -- популярность - production_companies -- студия производства - production_countries -- страна-производитель - release_date  -- дата производства (год - месяц - день) - revenue -- доход, кассовый сбор (доллары) - runtime -- продолжительность в минутах - spoken_languages -- языки фильма - status -- статус, вышел фильм или нет - tagline -- Слоган - title -- финальное название фильма - vote_average **(целевой признак)** -- средний рейтинг фильма - vote_count -- количество голосов<jupyter_code>def load_tmdb_movies(path):
    df = pd.read_csv(path)
    df['release_date'] = pd.to_datetime(df['release_date']).apply(lambda x: x.date())
    json_columns = ['genres', 'keywords', 'production_countries', 'production_companies', 'spoken_languages']
    for column in json_columns:
        df[column] = df[column].apply(json.loads)
    return df

def load_tmdb_credits(path):
    df = pd.read_csv(path)
    json_columns = ['cast', 'crew']
    for column in json_columns:
        df[column] = df[column].apply(json.loads)
    return df

movies = load_tmdb_movies("tmdb_5000_movies.csv")
credits = load_tmdb_credits("tmdb_5000_credits.csv")<jupyter_output><empty_output><jupyter_text>Часть 2. Первичный анализ признаков Посмотрим что у нас из себя представляют данные.<jupyter_code>movies.head(3)<jupyter_output><empty_output><jupyter_text>**Заключение:** Большинство признаков представляют собой json-контейнеры, которые ещё надо разворачивать и делать из них фичи.<jupyter_code>print(movies.shape)
print(movies.info())<jupyter_output><empty_output><jupyter_text>**Заключение:** Практически все важные поля имеют значения - это хорошо<jupyter_code>movies.describe()
p = movies.original_language.value_counts()
print(p.get_values())
print(movies.original_language.unique())
# распределение голосов в зависимости от языка
val_en_counts = movies[movies['original_language'] == 'en']['vote_average'].value_counts().sort_index()
val_ja_counts = movies[movies['original_language'] == 'ja']['vote_average'].value_counts().sort_index()
val_fr_counts = movies[movies['original_language'] == 'fr']['vote_average'].value_counts().sort_index()

plt.title('Распределение значений рейтинга')
plt.xlabel('vote_average'), plt.ylabel('Количество')
plt.plot(val_en_counts.keys(),np.log(val_en_counts.values))
plt.plot(val_ja_counts.keys(),np.log(val_ja_counts.values))
plt.plot(val_fr_counts.keys(),np.log(val_fr_counts.values))
plt.grid(True)
plt.show()<jupyter_output><empty_output><jupyter_text>**Заключение**. Очевидно, что англоязычных фильмов больше чем других, но распределение голосов похожее.<jupyter_code>p = movies.vote_average.value_counts().sort_index()

plt.title('Распределение значений рейтинга')
plt.xlabel('vote_average')
plt.ylabel('Количество')
plt.plot(p.keys(),p.values)
plt.grid(True)
plt.show()
plt.scatter(x=np.log(movies.budget+1), y=np.log(movies.revenue+1), c=movies.vote_average)
# plt.scatter(x=np.log(movies.budget), y=np.log(movies.revenue), c=movies.vote_average)
movies[ (movies['budget']>0) & (movies['revenue']>0) ].plot.scatter(x='budget', y='revenue', c='vote_average', figsize=(10, 10), s=45)
movies[ movies['budget'] <=0].head(3)
movies[ movies['revenue'] <=0 ].head(3)<jupyter_output><empty_output><jupyter_text>**Заключение**. Несмотря на то, что пропусков данных нет, в самих данных есть проблемы. TMDB ничего не знает о бюджете и доходах некоторых фильмов. (например, The Lovers, The Tuxedo). Видимо такие фильмы придётся в дальнейшем просто убирать из обучающей выборки.Для остальных фильмов наблюдается зависимость вложения и отдачи, но однозначно сказать что дорогой фильм будет очень востребован нельзя.<jupyter_code>movs = pd.concat([movies.budget, movies.revenue, movies.popularity, movies.vote_count, movies.vote_average], axis=1)
#movs.vote_average = np.log(movs.vote_average)
movs.popularity = np.log(movs.popularity+1)
movs.vote_count = np.log(movs.vote_count+1)
movs[ (movs.budget>0) & (movs.revenue>0)].plot.scatter(x='popularity', y='vote_average', figsize=(5, 5), c='vote_count')

del movs<jupyter_output><empty_output><jupyter_text>**Заключение**. Сказать что популярный фильм будет иметь высоки рейтинг нельзя. Есть фильмы, которые не так популярны, но имеют высокий рейтинг.<jupyter_code>rel_date_time = pd.to_datetime(movies.release_date)
rel_date_time[ rel_date_time > '1963-01-01' ].value_counts().plot(figsize=(20, 5))
del rel_date_time<jupyter_output><empty_output><jupyter_text>**Заключение**. TMDB в основном содержит фильмы 21 века. Остальные признаки посмотрим, когда возьмём их из JSONa   Часть 5. Предобработка данных  Вытяним из JSONa все жанры, языки фильмов, страну производителя и сделаем OneHotEnconding вручную (кто знает как сделать это красивее напишите мне в Слаке).<jupyter_code>all_genres = []
for i in range(0,movies.shape[0]):
    all_genres.append([actor['name'] for actor in movies['genres'].iloc[i][:10]])
all_genres = set(x for l in all_genres for x in l) # множество содержит только уникальные элементы

genres = pd.DataFrame(columns=all_genres)
for i in range(0,movies.shape[0]):
    a = [actor['name'] for actor in movies['genres'].iloc[i][:10]]
    for j in all_genres:
        genres.at[i,j] = 0
    for item in a:
        genres.at[i,item] = 1

genres.fillna(0, inplace=True)
print(genres.shape)

new_cols = 'genre_'+genres.columns
genres.columns = new_cols
# print(genres.info())
# print(genres.head(5)) # для проверки
# print(genres.tail(5)) # для проверки

genres.to_csv('genres.csv')
# genres = pd.read_csv('genres.csv')
# genres = genres.drop('Unnamed: 0', axis=1)
# for col in genres.columns:
#     genres[col] = pd.to_numeric(genres[col], errors='coerce', downcast='unsigned')
# Компаний очень много и комп медленно их обрабатывает, поэтому пока не трогаю
# all_prod_companies = []
# for i in range(0,movies.shape[0]):
#     all_prod_companies.append([comp['id'] for comp in movies['production_companies'].iloc[i][:10]])
# all_prod_companies = set(x for l in all_prod_companies for x in l)

# prod_comps = pd.DataFrame(columns=all_prod_companies)
# for i in range(0,movies.shape[0]):
#     a = [comp['id'] for comp in movies['production_companies'].iloc[i][:10]]
#     for j in all_prod_companies:
#         prod_comps.at[i,j] = 0
#     for item in a:
#         prod_comps.at[i,item] = 1

# prod_comps.fillna(0, inplace=True)
# print(prod_comps.shape)
# print(prod_comps.head(3))
all_prod_countrs = []
for i in range(0,movies.shape[0]):
    all_prod_countrs.append([comp['iso_3166_1'] for comp in movies['production_countries'].iloc[i][:10]])
all_prod_countrs = set(x for l in all_prod_countrs for x in l)
print(all_prod_countrs)

prod_countrs = pd.DataFrame(columns=all_prod_countrs)
for i in range(0,movies.shape[0]):
    a = [countr['iso_3166_1'] for countr in movies['production_countries'].iloc[i][:10]]
    for j in all_prod_countrs:
        prod_countrs.at[i,j] = 0
    for item in a:
        prod_countrs.at[i,item] = 1

prod_countrs.fillna(0, inplace=True)
new_cols = 'country_'+prod_countrs.columns
prod_countrs.columns = new_cols

print(prod_countrs.shape)
# print(prod_countrs.head(3))
prod_countrs.to_csv('prod_countrs.csv')
# prod_countrs = pd.read_csv('prod_countrs.csv')
# prod_countrs = prod_countrs.drop('Unnamed: 0', axis=1)
all_spok_langs = []
for i in range(0,movies.shape[0]):
    all_spok_langs.append([comp['iso_639_1'] for comp in movies['spoken_languages'].iloc[i][:10]])
all_spok_langs = set(x for l in all_spok_langs for x in l)
# print(all_spok_langs)

spok_langs = pd.DataFrame(columns=all_spok_langs)
for i in range(0,movies.shape[0]):
    a = [lang['iso_639_1'] for lang in movies['spoken_languages'].iloc[i][:10]]
    for j in all_spok_langs:
        spok_langs.at[i,j] = 0
    for item in a:
        spok_langs.at[i,item] = 1

spok_langs.fillna(0, inplace=True)
new_cols = 'country_'+spok_langs.columns
spok_langs.columns = new_cols

print(spok_langs.shape)
# print(spok_langs.head(3))
spok_langs.to_csv('spok_langs.csv')
# prod_countrs = pd.read_csv('prod_countrs.csv')
# prod_countrs = prod_countrs.drop('Unnamed: 0', axis=1)<jupyter_output><empty_output><jupyter_text>LabelEncoding оригинального языка:<jupyter_code>from sklearn.preprocessing import LabelEncoder

labelEnc = LabelEncoder()
movies.original_language = labelEnc.fit_transform(movies.original_language)
# print(dict(enumerate(labelEnc.classes_)))
# print(movies.original_language.head(3))      # для проверки<jupyter_output><empty_output><jupyter_text>Из даты релиза достаём год и месяц выпуска. Вдруг окажется что например, фильмы хорошо заходят перед новыми годом, а не перед новым учебным годом.<jupyter_code>temp_date_month = []
temp_date = pd.to_datetime(movies.release_date)
temp_date_data = [t.month for t in temp_date]
movies['release_month'] = temp_date_data
temp_date_data = [t.year for t in temp_date]
movies['release_year'] = temp_date_data<jupyter_output><empty_output><jupyter_text>Соединяем теперь все столбцы в один DataFrame<jupyter_code>movies = pd.concat([movies, genres, prod_countrs, spok_langs], axis=1)<jupyter_output><empty_output><jupyter_text>Удаляем все не нужные признаки: страница фильма, ИД в каталоге, оригинальное название, статус.<jupyter_code>movies.drop(['homepage', 'status', 'id', 'original_title', 'title', 'release_date'], axis=1, inplace=True)
movies.drop(['genres', 'production_countries', 'spoken_languages'], axis=1, inplace=True)

#   с чем я пока не умею работать
movies.drop(['tagline', 'keywords', 'overview', 'production_companies'], axis=1, inplace=True)<jupyter_output><empty_output><jupyter_text>Создаём наборы данных с признаками и целевым признаком:<jupyter_code>movies.columns[:50]
x_data = movies.copy()
x_data.drop('vote_average', axis=1, inplace=True)
y_data = movies['vote_average']

x_data.dropna(axis=0, inplace=True)
y_data = y_data[x_data.index]

data = pd.concat([x_data, y_data], axis=1)
data.to_csv('data1.csv')
from sklearn.model_selection import train_test_split

x_train, x_test, y_train, y_test = train_test_split(x_data, y_data, test_size=0.33, random_state=43)
x_train_f, x_test_f, y_train_f, y_test_f = train_test_split(x_data[(x_data.budget>0) & (x_data.revenue>0)], y_data[(x_data.budget>0) & (x_data.revenue>0)], test_size=0.33, random_state=43)<jupyter_output><empty_output><jupyter_text>Часть 3. Первичный визуальный анализ признаков **3. Первичный визуальный анализ данных (4 балла)**    (+) Построены визуализации (распределения признаков, матрица корреляций и т.д.), описана связь с анализом данным (п. 2). Присутствуют выводы;    (+/-) Построены визуализации (распределения признаков, матрица корреляций и т.д.). Присутствуют выводы с небольшими ошибками;    (-/+) Недостает важных визуализаций и/или присутствует много ошибок в выводах;    (-) Отсутствует.<jupyter_code># TODO Рейтинг фильмов, которые меняли своё название и не меняли.
movies_log = movies[(movies['budget']>0) & (movies['revenue']>0)][['vote_average', 'popularity', 'revenue', 'budget', 'vote_count','runtime']].copy()
movies_log.popularity = np.log(movies_log.popularity+1)
movies_log.revenue = np.log(movies_log.revenue+1)
movies_log.budget = np.log(movies_log.budget+1)
movies_log.vote_count = np.log(movies_log.vote_count+1)
# movies_log.vote_average = np.log(movies_log.vote_average+1)
sns.pairplot(data=movies_log, hue='vote_average')#, vars=['vote_average', 'popularity', 'revenue', 'budget', 'vote_count'])#,'runtime'])
print(movies.release_month.value_counts())
movies_log = movies[(movies['budget']>0) & (movies['revenue']>0)][['release_year', 'release_month', 'vote_average', 'popularity']].copy()
movies_log.release_year = np.log(movies_log.release_year+1)
movies_log.popularity = np.log(movies_log.popularity+1)
sns.pairplot(data=movies_log, hue='release_month')
f, ax = plt.subplots(nrows=1, ncols=2, figsize=(15, 3))
corr = movies[['vote_average', 'popularity', 'revenue', 'runtime', 'budget', 'vote_count', 'release_year', 'release_month']].corr()
sns.heatmap(corr, cmap='YlGnBu', annot=True, ax=ax[0], fmt='.1f')

corr = movies[['vote_average', 'popularity', 'revenue', 'runtime', 'budget', 'vote_count', 'release_year', 'release_month']].corr(method='spearman')
sns.heatmap(corr, cmap='YlGnBu', annot=True, ax=ax[1], fmt='.1f')
corr = movies[['vote_average','genre_Action', 'genre_Drama', 'genre_Adventure', 'genre_Crime',
        'genre_Western', 'genre_Comedy', 'genre_Mystery', 'genre_Music',
        'genre_History', 'genre_Documentary', 'genre_Fantasy', 'genre_Romance',
        'genre_Animation', 'genre_War', 'genre_Foreign', 'genre_TV Movie',
        'genre_Science Fiction', 'genre_Family', 'genre_Horror',
        'genre_Thriller']].corr()
f, ax = plt.subplots(figsize=(10, 10))
sns.heatmap(corr, cmap='YlGnBu', annot=True, ax=ax, fmt='.1f')<jupyter_output><empty_output><jupyter_text>**Заключение**. Что касается прогнозируемой величины: наиболее рейтинговые фильмы являются драмами. Рейтинг фильма сильно зависит от количества голосов, популярности и продолжительности.Просто наблюдения: семейный фильм скорее всего будет мультфильмом, драма скорее всего романтической и в историческом контексте, исторические фильмы чаще про войну, за популярные фильмы чаще всего голосуют. Наибольшее количество фильмов выходят в сентябре, что наверно не совсем логично. Например, в новогодние каникулы все отдыхают и обычно нечем заняться. С другой стороны это конец летнего сезона.   Часть 4. Закономерности, "инсайты", особенности данных Здесь описание того, что было показано до этого.Заключение по приведённым выше данным вполне очевидны. Например, семейный фильм - это значит что родители пойдут с детьми на мультфильмы (жанр - анимация). Далее как наблюдение - больше всего исторических фильмов о войне, нежели о великих достижениях и гениях своего времени.Также очевидно, что люди обсуждают и голосуют за те фильмы, на которые они ходили и возможно не раз или рассказали друзьям, что можно судит по кассовым сборам.   Часть 6. Создание новых признаков и описание этого процесса отсутствует, жаль   Часть 7. Кросс-валидация, подбор параметров  Построение пробной модели LinearRegression<jupyter_code>from sklearn.linear_model import LinearRegression#, RidgeCV, LassoCV
from sklearn.metrics import mean_absolute_error, mean_squared_error
lr = LinearRegression(n_jobs=-1)
lr.fit(x_train, y_train)
prediction = lr.predict(x_train)
print('MAE',mean_absolute_error(y_train, prediction))
print('MSE',mean_squared_error(y_train, prediction))
lr = LinearRegression(n_jobs=-1)
lr.fit(x_train_f, y_train_f)
prediction = lr.predict(x_train_f)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))
from sklearn.model_selection import cross_val_predict
prediction = cross_val_predict(lr, x_train, y_train, cv=5, n_jobs=-1)
print('MAE',mean_absolute_error(y_train, prediction))
print('MSE',mean_squared_error(y_train, prediction))
prediction = cross_val_predict(lr, x_train_f, y_train_f, cv=5, n_jobs=-1)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))<jupyter_output><empty_output><jupyter_text>**Вывод**. Если в модель не закладывать фильмы, бюджет и доход которых нулевой (здесь больше всего шумов, см. выше), то даже линейная регрессия лучше работает. Это видно по MSE, т.к. она сильнее штрафует за большие ошибки (выбросы). Кросс-валидация этот результат не улучшает. Выбираем такое количество признаков, которые описывают 98% всех решений и посмотрим на качество прогноза.<jupyter_code>from sklearn.decomposition import PCA
#  из 9 домашки 
def plotPCA(pca, perct=90):
    """
    График накопленного процента объясненной дисперсии по компонентам
    """
    features = range(pca.n_components_)
    variance = np.cumsum(np.round(pca.explained_variance_ratio_, decimals=4)*100)
    plt.figure(figsize=(15, 7))
    plt.bar(features, variance)
    
    # дополнительно отметим уровень, при котором объяснены 90% дисперсии
    plt.hlines(y = perct, xmin=0, xmax=len(features), linestyles='dashed', colors='red')
    
    plt.xlabel('PCA components')
    plt.ylabel('variance')
    plt.xticks(features)
    plt.show()
    
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(x_train)
x_train_scaled = scaler.transform(x_train)
x_test_scaled = scaler.transform(x_test)
prediction = cross_val_predict(lr, x_train_scaled, y_train, cv=5, n_jobs=-1)
print('MAE',mean_absolute_error(y_train, prediction))
print('MSE',mean_squared_error(y_train, prediction))

pca = PCA()
pca.fit(x_train_scaled, y_train)
plotPCA(pca)
from sklearn.preprocessing import StandardScaler

scaler = StandardScaler()
scaler.fit(x_train)
x_train_scaled = scaler.transform(x_train_f)
x_test_scaled = scaler.transform(x_test_f)
prediction = cross_val_predict(lr, x_train_scaled, y_train_f, cv=5, n_jobs=-1)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))

pca = PCA()
pca.fit(x_train_scaled, y_train_f)
plotPCA(pca)
features = range(pca.n_components_)
variance = np.cumsum(np.round(pca.explained_variance_ratio_, decimals=4)*100)
print(variance[16*9+5], features[16*9+5])
pca = PCA(n_components=144)
pca.fit(x_train_scaled, y_train_f)
pca_features_train = pca.transform(x_train_scaled)
pca_features_test = pca.transform(x_test_scaled)
lr.fit(pca_features_train, y_train_f)
prediction = lr.predict(pca_features_test)
print('MAE',mean_absolute_error(y_test_f, prediction))
print('MSE',mean_squared_error(y_test_f, prediction))<jupyter_output><empty_output><jupyter_text>**Заключение.** Уменьшение количества признаков сильно картину не улучшает, возможно это из-за масштабирования. (масштабирование коэффициентов не улучшает картину, либо я где-то ошибся, т.к. МАЕ и MSE были огромными)  Построение модели LassoCV<jupyter_code>from sklearn.linear_model import LassoCV
LS_CV = LassoCV(cv=5, n_jobs=-1)
LS_CV.fit(x_train_f,y_train_f)
prediction = LS_CV.predict(x_train_f)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))<jupyter_output><empty_output><jupyter_text>Построение модели RidgeCV<jupyter_code>from sklearn.linear_model import RidgeCV
Rg_CV = RidgeCV(cv=5)
Rg_CV.fit(x_train_f,y_train_f)
prediction = Rg_CV.predict(x_train_f)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))
score_list = [0.01, 0.1, 1, 10, 100, 1000 ] #[ 'svd', 'eigen'] #['explained_variance', 'neg_mean_absolute_error', 'neg_mean_squared_error','neg_mean_squared_log_error','neg_median_absolute_error','r2']
# for score in score_list:
Rg_CV = RidgeCV(cv=5, alphas=score_list)
Rg_CV.fit(x_train_f,y_train_f)
prediction = Rg_CV.predict(x_train_f)
print('MAE',mean_absolute_error(y_train_f, prediction), 'MSE',mean_squared_error(y_train_f, prediction))<jupyter_output><empty_output><jupyter_text>Построение модели ElasticNet<jupyter_code>from sklearn.linear_model import ElasticNet
from sklearn.model_selection import GridSearchCV
alphas = [.01, .05, .1, .2, 1.0]
l1_ratios = np.linspace(.05, .15, 10)
# alphas = [0.1, 1.0, 10]
# l1_ratios = np.linspace(.1, .9, 3)
el_net = ElasticNet()
parameters = {'alpha':alphas, 'l1_ratio':l1_ratios}
grid = GridSearchCV(el_net, param_grid=parameters, scoring='mean_absolute_error' ,verbose=1, cv=5, return_train_score=1, n_jobs=-1)
grid.fit(x_train_f, y_train_f)
print(grid.best_score_)
print(grid.best_estimator_)
el_net_best = grid.best_estimator_
prediction = el_net_best.predict(x_train_f)
print(el_net_best.score(x_train_f, y_train_f))
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))<jupyter_output><empty_output><jupyter_text>**Заключение.** Из рассмотренных моделей ElasticNet и RidgeCV показали хорошие результаты. Правда у ElasticNet коэффициент детерминации маловат и коэффициент `l1_ratio` такой что он по сути является RidgeCV (т.е. применятся Л2-регуляризация).  Обратимся к кривым валидации для проверки.<jupyter_code>from sklearn.ensemble import RandomForestRegressor
estimators = np.arange(5,60,20)
min_samples_leaf = np.arange(5,20,5)
parameters = {'n_estimators':estimators, 'min_samples_leaf':min_samples_leaf}
rfrr = RandomForestRegressor(criterion='mae', n_jobs=-1)
grid = GridSearchCV(rfrr, param_grid=parameters, scoring='mean_absolute_error', verbose=1, cv=5, return_train_score=1, n_jobs=-1)
grid.fit(x_train_f, y_train_f)
print(grid.best_score_)
print(grid.best_estimator_)
rfrr_best = grid.best_estimator_
prediction = rfrr_best.predict(x_train_f)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))<jupyter_output><empty_output><jupyter_text>**Заключение.** Лес дал неплохой результат.<jupyter_code>from sklearn.ensemble import AdaBoostRegressor

estimators = np.arange(5,60,20)
loss = ['linear', 'square', 'exponential']
parameters = {'n_estimators':estimators, 'loss':loss}
abrr = AdaBoostRegressor(random_state=42)
grid = GridSearchCV(abrr, param_grid=parameters, scoring='mean_absolute_error', verbose=1, cv=5, return_train_score=1, n_jobs=-1)
grid.fit(x_train_f, y_train_f)
print(grid.best_score_)
print(grid.best_estimator_)
abrr_best = grid.best_estimator_
prediction = abrr_best.predict(x_train_f)
print('MAE',mean_absolute_error(y_train_f, prediction))
print('MSE',mean_squared_error(y_train_f, prediction))<jupyter_output><empty_output><jupyter_text>Часть 8. Построение кривых валидации и обучения<jupyter_code>from sklearn.model_selection import learning_curve
# from http://scikit-learn.org/stable/auto_examples/model_selection/plot_learning_curve.html#sphx-glr-auto-examples-model-selection-plot-learning-curve-py
def plot_learning_curve(estimator, title, X, y, ylim=None, cv=None,
                        n_jobs=1, train_sizes=np.linspace(.1, 1.0, 5)):
    """
    Generate a simple plot of the test and training learning curve.

    Parameters
    ----------
    estimator : object type that implements the "fit" and "predict" methods
        An object of that type which is cloned for each validation.

    title : string
        Title for the chart.

    X : array-like, shape (n_samples, n_features)
        Training vector, where n_samples is the number of samples and
        n_features is the number of features.

    y : array-like, shape (n_samples) or (n_samples, n_features), optional
        Target relative to X for classification or regression;
        None for unsupervised learning.

    ylim : tuple, shape (ymin, ymax), optional
        Defines minimum and maximum yvalues plotted.

    cv : int, cross-validation generator or an iterable, optional
        Determines the cross-validation splitting strategy.
        Possible inputs for cv are:
          - None, to use the default 3-fold cross-validation,
          - integer, to specify the number of folds.
          - An object to be used as a cross-validation generator.
          - An iterable yielding train/test splits.

        For integer/None inputs, if ``y`` is binary or multiclass,
        :class:`StratifiedKFold` used. If the estimator is not a classifier
        or if ``y`` is neither binary nor multiclass, :class:`KFold` is used.

        Refer :ref:`User Guide <cross_validation>` for the various
        cross-validators that can be used here.

    n_jobs : integer, optional
        Number of jobs to run in parallel (default 1).
    """
    plt.figure()
    plt.title(title)
    if ylim is not None:
        plt.ylim(*ylim)
    plt.xlabel("Training examples")
    plt.ylabel("Score")
    train_sizes, train_scores, test_scores = learning_curve(
        estimator, X, y, cv=cv, n_jobs=n_jobs, train_sizes=train_sizes, scoring='mean_absolute_error')
    train_scores_mean = np.mean(train_scores, axis=1)
    train_scores_std = np.std(train_scores, axis=1)
    test_scores_mean = np.mean(test_scores, axis=1)
    test_scores_std = np.std(test_scores, axis=1)
    plt.grid()

    plt.fill_between(train_sizes, train_scores_mean - train_scores_std,
                     train_scores_mean + train_scores_std, alpha=0.1,
                     color="r")
    plt.fill_between(train_sizes, test_scores_mean - test_scores_std,
                     test_scores_mean + test_scores_std, alpha=0.1, color="g")
    plt.plot(train_sizes, train_scores_mean, 'o-', color="r",
             label="Training score")
    plt.plot(train_sizes, test_scores_mean, 'o-', color="g",
             label="Cross-validation score")

    plt.legend(loc="best")
    return plt
plot_learning_curve(lr, 'LR learning curves', x_train, y_train, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5))
plot_learning_curve(lr, 'LR learning curves (filtered data)', x_train_f, y_train_f, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5))<jupyter_output><empty_output><jupyter_text>**Заключение.** Судя по кривой обучения увеличение данных хорошо влияет, т.к. уменьшается вариация (varience).<jupyter_code>plot_learning_curve(LS_CV, 'LS learning curves', x_train_f, y_train_f, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5))<jupyter_output><empty_output><jupyter_text>**Заключение.** Использовать эту модель не стоит, т.к. очень большое отклонение; а близкое расположение кривых при увеличении обучающей выборки говорит о высоком смещении оценки.<jupyter_code>plot_learning_curve(Rg_CV, 'Rg learning curves', x_train_f, y_train_f, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.01, 1.0, 10))<jupyter_output><empty_output><jupyter_text>**Заключение.** Тут выглядит очень непонятно. Вроде как не надо много данных и модель сразу же получает хорошую оценку. Масштабирование с 0,01 до 0,2 размера выборки ничего хорошего не показало. Поэтому думаю оставить эту модель ии посмотреть, что будет на тесте.<jupyter_code>el_net_best = grid.best_estimator_
plot_learning_curve(el_net_best, 'el_net_best learning curves', x_train_f, y_train_f, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.01, .3, 5))
from sklearn.model_selection import cross_val_score
alphas = np.linspace(0.01, 2.0, 15) #[.01, .05, .1, .2, 1.0]
mse_array = []
mae_array = []
scores_array = []
scores_std_array = []

for alph in alphas:
    el_net_temp = ElasticNet(alpha=alph, l1_ratio=0.08333)
    el_net_temp.fit(x_train_f, y_train_f)
    
    scores = cross_val_score(el_net_temp, x_train_f, y_train_f, scoring='mean_absolute_error', cv=5, n_jobs=-1)
    prediction = el_net_temp.predict(x_train_f)
    
    scores_array.append(scores.mean())
    scores_std_array.append(scores.std())    
    mae_array.append(mean_absolute_error(y_train_f, prediction))
    mse_array.append(mean_squared_error(y_train_f, prediction))
#     print(alph, scores, 'MAE',mean_absolute_error(y_train_f, prediction), 'MSE',mean_squared_error(y_train_f, prediction))

plt.figure()
plt.title('Alpha - regularization')
plt.xlabel("Alpha")
plt.ylabel("Score")
plt.grid()
plt.fill_between(alphas, -np.asarray(scores_array) - np.asarray(scores_std_array),
                 -np.asarray(scores_array) + np.asarray(scores_std_array), alpha=0.1,
                 color="r")
plt.plot(alphas, -np.asarray(scores_array), 'o-', color="r", label="Cross-validation score")
plt.plot(alphas, mae_array, 'o-', color="g", label="Train score")
plt.legend(loc="best")<jupyter_output><empty_output><jupyter_text>**Заключение.** По валидационной кривой очень похоже на высокое смещение оценки. Как интерпретировать вторую кривую (скор от регуляризации) не знаю. Думал что тоже покажет мне или смещение или разброс, но не дало.<jupyter_code>plot_learning_curve(rfrr_best, 'RandomForest learning curves', x_train_f, y_train_f, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5))
plot_learning_curve(abrr_best, 'RandomForest learning curves', x_train_f, y_train_f, ylim=None, cv=5,
                        n_jobs=-1, train_sizes=np.linspace(.1, 1.0, 5))<jupyter_output><empty_output><jupyter_text>**Заключение.** Более привычный рисунок для проверки. Чем больше данных тем лучше, highbias.    Часть 9. Прогноз для тестовой или отложенной выборки  LinearRegression<jupyter_code>lr = LinearRegression(n_jobs=-1)
lr.fit(x_train, y_train)
prediction = lr.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))<jupyter_output><empty_output><jupyter_text>По отфильтрованной обучающей выборке:<jupyter_code>lr.fit(x_train_f, y_train_f)
prediction = lr.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))<jupyter_output><empty_output><jupyter_text>Остальные<jupyter_code>LS_CV = LassoCV(cv=5, n_jobs=-1)
LS_CV.fit(x_train_f, y_train_f)
prediction = LS_CV.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))
Rg_CV = RidgeCV(cv=5)
Rg_CV.fit(x_train_f, y_train_f)
prediction = Rg_CV.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))
el_net_best = ElasticNet(alpha=0.01, copy_X=True, fit_intercept=True,
      l1_ratio=0.083333333333333329, max_iter=1000, normalize=False,
      positive=False, precompute=False, random_state=None,
      selection='cyclic', tol=0.0001, warm_start=False)
el_net_best.fit(x_train_f, y_train_f)
prediction = Rg_CV.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))
rfrr = RandomForestRegressor(bootstrap=True, criterion='mae', max_depth=None,
           max_features='auto', max_leaf_nodes=None,
           min_impurity_decrease=0.0, min_impurity_split=None,
           min_samples_leaf=5, min_samples_split=2,
           min_weight_fraction_leaf=0.0, n_estimators=45, n_jobs=-1,
           oob_score=False, random_state=None, verbose=0, warm_start=False)
rfrr.fit(x_train_f, y_train_f)
prediction = rfrr.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))
abrr = AdaBoostRegressor(base_estimator=None, learning_rate=1.0, loss='linear',
         n_estimators=25, random_state=42)
abrr.fit(x_train_f, y_train_f)
prediction = abrr.predict(x_test)
print('MAE',mean_absolute_error(y_test, prediction))
print('MSE',mean_squared_error(y_test, prediction))<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.12137372013651877, 'fraction_numerical': 0.014200390053632375, 'mean_word_length': 6.0894361633182115, 'pattern_counts': {'":': 0, '<': 125, '<?xml version=': 0, '>': 136, 'https://': 2, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 1, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '30', 'dir': 'jupyter-structured-clean-dedup', 'id': '68827', 'license': 'Unlicense', 'n_tokens_mistral': 13119, 'n_tokens_neox': 13520, 'n_words': 2488, 'path': 'jupyter_russian/projects_individual/project_tmdb_ivanlipko.ipynb', 'repo_name': 'salman394/AI-ml--course', 'size': '32828'}