<jupyter_start><jupyter_text>Лабораторная работа №4_Анализ и визуализация данных в Python_Для начала о том, как пользоваться интерактивным блокнотом. Код помещается в ячейки, для выполнения кода в ячейке нужно кликнуть в ней мышкой, чтобы она выделилась, и нажать Shift-Enter. Поэкспериментируйте на ячейке ниже:<jupyter_code>1+1<jupyter_output><empty_output><jupyter_text>Если в ячейке находятся несколько выражений, то результатом выполнения ячейки будет результат последнего выражения в ней:<jupyter_code>1+1
1+2<jupyter_output><empty_output><jupyter_text>Теперь перейдём к работе с наборами данных при помощи бибилиотеки pandas  PandasДля того, чтобы начать работать с pandas, как и всегда в python, его нужно импортировать. Обычно это делают так:<jupyter_code>import pandas as pd<jupyter_output><empty_output><jupyter_text>Теперь попробуем загрузить набор данных. Для примера возьмём titanic.csv из каталога datasets, который можно загрузить при помощи функции read_csv:<jupyter_code>data = pd.read_csv('datasets/titanic.csv')<jupyter_output><empty_output><jupyter_text>Взглянем на загруженные данные<jupyter_code>data<jupyter_output><empty_output><jupyter_text>Можно попробовать найти в этих данных что-нибудь интересное. Например, посчитаем, какое количество мужчин и женщин было на корабле. Информация об этом хранится в столбце Sex, доступ к которому можно получить следующими способами<jupyter_code>data.Sex<jupyter_output><empty_output><jupyter_text>или Задание индивидуальаьное 1:<jupyter_code>filter_data = data.loc[data['Sex']=='female']
filter_data
str1 = r"Mrs\.\s+[^(]*\((\w+)"
filter1 = filter_data['Name'].str.extract(str1, expand=True).dropna()
filter1
str2 = r"Miss\.\s+(\w+)"
filter2 = filter_data['Name'].str.extract(str2, expand=True).dropna()
filter2
frames = [filter1,filter2]
filter3= pd.concat(frames, sort=False)
filter3
filter3.value_counts()<jupyter_output><empty_output><jupyter_text>Конец задания<jupyter_code>data['Sex']<jupyter_output><empty_output><jupyter_text>Чтобы посчитать количество мужчин и женщин воспользуемся методом value_counts:<jupyter_code>data.Sex.value_counts()<jupyter_output><empty_output><jupyter_text>Можем также получить процентное соотношение, указав флаг normalize:<jupyter_code>data.Sex.value_counts(normalize=True)<jupyter_output><empty_output><jupyter_text>Можем определить среднюю цену билета, обратившись к столбцу Fare и воспользовавшись методом mean:<jupyter_code>data.Fare.mean()<jupyter_output><empty_output><jupyter_text>Из нашего набора данных можно построить новый, выбрав только нужные столбцы при помощи свойства loc, например<jupyter_code>new_data = data.loc[:,['Name', 'Age']]
new_data<jupyter_output><empty_output><jupyter_text>Можно отфильтровать только выживших<jupyter_code>survived = new_data[data.Survived==1]
survived<jupyter_output><empty_output><jupyter_text>Полученный набор данных можно экспортировать обратно в csv функцией to_csv:<jupyter_code>survived.to_csv('survived.csv', index=False)<jupyter_output><empty_output><jupyter_text>NumpyNumpy -- это библиотека для работы с массивами в Python. Список из стандартной библиотеки не достаточно производителен и имеет достаточно скудный интерфейс, чтобы использовать его для научных вычислений. Начнём с импорта библиотеки, который обычно записывают так:<jupyter_code>import numpy as np<jupyter_output><empty_output><jupyter_text>Создадим массив<jupyter_code>arr = np.array([1,2,3,4])<jupyter_output><empty_output><jupyter_text>Ровно как и с питоновскими списками можно получать элемент по индексу и делать слайсы:<jupyter_code>arr[0]
arr[2:]<jupyter_output><empty_output><jupyter_text>Но можно и доставать элементы по спи А можно сделать из него матрицу 2x2:<jupyter_code>m = arr.reshape((2,2))
m<jupyter_output><empty_output><jupyter_text>Можно транспонировать эту матрицу<jupyter_code>m.T<jupyter_output><empty_output><jupyter_text>Вот так можно получить доступ к первой строке матрицы<jupyter_code>m[0]<jupyter_output><empty_output><jupyter_text>А вот так -- ко второму столбцу:<jupyter_code>m[:,1]<jupyter_output><empty_output><jupyter_text>Но самое интересное -- это применение операции ко всему массиву сразу. Например:<jupyter_code>a = arr * 2
a
b = arr + 1
b<jupyter_output><empty_output><jupyter_text>Можно даже применять арифметические операции для двух массивов поэлементно, при условии, что их размеры совпадают:<jupyter_code>a + b
a - b
a * b
a / b
a ** b<jupyter_output><empty_output><jupyter_text>Для нахождения скалярного произведения двух векторов есть оператор @<jupyter_code>a @ b<jupyter_output><empty_output><jupyter_text>Он же отвечает за умножение матрицы на вектор и перемножение матриц по правилу строка на столбец:<jupyter_code>m @ a[:2]
m @ m<jupyter_output><empty_output><jupyter_text>Также массив позволяет находить статистические характеристики<jupyter_code>arr.sum(), arr.mean(), arr.std()<jupyter_output><empty_output><jupyter_text>Можно фильтровать элементы массива по условию<jupyter_code>arr[arr < 3]<jupyter_output><empty_output><jupyter_text>MatplotlibДля визуализации данных в python есть пакет matplotlib. Обычно его импортируют так:<jupyter_code>from matplotlib import pyplot as plt
%matplotlib inline<jupyter_output><empty_output><jupyter_text>Вторая строчка нужна для того, чтобы графики отображались прямо в блокноте, а не в отдельном окне. Давайте что-нибудь построим:<jupyter_code>x = np.linspace(0, 2*np.pi, 100)
plt.plot(x, np.sin(x))
plt.show()
x = np.linspace(0, 2*np.pi, 100)
y = np.linspace(0, np.pi, 50)
xx, yy = np.meshgrid(x, y)
zz = np.sin(xx) * np.cos(yy)
plt.contourf(xx, yy, zz, levels=100)
plt.show()
x = np.linspace(0, 10, 100)
y = np.sin(x) + 0.1 * x
plt.scatter(x + np.random.rand(*x.shape), y + np.random.rand(*x.shape))
plt.show()<jupyter_output><empty_output><jupyter_text>Scikit-learnА теперь немного машинного обучения со scikit-learn. Рассмотрим примеры задач классификации с использованием решающих деревьев, метода k ближайших соседей, а также линейную регрессию.  Решающие деревьяРассмотрим знакомый уже нам набор данных о пассажирах титаника. Будем решать на них задачу классификации, в которой по различным характеристикам пассажиров требуется предсказать, кто из них выжил после крушения корабля и на основании полученной модели определим наиболее важные для выживания признаки.Для начала импортируем классификатор<jupyter_code>from sklearn.tree import DecisionTreeClassifier
clf = DecisionTreeClassifier()<jupyter_output><empty_output><jupyter_text>Теперь подготовим данные. Для начала импортируем их и оставим только такие признаки как пол, класс, цена билета и возраст. В качестве целевой переменной у нас будет факт выживания:<jupyter_code>data = pd.read_csv('datasets/titanic.csv')
interesting = data.loc[:, ['Sex', 'Pclass', 'Fare', 'Age', 'Survived']]<jupyter_output><empty_output><jupyter_text>Обратим внимание, что имеются пропуски в данных. Избавимся от них, удалив соответствующие строки<jupyter_code>interesting.dropna(inplace=True)<jupyter_output><empty_output><jupyter_text>Теперь отделим признаки от целевой переменной<jupyter_code>X = interesting.iloc[:, :-1]
y = interesting.iloc[:, -1]<jupyter_output><empty_output><jupyter_text>Заметим, что столбец Sex содержит текстовые данные и преобразуем их к числовым<jupyter_code>X.Sex = X.Sex.map(lambda x: 0 if x == 'female' else 1)<jupyter_output><empty_output><jupyter_text>Обучим классификатор<jupyter_code>clf.fit(X, y)<jupyter_output><empty_output><jupyter_text>Посмотрим на его результаты на обучающей выборке<jupyter_code>prediction = clf.predict(X)
prediction<jupyter_output><empty_output><jupyter_text>и определим долю правильных ответов<jupyter_code>from sklearn.metrics import accuracy_score
accuracy_score(y, prediction)<jupyter_output><empty_output><jupyter_text>Задание 2:<jupyter_code>from collections import Counter
count = Counter(prediction)
count
dol = count[1]/(count[0]+count[1])
dol
data['Pclass'].value_counts()
data['Pclass']<jupyter_output><empty_output><jupyter_text>Метод k ближайших соседейСейчас мы будем подбирать оптимальное значение k для алгоритма kNN. Будем использовать набор данных Wine, где требуется предсказать сорт винограда, из которого изготовлено вино, используя результаты химических анализовНачинаем с импорта классификатора<jupyter_code>from sklearn.neighbors import KNeighborsClassifier<jupyter_output><empty_output><jupyter_text>Загрузим данные<jupyter_code>data = pd.read_csv('datasets/wine.csv', header=None)
data<jupyter_output><empty_output><jupyter_text>Класс записан в первом столбце (три варианта), признаки — в столбцах со второго по последний.<jupyter_code>X = data.iloc[:, 1:]
y = data.iloc[:, 0]<jupyter_output><empty_output><jupyter_text>Для данного метода настраиваемым параметром является количество ближайших соседей k. Для определения качества классификации и оптимального количества соседей будем рассчитывать точность классификации на кросс-валидации для количества соседей в диапазоне от 1 до 50.Создадим генератор разбиений для проведения кросс-валидации<jupyter_code>from sklearn.model_selection import KFold
cv = KFold(y.size, n_splits=5, shuffle=True)<jupyter_output><empty_output><jupyter_text>И с помощью GridSearchCV будем искать оптимальное значение k<jupyter_code>from sklearn.model_selection import GridSearchCV

