Análise comparativa de mercados usados Carros alemães e franceses no segmento B e C

Olá Habr!

Neste post, eu queria compartilhar a experiência de usar várias ferramentas python para uma análise comparativa do mercado de carros usados ​​na Europa, usando o exemplo da Alemanha e da França.

imagem

Do ponto de vista da implementação, tudo será bastante baunilha. O zoológico das tecnologias utilizadas é um pouco redundante, porque era um fim em si - eu queria testá-lo.

Background. O pensamento de conduzir essa análise me visitou uma vez quando eu estava folheando um site de anúncios franceses. Eu claramente tinha a sensação de que o Citroën C3 era um carro extremamente pobre, que se deprecia em 20% ao ano, mas o Opel Corsa é quase imortal, por isso o preço não muda com a idade (ou vai subir tão bem Rolex). Foi uma observação engraçada, dado que os alemães consideravam Corsa um adulto como um sinal de um fiasco na implementação profissional. E até houve piadas sobre o fato de que em 10 anos qualquer carro se transforma em um Opel. Na ausência dos alemães ocidentais Trabant, o papel dos zaporozhets no folclore alemão foi desempenhado por essa marca em particular. O C3, tanto quanto eu sei, não está particularmente representado na Rússia, mas é útil saber que é o herdeiro espiritual do clássico 2CV da imagem de título, o lendário carro que perdeu a Internet por alguns anos (em produção antes de 1989) e ofereceu ao motorista uma incrível potência de nove cavalos.

Então, vamos ao que interessa. Para obter estatísticas, você precisa de uma fonte com uma amostra suficiente. Na Alemanha, este autoscout24.de na França é o melhor que eu já vi pelo número de anúncios - www.lacentrale.fr (a versão francesa do scout existe, mas é menos popular).

Selecionaremos de acordo com a classe B como a mais popular e na qual a questão inicial surgiu (com uma pequena entrada na classe C). Para coletar dados, escolheremos os modelos para os quais há dados nos últimos 10 anos e para os quais existem pelo menos 1000 anúncios nos dois sites. Caso contrário, a amostra será muito barulhenta.

Se você deseja obter uma datamining para uma pessoa saudável - o autoscout oferece uma API RESTful se você se registrar e receber uma chave.

Obviamente, eu não fiz isso e comecei a minerar um fumante - de frente através de um navegador sem cabeça.

A mineração de fumantes tinha a seguinte aparência - com base nos filtros desejados (que são descritos abaixo), formamos uma string de consulta, transferimos-a como um endereço para o navegador sem cabeçalho PhantomJS (desde que eu o instalei, ele foi suspenso por algum motivo).

Do não óbvio nesta fase - adicionei a expectativa de carregar um elemento com uma classe de característica, que continha dados sobre o número de opções para a solicitação correspondente.

with io.open("dump.html", "w", encoding="utf-8") as f: f.write(html) try: element = WebDriverWait(browser, 20).until( EC.presence_of_element_located((By.CLASS_NAME, "cl-filters-summary-counter")) ) # wait until element with summry statistics is present or drop after 20 sec 

O html gerado no navegador é alimentado no analisador BeautifulSoup e procuramos nele um elemento contendo a figura dos resultados encontrados.

 value = bsObj.findAll("span", {"class": "cl-filters-summary-counter"})[0].text value = value.replace(u'\xa0', u' ') # removes delimeter if results exceed 1000 

Como você pode imaginar, a solicitação gerada incluía o modelo, um pequeno preço e faixa etária, ou seja, havia muitas solicitações, com o número de solicitações acima de 500 que o servidor interrompeu a conexão. Se você deseja resolver o problema de maneira excelente, é melhor acessar esses serviços por meio de proxies que foram alterados ao longo do caminho (e se você tiver uma chave de API, não precisará). Em Habré, há um artigo inteligente sobre como trabalhar com um proxy. Resolvi o problema de baixa tecnologia - o preço segue uma lei linear com a idade, então calculei o escopo dessa linha e limitei os pedidos a apenas + .- 30-50% do preço linear e introduzi 10 segundos de pausa entre os pedidos. Isso foi o suficiente para não ser banido. A coleta de dados para um modelo levou cerca de meia hora para piscar silenciosamente no console.

