201 KiB
Начало лабораторной работы
import pandas as pd
df = pd.read_csv("..//static//csv//ds_salaries.csv")
print(df.columns)
df.head()
df.describe()
# Процент пропущенных значений признаков
for i in df.columns:
null_rate = df[i].isnull().sum() / len(df) * 100
if null_rate > 0:
print(f'{i} Процент пустых значений: %{null_rate:.2f}')
print(df.isnull().sum())
print(df.isnull().any())
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from typing import Tuple
import pandas as pd
from pandas import DataFrame
from sklearn.model_selection import train_test_split
# Загрузка данных
df = pd.read_csv("..//static//csv//ds_salaries.csv")
# Создание целевого признака
median_salary = df['salary_in_usd'].median()
df['above_median_salary'] = np.where(df['salary_in_usd'] > median_salary, 1, 0)
# Разделение на признаки и целевую переменную
X = df.drop(columns=['salary_in_usd', 'above_median_salary'])
y = df['above_median_salary']
# Примерная категоризация
df['salary_category'] = pd.cut(df['salary_in_usd'], bins=[0, 100000, 200000, np.inf], labels=[0, 1, 2])
# Выбор признаков и целевых переменных
X = df.drop(columns=['salary_in_usd', 'salary_category'])
def split_stratified_into_train_val_test(
df_input,
stratify_colname="y",
frac_train=0.6,
frac_val=0.15,
frac_test=0.25,
random_state=None,
) -> Tuple[DataFrame, DataFrame, DataFrame, DataFrame, DataFrame, DataFrame]:
if frac_train + frac_val + frac_test != 1.0:
raise ValueError(
"fractions %f, %f, %f do not add up to 1.0"
% (frac_train, frac_val, frac_test)
)
if stratify_colname not in df_input.columns:
raise ValueError("%s is not a column in the dataframe" % (stratify_colname))
X = df_input # Contains all columns.
y = df_input[
[stratify_colname]
] # Dataframe of just the column on which to stratify.
# Split original dataframe into train and temp dataframes.
df_train, df_temp, y_train, y_temp = train_test_split(
X, y, stratify=y, test_size=(1.0 - frac_train), random_state=random_state
)
if frac_val <= 0:
assert len(df_input) == len(df_train) + len(df_temp)
return df_train, pd.DataFrame(), df_temp, y_train, pd.DataFrame(), y_temp
# Split the temp dataframe into val and test dataframes.
relative_frac_test = frac_test / (frac_val + frac_test)
df_val, df_test, y_val, y_test = train_test_split(
df_temp,
y_temp,
stratify=y_temp,
test_size=relative_frac_test,
random_state=random_state,
)
assert len(df_input) == len(df_train) + len(df_val) + len(df_test)
return df_train, df_val, df_test, y_train, y_val, y_test
X_train, X_val, X_test, y_train, y_val, y_test = split_stratified_into_train_val_test(
df, stratify_colname="above_median_salary", frac_train=0.80, frac_val=0, frac_test=0.20, random_state=42
)
display("X_train", X_train)
display("y_train", y_train)
display("X_test", X_test)
display("y_test", y_test)
# Проверка преобразования
print(df.dtypes)
# Визуализация распределения зарплат
plt.figure(figsize=(10, 6))
sns.histplot(df['salary_in_usd'], bins=50, kde=True)
plt.title('Распределение зарплат')
plt.xlabel('Зарплата (USD)')
plt.ylabel('Частота')
plt.show()
# Визуализация зависимости между зарплатой и уровнем опыта
plt.figure(figsize=(10, 6))
sns.boxplot(x='experience_level', y='salary_in_usd', data=df)
plt.title('Зависимость зарплаты от уровня опыта')
plt.xlabel('Уровень опыта')
plt.ylabel('Зарплата (USD)')
plt.show()
import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import Pipeline
from sklearn.model_selection import train_test_split
# Загрузка данных
df = pd.read_csv("..//static//csv//ds_salaries.csv")
# Создание целевого признака
median_salary = df['salary_in_usd'].median()
df['above_median_salary'] = np.where(df['salary_in_usd'] > median_salary, 1, 0)
# Разделение на признаки и целевую переменную
X = df.drop(columns=['salary_in_usd', 'above_median_salary'])
y = df['above_median_salary']
# Разделение данных на тренировочный и тестовый наборы
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42, stratify=y)
# Построение конвейеров предобработки
class SalaryFeatures(BaseEstimator, TransformerMixin):
def __init__(self):
pass
def fit(self, X, y=None):
return self
def transform(self, X, y=None):
# Создание новых признаков
X = X.copy()
X["work_year_to_remote_ratio"] = X["work_year"] / X["remote_ratio"]
return X
def get_feature_names_out(self, features_in):
# Добавление имен новых признаков
new_features = ["work_year_to_remote_ratio"]
return np.append(features_in, new_features, axis=0)
# Обработка числовых данных. Числовой конвейер: заполнение пропущенных значений медианой и стандартизация
preprocessing_num_class = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
# Обработка категориальных данных: заполнение пропущенных значений наиболее частым значением и one-hot encoding
preprocessing_cat_class = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
# Определение столбцов
numeric_columns = ["work_year", "salary", "salary_in_usd", "remote_ratio"]
cat_columns = ["experience_level", "employment_type", "job_title", "salary_currency", "employee_residence", "company_location", "company_size"]
# Предобработка признаков
features_preprocessing = ColumnTransformer(
verbose_feature_names_out=False,
transformers=[
("prepocessing_num", preprocessing_num_class, numeric_columns),
("prepocessing_cat", preprocessing_cat_class, cat_columns),
],
remainder="passthrough"
)
# Удаление колонок
columns_to_drop = [] # Укажите столбцы, которые нужно удалить, если они есть
drop_columns = ColumnTransformer(
verbose_feature_names_out=False,
transformers=[
("drop_columns", "drop", columns_to_drop),
],
remainder="passthrough",
)
# Основной конвейер предобработки данных и конструирования признаков
pipeline_end = Pipeline(
[
("features_preprocessing", features_preprocessing),
("custom_features", SalaryFeatures()),
("drop_columns", drop_columns),
]
)
# Демонстрация работы конвейера для предобработки данных при классификации
preprocessing_result = pipeline_end.fit_transform(X_train)
# Получение имен столбцов после преобразования
feature_names = pipeline_end.named_steps['features_preprocessing'].get_feature_names_out(numeric_columns + cat_columns)
feature_names = np.append(feature_names, ["work_year_to_remote_ratio"])
# Создание DataFrame с преобразованными данными
preprocessed_df = pd.DataFrame(
preprocessing_result,
columns=feature_names,
)
preprocessed_df
Бизнес-цели
Предсказание заработной платы (Регрессия)
Цель: Предсказать заработную плату (salary_in_usd) на основе других характеристик, таких как уровень опыта (experience_level), тип занятости (employment_type), должность (job_title), место проживания сотрудника (employee_residence), размер компании (company_size) и другие факторы.
Применение: Это может быть полезно для HR-отделов, которые хотят оценить справедливую зарплату для новых сотрудников или для анализа рынка труда.
Классификация уровня опыта по зарплате (Классификация)
Цель: Классифицировать уровень опыта (experience_level) на основе заработной платы (salary_in_usd) и других факторов.
Применение: Это может помочь в оценке, на каком уровне опыта находится сотрудник, основываясь на его зарплате, что может быть полезно для оценки карьерного роста.
- Прогнозирование зарплаты
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
import seaborn as sns
import matplotlib.pyplot as plt
# Загружаем набор данных
df = pd.read_csv("..//static//csv//ds_salaries.csv")
# Устанавливаем случайное состояние
random_state = 42
# Предварительный анализ данных
print(df.head())
print(df.info())
print(df.describe())
# Проверка на пропущенные значения
print(df.isnull().sum())
# Предобработка данных
# Определяем категориальные и числовые столбцы
categorical_features = ['experience_level', 'employment_type', 'job_title', 'employee_residence', 'company_location', 'company_size']
numeric_features = ['work_year', 'remote_ratio']
# Создаем пайплайн для обработки данных
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)])
# Определяем целевую переменную и признаки
X = df.drop('salary_in_usd', axis=1)
y = df['salary_in_usd']
# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=random_state)
# Создаем и обучаем модель
model = Pipeline(steps=[
('preprocessor', preprocessor),
('regressor', LinearRegression())])
model.fit(X_train, y_train)
# Делаем предсказания на тестовой выборке
y_pred = model.predict(X_test)
# Оцениваем качество модели
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)
print(f"Mean Squared Error: {mse}")
print(f"R^2 Score: {r2}")
- Классифицировать уровень опыта
import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
import seaborn as sns
import matplotlib.pyplot as plt
# Загружаем набор данных
df = pd.read_csv("..//static//csv//ds_salaries.csv")
# Устанавливаем случайное состояние
random_state = 42
# Предобработка данных
# Определяем категориальные и числовые столбцы
categorical_features = ['employment_type', 'job_title', 'employee_residence', 'company_location', 'company_size']
numeric_features = ['work_year', 'salary_in_usd', 'remote_ratio']
# Создаем пайплайн для обработки данных
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)])
# Определяем целевую переменную и признаки
X = df.drop('experience_level', axis=1)
y = df['experience_level']
# Разделяем данные на обучающую и тестовую выборки
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=random_state)
# Создаем и обучаем модель
model = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', RandomForestClassifier(random_state=random_state))])
model.fit(X_train, y_train)
# Делаем предсказания на тестовой выборке
y_pred = model.predict(X_test)
# Оцениваем качество модели
print("Classification Report:")
print(classification_report(y_test, y_pred))
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
print(f"Accuracy Score: {accuracy_score(y_test, y_pred)}")
# Визуализация результатов
conf_matrix = confusion_matrix(y_test, y_pred)
sns.heatmap(conf_matrix, annot=True, fmt='d', cmap='Blues')
plt.xlabel('Predicted')
plt.ylabel('Actual')
plt.title('Confusion Matrix')
plt.show()
Ориентир
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score
df = pd.read_csv("..//static//csv//ds_salaries.csv")
# Предобработка данных
categorical_features = ['experience_level', 'employment_type', 'job_title', 'employee_residence', 'company_location', 'company_size']
numeric_features = ['work_year', 'remote_ratio']
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)])
X = df.drop('salary_in_usd', axis=1)
y = df['salary_in_usd']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = Pipeline(steps=[
('preprocessor', preprocessor),
('regressor', LinearRegression())])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
mae = mean_absolute_error(y_test, y_pred)
mse = mean_squared_error(y_test, y_pred)
rmse = mean_squared_error(y_test, y_pred, squared=False)
r2 = r2_score(y_test, y_pred)
print(f"MAE: {mae}")
print(f"MSE: {mse}")
print(f"RMSE: {rmse}")
print(f"R²: {r2}")
# Проверяем, достигнуты ли ориентиры
if r2 >= 0.75 and mae <= 15000 and rmse <= 20000:
print("Ориентиры для предсказания заработной платы достигнуты!")
else:
print("Ориентиры для предсказания заработной платы не достигнуты.")
import pandas as pd
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler, OneHotEncoder
from sklearn.compose import ColumnTransformer
from sklearn.pipeline import Pipeline
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
# Загружаем набор данных
df = pd.read_csv("..//static//csv//ds_salaries.csv")
# Предобработка данных
categorical_features = ['employment_type', 'job_title', 'employee_residence', 'company_location', 'company_size']
numeric_features = ['work_year', 'salary_in_usd', 'remote_ratio']
preprocessor = ColumnTransformer(
transformers=[
('num', StandardScaler(), numeric_features),
('cat', OneHotEncoder(handle_unknown='ignore'), categorical_features)])
X = df.drop('experience_level', axis=1)
y = df['experience_level']
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
model = Pipeline(steps=[
('preprocessor', preprocessor),
('classifier', RandomForestClassifier(random_state=42))])
model.fit(X_train, y_train)
y_pred = model.predict(X_test)
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy}")
print("Classification Report:")
print(classification_report(y_test, y_pred))
print("Confusion Matrix:")
print(confusion_matrix(y_test, y_pred))
# Проверяем, достигнуты ли ориентиры
if accuracy >= 0.80:
print("Ориентиры для классификации уровня опыта достигнуты!")
else:
print("Ориентиры для классификации уровня опыта не достигнуты.")
Конвейер
import numpy as np
import pandas as pd
from sklearn.base import BaseEstimator, TransformerMixin
from sklearn.compose import ColumnTransformer
from sklearn.impute import SimpleImputer
from sklearn.preprocessing import OneHotEncoder, StandardScaler
from sklearn.pipeline import Pipeline
# Определение столбцов
numeric_columns = ["work_year", "salary", "salary_in_usd", "remote_ratio"]
cat_columns = ["experience_level", "employment_type", "job_title", "salary_currency", "employee_residence", "company_location", "company_size"]
# Обработка числовых данных: заполнение пропущенных значений медианой и стандартизация
preprocessing_num_class = Pipeline(steps=[
('imputer', SimpleImputer(strategy='median')),
('scaler', StandardScaler())
])
# Обработка категориальных данных: заполнение пропущенных значений наиболее частым значением и one-hot encoding
preprocessing_cat_class = Pipeline(steps=[
('imputer', SimpleImputer(strategy='most_frequent')),
('onehot', OneHotEncoder(handle_unknown='ignore'))
])
# Объединение всех преобразований в один ColumnTransformer
features_preprocessing = ColumnTransformer(
verbose_feature_names_out=False,
transformers=[
("prepocessing_num", preprocessing_num_class, numeric_columns),
("prepocessing_cat", preprocessing_cat_class, cat_columns),
],
remainder="passthrough"
)
# Определение конвейера
pipeline_end = Pipeline(
[
("features_preprocessing", features_preprocessing),
]
)
# Разделение данных на тренировочный и тестовый наборы
X_train, X_test = train_test_split(df, test_size=0.2, random_state=42)
# Применение конвейера для предобработки данных
preprocessing_result = pipeline_end.fit_transform(X_train)
# Получение имен столбцов после преобразования
feature_names = pipeline_end.named_steps['features_preprocessing'].get_feature_names_out()
# Создание DataFrame с преобразованными данными
preprocessed_df = pd.DataFrame(
preprocessing_result,
columns=feature_names,
)
# Вывод преобразованного DataFrame
print(preprocessed_df)