[Pour les super débutants] Construction de l'environnement Python et grattage et apprentissage automatique et application pratique dont vous pouvez profiter en vous déplaçant avec copie [Trouvons une bonne propriété locative avec SUUMO! ]

introduction

Tout le monde, aimez-vous __ l'analyse des données __?

Ravi de vous rencontrer! Je m'appelle @ haraso_1130 et je suis mentor au DMM WEB CAMP.

Tout à coup, regardez l'image ci-dessous.

スクリーンショット 2019-12-15 18.13.43.png

5DK 80000 yens pour une propriété dans les 23 quartiers de Tokyo! ??

Si vous êtes dans la 23e salle, vous serez bien avec 80000 studios par mois ...

Cette propriété est la mienne ** Utilisation de "Python" ** Collectez des données en ** «grattant» ** Résultats de l'analyse des données avec ** "machine learning" ** C'est une propriété que j'ai pu découvrir.

Cet article est (essentiellement) ** un article pour analyser les données avec un simple copier-coller et vous faire aimer l'analyse de données **. En d'autres termes, le but est d'avoir l'impression de "Je peux faire quelque chose d'extraordinaire!" **.

Donc, si vous lisez quelque chose comme "Je ne sais pas ce que vous dites", pensez "Je ne suis tout simplement pas doué pour expliquer l'auteur" et continuez.

En tant que lecteur intentionnel, je pense comme suit. ** ・ Les personnes intéressées par l'analyse des données ・ Les personnes qui évitent l'analyse des données · Les autres gens **

De ce qui précède, je n'expliquerai pas le code en profondeur, mais me concentrerai sur "que faites-vous maintenant et pourquoi?" **.   Aussi, bien qu'il dise "déplacer avec copier-coller", j'ai l'intention de concevoir de sorte que vous puissiez comprendre le plaisir de l'analyse de données juste en ** lisant **!

C'est juste une publicité, mais si vous lisez cet article et que vous pensez "Je veux analyser les données!", J'ai écrit sur la façon d'étudier par moi-même sur Mon blog. Alors, veuillez vous y référer.

Que faire dans cet article

** ・ De la construction de l'environnement Python à la mise en œuvre du scraping et de l'apprentissage automatique ** ** ・ Créez un tableau de recherche de propriétés rentables comme l'image ci-dessous **: Découvrez des propriétés rentables en utilisant le modèle créé スクリーンショット 2019-12-17 13.30.58.png

Ce qu'il ne faut pas faire dans cet article

・ ** Explication détaillée du code ** ・ ** Explication de l'algorithme d'apprentissage automatique **

Cet article est juste pour que les gens aiment l'analyse de données. J'omettrai autant que possible les petites histoires difficiles! (Je pense que l'apprentissage de la programmation peut être appris beaucoup plus efficacement avec "pratique-> théorie / base" qu'avec "théorie / base-> pratique" ...)

Mon environnement

macOS High Sierra ver10.13.6 (~~ Ne vous lassez pas ~~) python3.7.3 Jupyter lab

Mise en garde

Le titre de l'article dit ** "Cela fonctionne avec le copier-coller" **, mais quand j'ai demandé à quelques connaissances de l'essayer, ** Jupyter Notebook ou le laboratoire ** devrait fonctionner presque sans erreur! * Au 17 décembre 2019 Si cela ne fonctionne pas, faites-le moi savoir ... De plus, si cela ne fonctionne pas, il est fort probable que la bibliothèque ne soit pas incluse. Veuillez installer avec «conda install» à chaque fois.

table des matières

table des matières
Flux global
Environnement
Grattage
L'analyse des données
Découvrir de bonnes affaires
Réellement...
À la fin

Flux global

Tout d'abord, vérifions le flux global. Dans cet article

  1. ** Construction de l'environnement ** pour l'exécution du code
  2. Acquérir automatiquement une grande quantité d'informations à l'aide du ** scraping **
  3. Créez un ** modèle d'apprentissage automatique ** basé sur les informations acquises
  4. Prédire les prix des logements à l'aide du modèle créé **
  5. Comparez la valeur prévue avec le prix réel ** Trouvez une bonne affaire. ** **

C'est un flux.

Je ne pense pas que ce soit une bonne idée de dire que c'est une valeur prédite par un modèle, mais ce n'est pas grave car je vais l'expliquer dans la partie apprentissage automatique ci-dessous!

Environnement

Comme je l'ai mentionné précédemment, tout le code de cet article est destiné à l'implémentation de Jupyter. Ici, nous allons vous présenter comment installer ** Jupyter lab **.

Tout d'abord, installez Anaconda à partir du lien ci-dessous. 【https://www.anaconda.com/distribution/】

スクリーンショット 2019-12-18 3.48.04.png

ensuite Pour les fenêtres 【https://www.python.jp/install/anaconda/windows/install.html 】 pour Mac 【https://www.python.jp/install/anaconda/macos/install.html 】

