<?xml version="1.0" encoding="utf-8" ?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:tt="http://teletype.in/" xmlns:opensearch="http://a9.com/-/spec/opensearch/1.1/"><title>Vladi PATOK</title><author><name>Vladi PATOK</name></author><id>https://teletype.in/atom/vladimirvanalytics</id><link rel="self" type="application/atom+xml" href="https://teletype.in/atom/vladimirvanalytics?offset=0"></link><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><link rel="next" type="application/rss+xml" href="https://teletype.in/atom/vladimirvanalytics?offset=10"></link><link rel="search" type="application/opensearchdescription+xml" title="Teletype" href="https://teletype.in/opensearch.xml"></link><updated>2026-04-05T16:07:07.417Z</updated><entry><id>vladimirvanalytics:analytics_skills</id><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics/analytics_skills?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><title>Какими навыками должен обладать аналитик данных?</title><published>2023-09-25T14:47:51.166Z</published><updated>2023-09-26T22:15:07.584Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/9d/b2/9db2464a-ca92-4ff4-8189-b43c9fd50850.png"></media:thumbnail><category term="parser" label="parser"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/7b/6c/7b6c4046-e3ac-4334-bee0-3449e4782a32.png&quot;&gt;Задался вопросом какими навыками должен обладать аналитик данных и чтобы не рыть весь интернет, решил провести свое мини исследование.</summary><content type="html">
  &lt;p id=&quot;ZEa9&quot;&gt;Задался вопросом, какими навыками должен обладать аналитик данных, и чтобы не рыть весь интернет, решил провести своё мини-исследование.&lt;/p&gt;
  &lt;p id=&quot;aTLE&quot;&gt;На сегодняшний день, 25.09.2023, на hh.ru 607 вакансий по запросу &amp;quot;аналитик данных&amp;quot; и 292 по запросу &amp;quot;Data analyst&amp;quot;. Соберу описание всех вакансий и построю облако тегов.&lt;/p&gt;
  &lt;figure id=&quot;wBXm&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3f/3c/3f3c3fbb-2022-4f2f-afc7-337607089f64.png&quot; width=&quot;471.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;aI1U&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/33/29/33299b69-f611-4188-bfcb-fe9f474307e3.png&quot; width=&quot;469.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;vqlZ&quot;&gt;Поехали&lt;/h2&gt;
  &lt;p id=&quot;3Obp&quot;&gt;Первое облако &lt;/p&gt;
  &lt;figure id=&quot;oZfE&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/48/db/48dba754-4643-4a4f-989c-c0da52a6f61c.png&quot; width=&quot;877&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;htWM&quot;&gt;Из этого облака не видно, какие навыки необходимы — алгоритм просто показал наиболее употребляемые слова. Добавляю нерелевантные фразы в список минус-слов (например, что-то из интернет-маркетинга).&lt;/p&gt;
  &lt;h2 id=&quot;CaEI&quot;&gt;Второй раунд&lt;/h2&gt;
  &lt;p id=&quot;jmEY&quot;&gt;Добавил список минус слов. &lt;/p&gt;
  &lt;figure id=&quot;hNAr&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/60/25/60255bda-3d05-4883-8d45-77975943baa6.png&quot; width=&quot;821&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;kHm3&quot;&gt;В этом варианте уже можно рассмотреть некоторые теги, однако слова &amp;quot;данные&amp;quot;, &amp;quot;анализ&amp;quot; мешают. Добавлю их в список.&lt;/p&gt;
  &lt;figure id=&quot;0Di2&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/ed/4b/ed4bf524-97d9-413b-ba75-bc0b5571f401.png&quot; width=&quot;839&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;7DJK&quot;&gt;Уже лучше, но всё равно много &amp;quot;шума&amp;quot;.&lt;/p&gt;
  &lt;h2 id=&quot;oEZk&quot;&gt;Третий вариант&lt;/h2&gt;
  &lt;figure id=&quot;3CwQ&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/3b/80/3b806121-2c2c-4007-b6ec-4f9784ebc9de.png&quot; width=&quot;819&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;TuSH&quot;&gt;Могу предположить, что вы &lt;strong&gt;&lt;u&gt;&lt;em&gt;должны уметь разбираться в бизнес-процессах&lt;/em&gt;&lt;/u&gt;&lt;/strong&gt;. Добавлю &amp;quot;бизнес&amp;quot;, &amp;quot;процесс&amp;quot;, &amp;quot;работа&amp;quot;, &amp;quot;рост&amp;quot;, &amp;quot;информация&amp;quot;, &amp;quot;современный&amp;quot; в список минус-слов.&lt;/p&gt;
  &lt;figure id=&quot;D1Py&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/07/56/0756c188-eb22-4017-8adc-c444b1fe93f2.png&quot; width=&quot;828&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;IqII&quot;&gt;Здесь уже можно рассмотреть SQL, Excel, Python, визуализацию. А также выделяются &amp;quot;отчёт&amp;quot;, &amp;quot;построение&amp;quot;.&lt;/p&gt;
  &lt;p id=&quot;pUPD&quot;&gt;Делаем вывод: &lt;strong&gt;&lt;em&gt;&lt;u&gt;умение построить и визуализировать отчёт, сбор и обработка данных. &lt;/u&gt;&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;
  &lt;p id=&quot;LY2i&quot;&gt;Разобрались с &amp;quot;умением&amp;quot; - добавлю его в список минус слов.&lt;/p&gt;
  &lt;h2 id=&quot;sAjr&quot;&gt;Окончательный вариант&lt;/h2&gt;
  &lt;p id=&quot;tZ9b&quot;&gt;Максимально окончательный вариант. Добавил больше 300 минус-слов, со словоформами и вот итог:&lt;/p&gt;
  &lt;figure id=&quot;4oZi&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6c/23/6c235ca5-e611-4277-b33e-675dfcfb2d97.png&quot; width=&quot;821&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;mqgj&quot;&gt;&lt;em&gt;&lt;strong&gt;В любом случае придется работать как бы намёк!&lt;/strong&gt;&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;8PnP&quot;&gt;Делаем вывод, для аналитика данных, основные навыки:&lt;/p&gt;
  &lt;ul id=&quot;E4Nu&quot;&gt;
    &lt;li id=&quot;4HI3&quot;&gt;Умение работать)&lt;/li&gt;
    &lt;li id=&quot;mBJD&quot;&gt;Построение различный моделей&lt;/li&gt;
    &lt;li id=&quot;YRGl&quot;&gt;Визуализация отчетов&lt;/li&gt;
    &lt;li id=&quot;EK38&quot;&gt;Умение разбираться в бизнес процессах&lt;/li&gt;
    &lt;li id=&quot;rtlB&quot;&gt;Умеете sql, python, excel&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;LcAv&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;IX1p&quot;&gt;Финал&lt;/h2&gt;
  &lt;p id=&quot;jKVN&quot;&gt;После двух дней и 3000 минус-слов, получилось добраться до технологий&lt;/p&gt;
  &lt;figure id=&quot;uEpm&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img2.teletype.in/files/91/dc/91dc78bc-9e00-4bbb-936d-4f248560d178.png&quot; width=&quot;815&quot; /&gt;
  &lt;/figure&gt;

