<jupyter_start><jupyter_text>[Линейная регрессия: прогноз оклада по описанию вакансии](https://www.coursera.org/learn/vvedenie-mashinnoe-obuchenie/programming/QFvJY/linieinaia-rieghriessiia-proghnoz-oklada-po-opisaniiu-vakansii)  ВведениеЛинейные методы хорошо подходят для работы с разреженными данными — к таковым относятся, например, тексты. Это можно объяснить высокой скоростью обучения и небольшим количеством параметров, благодаря чему удается избежать переобучения.Линейная регрессия имеет несколько разновидностей в зависимости от того, какой регуляризатор используется. Мы будем работать с гребневой регрессией, где применяется квадратичный, или L2-регуляризатор.  1. Загрузите данные об описаниях вакансий и соответствующих годовых зарплатах из файла salary-train.csv (либо его заархивированную версию salary-train.zip).<jupyter_code>import pandas as pd
import numpy as np
from sklearn.linear_model import Ridge
data = pd.read_csv('./data/9_salary-train.csv')
data.head()<jupyter_output><empty_output><jupyter_text>2. Проведите предобработку:* Приведите тексты к нижнему регистру (text.lower()).<jupyter_code>data['FullDescription'] = data['FullDescription'].str.lower()
data['LocationNormalized'] = data['LocationNormalized'].str.lower()
data['ContractTime'] = data['ContractTime'].str.lower()
data.head()<jupyter_output><empty_output><jupyter_text>* Замените все, кроме букв и цифр, на пробелы — это облегчит дальнейшее разделение текста на слова. Для такой замены в строке text подходит следующий вызов: re.sub('[^a-zA-Z0-9]', ' ', text). Также можно воспользоваться методом replace у DataFrame, чтобы сразу преобразовать все тексты:<jupyter_code>data = data.replace('[^a-zA-Z0-9]', ' ', regex=True)
data.head()<jupyter_output><empty_output><jupyter_text>* Примените TfidfVectorizer для преобразования текстов в векторы признаков. Оставьте только те слова, которые встречаются хотя бы в 5 объектах (параметр min_df у TfidfVectorizer).<jupyter_code>from sklearn.feature_extraction.text import TfidfVectorizer
vectorizer = TfidfVectorizer(min_df=5)
X = vectorizer.fit_transform(data['FullDescription'])<jupyter_output><empty_output><jupyter_text>* Замените пропуски в столбцах LocationNormalized и ContractTime на специальную строку 'nan'. Код для этого был приведен выше.<jupyter_code>data['LocationNormalized'].fillna('nan', inplace=True)
data['ContractTime'].fillna('nan', inplace=True)<jupyter_output><empty_output><jupyter_text>* Примените DictVectorizer для получения one-hot-кодирования признаков LocationNormalized и ContractTime.<jupyter_code>from sklearn.feature_extraction import DictVectorizer
enc = DictVectorizer()
a = enc.fit_transform(data[['LocationNormalized', 'ContractTime']].to_dict('records'))

# Сильно разряженая матрица из всех столюцоы только два не нулехвых 
# так как в столбцах 'LocationNormalized', 'ContractTime' всего 2 значения
for i in np.nditer(a[0,:].toarray()):
    if i != 0:
        print("one")
a[0,:].toarray().argmax()<jupyter_output>one
one<jupyter_text>* Объедините все полученные признаки в одну матрицу "объекты-признаки". Обратите внимание, что матрицы для текстов и категориальных признаков являются разреженными. Для объединения их столбцов нужно воспользоваться функцией scipy.sparse.hstack.<jupyter_code>from scipy.sparse import hstack
X = hstack([X, a])<jupyter_output><empty_output><jupyter_text>3. Обучите гребневую регрессию с параметрами alpha=1 и random_state=241. Целевая переменная записана в столбце SalaryNormalized.<jupyter_code>from sklearn.linear_model import Ridge
y = data['SalaryNormalized']
clf = Ridge(alpha=1, random_state=241)
clf.fit(X, y)<jupyter_output><empty_output><jupyter_text>4. Постройте прогнозы для двух примеров из файла salary-test-mini.csv. Значения полученных прогнозов являются ответом на задание. Укажите их через пробел.<jupyter_code>test_data = pd.read_csv('./data/salary-test-mini.csv')
test_data['FullDescription'] = test_data['FullDescription'].str.lower()
test_data['LocationNormalized'] = test_data['LocationNormalized'].str.lower()
test_data['ContractTime'] = test_data['ContractTime'].str.lower()
test_data
x = vectorizer.transform(test_data['FullDescription'])
a = enc.transform(test_data[['LocationNormalized', 'ContractTime']].to_dict('records'))
x = hstack([x, a])
x
clf.predict(x)
round(56555.61500155, 2)
round(37188.32442618, 2)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10791037951531779, 'fraction_numerical': 0.01188843164151806, 'mean_word_length': 7.802816901408451, 'pattern_counts': {'":': 0, '<': 36, '<?xml version=': 0, '>': 36, 'https://': 1, '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': '9', 'dir': 'jupyter-structured-clean-dedup', 'id': '221058', 'license': 'MIT', 'n_tokens_mistral': 1675, 'n_tokens_neox': 1833, 'n_words': 341, 'path': '4_week_1_independent_work.ipynb', 'repo_name': 'Factotum8/coursera_independent_works_ml_introduction', 'size': '4374'}