Algumas palavras sobre os filtros. Para obter uma seleção informativa, apliquei os seguintes filtros:

  • Todos os carros vêm em configurações de 4-5 portas (Kors, Klio e alguns dos modelos apresentados têm opções mais baratas de 3 portas).
  • Todos os carros são ocupados com 4-5 assentos - esse é um recurso separado do anterior, porque o Clio, C3 e 308 têm uma versão Société (Entreprise) e existem muitos no mercado - são carros de serviço de todos os eletricistas e montadores, há uma caixa em vez do banco traseiro para lixo, e custam menos por alguns kiloeuvres ceteris paribus.
  • A potência do motor é limitada a 129 hp. Porque, mais adiante neste segmento, as versões cobradas começam e os preços não correspondem ao seu status modesto. Se você repetir o Achtung - uma autoscout no endereço usa energia, não em cavalos de potência, mas em quilowatts.

Motores e caixas de câmbio não são especializados, mas em 99% são mecânicos e, no caso da França, há muito diesel lá, simplesmente porque foi promovido lá 10 anos antes do dieselgate. E agora eles querem transplantar todo mundo com ele, do desgosto diante de uma inconstância moral do governo, os franceses, pela segunda semana, se entregam a duas adoradas diversões nacionais - uma greve e incêndio criminoso de carros.

Os dados são coletados, dispostos modelo por folha em arquivos do Excel (que dataaens sem excel, você o que! Obrigado, openpyxl - pela conveniência de alternar ). Para visualização, todos os dados em todos os modelos são resumidos em um arquivo CSV.

Para visualização, eu queria arquivar uma interface web simples. Em princípio, a versão atual não requer um back-end. Há poucos dados, o processamento é rudimentar, você pode despejar tudo com um JSON longo junto com os gráficos e processá-lo no lado do cliente. Mas eu queria testar o servidor com vista a usá-lo mais tarde para tarefas com cálculos não tão triviais. E como não sei usar JS, teria que me atormentar com o lado do cliente, e o servidor também pode ser montado em python, pois existem ferramentas.

Para implementar o servidor, fiquei atormentado entre o bokeh com o qual havia mexido antes e o pacote Plotly + Dash. Em várias tarefas anteriores, fiquei muito satisfeito com o bokeh, principalmente porque ele pode ser incorporado ao Jupyter Notebook (com o Jupyter Labs, não é tão simples) e pelo fato de ser muito fácil organizar componentes interativos dentro de notebooks sem iniciar o servidor bokeh (). Bokeh é a porta de entrada para o mundo do d3.js. para quem não sabe usar o JS.

Para esta tarefa, decidi usar o pacote Plotly + Dash (o último é a porta de entrada para o mundo React para aqueles que não sabem usar JS). A escolha é mais provável de tentar. Como você pode ver na comparação - a diferença não é fundamental

Prosseguimos com a implementação da interface.

Estamos puxando nosso CSV, empurrando-o sobre alguns quadros de dados.

Para estilizar adequadamente a página e usar o design responsivo, habilitamos o CSS local.

 app = dash.Dash(__name__, static_folder='assets') # resource folder app.scripts.config.serve_locally = True app.css.config.serve_locally = True 