Veuillez vous référer à pour terminer l'installation d'Anaconda.

Et le récent Anaconda a un laboratoire de jupyter depuis le début.

$ jupyter lab

Exécutez le code ci-dessus à partir de l'invite de commande pour Windows et depuis le terminal pour mac.

Aussi, si vous avez Anaconda en premier lieu

$ conda install -c conda-forge jupyterlab
$ jupyter lab

Ça va.

C'est la fin de la construction de l'environnement. C'est trop facile ...!

Créez un dossier sur votre bureau et créez-y un cahier. スクリーンショット 2019-12-18 3.52.26.png

Grattage

Au fait, qu'est-ce que le «grattage» en premier lieu? Selon wikipedia

Le scraping Web n'est rien d'autre que le processus de collecte automatique d'informations sur le WWW.

En d'autres termes, ** "collecte automatiquement des informations sur Internet" **. (~~ C'est trop bien ~~)

Dans cette analyse, nous utilisons des données sur des propriétés locatives telles que des milliers, et dans certains cas des dizaines de milliers, pour une propriété.

・ Nom de la propriété ・ Louer ・ Zone ・ Mise en page ・ Emplacement (gare la plus proche, distance de la gare la plus proche, adresse détaillée) etc...

Je saisis manuellement ceci dans Excel des milliers de fois, des dizaines de milliers de fois ... rien que d'y penser me rend malade. Par conséquent, les données sont collectées à la fois par programmation.

Il y a une remarque importante ici. ** Assurez-vous de vérifier les termes et conditions du site avant de gratter. ** ** Le grattage est interdit sur certains sites en raison de problèmes tels que le droit d'auteur et l'impossibilité sur le serveur. Heureusement, Conditions d'utilisation de SUUMO

"L'utilisateur ne doit pas utiliser tout le contenu fourni via ce site au-delà de la portée de son utilisation personnelle prévue par la loi sur le droit d'auteur sans notre consentement préalable."

Il est écrit uniquement, et cette fois, ce sera bien car c'est pour un usage privé.

Ouvrez Jupyter,

#url (veuillez entrer l'URL ici)
url = ''

Veuillez entrer l'url de votre quartier préféré dans les 23 quartiers de Tokyo entre les guillemets simples et exécutez le code. Vous pouvez sauter à l'écran pour sélectionner la 23e salle à partir du lien ci-dessous. 【https://suumo.jp/chintai/tokyo/city/ 】 Par exemple, dans Bunkyo Ward, `` https://suumo.jp/jj/chintai/ichiran/FR301FC001/?ar=030&bs=040&ta=13&sc=13101&cb=0.0&ct=9999999&mb=0&mt=9999999&et=9999999&cn=99992shkr3kr3&shkr3&shkr3 = 03 & sngz = & po1 = 09 & pc = 50` La collecte des données prend beaucoup de temps, il est donc recommandé de l'exécuter avant d'aller au lit.

__ * Ajout (2019/12/29) __ __ Actuellement, nous vérifions les cas qui ne fonctionnent pas dans "l'ordre recommandé". __ __ Il s'agit d'une mesure symptomatique, mais elle semble fonctionner si elle est triée par «ordre d'arrivée». __ __ Je le mettrai à jour à nouveau dès que la cause première sera connue. __