grid = {'n_neighbors': np.arange(50) + 1}
clf = KNeighborsClassifier()
gs = GridSearchCV(clf, grid, scoring='accuracy', cv=cv)
gs.fit(X, y)<jupyter_output><empty_output><jupyter_text>Оптимальное значение количества соседей<jupyter_code>gs.best_params_<jupyter_output><empty_output><jupyter_text>А точность при этом<jupyter_code>gs.best_score_<jupyter_output><empty_output><jupyter_text>Задание 3<jupyter_code>from sklearn.preprocessing import scale
XX = scale(X)
cv = KFold(y.size, n_splits=5, shuffle=True)
grid = {'n_neighbors': np.arange(50) + 1}
clf = KNeighborsClassifier()
gs = GridSearchCV(clf, grid, scoring='accuracy', cv=cv)
gs.fit(XX, y)
gs.best_params_
gs.best_score_<jupyter_output><empty_output><jupyter_text>Конец задания 3  Логистическая регрессияЕщё одним способом классификации, несмотря на слово "регрессия" в названии, является логистическая регрессия. Одной из ее особенностей является возможность оценивания вероятностей классов, тогда как большинство линейных классификаторов могут выдавать только номера классов.Загрузим данные:<jupyter_code>data = pd.read_csv('datasets/data-logistic.csv', header=None)
data<jupyter_output><empty_output><jupyter_text>Импортируем классификатор<jupyter_code>from sklearn.linear_model import LogisticRegression
clf = LogisticRegression(C=0.1)<jupyter_output><empty_output><jupyter_text>Обучим классификатор<jupyter_code>clf.fit(data.iloc[:,1:], data.iloc[:,0])<jupyter_output><empty_output><jupyter_text>Визуализируем результат<jupyter_code>xx,yy = np.meshgrid(np.linspace(data.iloc[:,1].min(), data.iloc[:,1].max(), 100),
                    np.linspace(data.iloc[:,2].min(), data.iloc[:,2].max(), 100))