Em seguida, criamos o layout mais simples usando uma tabela de duas colunas, 6 em 12 padrão para layouts adaptáveis.

 app.layout = html.Div([ # include custom local css to allow two-column responsive html.Link(href='/assets/twocolumns_dash.css', rel='stylesheet'), html.Div([ # row div html.Div([ # column div html.H3('Average'), dcc.Graph(id='market-app', ), html.H4('Select model'), dcc.Dropdown(id='model_pick', options=model_options, value=None, multi=True) ], className="six columns"), html.Div([ # column div html.H3('Distribution'), dcc.Graph(id='market-app2', ), html.H4('Select year'), dcc.Slider( id='year-slider', min=years.min(), max=years.max(), value=years.min(), step=None, marks={str(year): str(year) for year in years} ) ], className="six columns"), ], className="row") ]) 

Os controles são implementados de maneira muito despretensiosa, com os recursos - pode haver muitas entradas e apenas uma saída (por exemplo, o gráfico esquerdo aceita dados no menu suspenso e no controle deslizante do ano, mas apenas um elemento pode ser atualizado, esse é um recurso do Dash, que é necessário ignorar).

 @app.callback(Output('market-app2', 'figure'), [Input('model_pick', 'value'), Input('year-slider', 'value')]) def update_figure_dist(selected_models, year_picked): traces = [] for model in selected_models: traces.append(go.Bar( x=df_filtered.loc[model, year_picked, :].index.values.tolist(), y=df_filtered.loc[model, year_picked, :]['results'].values.tolist(), name=model )) return { 'data': traces, 'layout': go.Layout( xaxis={'title': 'price'}, yaxis={'title': 'offers'}, hovermode='closest', legend=dict(orientation="h", xanchor="center", y=1.2, x=0.5) ) } 

Interface pronta - http://eu-carmarket.herokuapp.com/

Para dados alemães, entre parênteses é (DE) para França (FR).

À esquerda, vemos a média dos preços para todo o período em cada ano. A seguir, todos os preços em euros, de acordo com as regras para publicação em sites - os preços incluem IVA. À direita está a distribuição de ofertas por preço no ano selecionado. A distribuição era barulhenta para muitos modelos; portanto, ao construí-la, ela é suavizada sobre os vizinhos mais próximos com um núcleo de 5 elementos (foi olhando para ela que decidi não usar modelos com menos de 1000 anúncios)

Então, o que vemos nos dados?

Respondendo a uma pergunta que motivou o estudo - não, o Citroen não se deprecia a uma velocidade terrível em comparação com o atemporal Corsa.

imagem

A forte diferença de preço em 2017 não é a forte depreciação primária da Citroens no primeiro ano. Este é realmente o aumento de preço com a transição para uma nova geração. Agora, em vez de se homologar com o antigo 2CV Citroen, eles são mais parecidos com o Mini, com mira na moda para o crossover - juventude elegante e moderna.

Se você escolher um modelo, a diferença nos mercados alemão e francês é chocante porque ele não existe, nem em valores nem na taxa de depreciação (embora um carro não destruído com mais de 2 anos de idade na França seja encontrado apenas se for armazenado em uma garagem trancada).

imagem

imagem

imagem

Se você adota o mercado, que é popular entre o pessoal de TI russo por mudar a Holanda, precisa pagar 20% pelo preço alemão.Embora não haja fronteiras alfandegárias entre os países da Europa, não funcionará apenas para transportar um carro comprado se ele não passar como coisas pessoais que se movem com ele. por você. Isso exige que você viva no país anterior por mais de seis meses. Caso contrário, todos os benefícios pretendidos serão removidos quando você tentar colocar o carro no registro.

Se você comparar os modelos em uma pilha grande, poderá ver várias observações interessantes. Após 10 anos, tudo converge para aproximadamente um ponto, embora a depreciação da Peugeot, Mazda ou Seat seja mais forte que a Volkswagen Polo, a Opel Meriva ou a Skoda Fabia. Então, sim, após 10 anos, qualquer carro se torna Opel, mas não o Corsa, apenas os favoritos como o C3 se tornam o Corsa.

imagem

A taxa de depreciação não depende significativamente do modelo. E do país. Pequenos desvios da uniformidade linear universal (por exemplo, Renault Megane
em 2016, o Ford Fiesta em 2017) é simplesmente uma mudança na geração do modelo.

imagem

imagem

Como a depreciação neste caso não é um conceito físico, isso não significa que os carros estarão na mesma condição. Em francês, haverá lados enrugados, escoriações, pára-choques lascados, espelhos envoltos em fita adesiva e um legado de milhares de quilômetros de distância com um jogo de damas. Mas os franceses estão convencidos de que o grau de depreciação é o mesmo dos alemães e pagam de acordo com suas crenças. Mas convencer os alemães a comprar usados um carro das mãos atenciosas dos motoristas e mecânicos franceses - eles mentirão?

Em relação aos preços em comparação com a Rússia. Há algum problema com o fato de muitos dos modelos descritos não serem vendidos na Rússia. Dos poucos recursos comuns para ambos os mercados, você pode encontrar o novo Polo no site da Volkswagen (embora na Rússia seja um sedan e na Europa um hatchback). Na Rússia, custa 8300 novos, na Alemanha é novo de 13500 e para 8300 será 2012 (fora da tabela da mencionada Holanda - 16200 novos). Uma boa comparação pode ser representada em todos os lugares Kia Rio: Rússia - 9000, Alemanha - 11950 (óbvio dumping contra o autopatriotismo alemão), França - 13700, Holanda - 19950 (Ja-ja, um lamas e meio para um Kirusha ao preço da Volkswagen Tiguan / Hyundai Tussan / Nissan X -trail: abraça, chora e lembra-se de pedalar).

Source: https://habr.com/ru/post/pt433448/


All Articles