</content></entry><entry><id>vladimirvanalytics:cars_predict</id><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics/cars_predict?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><title>Предсказание цены автомобиля с помощью методов машинного обучения</title><published>2023-09-23T22:14:13.174Z</published><updated>2023-09-24T20:57:37.573Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/03/af/03af0697-6f26-4db2-bc36-ec7bf682228e.png"></media:thumbnail><category term="machine-learning" label="machine learning"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/0a/85/0a85d267-cf69-4fd2-b3b1-775c6c133bed.png&quot;&gt;В прошлом посте провели разведочный анализ данных по автомобилям собранным с сайта.</summary><content type="html">
  &lt;p id=&quot;Q6N7&quot;&gt;В прошлом &lt;a href=&quot;https://teletype.in/@vladimirvanalytics/pandas_eda_analysis&quot; target=&quot;_blank&quot;&gt;посте&lt;/a&gt; провел разведочный анализ данных по автомобилям собранным с сайта. &lt;/p&gt;
  &lt;p id=&quot;jXeG&quot;&gt;В этом посте применим методы машинного обучения чтобы попытаться предсказать цену автомобиля.&lt;/p&gt;
  &lt;p id=&quot;lI2v&quot;&gt;Вот несколько алгоритмов, которые могут подойти для этой задачи:&lt;/p&gt;
  &lt;ol id=&quot;MNlc&quot;&gt;
    &lt;li id=&quot;bWFG&quot;&gt;&lt;strong&gt;Линейная регрессия (Linear Regression)&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;vZhq&quot;&gt;
      &lt;li id=&quot;wzOK&quot;&gt;Простой и интерпретируемый метод.&lt;/li&gt;
      &lt;li id=&quot;3Fj2&quot;&gt;Хорошо работает, если существует линейная зависимость между признаками и целевой переменной.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;4jQg&quot;&gt;&lt;strong&gt;Решающие деревья (Decision Trees) и Случайный лес (Random Forest)&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;Jfgm&quot;&gt;
      &lt;li id=&quot;PFDV&quot;&gt;Могут улавливать нелинейные зависимости.&lt;/li&gt;
      &lt;li id=&quot;QRxB&quot;&gt;Random Forest обычно предоставляет более точные прогнозы, чем отдельное решающее дерево, за счет усреднения прогнозов множества деревьев.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;eUD1&quot;&gt;&lt;strong&gt;Градиентный бустинг (Gradient Boosting)&lt;/strong&gt;, например, XGBoost или LightGBM:&lt;/li&gt;
    &lt;ul id=&quot;8IjS&quot;&gt;
      &lt;li id=&quot;Jtws&quot;&gt;Эффективные алгоритмы, которые часто показывают высокую производительность в задачах регрессии.&lt;/li&gt;
      &lt;li id=&quot;JN6z&quot;&gt;Они строят ансамбль деревьев последовательно, каждое следующее дерево пытается исправить ошибки предыдущих.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;vsUC&quot;&gt;&lt;strong&gt;Нейронные сети (Neural Networks)&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;begf&quot;&gt;
      &lt;li id=&quot;Qgi4&quot;&gt;Могут быть полезными, если у вас большое количество данных.&lt;/li&gt;
      &lt;li id=&quot;gnUA&quot;&gt;Способны улавливать сложные нелинейные зависимости.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;CXgd&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;Iaz5&quot;&gt;Линейная регрессия&lt;/h3&gt;
  &lt;p id=&quot;BTUY&quot;&gt;Линейная регрессия предполагает, что мы хотим прогнозировать одну переменную на основе других переменных. &lt;/p&gt;
  &lt;p id=&quot;0ArT&quot;&gt;&lt;/p&gt;
  &lt;pre id=&quot;aDw1&quot; data-lang=&quot;python&quot;&gt;# Разделение данных на обучающие и тестовые 
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)&lt;/pre&gt;
  &lt;pre id=&quot;84Wh&quot; data-lang=&quot;python&quot;&gt;# Создание и обучение модели 
LR = LinearRegression() 
LR.fit(X_train, y_train)&lt;/pre&gt;
  &lt;pre id=&quot;3iGP&quot; data-lang=&quot;python&quot;&gt;# Прогнозирование 
y_pred = LR.predict(X_test)
&lt;/pre&gt;
  &lt;pre id=&quot;DpTy&quot; data-lang=&quot;python&quot;&gt;# Оценка модели 