zz = clf.predict(np.column_stack((xx.ravel(), yy.ravel())))
zz = zz.reshape(xx.shape)
plt.contourf(xx, yy, zz, levels=100)
plt.scatter(data[data[0]==-1].iloc[:,1], data[data[0]==-1].iloc[:,2], marker='v')
plt.scatter(data[data[0]==1].iloc[:,1], data[data[0]==1].iloc[:,2], marker='^')<jupyter_output><empty_output><jupyter_text>Определим качество классификации при помощи метрики ROC-AUC:<jupyter_code>from sklearn.metrics import roc_auc_score
roc_auc_score(data[0], clf.predict(data.iloc[:, 1:]))<jupyter_output><empty_output><jupyter_text>Линейная регрессияА сейчас мы будем предсказывать зарплату по описанию вакансии! Начнём с загрузки данных<jupyter_code>data = pd.read_csv('datasets/salary-train.csv')
data<jupyter_output><empty_output><jupyter_text>Подготовим данные. Для начала преобразуем все слова в столбце FullDescription в нижний регистр и заменим все спецсимволы на пробелы<jupyter_code>data.FullDescription = data.FullDescription.str.lower()
data.FullDescription = data.FullDescription.replace('[^a-zA-Z0-9]', ' ', regex = True)<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>Теперь нам нужно преобразовать текст из столбца FullDescription в набор признаков. Одним из способов это сделать является TfidVectorizer.<jupyter_code>from sklearn.feature_extraction.text import TfidfVectorizer
tfid = TfidfVectorizer(min_df=5)
X_train_tfid = tfid.fit_transform(data.FullDescription)<jupyter_output><empty_output><jupyter_text>Чтобы представить в виде набора числовых признаков содержимое столбцов LocationNormalized и ContractTime воспользуемся DictVectorizer<jupyter_code>from sklearn.feature_extraction import DictVectorizer
enc = DictVectorizer()
X_train_categ = enc.fit_transform(data[['LocationNormalized', 'ContractTime']].to_dict('records'))<jupyter_output><empty_output><jupyter_text>Объединим матрицы признаков<jupyter_code>from scipy.sparse import hstack
X = hstack((X_train_categ, X_train_tfid))<jupyter_output><empty_output><jupyter_text>Обучим на этих признаках регрессор<jupyter_code>from sklearn.linear_model import Ridge
reg = Ridge(alpha=1)
reg.fit(X, data.SalaryNormalized)<jupyter_output><empty_output><jupyter_text>Загрузим и преобразуем тестовые данные тем же образом<jupyter_code>test = pd.read_csv('datasets/salary-test-mini.csv')
test.FullDescription = test.FullDescription.str.lower()
test.FullDescription = test.FullDescription.replace('[^a-zA-Z0-9]', ' ', regex = True)
test<jupyter_output><empty_output><jupyter_text>Выделим признаки и получим предсказания зарплат<jupyter_code>X_test_tfid = tfid.transform(test.FullDescription)
X_test_categ = enc.transform(test[['LocationNormalized', 'ContractTime']].to_dict('records'))
X_test = hstack((X_test_categ, X_test_tfid))

