Merge pull request 'mashkova_margarita_lab_4 ready' (#198) from mashkova_margarita_lab_4 into main
Reviewed-on: http://student.git.athene.tech/Alexey/IIS_2023_1/pulls/198
This commit is contained in:
commit
a840788afb
108
mashkova_margarita_lab_4/README.md
Normal file
108
mashkova_margarita_lab_4/README.md
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
# Лабораторная работа №4
|
||||||
|
## ПИбд-42 Машкова Маргарита (Вариант 19)
|
||||||
|
## Задание
|
||||||
|
C помощью метод кластеризации DBSCAN решить задачу:
|
||||||
|
Сгруппировать телефоны по объему аккумулятора, размеру экрана, RAM и прочим показателям.
|
||||||
|
Интерпретировать результаты и оценить, насколько хорошо он подходит для решения сформулированной задачи.
|
||||||
|
|
||||||
|
### Данные:
|
||||||
|
> Датасет о характеристиках мобильных телефонов и их ценах
|
||||||
|
>
|
||||||
|
> Ссылка на датасет в kaggle: [Mobile Phone Specifications and Prices](https://www.kaggle.com/datasets/pratikgarai/mobile-phone-specifications-and-prices/data)
|
||||||
|
|
||||||
|
### Модели:
|
||||||
|
|
||||||
|
> - DBSCAN
|
||||||
|
|
||||||
|
> **Note**
|
||||||
|
>
|
||||||
|
> Метод DBSCAN позволяет получить оптимальное разбиение точек на оптимальное количество кластеров,
|
||||||
|
а также выявить атипичные объекты (шум). Оценивается при помощи метрики `Силуэт (Silhouette Score)` - насколько
|
||||||
|
плотно объекты прилегают к центру кластера. Данная метрика оценивает качество кластеризации путем
|
||||||
|
измерения среднего значения силуэта для каждой точки данных.
|
||||||
|
Значение Silhouette Score находится в диапазоне от -1 до 1, где ближе к 1 означает лучшую кластеризацию.
|
||||||
|
Высокое значение Silhouette Score указывает на хорошую разделимость кластеров,
|
||||||
|
а низкое значение может указывать на перекрывающиеся кластеры.
|
||||||
|
|
||||||
|
## Запуск программы
|
||||||
|
Для запуска программы необходимо запустить файл main.py
|
||||||
|
|
||||||
|
## Используемые технологии
|
||||||
|
> **Язык программирования:** python
|
||||||
|
>
|
||||||
|
> **Библиотеки:**
|
||||||
|
> - `pandas` - предоставляет функциональность для обработки и анализа набора данных.
|
||||||
|
> - `sklearn` - предоставляет широкий спектр инструментов для машинного обучения, статистики и анализа данных.
|
||||||
|
## Описание работы программы
|
||||||
|
|
||||||
|
### Описание набора данных
|
||||||
|
Данный набор содержит характеристики различных телефонов, в том числе их цену.
|
||||||
|
|
||||||
|
Названия столбцов набора данных и их описание:
|
||||||
|
|
||||||
|
- **Id** - идентификатор строки (int)
|
||||||
|
- **Name** - наименование телефона (string)
|
||||||
|
- **Brand** - наименование бренда телефона (string)
|
||||||
|
- **Model** - модель телефона (string)
|
||||||
|
- **Battery capacity (mAh)** - емкость аккумулятора в мАч (int)
|
||||||
|
- **Screen size (inches)** - размер экрана в дюймах по противоположным углам (float)
|
||||||
|
- **Touchscreen** - имеет телефон сенсорный экран или нет (string - Yes/No)
|
||||||
|
- **Resolution x** - разрешение телефона по ширине экрана (int)
|
||||||
|
- **Resolution y** - разрешение телефона по высоте экрана (int)
|
||||||
|
- **Processor** - количество ядер процессора (int)
|
||||||
|
- **RAM (MB)** - доступная оперативная память телефона в МБ (int)
|
||||||
|
- **Internal storage (GB)** - внутренняя память телефона в ГБ (float)
|
||||||
|
- **Rear camera** - разрешение задней камеры в МП (0, если недоступно) (float)
|
||||||
|
- **Front camera** - разрешение фронтальной камеры в МП (0, если недоступно) (float)
|
||||||
|
- **Operating system** - ОС, используемая в телефоне (string)
|
||||||
|
- **Wi-Fi** - имеет ли телефон функция Wi-Fi (string - Yes/No)
|
||||||
|
- **Bluetooth** - имеет ли телефон функцию Bluetooth (string - Yes/No)
|
||||||
|
- **GPS** - имеет ли телефон функцию GPS (string - Yes/No)
|
||||||
|
- **Number of SIMs** - количество слотов для SIM-карт в телефоне (int)
|
||||||
|
- **3G** - имеет ли телефон сетевую функкцию 3G (string - Yes/No)
|
||||||
|
- **4G/ LTE** - имеет ли телефон сетевую функкцию 4G/LTE (string - Yes/No)
|
||||||
|
- **Price** - цена телефона в индийских рупиях (int)
|
||||||
|
|
||||||
|
Первоначально данные обрабатываются: все строковые значения признаков необходимо привести к численным.
|
||||||
|
|
||||||
|
Метод не требует предварительных предположений о числе кластеров,
|
||||||
|
но нужно настроить два других параметра: `eps` и `min_samples`.
|
||||||
|
Данные параметры – это соответственно максимальное расстояние между соседними точками и минимальное число точек
|
||||||
|
в окрестности (количество соседей), когда можно говорить, что эти экземпляры данных образуют один кластер.
|
||||||
|
|
||||||
|
Далее выполняется два этапа предобработки данных:
|
||||||
|
1. Масшатабирование: Создается экземпляр класса `StandardScaler()`.
|
||||||
|
Метод `fit_transform(data)` этого класса применяется к данным, чтобы выполнить масштабирование.
|
||||||
|
Результат масштабирования сохраняется в переменной `X_scaled`.
|
||||||
|
2. Нормализация: Метод `normalize(X_scaled)` применяется к масштабированным данным `X_scaled`, чтобы выполнить нормализацию.
|
||||||
|
Результат нормализации сохраняется в переменной `X_normalized`.
|
||||||
|
|
||||||
|
Затем выполняется анализ главных компонент (PCA) на нормализованных данных и преобразование их в двумерное пространство.
|
||||||
|
Это позволяет снизить размерность данных и выделить наиболее информативные признаки.
|
||||||
|
Результат преобразования сохраняется в переменной `X_principal`.
|
||||||
|
|
||||||
|
Создается и обучается модель `dbscan` на нормализованных и масштабированных данных.
|
||||||
|
На основе всех признаков данные разбиваются на кластеры. В поле `labels` в алгоритме DBSCAN хранятся метки кластеров,
|
||||||
|
к которым были присвоены точки данных.
|
||||||
|
Каждая точка данных будет иметь свою метку, указывающую на принадлежность к определенному кластеру или на то,
|
||||||
|
что она не принадлежит ни одному кластеру и считается выбросом (кластер `-1`).
|
||||||
|
|
||||||
|
Вычисляется и выводятся в консоль количество кластеров и шумовых точек.
|
||||||
|
|
||||||
|
Качество кластеризации оценивается с помощью `silhouette_score` и выводится в консоль.
|
||||||
|
|
||||||
|
Отображается график кластеризации.
|
||||||
|
|
||||||
|
## Тесты
|
||||||
|
### Получившиеся кластеры и оценка качества кластеризации:
|
||||||
|
|
||||||
|
![Получившиеся кластеры](clusters.png)
|
||||||
|
|
||||||
|
### График кластеризации:
|
||||||
|
|
||||||
|
![График кластеризации](dbscan_plot.png)
|
||||||
|
|
||||||
|
Шумовые точки изображены фиолетовым цветом.
|
||||||
|
|
||||||
|
**Вывод:** исходя из полученных результатов, значение метрики "силуэт" составляет всего 2%, что указывает на низкое
|
||||||
|
качество кластеризации и перекрывающиеся кластеры. Метод кластеризации `DBSCAN` плохо работает на этих данных.
|
BIN
mashkova_margarita_lab_4/clusters.png
Normal file
BIN
mashkova_margarita_lab_4/clusters.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 21 KiB |
BIN
mashkova_margarita_lab_4/dbscan_plot.png
Normal file
BIN
mashkova_margarita_lab_4/dbscan_plot.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 112 KiB |
72
mashkova_margarita_lab_4/main.py
Normal file
72
mashkova_margarita_lab_4/main.py
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import pandas as pd
|
||||||
|
import matplotlib.pyplot as plt
|
||||||
|
from sklearn.feature_extraction.text import TfidfVectorizer
|
||||||
|
from sklearn.preprocessing import LabelEncoder
|
||||||
|
from sklearn.cluster import DBSCAN
|
||||||
|
from sklearn.decomposition import PCA
|
||||||
|
from sklearn.metrics import silhouette_score
|
||||||
|
from sklearn.preprocessing import StandardScaler
|
||||||
|
from sklearn.preprocessing import normalize
|
||||||
|
from collections import Counter
|
||||||
|
|
||||||
|
filename = "mobiles.csv"
|
||||||
|
# Считываем данные из файла в DataFrame
|
||||||
|
data = pd.read_csv(filename, sep=',')
|
||||||
|
# Удаляем столбец с идентификатором
|
||||||
|
data.pop("Id")
|
||||||
|
|
||||||
|
# Приведение строковых значений признаков к численным при помощи векторайзера с суммированием
|
||||||
|
FEATURE_COLUMNS_TO_PROC = ['Name', 'Brand', 'Model', 'Operating system']
|
||||||
|
for column_name in FEATURE_COLUMNS_TO_PROC:
|
||||||
|
vectorizer = TfidfVectorizer()
|
||||||
|
train_text_feature_matrix = vectorizer.fit_transform(data[column_name]).toarray()
|
||||||
|
a = pd.DataFrame(train_text_feature_matrix)
|
||||||
|
data[column_name] = a[a.columns[1:]].apply(lambda x: sum(x.dropna().astype(float)), axis=1)
|
||||||
|
|
||||||
|
# Приведение строковых значений к численным при помощи числового кодирования LabelEncoder
|
||||||
|
le = LabelEncoder()
|
||||||
|
data['Touchscreen'] = le.fit_transform(data['Touchscreen'])
|
||||||
|
data['Wi-Fi'] = le.fit_transform(data['Wi-Fi'])
|
||||||
|
data['Bluetooth'] = le.fit_transform(data['Bluetooth'])
|
||||||
|
data['GPS'] = le.fit_transform(data['GPS'])
|
||||||
|
data['3G'] = le.fit_transform(data['3G'])
|
||||||
|
data['4G/ LTE'] = le.fit_transform(data['4G/ LTE'])
|
||||||
|
|
||||||
|
scaler = StandardScaler()
|
||||||
|
X_scaled = scaler.fit_transform(data)
|
||||||
|
# Нормализация масштабированных данных
|
||||||
|
X_normalized = normalize(X_scaled)
|
||||||
|
X_normalized = pd.DataFrame(X_normalized)
|
||||||
|
|
||||||
|
pca = PCA(n_components=2)
|
||||||
|
X_principal = pca.fit_transform(X_normalized)
|
||||||
|
X_principal = pd.DataFrame(X_principal)
|
||||||
|
X_principal.columns = ['P1', 'P2']
|
||||||
|
|
||||||
|
# Определяем и обучаем модель
|
||||||
|
dbscan = DBSCAN(eps=0.05, min_samples=5).fit(X_principal)
|
||||||
|
labels = dbscan.labels_
|
||||||
|
|
||||||
|
# Вычисление количества кластеров
|
||||||
|
N_clus = len(set(labels))-(1 if -1 in labels else 0)
|
||||||
|
print('Количество получившихся кластеров: %d' % N_clus)
|
||||||
|
counter = Counter(dbscan.labels_)
|
||||||
|
clusters_df = pd.DataFrame({'Номер кластера': counter.keys(), 'Кол-во элементов': counter.values()}) \
|
||||||
|
.sort_values(by='Кол-во элементов', ascending=False)
|
||||||
|
print(clusters_df.reset_index(drop=True))
|
||||||
|
|
||||||
|
# Вычисление количества шумовых точек
|
||||||
|
n_noise = list(dbscan.labels_).count(-1)
|
||||||
|
print('Количество шумовых точек: %d' % n_noise)
|
||||||
|
|
||||||
|
# Оценка качества кластеризации с помощью silhouette_score
|
||||||
|
silhouette_avg = silhouette_score(X_principal, labels)
|
||||||
|
|
||||||
|
print("Silhouette Score:", silhouette_avg)
|
||||||
|
|
||||||
|
plt.scatter(X_principal['P1'], X_principal['P2'], c=labels)
|
||||||
|
plt.savefig('dbscan_plot.png')
|
||||||
|
# plt.show()
|
||||||
|
|
||||||
|
|
||||||
|
|
1360
mashkova_margarita_lab_4/mobiles.csv
Normal file
1360
mashkova_margarita_lab_4/mobiles.csv
Normal file
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user