<jupyter_start><jupyter_text>Programming Assignment: Линейная регрессия: прогноз оклада по описанию вакансии ВведениеЛинейные методы хорошо подходят для работы с разреженными данными — к таковым относятся, например, тексты. Это можно объяснить высокой скоростью обучения и небольшим количеством параметров, благодаря чему удается избежать переобучения.Линейная регрессия имеет несколько разновидностей в зависимости от того, какой регуляризатор используется. Мы будем работать с гребневой регрессией, где применяется квадратичный, или `L2`-регуляризатор. Реализация в Scikit-LearnДля извлечения `TF-IDF`-признаков из текстов воспользуйтесь классом `sklearn.feature_extraction.text.TfidfVectorizer`.Для предсказания целевой переменной мы будем использовать гребневую регрессию, которая реализована в классе `sklearn.linear_model.Ridge`.Обратите внимание, что признаки `LocationNormalized` и `ContractTime` являются строковыми, и поэтому с ними нельзя работать напрямую. Такие нечисловые признаки с неупорядоченными значениями называют категориальными или номинальными. Типичный подход к их обработке — кодирование категориального признака с m возможными значениями с помощью m бинарных признаков. Каждый бинарный признак соответствует одному из возможных значений категориального признака и является индикатором того, что на данном объекте он принимает данное значение. Данный подход иногда называют `one-hot`-кодированием. Воспользуйтесь им, чтобы перекодировать признаки `LocationNormalized` и `ContractTime`. Он уже реализован в классе `sklearn.feature_extraction.DictVectorizer`. Пример использования:<jupyter_code>from sklearn.feature_extraction import DictVectorizer
enc = DictVectorizer()
X_train_categ = enc.fit_transform(data_train[['LocationNormalized', 'ContractTime']].to_dict('records'))
X_test_categ = enc.transform(data_test[['LocationNormalized', 'ContractTime']].to_dict('records'))<jupyter_output><empty_output><jupyter_text>Вам понадобится производить замену пропущенных значений на специальные строковые величины (например, `'nan'`). Для этого подходит следующий код:<jupyter_code>data_train['LocationNormalized'].fillna('nan', inplace=True)
data_train['ContractTime'].fillna('nan', inplace=True)<jupyter_output><empty_output><jupyter_text>Инструкция по выполнению Шаг 1:Загрузите данные об описаниях вакансий и соответствующих годовых зарплатах из файла `salary-train.csv` (либо его заархивированную версию `salary-train.zip`).<jupyter_code>import pandas as pd
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.feature_extraction import DictVectorizer
from sklearn.linear_model import Ridge
from scipy.sparse import hstack
train = pd.read_csv('salary-train.csv')
test = pd.read_csv('salary-test-mini.csv')
train.head()
test.head()<jupyter_output><empty_output><jupyter_text>Шаг 2:Проведите предобработку:* Приведите тексты к нижнему регистру (`text.lower()`).* Замените все, кроме букв и цифр, на пробелы — это облегчит дальнейшее разделение текста на слова. Для такой замены в строке `text` подходит следующий вызов: `re.sub('[^a-zA-Z0-9]', ' ', text)`. Также можно воспользоваться методом `replace` у `DataFrame`, чтобы сразу преобразовать все тексты:<jupyter_code>train['FullDescription'] = train['FullDescription'].replace('[^a-zA-Z0-9]', ' ', regex = True)<jupyter_output><empty_output><jupyter_text>* Примените `TfidfVectorizer` для преобразования текстов в векторы признаков. Оставьте только те слова, которые встречаются хотя бы в 5 объектах (параметр `min_df` у `TfidfVectorizer`).* Замените пропуски в столбцах `LocationNormalized` и `ContractTime` на специальную строку `'nan'`. Код для этого был приведен выше.* Примените `DictVectorizer` для получения `one-hot`-кодирования признаков `LocationNormalized` и `ContractTime`.* Объедините все полученные признаки в одну матрицу "объекты-признаки". Обратите внимание, что матрицы для текстов и категориальных признаков являются разреженными. Для объединения их столбцов нужно воспользоваться функцией `scipy.sparse.hstack`.<jupyter_code>train['FullDescription'] = train['FullDescription'].replace('[^a-zA-Z0-9]', ' ', regex = True).str.lower()
test['FullDescription'] = test['FullDescription'].replace('[^a-zA-Z0-9]', ' ', regex = True).str.lower()
train.head()
test.head()
vectorizer = TfidfVectorizer(min_df = 5)

X_train = vectorizer.fit_transform(train['FullDescription'])
X_test = vectorizer.transform(test['FullDescription'])
train['LocationNormalized'].fillna('nan', inplace=True)
train['ContractTime'].fillna('nan', inplace=True)
enc = DictVectorizer()

X_train_categ = enc.fit_transform(train[['LocationNormalized', 'ContractTime']].to_dict('records'))
X_test_categ = enc.transform(test[['LocationNormalized', 'ContractTime']].to_dict('records'))
X = hstack([X_train, X_train_categ])
y = train['SalaryNormalized']<jupyter_output><empty_output><jupyter_text>Шаг 3:Обучите гребневую регрессию с параметрами `alpha=1` и `random_state=241`. Целевая переменная записана в столбце `SalaryNormalized`.<jupyter_code>clf = Ridge(alpha=1, random_state=241)
clf.fit(X, y)<jupyter_output><empty_output><jupyter_text>Шаг 4: Постройте прогнозы для двух примеров из файла `salary-test-mini.csv`. Значения полученных прогнозов являются ответом на задание. Укажите их через пробел.<jupyter_code>X = hstack([X_test, X_test_categ])

ans = clf.predict(X)
ans
def write_answer(ans, n):
    with open("ans{}.txt".format(n), "w") as fout:
        fout.write(str(ans))
        
write_answer(str(ans)[1:-1], 1)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.10389140271493212, 'fraction_numerical': 0.004705882352941176, 'mean_word_length': 7.813397129186603, 'pattern_counts': {'":': 0, '<': 29, '<?xml version=': 0, '>': 29, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, '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': '7', 'dir': 'jupyter-structured-clean-dedup', 'id': '7636', 'license': 'MIT', 'n_tokens_mistral': 2070, 'n_tokens_neox': 2350, 'n_words': 458, 'path': 'Week-4/linreg.ipynb', 'repo_name': 'MLunov/Introduction-to-Machine-Learning-HSE-Yandex', 'size': '5525'}