Compare commits
2 Commits
a8c58683dd
...
d85cfc5dc0
Author | SHA1 | Date | |
---|---|---|---|
d85cfc5dc0 | |||
6c43c5a693 |
83
malkova_anastasia_lab_4/README.md
Normal file
@ -0,0 +1,83 @@
|
||||
# Лабораторная работа №4
|
||||
|
||||
> Кластеризация
|
||||
|
||||
### Как запустить лабораторную работу
|
||||
|
||||
1. Установить python, numpy, sklearn, matplotlib, plotly
|
||||
2. Запустить команду `python tnse.py` в корне проекта
|
||||
|
||||
### Использованные технологии
|
||||
|
||||
* Язык программирования `python`
|
||||
* Библиотеки `numpy, sklearn, matplotlib, plotly`
|
||||
* Среда разработки `PyCharm`
|
||||
|
||||
### Что делает программа?
|
||||
|
||||
Цель программы: кластеризовать ценовые диапазоны автомобилей на вторичном рынке.
|
||||
Используя метод кластеризации t-SNE, происходит обучение, оценка и вывод результатов кластеризации в виде графика.
|
||||
|
||||
Так как метод визуальный, то оценка будет проводится субъективно
|
||||
по критериям общего цвета и отдалённости кластеров друг от друга.
|
||||
|
||||
#### Эксперимент
|
||||
|
||||
Текущие параметры:
|
||||
|
||||
- mileage
|
||||
- year
|
||||
- price
|
||||
|
||||
##### TSNE(learning_rate=100)
|
||||
|
||||
На размере данных в 1000 строк
|
||||
![1 эксперимент на небольшом кол-ве данных](exp1_small.png)
|
||||
|
||||
На размере данных в 15000 строк
|
||||
![1 эксперимент на большом кол-ве данных](exp1.png)
|
||||
|
||||
##### TSNE(learning_rate=200, perplexity=50, early_exaggeration=6)
|
||||
|
||||
early_exaggeration - определяет, насколько плотными будут естественные кластеры исходного пространстве
|
||||
во вложенном пространстве и сколько места будет между ними. (12 по умолчанию)
|
||||
|
||||
На размере данных в 1000 строк
|
||||
![2 эксперимент на небольшом кол-ве данных](exp2_small.png)
|
||||
|
||||
На размере данных в 15000 строк
|
||||
![2 эксперимент на большом кол-ве данных](exp2.png)
|
||||
|
||||
##### TSNE(learning_rate=200, perplexity=50, early_exaggeration=6, angle=0.1)
|
||||
|
||||
angle - Используется только если метод='barnes_hut'
|
||||
Это компромисс между скоростью и точностью в случае T-SNE с применением алгоритма Барнса-Хата. (0.5 по умолчанию)
|
||||
|
||||
На размере данных в 1000 строк
|
||||
![3 эксперимент на небольшом кол-ве данных](exp3_small.png)
|
||||
|
||||
На размере данных в 15000 строк
|
||||
![3 эксперимент на большом кол-ве данных](exp3.png)
|
||||
|
||||
|
||||
**Выводы:**
|
||||
Чем больше данных, тем лучше алгоритм выделяет кластеры.
|
||||
Настроив параметры алгоритма удалось достичь улучшения результата,
|
||||
но качество все равно можно считать неполностью удовлетворительным, так как кластеры выделяются с заметным уровнем шума.
|
||||
Другие методы кластеризации справляются лучше, если провести дополнительный эксперимент,
|
||||
то можно четко выделить ценовые диапазоны, например:
|
||||
|
||||
Ценовые диапазоны по пробегу
|
||||
![дополнительный эксперимент 1](exp1_addi.png)
|
||||
|
||||
Ценовые диапазоны по году выпуска
|
||||
![дополнительный эксперимент 2](exp2_addi.png)
|
||||
|
||||
В данных примерах можно особенно точно проследить зависимость между параметрами
|
||||
|
||||
#### Итоговые выводы
|
||||
|
||||
Алгоритм t-SNE визуальный и точность определяется восприятием графика. Поэтому использовать его лучше только в целях визуализации.
|
||||
Для данной задачи алгоритм не подходит, так как решает её недостаточно качественно.
|
||||
|
||||
|
3
malkova_anastasia_lab_4/constants.py
Normal file
@ -0,0 +1,3 @@
|
||||
NUMBER_OF_CLUSTERS = 3
|
||||
DATA_SIZE = 1000
|
||||
|
31
malkova_anastasia_lab_4/data.py
Normal file
@ -0,0 +1,31 @@
|
||||
import pandas as pd
|
||||
|
||||
from constants import DATA_SIZE
|
||||
|
||||
|
||||
def load_data():
|
||||
data = read_data()
|
||||
Y = data['Model']
|
||||
X = data[['Year', 'Price', 'Mileage']]
|
||||
|
||||
return X, Y
|
||||
|
||||
|
||||
def fit_model(model, x):
|
||||
transformed = model.fit_transform(x)
|
||||
|
||||
return transformed[:, 0], transformed[:, 1]
|
||||
|
||||
|
||||
def create_data():
|
||||
data = read_data()
|
||||
return data[['Year', 'Price']]
|
||||
|
||||
|
||||
def read_data():
|
||||
data = pd.read_csv('true_car_listings.csv')[:DATA_SIZE]
|
||||
|
||||
unique_numbers = list(set(data['Model']))
|
||||
data['Model'] = data['Model'].apply(unique_numbers.index)
|
||||
return data
|
||||
|
72
malkova_anastasia_lab_4/drawing.py
Normal file
@ -0,0 +1,72 @@
|
||||
import numpy as np
|
||||
from sklearn.manifold import TSNE
|
||||
from matplotlib import pyplot as plt
|
||||
from sklearn.cluster import AgglomerativeClustering
|
||||
import plotly.express as px
|
||||
from constants import *
|
||||
from data import load_data, fit_model, create_data
|
||||
|
||||
|
||||
def show_plots(y, x_axis, y_axis, plot_name):
|
||||
only_labels = y.to_list()
|
||||
|
||||
labels = {
|
||||
"x": "Price",
|
||||
"y": "Value",
|
||||
}
|
||||
|
||||
fig = px.scatter(None, x=x_axis, y=y_axis, labels=labels, opacity=1, color=only_labels)
|
||||
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='lightgrey',
|
||||
zeroline=True, zerolinewidth=1, zerolinecolor='lightgrey',
|
||||
showline=True, linewidth=1, linecolor='black')
|
||||
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='lightgrey',
|
||||
zeroline=True, zerolinewidth=1, zerolinecolor='lightgrey',
|
||||
showline=True, linewidth=1, linecolor='black')
|
||||
|
||||
fig.update_layout(title_text=plot_name, plot_bgcolor='white')
|
||||
fig.update_traces(marker=dict(size=4))
|
||||
|
||||
fig.write_html(f'images/image.html')
|
||||
|
||||
|
||||
def build_launch_name(filename: str, model: TSNE):
|
||||
data = [
|
||||
filename, ' t-SNE ',
|
||||
'learning_rate=', str(model.learning_rate), ' ',
|
||||
'perplexity=', str(model.perplexity), ' ',
|
||||
'early_exaggeration=', str(model.early_exaggeration), ' ',
|
||||
'n_iter=', str(model.n_iter), ' ',
|
||||
'n_iter_without_progress=', str(model.n_iter_without_progress), ' ',
|
||||
'min_grad_norm=', str(model.min_grad_norm), ' ',
|
||||
'metric=', str(model.metric), ' ',
|
||||
'init=', str(model.init), ' ',
|
||||
'method=', str(model.method), ' ',
|
||||
'angle=', str(model.angle),
|
||||
]
|
||||
return ''.join(data)
|
||||
|
||||
|
||||
def launch(filename, X, Y, model: TSNE):
|
||||
x_axis, y_axis = fit_model(model, X)
|
||||
plot_name = build_launch_name(filename, model)
|
||||
show_plots(Y, x_axis, y_axis, plot_name=plot_name)
|
||||
|
||||
|
||||
def draw_experimental_clusters():
|
||||
data = create_data()
|
||||
cluster = AgglomerativeClustering(n_clusters=NUMBER_OF_CLUSTERS, affinity='euclidean', linkage='ward')
|
||||
|
||||
plt.xlabel("Год", fontweight="bold")
|
||||
plt.ylabel("Цена", fontweight="bold")
|
||||
|
||||
corr = np.array(data)
|
||||
cluster.fit_predict(corr)
|
||||
|
||||
plt.scatter(corr[:, 0], corr[:, 1], c=cluster.labels_, cmap='rainbow')
|
||||
plt.show()
|
||||
|
||||
|
||||
def tnse_cluster():
|
||||
X, Y = load_data()
|
||||
model = TSNE(n_components=2, learning_rate=200, perplexity=50, early_exaggeration=6, angle=0.1)
|
||||
launch(filename='true_car_listings.csv', X=X, Y=Y, model=model)
|
BIN
malkova_anastasia_lab_4/exp1.png
Normal file
After Width: | Height: | Size: 498 KiB |
BIN
malkova_anastasia_lab_4/exp1_addi.png
Normal file
After Width: | Height: | Size: 38 KiB |
BIN
malkova_anastasia_lab_4/exp1_small.png
Normal file
After Width: | Height: | Size: 120 KiB |
BIN
malkova_anastasia_lab_4/exp2.png
Normal file
After Width: | Height: | Size: 512 KiB |
BIN
malkova_anastasia_lab_4/exp2_addi.png
Normal file
After Width: | Height: | Size: 49 KiB |
BIN
malkova_anastasia_lab_4/exp2_small.png
Normal file
After Width: | Height: | Size: 113 KiB |
BIN
malkova_anastasia_lab_4/exp3.png
Normal file
After Width: | Height: | Size: 494 KiB |
BIN
malkova_anastasia_lab_4/exp3_small.png
Normal file
After Width: | Height: | Size: 111 KiB |
4
malkova_anastasia_lab_4/experimental_clustering.py
Normal file
@ -0,0 +1,4 @@
|
||||
from drawing import draw_experimental_clusters
|
||||
|
||||
if __name__ == '__main__':
|
||||
draw_experimental_clusters()
|
4
malkova_anastasia_lab_4/tnse.py
Normal file
@ -0,0 +1,4 @@
|
||||
from drawing import tnse_cluster
|
||||
|
||||
if __name__ == '__main__':
|
||||
tnse_cluster()
|