test.SalaryNormalized = reg.predict(X_test)
test<jupyter_output><empty_output><jupyter_text>Задание 4<jupyter_code>monetpr = reg.predict(X)
from sklearn.metrics import r2_score
r2_score(data.SalaryNormalized, monetpr)<jupyter_output><empty_output><jupyter_text>Конец задания 4 Индивидуальное задание 2:<jupyter_code>data = pd.read_csv('datasets/europe.csv')
data
work = data.loc[:, ['Life.expect', 'Area', 'GDP', 'Inflation', 'Military', 'Pop.growth', 'Unemployment']]
work
from sklearn import preprocessing
from sklearn import utils
clf = DecisionTreeClassifier()
X = work.iloc[:, 1:]
Y = work.iloc[:, 0]
Y
encoder = preprocessing.LabelEncoder()
y=encoder.fit_transform(Y)
clf.fit(X,y)
prediction = clf.predict(X)
prediction
r2_score(y, prediction)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1057731677357718, 'fraction_numerical': 0.008871297939129249, 'mean_word_length': 9.127850725639254, 'pattern_counts': {'":': 0, '<': 250, '<?xml version=': 0, '>': 249, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 1, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '62', 'dir': 'jupyter-structured-clean-dedup', 'id': '236523', 'license': 'MIT', 'n_tokens_mistral': 6009, 'n_tokens_neox': 6538, 'n_words': 1079, 'path': 'programming-technologies-4-main/lab4.ipynb', 'repo_name': 'PavelBelka/Laba-4-TP', 'size': '14654'}