mse = mean_squared_error(y_test, y_pred) 
rmse = mean_squared_error(y_test, y_pred, squared=False) 
mae = mean_absolute_error(y_test, y_pred) 
r2 = r2_score(y_test, y_pred) 
adj_r2 = 1 - (1-r2)*(len(y_test)-1)/(len(y_test)-X_test.shape[1]-1) 
print(f&amp;#x27;Mean Squared Error: {mse}&amp;#x27;) 
print(f&amp;#x27;Root Mean Squared Error: {rmse}&amp;#x27;) 
print(f&amp;#x27;Mean Absolute Error: {mae}&amp;#x27;) 
print(f&amp;#x27;R^2: {r2}&amp;#x27;) 
print(f&amp;#x27;Adjusted R^2: {adj_r2}&amp;#x27;)
Mean Squared Error: 16902445328.964172 
Root Mean Squared Error: 130009.40477120943 
Mean Absolute Error: 102777.23299243717 
R^2: 0.3387269809586828 Adjusted 
R^2: 0.3318098991695476&lt;/pre&gt;
  &lt;p id=&quot;Vkvx&quot;&gt;интерпретируем метрики:&lt;/p&gt;
  &lt;ol id=&quot;IxF9&quot;&gt;
    &lt;li id=&quot;LDPS&quot;&gt;&lt;strong&gt;Mean Squared Error (MSE): 16,902,445,328.96&lt;/strong&gt;&lt;br /&gt;MSE является мерой качества, где меньшее значение MSE указывает на лучшее качество. Это значение довольно высокое, что может указывать на наличие больших ошибок между фактическими и прогнозируемыми значениями.&lt;/li&gt;
    &lt;li id=&quot;LtwK&quot;&gt;&lt;strong&gt;Root Mean Squared Error (RMSE): 130,009.40&lt;/strong&gt;&lt;br /&gt;RMSE интерпретируется в тех же единицах измерения, что и исходные данные (в данном случае, цена). Модель ошибается в среднем на 130,009.40  рублей при прогнозировании цены.&lt;/li&gt;
    &lt;li id=&quot;4Mp2&quot;&gt;&lt;strong&gt;Mean Absolute Error (MAE): 102,777.23&lt;/strong&gt;&lt;br /&gt;MAE представляет собой среднюю абсолютную ошибку между прогнозируемыми и фактическими значениями. Это говорит о том, что модель в среднем ошибается на 102,777.23 единиц.&lt;/li&gt;
    &lt;li id=&quot;IOCr&quot;&gt;&lt;strong&gt;R^2: 0.3387&lt;/strong&gt;&lt;br /&gt;R^2 измеряет долю дисперсии зависимой переменной, объясненную моделью. Значение 0.3387 говорит о том, модель объясняет только 33.87% дисперсии в данных. Это довольно низкое значение, что указывает на то, что модель может быть не очень хорошо подобрана или что может быть много нерассмотренных или нерелевантных признаков.&lt;/li&gt;
    &lt;li id=&quot;S8Wx&quot;&gt;&lt;strong&gt;Adjusted R^2: 0.3318&lt;/strong&gt;&lt;br /&gt;Это корректировка R^2, учитывающая количество признаков в модели. Поскольку оно близко к обычному R^2&lt;/li&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;2f5S&quot;&gt;В целом, на основе представленных метрик, модель не идеальна и может потребовать доработки. Это может включать добавление новых признаков, преобразование существующих признаков, проверку на наличие выбросов в данных или использование другой модели для прогнозирования.&lt;/p&gt;
  &lt;figure id=&quot;i43p&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/0a/85/0a85d267-cf69-4fd2-b3b1-775c6c133bed.png&quot; width=&quot;387&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;JuPT&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;8hzg&quot;&gt;Настройка модели&lt;/h3&gt;
  &lt;p id=&quot;cO4l&quot;&gt;Проверяем на наличием выбросов. &lt;/p&gt;
  &lt;figure id=&quot;xquG&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7c/0f/7c0fc578-46f4-4ee0-8b24-d84365c8cd34.png&quot; width=&quot;939&quot; /&gt;
    &lt;figcaption&gt;Красным выделены значения которые считаются выбросами&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;pre id=&quot;HSQ5&quot; data-lang=&quot;python&quot;&gt;#Есть выбросы их надо удалить
for column in [&amp;#x27;price&amp;#x27;, &amp;#x27;Year&amp;#x27;,&amp;#x27;Mileage&amp;#x27;,&amp;#x27;Power&amp;#x27;]:
  # если столбец числовой  
  Q1 = data[column].quantile(0.25)  
  Q3 = data[column].quantile(0.75)  IQR = Q3 - Q1
  # Границы выбросов  
  lower_bound = Q1 - 1.5 * IQR  
  upper_bound = Q3 + 1.5 * IQR
  # Отфильтровать выбросы  
  data = data[(data[column] &amp;gt;= lower_bound) &amp;amp; (data[column] &amp;lt;= upper_bound)]&lt;/pre&gt;
  &lt;p id=&quot;K6jZ&quot;&gt;&lt;/p&gt;
  &lt;figure id=&quot;loY3&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7e/9d/7e9d1c8a-450a-4f6d-8392-c23a4a99cbea.png&quot; width=&quot;941&quot; /&gt;
  &lt;/figure&gt;
  &lt;figure id=&quot;KkkR&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/61/37/61370561-86c4-4290-bfa5-2a71ebf99722.png&quot; width=&quot;393&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;HB52&quot;&gt;Удаление выбросов не помогло.&lt;/p&gt;
  &lt;p id=&quot;6bNP&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;KsGb&quot;&gt;Полный код есть на &lt;a href=&quot;https://github.com/vladbegin/pandas_eda_analysis/blob/main/_avito_car_analyze_ipynb_.ipynb&quot; target=&quot;_blank&quot;&gt;github&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>vladimirvanalytics:t-kavFplHSf</id><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics/t-kavFplHSf?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><title>Продвинутые возможности SQL: Погружение в конструкцию WITH</title><published>2023-09-23T19:55:16.362Z</published><updated>2023-09-23T19:55:16.362Z</updated><summary type="html">Многие специалисты по базам данных начинают свой путь с изучения основ SQL. Они быстро осваивают базовые запросы, такие как SELECT, INSERT, UPDATE и DELETE. Однако после освоения этих базовых навыков многие останавливаются, полагая, что это достаточно для большинства задач. На самом деле, SQL предлагает гораздо более мощные инструменты, которые могут существенно упростить и оптимизировать вашу работу с данными. Одним из таких инструментов является конструкция WITH, также известная как Common Table Expressions (CTE).</summary><content type="html">
  &lt;p id=&quot;YvDY&quot;&gt;Многие специалисты по базам данных начинают свой путь с изучения основ SQL. Они быстро осваивают базовые запросы, такие как &lt;code&gt;SELECT&lt;/code&gt;, &lt;code&gt;INSERT&lt;/code&gt;, &lt;code&gt;UPDATE&lt;/code&gt; и &lt;code&gt;DELETE&lt;/code&gt;. Однако после освоения этих базовых навыков многие останавливаются, полагая, что это достаточно для большинства задач. На самом деле, SQL предлагает гораздо более мощные инструменты, которые могут существенно упростить и оптимизировать вашу работу с данными. Одним из таких инструментов является конструкция &lt;code&gt;WITH&lt;/code&gt;, также известная как Common Table Expressions (CTE).&lt;/p&gt;
  &lt;h3 id=&quot;0Gz7&quot;&gt;Что такое CTE (Common Table Expressions)?&lt;/h3&gt;
  &lt;p id=&quot;7yyx&quot;&gt;CTE представляет собой временный результат запроса, который можно использовать в последующем запросе. Это похоже на создание временной таблицы, но CTE существует только во время выполнения запроса.&lt;/p&gt;
  &lt;h3 id=&quot;qN3S&quot;&gt;Преимущества использования CTE:&lt;/h3&gt;
  &lt;p id=&quot;h5Pf&quot;&gt;Допустим у нас есть таблица &lt;code&gt;org_structure&lt;/code&gt;, которая представляет собой иерархическую структуру организации. Нам нужно получить полный путь иерархии для каждого сотрудника.&lt;/p&gt;
  &lt;pre id=&quot;9CgU&quot; data-lang=&quot;sql&quot;&gt;WITH Hierarchy AS (
    -- Базовый случай: верхний уровень иерархии (например, компания)
    SELECT ID, Name, ParentID, 
           CAST(Name AS VARCHAR(255)) AS Path
    FROM org_structure
    WHERE ParentID IS NULL

    UNION ALL

    -- Рекурсивный случай: добавляем каждый следующий уровень иерархии
    SELECT o.ID, o.Name, o.ParentID,
           CAST(h.Path + &amp;#x27; -&amp;gt; &amp;#x27; + o.Name AS VARCHAR(255))
    FROM org_structure o
    JOIN Hierarchy h ON o.ParentID = h.ID
)

SELECT Path AS Hierarchy
FROM Hierarchy
WHERE Name = &amp;#x27;Сотрудник&amp;#x27;
ORDER BY Path;&lt;/pre&gt;
  &lt;p id=&quot;7cO0&quot;&gt;Иерархические структуры данных часто встречаются в реальной жизни, особенно в организационных структурах, деревьях категорий и так далее. Также часто такие задания дают на собеседованиях. &lt;/p&gt;

</content></entry><entry><id>vladimirvanalytics:pandas_eda_analysis</id><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics/pandas_eda_analysis?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><title>Разведочный анализ данных с использованием библиотеки Pandas</title><published>2023-09-23T07:21:35.069Z</published><updated>2023-09-24T20:58:38.712Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img4.teletype.in/files/39/8e/398ef1c1-666d-4113-ac41-bd9f24ecb2c0.png"></media:thumbnail><category term="pandas" label="Pandas"></category><summary type="html">&lt;img src=&quot;https://img1.teletype.in/files/42/20/4220c2ca-5a50-45b2-a6b6-edfdc5107ce5.png&quot;&gt;В прошлой статье собрал данные с сайта о продаже автомобилей, и теперь хочу провести первичный анализ этих данных.</summary><content type="html">
  &lt;p id=&quot;cSGO&quot;&gt;В прошлой&lt;a href=&quot;https://teletype.in/@vladimirvanalytics/parsing_avito&quot; target=&quot;_blank&quot;&gt; статье &lt;/a&gt;собрал данные с сайта о продаже автомобилей, и теперь хочу провести первичный анализ этих данных.&lt;/p&gt;
  &lt;p id=&quot;toSN&quot;&gt;&lt;/p&gt;
  &lt;pre id=&quot;XMSu&quot; data-lang=&quot;python&quot;&gt;import pandas as pd

# Загружаем данные из CSV
data = pd.read_csv(&amp;quot;path_to_file.csv&amp;quot;)&lt;/pre&gt;
  &lt;p id=&quot;za2F&quot;&gt;&lt;/p&gt;
  &lt;h4 id=&quot;bDLg&quot;&gt;2. Осмотр данных&lt;/h4&gt;
  &lt;pre id=&quot;cNvk&quot; data-lang=&quot;python&quot;&gt;# Первые 5 записей
print(data.head())

# Основная информация о данных
print(data.info())

# Описательная статистика
print(data.desc&lt;/pre&gt;
  &lt;h4 id=&quot;ybvh&quot;&gt;3. Проверка пропущенных значений&lt;/h4&gt;
  &lt;pre id=&quot;CNyK&quot; data-lang=&quot;python&quot;&gt;# Считаем количество пропущенных значений для каждой колонки
print(data.isnull().sum())&lt;/pre&gt;
  &lt;h4 id=&quot;5b2Z&quot;&gt;4. Визуализация данных&lt;/h4&gt;
  &lt;pre id=&quot;6VwX&quot; data-lang=&quot;python&quot;&gt;import matplotlib.pyplot as plt
import seaborn as sns
f# График средней цены автомобилей по годам выпуска
avg_price_per_year.plot(kind=&amp;#x27;bar&amp;#x27;)
plt.title(&amp;quot;Средняя цена автомобилей по годам&amp;quot;)
plt.ylabel(&amp;quot;Средняя цена&amp;quot;)
plt.xlabel(&amp;quot;Год выпуска&amp;quot;)
plt.show()&lt;/pre&gt;
  &lt;figure id=&quot;hTmh&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/60/eb/60ebc464-58a5-41d3-a1e8-7dcc66b0f39b.png&quot; width=&quot;567&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;OidP&quot;&gt;Ящик с усами. Ищу выбросы&lt;/h3&gt;
  &lt;pre id=&quot;4S7S&quot; data-lang=&quot;python&quot;&gt;data.plot(kind=&amp;#x27;box&amp;#x27;, subplots=True, layout=(4,4), sharex=False, sharey=False, figsize=(15,18))
plt.show()&lt;/pre&gt;
  &lt;figure id=&quot;QeQD&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/04/e9/04e92c26-da44-4f47-94e6-295b1395ac88.png&quot; width=&quot;628&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;XZSd&quot;&gt;Scatter plot&lt;/h3&gt;
  &lt;pre id=&quot;6yvJ&quot; data-lang=&quot;python&quot;&gt;f plt.figure(figsize=(15, 10))
sns.stripplot(data=data, x=&amp;quot;Year&amp;quot;, y=&amp;quot;price&amp;quot;)
plt.axhline(y=data[&amp;#x27;price&amp;#x27;].quantile(0.25), color=&amp;#x27;green&amp;#x27;, label=&amp;#x27;Цена ниже рынка&amp;#x27;)
plt.axhline(y=data[&amp;#x27;price&amp;#x27;].quantile(0.5), color=&amp;#x27;blue&amp;#x27;, label=&amp;#x27;средняя цена по рынку&amp;#x27;)
plt.axhline(y=data[&amp;#x27;price&amp;#x27;].quantile(0.75),color=&amp;#x27;red&amp;#x27;, label=&amp;#x27;цена выше рынка&amp;#x27;)
plt.axvline(x=&amp;#x27;2013&amp;#x27;, label=&amp;#x27;Медианный год&amp;#x27;)
plt.axvline(x=&amp;#x27;2011&amp;#x27;, label=&amp;#x27;25% самых старых автомобилей&amp;#x27; )
plt.axvline(x=&amp;#x27;2016&amp;#x27;,label=&amp;#x27;25% самых молодых автомобилей&amp;#x27;)
plt.legend(loc=&amp;quot;upper right&amp;quot;)
plt.show()&lt;/pre&gt;
  &lt;figure id=&quot;5ThY&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/e3/9f/e39ffac6-babb-493c-b033-f809227dd468.png&quot; width=&quot;616.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;vmrg&quot;&gt;Эти базовые операции помогут быстро оценить собранные данные, увидеть основные тенденции и определить направления для дальнейшего анализа.&lt;/p&gt;
  &lt;p id=&quot;6CLs&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;WZqq&quot;&gt;C полным кодом можно знакомиться на &lt;a href=&quot;https://github.com/vladbegin/pandas_eda_analysis/blob/main/_avito_car_analyze_ipynb_.ipynb&quot; target=&quot;_blank&quot;&gt;github&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>vladimirvanalytics:parsing_avito</id><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics/parsing_avito?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><title>Парсинг данных с avito.ru: Введение и Первые шаги</title><published>2023-09-23T06:54:55.487Z</published><updated>2023-09-24T21:00:02.204Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img1.teletype.in/files/cc/6e/cc6e2229-6113-49c6-849d-609f4cf1d1e2.png"></media:thumbnail><category term="scraping" label="scraping"></category><summary type="html">&lt;img src=&quot;https://img3.teletype.in/files/6e/94/6e945f1e-9a4b-404e-a0cc-52c8a1b8cdd5.gif&quot;&gt;Avito.ru - один из крупнейших рекламных сайтов в России, и извлечение информации с него может быть полезным для многих задач: от изучения рынка до анализа конкурентов.</summary><content type="html">
  &lt;p id=&quot;WAoS&quot;&gt;Avito.ru - один из крупнейших рекламных сайтов в России, и извлечение информации с него может быть полезным для многих задач: от изучения рынка до анализа конкурентов.&lt;/p&gt;
  &lt;p id=&quot;e1kv&quot;&gt;&lt;strong&gt;Основные понятия&lt;/strong&gt;&lt;/p&gt;
  &lt;ul id=&quot;7iur&quot;&gt;
    &lt;li id=&quot;EaJl&quot;&gt;&lt;strong&gt;Selenium&lt;/strong&gt; - инструмент для автоматизации браузерных действий, часто используется для тестирования веб-приложений или парсинга данных.&lt;/li&gt;
    &lt;li id=&quot;Hxah&quot;&gt;&lt;strong&gt;Python&lt;/strong&gt; - высокоуровневый язык программирования, который из-за своей универсальности и доступности стал стандартом в анализе данных и веб-парсинге.&lt;/li&gt;
    &lt;li id=&quot;wSCR&quot;&gt;&lt;strong&gt;Базы данных&lt;/strong&gt; - это структурированные наборы данных, которые могут легко быть доступны, управляемы и обновляемы.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;C5fW&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;HeZ3&quot;&gt;&lt;strong&gt;Подготовка к работе&lt;/strong&gt;&lt;br /&gt;Прежде всего, вам потребуется установить необходимое программное обеспечение:&lt;/p&gt;
  &lt;ul id=&quot;y9Xj&quot;&gt;
    &lt;li id=&quot;f8xq&quot;&gt;Убедитесь, что у вас установлен Python. Если нет, его можно скачать &lt;a href=&quot;https://www.python.org/downloads/&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;.&lt;/li&gt;
    &lt;li id=&quot;7UcI&quot;&gt;Установите библиотеку Selenium. Это можно сделать с помощью pip:&lt;/li&gt;
  &lt;/ul&gt;
  &lt;pre id=&quot;31mQ&quot; data-lang=&quot;python&quot;&gt;pip install selenium&lt;/pre&gt;
  &lt;p id=&quot;6GlI&quot;&gt;Также рекомендуется установить браузерный драйвер для Selenium, например, для Chrome - chromedriver.&lt;/p&gt;
  &lt;figure id=&quot;EwJ5&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/6e/94/6e945f1e-9a4b-404e-a0cc-52c8a1b8cdd5.gif&quot; width=&quot;607.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;iQkA&quot;&gt;&lt;strong&gt;Пример кода&lt;/strong&gt;&lt;br /&gt;Вот простой пример того, как можно использовать Selenium для открытия браузера и перехода на avito.ru:&lt;/p&gt;
  &lt;pre id=&quot;x2Dt&quot; data-lang=&quot;python&quot;&gt;from selenium import webdriver

driver = webdriver.Chrome(executable_path=&amp;#x27;path_to_chromedriver&amp;#x27;)
driver.get(&amp;#x27;https://www.avito.ru&amp;#x27;)&lt;/pre&gt;
  &lt;figure id=&quot;n6VO&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7c/d1/7cd1cb1f-24ca-4b49-b3fd-d810a74d191b.gif&quot; width=&quot;607.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;mrny&quot;&gt;Поиск и взаимодействие с элементами сайта&lt;/h3&gt;
  &lt;p id=&quot;YDVp&quot;&gt;Мы начинаем с доступа к URL с объявлениями о продаже автомобилей. Затем извлекаем количество объявлений на сайте и определяем количество страниц, которые нужно будет обработать.&lt;/p&gt;
  &lt;p id=&quot;vqPk&quot;&gt;Далее, для каждой страницы, мы извлекаем ссылки на все объявления и сохраняем их в csv файл.&lt;/p&gt;
  &lt;p id=&quot;Pfat&quot;&gt;&lt;strong&gt;Ищу ссылки на все объявления на странице&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;J1KC&quot; data-lang=&quot;python&quot;&gt;ads_elements = driver.find_elements(by=By.XPATH, 
                                    value=&amp;#x27;//a[@data-marker=&amp;quot;item-title&amp;quot;]&amp;#x27;)&lt;/pre&gt;
  &lt;p id=&quot;45yZ&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;nb5L&quot;&gt;&lt;strong&gt;Ищу количество объявлений &lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;YJOn&quot; data-lang=&quot;python&quot;&gt;ads_count = driver.find_element(by=By.XPATH, value=&amp;quot;//span[@data-marker=&amp;#x27;page-title/count&amp;#x27;]&amp;quot;).text.replace(&amp;#x27; &amp;#x27;,&amp;#x27;&amp;#x27;)&lt;/pre&gt;
  &lt;ol id=&quot;zScQ&quot;&gt;
    &lt;li id=&quot;A2aj&quot;&gt;&lt;strong&gt;by=By.XPATH&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;QI18&quot;&gt;
      &lt;li id=&quot;SUOz&quot;&gt;Здесь используется метод поиска элемента по XPath. XPath (XML Path Language) — это язык, который позволяет определить местоположение элемента на веб-странице.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;7SE4&quot;&gt;&lt;strong&gt;value=&amp;quot;//span[@data-marker=&amp;#x27;page-title/count&amp;#x27;]&amp;quot;&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;tZ5P&quot;&gt;
      &lt;li id=&quot;zSHE&quot;&gt;Это конкретный XPath запрос. Он ищет элемент &lt;code&gt;span&lt;/code&gt; с атрибутом &lt;code&gt;data-marker&lt;/code&gt;, значение которого равно &amp;#x27;page-title/count&amp;#x27;.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;JIHz&quot;&gt;&lt;strong&gt;.text&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;USyU&quot;&gt;
      &lt;li id=&quot;2sC6&quot;&gt;Это свойство возвращает текстовое содержимое найденного элемента. То есть после того как вы нашли нужный элемент на странице.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;uswf&quot;&gt;&lt;strong&gt;.replace(&amp;#x27; &amp;#x27;,&amp;#x27;&amp;#x27;)&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;2tiT&quot;&gt;
      &lt;li id=&quot;wD9D&quot;&gt;Этот метод строки Python заменяет все пробелы в строке на пустую строку, то есть удаляет их. Это может быть полезно, если в текстовом содержимом элемента есть пробелы, которые вы хотите удалить.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;Umcn&quot;&gt;В итоге, переменная &lt;code&gt;ads_count&lt;/code&gt; будет содержать текстовое значение из элемента &lt;code&gt;span&lt;/code&gt; без пробелов. &lt;/p&gt;
  &lt;p id=&quot;BT8R&quot;&gt;Зная, что на каждой странице отображается 50 объявлений, рассчитываю общее количество страниц на сайте.&lt;/p&gt;
  &lt;pre id=&quot;4nbz&quot; data-lang=&quot;python&quot;&gt;if ads_count % 50 &amp;gt; 0:
    page_count = (ads_count // 50) + 1
else:
    page_count = ads_count // 50&lt;/pre&gt;
  &lt;ul id=&quot;HNni&quot;&gt;
    &lt;li id=&quot;pL2L&quot;&gt;&lt;code&gt;ads_count % 50&lt;/code&gt; определяет остаток от деления количества объявлений на 50.&lt;/li&gt;
    &lt;li id=&quot;CnWb&quot;&gt;Если остаток больше 0, это значит, что на последней странице будет менее 50 объявлений, поэтому нужно добавить еще одну страницу (&lt;code&gt;(ads_count // 50) + 1&lt;/code&gt;).&lt;/li&gt;
    &lt;li id=&quot;WyIJ&quot;&gt;В противном случае (если объявлений ровно 50 или кратно 50), общее количество страниц будет равно &lt;code&gt;ads_count // 50&lt;/code&gt;.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;zDWZ&quot;&gt;Теперь, зная &lt;code&gt;page_count&lt;/code&gt;, можно определить, сколько раз нужно будет переходить на следующую страницу, чтобы обработать все объявления на сайте.&lt;/p&gt;
  &lt;p id=&quot;SCde&quot;&gt;&lt;strong&gt;Пагинация по страницам&lt;/strong&gt;&lt;/p&gt;
  &lt;pre id=&quot;D4V5&quot; data-lang=&quot;python&quot;&gt;for page in range(1, page_count + 1):
    driver.get(f&amp;quot;{url}&amp;amp;p={page}&amp;quot;)    
    driver.implicitly_wait(3)    
    ads_elements = driver.find_elements(by=By.XPATH, 
                                        value=&amp;#x27;//a[@data-marker=&amp;quot;item-title&amp;quot;]&amp;#x27;) 
    
    for ad in ads_elements:
            link = ad.get_attribute(&amp;quot;href&amp;quot;)        
            #Записываем ссылку на страницу с объявлениями в csv
            with open(&amp;quot;info.csv&amp;quot;, mode=&amp;#x27;a&amp;#x27;, encoding=&amp;#x27;utf-8-sig&amp;#x27;) as csv_file:
             writer = csv.writer(csv_file)    
             # Записываем данные    
             writer.writerow((url))&lt;/pre&gt;
  &lt;p id=&quot;T5BP&quot;&gt;Этот код переходит на следующую страницу сайта. К базовому URL сайта, добавляется параметр &lt;code&gt;p&lt;/code&gt;, который указывает на номер страницы. Ищет на странице все объявления, и записывает их в файл csv&lt;/p&gt;
  &lt;figure id=&quot;eM1J&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/4b/55/4b5513fb-4358-446c-af9e-c019da1746f8.gif&quot; width=&quot;607.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;Jlua&quot;&gt;Отлично, теперь у нас есть все ссылки на объявления. &lt;/p&gt;
  &lt;h3 id=&quot;fhK1&quot;&gt;Собираем технические характеристики автомобиля&lt;/h3&gt;
  &lt;p id=&quot;qBrz&quot;&gt;&lt;/p&gt;
  &lt;pre id=&quot;qBrz&quot; data-lang=&quot;python&quot;&gt;data = []
def open_info_csv():
    # Инициализация драйвера
    with open(&amp;quot;info.csv&amp;quot;, mode=&amp;#x27;r&amp;#x27;, encoding=&amp;#x27;utf-8-sig&amp;#x27;) as csv_file:
        reader = csv.reader(csv_file)
        for row in reader:
        data.append(row)
# Вызываем функцию
open_info_csv()
&lt;/pre&gt;
  &lt;pre id=&quot;7o8D&quot; data-lang=&quot;python&quot;&gt;list_of_url = open_info_csv()
for row in list_of_url:
    driver.get(row)
    #ищу название объявления
    title = driver.find_element(By.XPATH, &amp;quot;//h1[@data-marker=&amp;#x27;item-view/title-info&amp;#x27;]&amp;quot;).text.split(&amp;#x27;,&amp;#x27;)[0].strip(&amp;#x27;&amp;quot;&amp;#x27;)
    #Цену
    price = driver.find_element(By.XPATH,&amp;#x27;//span[@data-marker=&amp;quot;item-view/item-price&amp;quot;]&amp;#x27;).get_attribute(&amp;#x27;content&amp;#x27;)
    #Тип продавца
    seller_type = driver.find_element(by=By.XPATH, value=&amp;#x27;//div[@data-marker=&amp;quot;seller-info/label&amp;quot;]&amp;#x27;).text
    #Адрес
    address = driver.find_element(by=By.XPATH, value=&amp;quot;//div[@itemprop=&amp;#x27;address&amp;#x27;]/span&amp;quot;).text
    
    #cохраняю в файл
    with open(&amp;quot;car_info.csv&amp;quot;, mode=&amp;#x27;a&amp;#x27;, encoding=&amp;#x27;utf-8-sig&amp;#x27;) as csv_file:
             writer = csv.writer(csv_file)    
             # Записываем данные    
             writer.writerow((title,price, seller_type,address))
    driver.close()
    driver.quit()&lt;/pre&gt;
  &lt;p id=&quot;FE2q&quot;&gt;&lt;/p&gt;
  &lt;figure id=&quot;g7RR&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/29/e8/29e8f5a4-a1cd-4d02-aa28-5a959773afdd.gif&quot; width=&quot;574&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;rBMi&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;jfkB&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;Gya6&quot;&gt;Полный код на код на &lt;a href=&quot;https://boosty.to/vladiview/donate&quot; target=&quot;_blank&quot;&gt;Boosty&lt;/a&gt;&lt;/p&gt;

</content></entry><entry><id>vladimirvanalytics:parsim_analiziruem_vibiraem</id><link rel="alternate" type="text/html" href="https://teletype.in/@vladimirvanalytics/parsim_analiziruem_vibiraem?utm_source=teletype&amp;utm_medium=feed_atom&amp;utm_campaign=vladimirvanalytics"></link><title>Парсим, анализируем, предсказываем: Выбираем автомобиль</title><published>2023-09-23T05:05:31.002Z</published><updated>2023-09-24T20:56:14.620Z</updated><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://img2.teletype.in/files/d8/a5/d8a51540-a881-430e-8d2d-7d91d4855287.png"></media:thumbnail><category term="machine-learning" label="machine learning"></category><summary type="html">&lt;img src=&quot;https://img4.teletype.in/files/7f/ee/7feef1fd-57d1-405e-be99-5851d71da0bd.png&quot;&gt;Родственники жены, рассказали что выбирают автомобиль и как это обычно бывает, на эту роль претендовали несколько конкурентов. Их требованиям отвечали сотни, а для некоторых моделей и тысячи, автомобилей.  Решил им помочь отобрать выгодные (цена которых относительно рынка занижена).</summary><content type="html">
  &lt;figure id=&quot;HBYl&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7f/ee/7feef1fd-57d1-405e-be99-5851d71da0bd.png&quot; width=&quot;512&quot; /&gt;
    &lt;figcaption&gt;сгенерировано нейросетью stable diffusion&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;h2 id=&quot;qIsx&quot;&gt;Предыстория&lt;/h2&gt;
  &lt;p id=&quot;f8sY&quot;&gt;Родственники жены, рассказали что выбирают автомобиль и как это обычно бывает, на эту роль претендовали несколько конкурентов. Их требованиям отвечали сотни, а для некоторых моделей и тысячи, автомобилей.  Решил им помочь отобрать выгодные (цена которых относительно рынка занижена). &lt;/p&gt;
  &lt;p id=&quot;HWNB&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;yyxX&quot;&gt;Сбор данных.&lt;/h2&gt;
  &lt;p id=&quot;tkA7&quot;&gt;Данные собирал с одного известного сайта объявлений. Меня интересовали следующие параметры при выборе автомобиля:&lt;/p&gt;
  &lt;ul id=&quot;NudN&quot;&gt;
    &lt;li id=&quot;KHx2&quot;&gt;Цена (price)&lt;/li&gt;
    &lt;li id=&quot;cFKI&quot;&gt;Год выпуска(year)&lt;/li&gt;
    &lt;li id=&quot;HCP8&quot;&gt;Пробег&lt;/li&gt;
    &lt;li id=&quot;2kJH&quot;&gt;Количество владельцев по ПТС&lt;/li&gt;
    &lt;li id=&quot;3OFN&quot;&gt;Мощность двигателя&lt;/li&gt;
    &lt;li id=&quot;iV6Z&quot;&gt;Тип коробки передач&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;2mIL&quot;&gt;Реализация.&lt;/h3&gt;
  &lt;p id=&quot;LNXj&quot;&gt;Написал код, используя Selenium, для автоматического сбора данных с сайта. Данные по автомобилям сохранялись в базу данных SQLite3. Код состоит из двух основных функций &lt;code&gt;parser, worker&lt;/code&gt;&lt;/p&gt;
  &lt;p id=&quot;8fvu&quot;&gt;&lt;strong&gt;Парсинг данных&lt;/strong&gt;:&lt;/p&gt;
  &lt;ul id=&quot;4EFd&quot;&gt;
    &lt;li id=&quot;zijb&quot;&gt;Функция &lt;code&gt;parser&lt;/code&gt; принимает URL в качестве аргумента и начинает процесс сбора данных.&lt;/li&gt;
    &lt;li id=&quot;Z2GH&quot;&gt;Открывается URL в браузере через драйвер Selenium.&lt;/li&gt;
    &lt;li id=&quot;znDm&quot;&gt;Браузер пытается найти и взаимодействовать с некоторыми элементами на странице.&lt;/li&gt;
    &lt;li id=&quot;OKR0&quot;&gt;Браузер определяет количество объявлений на странице и вычисляет, сколько всего страниц в пагинации.&lt;/li&gt;
    &lt;li id=&quot;05F3&quot;&gt;Затем проходится по каждой странице, извлекает ссылки на объявления и их идентификаторы, после чего добавляет их в базу данных&lt;/li&gt;
  &lt;/ul&gt;
  &lt;p id=&quot;WOjv&quot;&gt;&lt;/p&gt;
  &lt;figure id=&quot;qS3r&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img4.teletype.in/files/7c/d1/7cd1cb1f-24ca-4b49-b3fd-d810a74d191b.gif&quot; width=&quot;607.5&quot; /&gt;
  &lt;/figure&gt;
  &lt;h3 id=&quot;G3OW&quot;&gt;Функция &lt;code&gt; worker&lt;/code&gt;&lt;/h3&gt;
  &lt;ul id=&quot;g0iO&quot;&gt;
    &lt;li id=&quot;Y94D&quot;&gt;В бесконечном цикле пытается извлекать следующий URL для обработки из базы данных.После получения URL, обновляет его статус на «обрабатывается»&lt;/li&gt;
    &lt;li id=&quot;mSzk&quot;&gt;Открывает URL в драйвере Selenium.Проверяет наличие определенных элементов на странице (например, если объявление было снято с публикации).&lt;/li&gt;
    &lt;li id=&quot;8YSK&quot;&gt;Если таких элементов нет, пытается сохранить данные с помощью функции &lt;code&gt;save_test_data&lt;/code&gt;.&lt;/li&gt;
    &lt;li id=&quot;qDWr&quot;&gt;Если возникнет исключение в любой части процесса, статус URL обновляется на «ожидание ошибки», драйвер закрывается и прерывает текущую итерацию.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;figure id=&quot;ty9F&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/29/e8/29e8f5a4-a1cd-4d02-aa28-5a959773afdd.gif&quot; width=&quot;574&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;KzmB&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;BS85&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;GhXA&quot;&gt;Анализ полученных данных.&lt;/h2&gt;
  &lt;pre id=&quot;FFVH&quot; data-lang=&quot;python&quot;&gt;import pandas as pd
import numpy as np&lt;/pre&gt;
  &lt;p id=&quot;ir8r&quot;&gt;&lt;em&gt;Код знакомый многим кто увлекается данными&lt;/em&gt;&lt;/p&gt;
  &lt;p id=&quot;ghEj&quot;&gt;Подробно описано в предыдущем&lt;a href=&quot;https://teletype.in/@vladimirvanalytics/pandas_eda_analysis&quot; target=&quot;_blank&quot;&gt; посте&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;MJej&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;mBiH&quot;&gt;Первая попытка. Процентили, Квартили.&lt;/h3&gt;
  &lt;p id=&quot;xdDB&quot;&gt;Первая попытка выбрать оптимальный автомобиль. Оптимальны автомобиль - у которого год, будет выше чем у 75% автомобилей в выборке, цена будет ниже чем у 25% самых дорогих автомобилей.&lt;/p&gt;
  &lt;figure id=&quot;eGsn&quot; class=&quot;m_retina&quot;&gt;
    &lt;img src=&quot;https://img3.teletype.in/files/69/86/69866ebb-9bb2-4ee2-9c39-fa34a67f13d3.png&quot; width=&quot;500.5&quot; /&gt;
    &lt;figcaption&gt;График распределения автомобилей по цене и году. Точки это автомобили.&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;XNvA&quot;&gt;Зеленым цветом выделена область в которой находятся оптимальные автомобили. &lt;/p&gt;
  &lt;p id=&quot;Vszo&quot;&gt;Этот подход был отвергнут так как не учитывал другие параметры - пробег, количество владельцев по ПТС&lt;/p&gt;
  &lt;p id=&quot;e1LC&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;vpZw&quot;&gt;Вторая попытка. Скоринг.&lt;/h3&gt;
  &lt;p id=&quot;KtXV&quot;&gt;Следующая попытка расчет баллов для каждого автомобиля. Например если цена выше, то бал ниже, пробег выше цена ниже, год старше бал ниже. &lt;/p&gt;
  &lt;p id=&quot;oylg&quot;&gt;Такой подход был получше, но чего-то не хватало. &lt;/p&gt;
  &lt;p id=&quot;J6dk&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;b2Dm&quot;&gt;Третья попытка. Машинное обучение нейросети&lt;/h3&gt;
  &lt;figure id=&quot;G3GT&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/48/73/487377d0-e48e-4e83-9026-ca8f60ff4145.png&quot; width=&quot;512&quot; /&gt;
    &lt;figcaption&gt;изображение сгенерировано нейросетью Stable Diffusion&lt;/figcaption&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;rAB4&quot;&gt;&lt;strong&gt;Подготовка данных&lt;/strong&gt;:&lt;/p&gt;
  &lt;ul id=&quot;2C49&quot;&gt;
    &lt;li id=&quot;hlR8&quot;&gt;Использовал Python и библиотеку Pandas для обработки и анализа данных.&lt;/li&gt;
    &lt;li id=&quot;Z1ps&quot;&gt;Манипуляции с данными, такие как чистка, трансформация, поиск выбросов и масштабирование.&lt;/li&gt;
  &lt;/ul&gt;
  &lt;h3 id=&quot;BcQ4&quot;&gt;Прогноз&lt;/h3&gt;
  &lt;p id=&quot;kjgp&quot;&gt;Для предсказания справедливой цены автомобиля использовал нейронные сети, обучил различные модели машинного обучения, начиная с простой множественной регрессии и заканчивая сложными методами ансамблирования, такими как стекинг. Пробовал различные алгоритмы бустинга, включая XGBoost, AdaBoost, GBM и LightGBM. &lt;/p&gt;
  &lt;p id=&quot;7n51&quot;&gt;В целом, результаты говорят о том, что модель дает слабые прогнозы на новых данных. &lt;/p&gt;
  &lt;p id=&quot;HPuO&quot;&gt;И как я не пытался улучшить данные для модели, удалить выбросы, &amp;quot;поиграть&amp;quot; с настройками сети. Результат был плюс, минус такой же - 60000 - 80000 разница между фактической ценой и предсказанной. &lt;/p&gt;
  &lt;p id=&quot;Kfas&quot;&gt;Подробно об этом написано &lt;a href=&quot;https://teletype.in/@vladimirvanalytics/cars_predict&quot; target=&quot;_blank&quot;&gt;здесь&lt;/a&gt;&lt;/p&gt;
  &lt;p id=&quot;iO2h&quot;&gt;&lt;/p&gt;
  &lt;h3 id=&quot;LjiD&quot;&gt;Четвертая попытка. Возврат к скорингу.&lt;/h3&gt;
  &lt;p id=&quot;uFws&quot;&gt;&lt;/p&gt;
  &lt;p id=&quot;J2Gy&quot;&gt;Для определения оптимального автомобиля разработал систему скоринга. Эта система учитывает разницу в цене, пробеге и количестве владельцев автомобиля. Каждому критерию был присвоен вес, и на основе этой информации для каждого автомобиля был рассчитан общий балл. Автомобиль с наивысшим баллом считается наиболее оптимальным.&lt;/p&gt;
  &lt;ol id=&quot;bKIy&quot;&gt;
    &lt;li id=&quot;cj8h&quot;&gt;&lt;strong&gt;Определение весов для каждого критерия&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;QLZn&quot;&gt;
      &lt;li id=&quot;zqCN&quot;&gt;Например, разница в цене может иметь больший вес, чем разница в пробеге, так как цена может быть более важным фактором для покупателя.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;UOhX&quot;&gt;&lt;strong&gt;Вычисление баллов для каждого автомобиля&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;5CkP&quot;&gt;
      &lt;li id=&quot;4CzN&quot;&gt;&lt;code&gt;AveragePriceModelDiff&lt;/code&gt;: Положительная разница (если средняя цена модели выше, чем цена конкретного автомобиля) будет добавлять баллы, так как это может указывать на более выгодное предложение.&lt;/li&gt;
      &lt;li id=&quot;M0GI&quot;&gt;&lt;code&gt;average_mileage_model_year_diff&lt;/code&gt;: Отрицательная разница (если пробег автомобиля выше среднего по модели и году) будет убавлять баллы.&lt;/li&gt;
      &lt;li id=&quot;gAVy&quot;&gt;&lt;code&gt;average_pts_diff&lt;/code&gt;: количество владельцев автомобиля, меньшее значение &lt;code&gt;PTS&lt;/code&gt; будет предпочтительнее, так как автомобиль с меньшим количеством владельцев может быть в лучшем состоянии.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;08Ze&quot;&gt;&lt;strong&gt;Суммирование баллов для каждого автомобиля&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;1tYi&quot;&gt;
      &lt;li id=&quot;BXxo&quot;&gt;Веса из пункта 1 умножались на разницы каждого критерия на его вес, а затем складывал все вместе, чтобы получить общий балл для каждого автомобиля.&lt;/li&gt;
    &lt;/ul&gt;
    &lt;li id=&quot;L9Qz&quot;&gt;&lt;strong&gt;Выбор автомобиля с наивысшим баллом&lt;/strong&gt;:&lt;/li&gt;
    &lt;ul id=&quot;hAdl&quot;&gt;
      &lt;li id=&quot;gT8h&quot;&gt;Автомобиль с наивысшим баллом будет считаться наиболее оптимальным.&lt;/li&gt;
    &lt;/ul&gt;
  &lt;/ol&gt;
  &lt;p id=&quot;HXGq&quot;&gt;Такой подход оказался быстрым и эффективным. &lt;/p&gt;
  &lt;p id=&quot;Rx9K&quot;&gt;&lt;/p&gt;
  &lt;h2 id=&quot;lh6C&quot;&gt;Вишенка на торте&lt;/h2&gt;
  &lt;p id=&quot;Wfrv&quot;&gt;Ну и на последок, сделал группу в телеграм, где бот присылает ссылки на автомобиль с расчетом показателей.&lt;/p&gt;
  &lt;figure id=&quot;xKWs&quot; class=&quot;m_original&quot;&gt;
    &lt;img src=&quot;https://img1.teletype.in/files/48/a8/48a86875-14ec-4263-90a2-d953982570b5.png&quot; width=&quot;716&quot; /&gt;
  &lt;/figure&gt;
  &lt;p id=&quot;d3yw&quot;&gt;&lt;/p&gt;
  &lt;hr /&gt;
  &lt;p id=&quot;gdbj&quot;&gt;В заключении хочется отметить для меня это было  уникальным опытом, который стал для меня первым глубоким погружением в область данных и машинного обучения. Этот проект стал своеобразным кульминационным моментом, объединив в себе все мои навыки и знания: от программирования на Python и работы с библиотекой pandas до парсинга веб-сайтов и сохранения данных в базу данных SQLite3. Это был настоящий вызов и большое удовольствие одновременно!&lt;/p&gt;

</content></entry></feed>