De plus, ce code peut acquérir des informations non seulement dans les 23 quartiers de Tokyo mais aussi en dehors de Tokyo. (Quand je l'ai essayé, j'ai pu obtenir les données de la préfecture d'Okayama.) Cependant, étant donné que la partie analyse des données dans la seconde moitié de cet article est codée en supposant les données des 23 quartiers de Tokyo, cela ne fonctionne souvent pas uniquement avec le copier-coller. Il y a.


from bs4 import BeautifulSoup
import urllib3
import re
import requests
import time
import pandas as pd
from pandas import Series, DataFrame

#URL (veuillez entrer l'URL ici)
url = ''

result = requests.get(url)
c = result.content

soup = BeautifulSoup(c)

summary = soup.find("div",{'id':'js-bukkenList'})
body = soup.find("body")
pages = body.find_all("div",{'class':'pagination pagination_set-nav'})
pages_text = str(pages)
pages_split = pages_text.split('</a></li>\n</ol>')
pages_split0 = pages_split[0]
pages_split1 = pages_split0[-3:]
pages_split2 = pages_split1.replace('>','')
pages_split3 = int(pages_split2)

urls = []

urls.append(url)

for i in range(pages_split3-1):
    pg = str(i+2)
    url_page = url + '&page=' + pg
    urls.append(url_page)

names = [] 
addresses = [] 
locations0 = [] 
locations1 = [] 
locations2 = [] 
ages = [] 
heights = [] 
floors = []
rent = [] 
admin = []
others = [] 
floor_plans = [] 
areas = []
detail_urls = [] 

for url in urls:
    result = requests.get(url)
    c = result.content
    soup = BeautifulSoup(c)
    summary = soup.find("div",{'id':'js-bukkenList'})
    apartments = summary.find_all("div",{'class':'cassetteitem'})

    for apartment in apartments:

        room_number = len(apartment.find_all('tbody'))

        name = apartment.find('div', class_='cassetteitem_content-title').text
        address = apartment.find('li', class_='cassetteitem_detail-col1').text

        for i in range(room_number):
            names.append(name)
            addresses.append(address)

        sublocation = apartment.find('li', class_='cassetteitem_detail-col2')
        cols = sublocation.find_all('div')
        for i in range(len(cols)):
            text = cols[i].find(text=True)
            for j in range(room_number):
                if i == 0:
                    locations0.append(text)
                elif i == 1:
                    locations1.append(text)
                elif i == 2:
                    locations2.append(text)

        age_and_height = apartment.find('li', class_='cassetteitem_detail-col3')
        age = age_and_height('div')[0].text
        height = age_and_height('div')[1].text

        for i in range(room_number):
            ages.append(age)
            heights.append(height)

        table = apartment.find('table')
        rows = []
        rows.append(table.find_all('tr'))

        data = []
        for row in rows:
            for tr in row:
                cols = tr.find_all('td')
                if len(cols) != 0:
                    _floor = cols[2].text
                    _floor = re.sub('[\r\n\t]', '', _floor)

                    _rent_cell = cols[3].find('ul').find_all('li')
                    _rent = _rent_cell[0].find('span').text
                    _admin = _rent_cell[1].find('span').text

                    _deposit_cell = cols[4].find('ul').find_all('li')
                    _deposit = _deposit_cell[0].find('span').text
                    _reikin = _deposit_cell[1].find('span').text
                    _others = _deposit + '/' + _reikin

                    _floor_cell = cols[5].find('ul').find_all('li')
                    _floor_plan = _floor_cell[0].find('span').text
                    _area = _floor_cell[1].find('span').text

                    _detail_url = cols[8].find('a')['href']
                    _detail_url = 'https://suumo.jp' + _detail_url

                    text = [_floor, _rent, _admin, _others, _floor_plan, _area, _detail_url]
                    data.append(text)

        for row in data:
            floors.append(row[0])
            rent.append(row[1])
            admin.append(row[2])
            others.append(row[3])
            floor_plans.append(row[4])
            areas.append(row[5])
            detail_urls.append(row[6])


        time.sleep(3)

names = Series(names)
addresses = Series(addresses)
locations0 = Series(locations0)
locations1 = Series(locations1)
locations2 = Series(locations2)
ages = Series(ages)
heights = Series(heights)
floors = Series(floors)
rent = Series(rent)
admin = Series(admin)
others = Series(others)
floor_plans = Series(floor_plans)
areas = Series(areas)
detail_urls = Series(detail_urls)

suumo_df = pd.concat([names, addresses, locations0, locations1, locations2, ages, heights, floors, rent, admin, others, floor_plans, areas, detail_urls], axis=1)

suumo_df.columns=['Nom de l'appartement','adresse de rue','Emplacement 1','Emplacement 2','Emplacement 3','Âge','Hauteur du bâtiment','hiérarchie','Location','Frais de gestion', 'Shiki/Je vous remercie/garantie/Shiki引,Amortissement','Plan d'étage','Zone occupée', 'URL détaillée']

suumo_df.to_csv('suumo.csv', sep = '\t', encoding='utf-16', header=True, index=False)

Si vous ne lancez pas d'erreur après environ 10 secondes, vous réussissez. Attendons patiemment.

Expliquez ce que fait ce code. La plupart des pages Web sont écrites dans le langage HTML. Vérifions la structure du site Web de SUUMO à l'aide de l'outil de vérification de Chrome. スクリーンショット 2019-12-17 18.47.06.png

En regardant ce qui précède, vous pouvez voir que le nom de la location est marqué avec cassetteitem_content-title. Dans le scraping, les données sont acquises en utilisant les informations de marque attachées à ce HTML.

En fait, j'aimerais acquérir toutes les données des informations de location à Tokyo, mais cela prendra énormément de temps, donc cette fois je me concentrerai sur un seul quartier.

L'analyse des données

Bonjour. Si vous pouvez obtenir les données, vous devriez avoir un fichier appelé suumo.csv dans le même répertoire que le cahier récupéré. スクリーンショット 2019-12-17 18.55.05.png Les données ressemblent à celles ci-dessus. Il y a de la mémoire qui a été impressionné par ** "la croûte Oh Oh !!! génial !!!" ** quand il a réussi la première fois l'acquisition de grosses données par ses propres moyens, qu'en est-il de tout le monde.

Nous analyserons les données à l'aide de ces données, mais avant cela, j'expliquerai un petit concept de base sur le modèle d'apprentissage automatique.

Apprendre avec un enseignant

L'apprentissage à effectuer cette fois est une méthode d'apprentissage (méthode d'analyse de données) appelée ** apprentissage supervisé **. Selon Wikipedia

Le nom vient du fait que les données fournies à l'avance sont considérées comme un "exemple (= conseil de l'enseignant)" et que l'apprentissage (= une certaine adaptation aux données) est effectué en l'utilisant comme guide.

... Apparemment ... Cela ne sort pas très bien, alors considérons un exemple concret.

Cette fois, nous allons créer un modèle qui prédit le prix de location à partir des informations de location. Nous avons généralement les connaissances suivantes sur le loyer:

Plus la superficie est grande, plus le loyer est élevé Plus la gare est proche, plus le loyer est élevé Plus l'âge du bâtiment est petit, plus le loyer est élevé

La raison pour laquelle je peux avoir cette connaissance n'est autre que de connaître de tels cas. Vous pouvez également prédire le loyer dans une certaine mesure à partir de ces connaissances.

L'apprentissage automatique consiste à laisser les machines faire cela.

Un grand nombre de données sont entraînées par une machine, le loyer est émis sous la forme d'une valeur prédite de la zone, de la distance à la gare, de l'âge, etc., et le loyer est prédit de sorte que la différence entre la valeur prédite et le loyer réel (données de l'enseignant) devienne plus petite. Faire.

Aussi comme terme La valeur à afficher en tant que valeur prédite telle que le loyer est la ** variable objective ** Informations qui caractérisent la variable objective, telles que la superficie et l'âge, ** la quantité de caractéristiques ** Est appelé.

Superapprentissage

La plus grande difficulté de l'apprentissage automatique est ce ** surapprentissage **. Le surentraînement est ** "surajustement à certaines données" **.

Supposons que vous ayez créé un modèle qui prédit le loyer par superficie. L'image ci-dessous est cette image. スクリーンショット 2019-12-19 9.15.36.png

Compliquons le modèle pour réduire davantage cette erreur. スクリーンショット 2019-12-19 9.15.42.png

Hou la la! Je peux prédire parfaitement le loyer avec une précision de 100% !!!! ... et ** je ne suis pas content. ** ** Utilisons ce modèle et appliquons-le à d'autres données avec une distribution similaire. スクリーンショット 2019-12-19 9.18.26.png

Le modèle simple de gauche offre des performances similaires, tandis que le modèle complexe de droite ** ne parvient clairement pas à prédire **.

L'objectif de l'apprentissage automatique est généralement ** de créer le modèle le plus performant pour les ensembles de données inconnus **. Les performances du modèle pour cet ensemble de données inconnu sont appelées ** performances de généralisation **.

Alors, comment créer un modèle avec des performances de généralisation élevées? Le moyen le plus simple consiste à ** diviser les données ** comme indiqué dans l'image ci-dessous. スクリーンショット 2019-12-18 4.53.29.png Suivez la procédure ci-dessous pour mesurer les performances de généralisation.

  1. Divisez les données en données d'entraînement et données de test.
  2. Créez un modèle à l'aide de ** données d'entraînement uniquement **.
  3. À l'aide du modèle créé, appliquez-le aux ** données de test ** et calculez la valeur prévue.
  4. Mesurer les performances du modèle en utilisant la "valeur estimée calculée" et la "valeur réelle des données de test (données de l'enseignant)"

Dans cette partie d'apprentissage automatique, 67% des données collectées sont divisées en données d'entraînement et les 33% restants sont divisés en données de test.

Prétraitement

En fait, c'est la partie qui constitue l'essentiel de l'analyse des données, et l'analyse des données nécessite de traiter les données sous une forme lisible par machine.

Par exemple, regardons la colonne d'âge (le nom de la colonne). スクリーンショット 2019-12-17 19.15.41.png Nous, les humains, pouvons le voir et reconnaître que ** "L'âge du bâtiment est une nouvelle construction <7 ans <21 ans" "**. Vous pouvez le prendre pour acquis, mais les machines ne peuvent pas le reconnaître. Alors ** Nouvelle construction → 0 7 ans → 7 21 ans → 21 ** Il est nécessaire de le traiter pour que la machine puisse reconnaître [0 <7 <21].

De plus, la mise en page de 2LDK etc. est traitée en utilisant la méthode ** codage à chaud (variable factice) **, et la station la plus proche etc. est traitée en utilisant la méthode ** Codage d'étiquette **. (Veuillez vérifier si vous êtes intéressé)

Vous devrez peut-être également gérer les valeurs manquantes. (Le complément de valeur manquante est un marais, donc je n'y toucherai pas ici ...)

Le traitement effectué sur les données avant l'apprentissage est appelé collectivement ** prétraitement **.

Maintenant, exécutons réellement le code.

import pandas as pd
import numpy as np
from sklearn.preprocessing import OrdinalEncoder
from sklearn import preprocessing
import pandas_profiling as pdp 

df = pd.read_csv('suumo.csv', sep='\t', encoding='utf-16')

splitted1 = df['Emplacement 1'].str.split('Ayumu', expand=True)
splitted1.columns = ['Emplacement 11', 'Emplacement 12']
splitted2 = df['Emplacement 2'].str.split('Ayumu', expand=True)
splitted2.columns = ['Emplacement 21', 'Emplacement 22']
splitted3 = df['Emplacement 3'].str.split('Ayumu', expand=True)
splitted3.columns = ['Emplacement 31', 'Emplacement 32']

splitted4 = df['Shiki/Je vous remercie/garantie/Shiki引,Amortissement'].str.split('/', expand=True)
splitted4.columns = ['Dépôt', 'de l'argent clé']

df = pd.concat([df, splitted1, splitted2, splitted3, splitted4], axis=1)

df.drop(['Emplacement 1','Emplacement 2','Emplacement 3','Shiki/Je vous remercie/garantie/Shiki引,Amortissement'], axis=1, inplace=True)

df = df.dropna(subset=['Location'])

df['Location'] = df['Location'].str.replace(u'Dix mille yens', u'')
df['Dépôt'] = df['Dépôt'].str.replace(u'Dix mille yens', u'')
df['de l'argent clé'] = df['de l'argent clé'].str.replace(u'Dix mille yens', u'')
df['Frais de gestion'] = df['Frais de gestion'].str.replace(u'Cercle', u'')
df['Âge'] = df['Âge'].str.replace(u'Nouvelle construction', u'0') 
df['Âge'] = df['Âge'].str.replace(u'Plus de 99 ans', u'0') #
df['Âge'] = df['Âge'].str.replace(u'Construit', u'')
df['Âge'] = df['Âge'].str.replace(u'Année', u'')
df['Zone occupée'] = df['Zone occupée'].str.replace(u'm', u'')
df['Emplacement 12'] = df['Emplacement 12'].str.replace(u'Minutes', u'')
df['Emplacement 22'] = df['Emplacement 22'].str.replace(u'Minutes', u'')
df['Emplacement 32'] = df['Emplacement 32'].str.replace(u'Minutes', u'')

df['Frais de gestion'] = df['Frais de gestion'].replace('-',0)
df['Dépôt'] = df['Dépôt'].replace('-',0)
df['de l'argent clé'] = df['de l'argent clé'].replace('-',0)

splitted5 = df['Emplacement 11'].str.split('/', expand=True)
splitted5.columns = ['Route 1', 'Station 1']
splitted5['1 à pied'] = df['Emplacement 12']
splitted6 = df['Emplacement 21'].str.split('/', expand=True)
splitted6.columns = ['Route 2', 'Station 2']
splitted6['2 à pied'] = df['Emplacement 22']
splitted7 = df['Emplacement 31'].str.split('/', expand=True)
splitted7.columns = ['Route 3', 'Station 3']
splitted7['3 à pied'] = df['Emplacement 32']

df = pd.concat([df, splitted5, splitted6, splitted7], axis=1)

df.drop(['Emplacement 11','Emplacement 12','Emplacement 21','Emplacement 22','Emplacement 31','Emplacement 32'], axis=1, inplace=True)

df['Location'] = pd.to_numeric(df['Location'])
df['Frais de gestion'] = pd.to_numeric(df['Frais de gestion'])
df['Dépôt'] = pd.to_numeric(df['Dépôt'])
df['de l'argent clé'] = pd.to_numeric(df['de l'argent clé'])
df['Âge'] = pd.to_numeric(df['Âge'])
df['Zone occupée'] = pd.to_numeric(df['Zone occupée'])

df['Location'] = df['Location'] * 10000
df['Dépôt'] = df['Dépôt'] * 10000
df['de l'argent clé'] = df['de l'argent clé'] * 10000

df['1 à pied'] = pd.to_numeric(df['1 à pied'])
df['2 à pied'] = pd.to_numeric(df['2 à pied'])
df['3 à pied'] = pd.to_numeric(df['3 à pied'])

splitted8 = df['hiérarchie'].str.split('-', expand=True)
splitted8.columns = ['1er étage', '2e étage']
splitted8['1er étage'].str.encode('cp932')
splitted8['1er étage'] = splitted8['1er étage'].str.replace(u'Sol', u'')
splitted8['1er étage'] = splitted8['1er étage'].str.replace(u'B', u'-')
splitted8['1er étage'] = splitted8['1er étage'].str.replace(u'M', u'')
splitted8['1er étage'] = pd.to_numeric(splitted8['1er étage'])
df = pd.concat([df, splitted8], axis=1)

df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 1 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 2 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 3 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 4 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 5 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 6 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'7 souterrains', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'8 souterrains', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Souterrain 9 hors sol', u'')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Une histoire', u'1')
df['Hauteur du bâtiment'] = df['Hauteur du bâtiment'].str.replace(u'Sol', u'')
df['Hauteur du bâtiment'] = pd.to_numeric(df['Hauteur du bâtiment'])

df = df.reset_index(drop=True)
df['Disposition DK'] = 0
df['Disposition K'] = 0
df['Disposition L'] = 0
df['Disposition S'] = 0
df['Plan d'étage'] = df['Plan d'étage'].str.replace(u'Studio', u'1') 

for x in range(len(df)):
    if 'DK' in df['Plan d'étage'][x]:
        df.loc[x,'Disposition DK'] = 1
df['Plan d'étage'] = df['Plan d'étage'].str.replace(u'DK',u'')

for x in range(len(df)):
    if 'K' in df['Plan d'étage'][x]:
        df.loc[x,'Disposition K'] = 1        
df['Plan d'étage'] = df['Plan d'étage'].str.replace(u'K',u'')

for x in range(len(df)):
    if 'L' in df['Plan d'étage'][x]:
        df.loc[x,'Disposition L'] = 1        
df['Plan d'étage'] = df['Plan d'étage'].str.replace(u'L',u'')

for x in range(len(df)):
    if 'S' in df['Plan d'étage'][x]:
        df.loc[x,'Disposition S'] = 1        
df['Plan d'étage'] = df['Plan d'étage'].str.replace(u'S',u'')

df['Plan d'étage'] = pd.to_numeric(df['Plan d'étage'])

splitted9 = df['adresse de rue'].str.split('quartier', expand=True)
splitted9.columns = ['quartier', 'Municipal']
splitted9['quartier'] = splitted9['quartier'] + 'quartier'
splitted9['quartier'] = splitted9['quartier'].str.replace('Tokyo','')
df = pd.concat([df, splitted9], axis=1)

df_for_search = df.copy()

df[['Route 1','Route 2','Route 3', 'Station 1', 'Station 2','Station 3','Municipal']] = df[['Route 1','Route 2','Route 3', 'Station 1', 'Station 2','Station 3','Municipal']].fillna("NAN")

oe = preprocessing.OrdinalEncoder()
df[['Route 1','Route 2','Route 3', 'Station 1', 'Station 2','Station 3','Municipal']] = oe.fit_transform(df[['Route 1','Route 2','Route 3', 'Station 1', 'Station 2','Station 3','Municipal']].values) 

df['Location+Frais de gestion'] = df['Location'] + df['Frais de gestion']

#Fixer le prix maximum
df = df[df['Location+Frais de gestion'] < 300000]

df = df[["Nom de l'appartement",'Location+Frais de gestion', 'Âge', 'Hauteur du bâtiment', '1er étage',
       'Zone occupée','Route 1','Route 2','Route 3', 'Station 1', 'Station 2','Station 3','1 à pied', '2 à pied','3 à pied','Plan d'étage', 'Plan d'étageDK', 'Plan d'étageK', 'Plan d'étageL', 'Plan d'étageS',
       'Municipal']]

df.columns = ['name','real_rent','age', 'hight', 'level','area', 'route_1','route_2','route_3','station_1','station_2','station_3','distance_1','distance_2','distance_3','room_number','DK','K','L','S','adress']


pdp.ProfileReport(df)

Je vais expliquer quatre points. ・ Puisqu'il a été jugé que cela n'est pas nécessaire pour l'analyse, les informations telles que «service» et «URL détaillée» ne sont pas incluses. Par exemple, cette fois, je le fais dans Bunkyo Ward, mais comme toutes les données proviennent de Bunkyo Ward, ces informations ne seront pas utiles. Cependant, veuillez noter que les informations sur les «quartiers» sont très importantes, par exemple, lors de l'analyse des données des 23 quartiers de Tokyo.

・ Les informations sur "Shikikin" et "Reikin" ne sont pas incluses. En effet, contrairement à la raison précédente, il est trop facile à prévoir (cela n'a pas de sens). Pour la plupart des locations, les dépôts et la gratitude sont fixés au même niveau que deux à trois fois le loyer. Même si vous dites: "Je prédis que le loyer pour un loyer de 70 000 yens sera de 70 000 yens!", Vous n'obtiendrez rien ...

・ La variable objective est «loyer + frais de gestion» au lieu du loyer. Le paiement mensuel effectif est "loyer + frais de gestion". En outre, les données des propriétés dont le loyer + coût de gestion dépasse 300 000 yens constituent la troisième ligne à partir du bas.


df = df[df['Location+Frais de gestion'] < 300000]

Il est exclu par. J'ai analysé même s'il n'y avait pas de limite supérieure de loyer et j'ai essayé de trouver une bonne affaire, mais j'ai dit: "Le loyer estimé pour cette propriété est de 2 millions de yens, mais en réalité il est de 1,5 million de yens! Un énorme 500 000 yens par mois!" Je me suis senti triste quand on m'a dit. (Je ne peux même pas vivre dans une maison avec un loyer de 300 000 ...) Ce n'est pas grave si vous changez le prix vous-même.

・ Le profilage Pandas est utilisé pour ** l'analyse exploratoire des données (EDA) **. C'est une bibliothèque que j'aime beaucoup personnellement.

De toutes les informations des données ... スクリーンショット 2019-12-17 20.06.56.png Statistiques de base de chaque variable, スクリーンショット 2019-12-17 20.07.09.png Il affiche même la matrice des coefficients de corrélation ... Trop pratique ...

スクリーンショット 2019-12-17 20.13.33.png

** Addendum (2020/1/7) ** ** Actuellement, lightgbm ne semble pas pouvoir utiliser le japonais pour les noms de quantité d'entités **

Création de fonctionnalités

Vient ensuite la partie création de fonctionnalités. Ceci est également inclus dans le prétraitement.

Ici, nous allons créer une nouvelle quantité de caractéristiques qui semble efficace (elle semble pouvoir bien expliquer les variables explicatives) à partir de la quantité de caractéristiques existante. Par exemple, dans le code ci-dessous ・ Superficie par pièce divisée par le nombre de pièces ・ Le produit du type de gare la plus proche et de la distance à la gare la plus proche (cette dernière semble être plus chère si elle se trouve à 5 minutes à pied d'une gare mineure et à 5 minutes à pied d'une gare principale) Nous avons créé et ajouté des fonctionnalités telles que.

Si vous avez une expérience avec Python, essayez de créer votre propre quantité de fonctionnalités.


df["per_area"] = df["area"]/df["room_number"]
df["height_level"] = df["height"]*df["level"]
df["area_height_level"] = df["area"]*df["height_level"]
df["distance_staion_1"] = df["station_1"]*df["distance_1"]

Apprentissage automatique

C'est enfin apprendre! !! !! Nous créerons un modèle de prévision de prix basé sur les données mises en forme et créées.

L'algorithme d'apprentissage automatique utilisé ici est ** lightgbm **. · Haute précision ・ Le traitement est rapide On peut dire que c'est la méthode la plus importante dans les compétitions pour la précision de l'apprentissage automatique. (Dans la compétition hors ligne avec une limite de temps serrée à laquelle j'ai participé auparavant, toutes les 10 meilleures personnes ont utilisé cet algorithme ...!)

D'abord au terminal ou à l'invite de commande

conda install -c conda-forge lightgbm

Installons lightgbm.

Maintenant, exécutons le code.


import matplotlib.pyplot as plt
import japanize_matplotlib
import lightgbm as lgb
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import LabelEncoder
from sklearn.metrics import mean_squared_error
from sklearn.metrics import r2_score

y = df["real_rent"]
X = df.drop(['real_rent',"name"], axis=1) 

X_train, X_test, y_train, y_test = train_test_split(X, y,test_size=0.33, random_state=0)

lgb_train = lgb.Dataset(X_train, y_train)
lgb_eval = lgb.Dataset(X_test, y_test, reference=lgb_train)

lgbm_params = {
        'objective': 'regression',
        'metric': 'rmse',
        'num_leaves':80
}

model = lgb.train(lgbm_params, lgb_train, valid_sets=lgb_eval, verbose_eval=-1)
    
y_pred = model.predict(X_test, num_iteration=model.best_iteration)

print(r2_score(y_test, y_pred)  )
lgb.plot_importance(model, figsize=(12, 6))
plt.show()


Résultat
スクリーンショット 2019-12-17 20.44.49.png

J'ajouterai ici aussi quelques explications.

-Les nombres résultants représentent la ** précision du modèle **. Cet indice prend une valeur de 0 à 1, et plus il est proche de ** 1, mieux c'est **. À partir de l'indice de "0,945" que j'ai obtenu cette fois dans mon analyse, vous pouvez voir que ce modèle est très performant. En tant qu'image, il peut être prédit avec une précision d'environ 94%.

-Feature_importance indique ** l'importance de chaque quantité de fonction **. Après tout, vous pouvez voir que la zone occupée et l'âge sont importants. ~~ Je suis content que le nombre de fonctionnalités que j'ai créées fonctionne assez bien. ~~

Recherche de propriétés à bon rapport qualité-prix

pred = list(model.predict(X, num_iteration=model.best_iteration))
pred = pd.Series(pred, name="Valeur prédite")
diff = pd.Series(df["Location+Frais de gestion"]-pred,name="Différence par rapport à la valeur prédite")
df_search = pd.concat([df_for_search,diff,pred], axis=1)
df_search = df_search.sort_values("Différence par rapport à la valeur prédite")
df_search = df_search[["Nom de l'appartement",'Location+Frais de gestion', 'Valeur prédite',  'Valeur préditeとの差', 'URL détaillée']]
df_search.to_csv('otoku.csv', sep = '\t',encoding='utf-16')

L'exécution du code ci-dessus créera un fichier csv comme celui ci-dessous. Ce code utilise le modèle créé pour prédire le loyer de toutes les propriétés et créer une table où la différence est importante, c'est-à-dire triée par ordre de profit. En d'autres termes, plus il est allumé ** dans le fichier csv créé, mieux c'est **.

スクリーンショット 2019-12-17 21.26.35.png Par exemple, découvrons la propriété "A-standard Hongo 3-chome", qui est considérée comme la propriété la plus rentable de ce modèle. Vous pouvez voler à partir de l'URL des détails sur la droite. スクリーンショット 2019-12-17 21.27.47.png スクリーンショット 2019-12-17 21.35.16.png

3 minutes à pied de la gare la plus proche 2LDK 54㎡ 7 ans 9ème étage

Avec cela, 130000 yens par mois est certainement une très bonne condition ... ** Je veux vivre de façon insensée pour dire le moins ... ** La valeur prévue était de 230000 yens, donc ・ Bunkyo Ward ・ Dans les 10 ans suivant la construction ・ À moins de 10 minutes à pied de la gare la plus proche ・ Zone 45㎡ ou plus Lorsque j'ai cherché avec SUUMO en précisant les conditions de, j'ai trouvé qu'il y avait vraiment beaucoup de propriétés d'environ 200 000 à 230 000, et cette propriété est une bonne affaire. (Au fait, ce n'était pas une propriété accidentelle)

Veuillez utiliser ce tableau pour rechercher des propriétés!

Réellement ...

Dans ce chapitre, nous parlerons de "** Vous pouvez facilement vous tromper si vous n'étudiez pas l'apprentissage automatique **". Le tableau que j'ai fait plus tôt semble extrêmement efficace et merveilleux. ** Mais en fait, 67% des informations de ce tableau sont presque dénuées de sens ** En fait, il y a une bonne possibilité qu'il y ait une propriété dans ces données qui soit plus rentable que la propriété que vous pensez être la plus rentable actuellement.

La raison en est "Puisque le modèle créé à l'aide des données d'entraînement est appliqué aux données d'entraînement, il n'est pas possible de reconnaître le profit comme un profit."

En premier lieu, une propriété de bonne valeur est une propriété qui a une grande (valeur estimée) - (prix réel (données de l'enseignant)). J'ai prédit que ce serait 230 000 yens pour l'appartement que j'ai mentionné plus tôt, mais en réalité c'est 130 000 yens, ce qui peut être considéré comme beaucoup de 100 000 yens. Cependant, si cette propriété est incluse dans les données d'apprentissage, la valeur prévue sera calculée comme "Non, je le sais", ce qui est presque le même que le prix réel. En bref, quelque chose comme la «mise en conserve» se produit. Peu importe la difficulté et la spécificité du problème, si vous connaissez la réponse, vous pouvez le résoudre. Puisque le but était "Trouvons une bonne affaire", ce problème est évidemment assez grave.

En d'autres termes, ** N'incluez pas les données que vous souhaitez prédire dans les données d'entraînement **.

En passant, comme solution, comme le montre l'image ci-dessous, vous pouvez penser à une méthode d'apprentissage et de prédiction en plusieurs étapes. スクリーンショット 2019-12-18 1.27.04.png

Ce n'est pas grave si vous pensez "je ne sais pas ce que c'est". Ne vous inquiétez pas, nous parlons un peu compliqué. Dans ce chapitre ** Vous pouvez facilement être dupé sans connaissance de l'analyse des données ... ** ** L'analyse des données est approfondie ** Je l'écris parce que je veux présenter cela.

À la fin

Ceci est la fin de cet article. Merci beaucoup d'être resté avec nous jusqu'à présent! Je serais très heureux si vous pouviez ressentir le plaisir et la dynamique de l'analyse des données, ainsi que l'horreur et la profondeur. L'analyse des données est importante pour que vous puissiez être heureux et non pas malheureux. Les humains sont plus vulnérables aux chiffres qu'ils ne le pensent. De plus, si vous souhaitez étudier l'analyse des données avec cela, Article différent présente la méthode d'auto-étude. Veuillez essayer de faire référence.

référence

J'ai utilisé l'apprentissage automatique pour trouver une propriété à louer à bon prix dans les 23 quartiers de Tokyo La plupart du code de scraping était basé sur le code de cette personne. Cependant, certaines parties ne fonctionnaient pas avec le même copier-coller, donc je suis en train de le réparer.

Recommended Posts

[Pour les super débutants] Construction de l'environnement Python et grattage et apprentissage automatique et application pratique dont vous pouvez profiter en vous déplaçant avec copie [Trouvons une bonne propriété locative avec SUUMO! ]
J'étais frustré par Kaggle, alors j'ai essayé de trouver une bonne propriété locative en grattant et en apprentissage automatique
Créer un environnement de développement d'applications d'apprentissage automatique avec Python
Création d'un environnement Windows 7 pour une introduction à l'apprentissage automatique avec Python
Créer un environnement d'apprentissage automatique Python avec des conteneurs
Jusqu'à ce que vous créiez un environnement d'apprentissage automatique avec Python sur Windows 7 et que vous l'exécutiez
Mémo de construction d'environnement d'apprentissage automatique par Python
Vous pouvez l'essayer avec une copie! Dessinons un diagramme de réseau sympa avec networkx de Python