<jupyter_start><jupyter_text>Modelo para cálculo de imóveis na cidade de São PauloO objetivo deste projeto é construir um modelo preditivo capaz de calcular o preço de um imóvel no bairro Paraíso na cidade de São Paulo. Para completar este projeto cada aluno deverá seguir as orientações que estão neste notebook e preencher as células vazias.   Aquisição, pré-processamento e análise descritiva<jupyter_code>import pandas as pd
import io
import requests
url="https://raw.githubusercontent.com/fbarth/ds-saint-paul/master/data/20140917_imoveis_filtrados_final.csv_shaped.csv"
s=requests.get(url).content
df = pd.read_csv(io.StringIO(s.decode('utf-8')), sep=",")
df.head()
%matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
plt.subplots(figsize=(10, 8))
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
ax = sns.scatterplot(x="area", y="preco",
                     hue="suites", size="vagas",
                     palette=cmap, sizes=(10, 200),
                     data=df)<jupyter_output><empty_output><jupyter_text>* Listar a quantidade de imóveis por bairro existente no dataset<jupyter_code># TODO: completar com o nome da variavel correta
df['<PREENCHER>'].value_counts()<jupyter_output><empty_output><jupyter_text>* Considere apenas os imóveis do bairo paraiso<jupyter_code># TODO: preencher com o nome do bairro correto
df = df[df['bairro'] == '<PREENCHER>']<jupyter_output><empty_output><jupyter_text>* Depois de considerar apenas os imóveis do bairro paraiso o tamanho do dataset precisa ser exatamente igual a (809,7)<jupyter_code>df.shape
%matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
plt.subplots(figsize=(10, 8))
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
ax = sns.scatterplot(x="area", y="preco",
                     hue="suites", size="vagas",
                     palette=cmap, sizes=(10, 200),
                     data=df)
df.head()<jupyter_output><empty_output><jupyter_text>* A quantidade suites não pode ser maior que a quantidade de dormitórios e a quantidade de suites também não pode ser maior que a quantidade de banheiros. Exclua todos os exemplos que não satisfazem esta restrição. Estes exemplos provavelmente são erros de coleta de dados.<jupyter_code># TODO: completar a regra
df = df['COMPLETAR' <= df['dormitorios']]
df = df['COMPLETAR' <= df['banheiros']]<jupyter_output><empty_output><jupyter_text>* Depois deste filtro o dataset precisa ter o tamanho (786, 7).<jupyter_code>df.shape
%matplotlib inline
import seaborn as sns
import matplotlib.pyplot as plt
plt.subplots(figsize=(10, 8))
cmap = sns.cubehelix_palette(rot=-.2, as_cmap=True)
ax = sns.scatterplot(x="area", y="preco",
                     hue="suites", size="vagas",
                     palette=cmap, sizes=(10, 200),
                     data=df)<jupyter_output><empty_output><jupyter_text>* Visto que agora a variável bairro tem apenas um valor, você deve remover a mesma<jupyter_code># TODO remover o atributo bairro
df = df.drop(columns=['<PREENCHER>'])<jupyter_output><empty_output><jupyter_text>* Depois deste filtro o dataset precisa ter a seguinte estrutura:<jupyter_code>df.head()<jupyter_output><empty_output><jupyter_text>* Qual é o valor mínimo e máximo dos preços dos imóveis?<jupyter_code># TODO completar com o nome correto do atributo
x = df['<PREENCHER>'].describe()
x
df['preco'].plot(kind='hist', color='gray', title='Preço dos imóveis', rot=90)
import seaborn as sns
sns.pairplot(df)
df.corr()<jupyter_output><empty_output><jupyter_text>* Qual é a informação que a tabela acima nos fornece?   Divisão dos datasets<jupyter_code>df.head()<jupyter_output><empty_output><jupyter_text>* dividindo o dataset em 80% para treino e 20% para teste<jupyter_code># neste código você precisa informar o percentual de exemplos que serão utilizados no teste

percentual = #<PREENCHER>

from sklearn.model_selection import train_test_split
x_train, x_test, y_train, y_test = train_test_split(df.iloc[:,1:6], df['preco'], test_size=percentual, random_state=4)
x_train.head()<jupyter_output><empty_output><jupyter_text>Criação e avaliação do modelo preditivoCrie um modelo de regressão utilizando os algoritmos e transformações nos atributos que você considera mais adequados.Valide o modelo desenvolvido considerando os datasets X_test e y_test. Espera-se que o erro médio absoluto seja inferior a duzentos mil reais (R$ 200.000,00). Descreva nas células abaixo todas as etapas necessárias para o desenvolvimento e validação do modelo.  Regressão Linear<jupyter_code>print(x_train.shape)
print(y_train.shape)
print(x_test.shape)
from sklearn.linear_model import LinearRegression
model = LinearRegression().fit(x_train, y_train)<jupyter_output><empty_output><jupyter_text>Validação do modelo no conjunto de treinamento<jupyter_code>predicted = model.predict(x_train)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_train, predicted)
r2 = r2_score(y_train, predicted)
mae = mean_absolute_error(y_train, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)<jupyter_output>rmse = % 150142973325.56418
r2 = % 0.8223876116718476
mae = % 265630.1450275685<jupyter_text>* O erro médio absoluto está próximo do objetivo?<jupyter_code>resultado = pd.DataFrame({'real': y_train, 'predicted': predicted, 'diff': (y_train - predicted)})
resultado = pd.concat([x_train, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>* Qual é o significado do eixo Y deste gráfico? * Qual é o comportamento do erro no dataset de treinamento?   Validação do modelo no conjunto de teste<jupyter_code>predicted = model.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_test, predicted)
r2 = r2_score(y_test, predicted)
mae = mean_absolute_error(y_test, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)<jupyter_output>rmse = % 96552254398.05544
r2 = % 0.8343976815354153
mae = % 241653.09231124964<jupyter_text>* O erro médio absoluto no conjunto de teste é similar ao erro médio absoluto no conjunto de treinamento?<jupyter_code>resultado = pd.DataFrame({'real': y_test, 'predicted': predicted, 'diff': (y_test - predicted)})
resultado = pd.concat([x_test, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Regressão Linear com transformação polinomial **Testar com degree igual a 2, 3, 4 e 8. Analisar possível overfitting**<jupyter_code>#Generate a new feature matrix consisting of all polynomial combinations 
#of the features with degree less than or equal to the specified degree. 
#For example, if an input sample is two dimensional and of the form [a, b], 
#the degree-2 polynomial features are [1, a, b, a^2, ab, b^2].

grau='<PREENCHER>'

from sklearn.preprocessing import PolynomialFeatures
transformer = PolynomialFeatures(degree=grau, include_bias=False)
transformer.fit(x_train)
train_ = transformer.transform(x_train)
print(x_train.shape)
print(train_.shape)<jupyter_output>(628, 5)
(628, 1286)<jupyter_text>* Por que este dataset tem dimensões diferentes?<jupyter_code>from sklearn.linear_model import LinearRegression
model = LinearRegression().fit(train_, y_train)<jupyter_output><empty_output><jupyter_text>Validação do modelo no conjunto de treinamento<jupyter_code>predicted = model.predict(train_)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_train, predicted)
r2 = r2_score(y_train, predicted)
mae = mean_absolute_error(y_train, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_train, 'predicted': predicted, 'diff': (y_train - predicted)})
resultado = pd.concat([x_train, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Validação do modelo no conjunto de teste * antes de usar a função predict, você precisa aplicar a mesma transformação feita sobre o dataset x_train no dataset x_test. Preste atenção que o nome da variável esperada é test_<jupyter_code>transformer.fit(x_test)
test_ = transformer.transform(x_test)
predicted = model.predict(test_)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_test, predicted)
r2 = r2_score(y_test, predicted)
mae = mean_absolute_error(y_test, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)<jupyter_output>rmse = % 41182864009546.375
r2 = % -69.63509602661267
mae = % 1135967.8869046264<jupyter_text>* A diferença do erro do conjunto de treinamento com o conjunto de testes foi muito diferente? O que aconteceu?<jupyter_code>resultado = pd.DataFrame({'real': y_test, 'predicted': predicted, 'diff': (y_test - predicted)})
resultado = pd.concat([x_test, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Random Forest sem modificação adicional de atributos e modificando apenas a quantidade de árvores<jupyter_code>from sklearn.ensemble import RandomForestRegressor
results = pd.DataFrame(columns=['estimators','r2'])
for i in range(100, 5000, 100):
    clf = RandomForestRegressor(n_estimators=i, max_depth=None, random_state=4, oob_score=True)
    clf.fit(x_train, y_train)
    results = results.append({'estimators':i, 'r2': clf.oob_score_}, ignore_index=True)
ax = results.plot(x='estimators', y='r2')
ax.set_title('Relação R2 com a quantidade de árvores utilizadas no modelo RandomForest')<jupyter_output><empty_output><jupyter_text>* o modelo com 4900 árvores é o modelo com melhor $R^{2}$<jupyter_code>clf = RandomForestRegressor(n_estimators=4900, max_depth=None, random_state=4, oob_score=True)<jupyter_output><empty_output><jupyter_text>* crie o modelo usando a função fit é os datasets x_train e y_train<jupyter_code>clf.fit(x_train, y_train)<jupyter_output><empty_output><jupyter_text>* Nível de importância dos atributos para o modelo preditivo:<jupyter_code>print(clf.oob_score_)
print(clf.feature_importances_)
print(x_train.columns)<jupyter_output>0.8978754005039717
[0.33587576 0.18957595 0.01128215 0.01847831 0.44478783]
Index(['area', 'suites', 'dormitorios', 'banheiros', 'vagas'], dtype='object')<jupyter_text>* Quais são os atributos que têm maior importância no modelo?   Validação do modelo no conjunto de treinamento<jupyter_code>predicted = clf.predict(x_train)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_train, predicted)
r2 = r2_score(y_train, predicted)
mae = mean_absolute_error(y_train, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_train, 'predicted': predicted, 'diff': (y_train - predicted)})
resultado = pd.concat([x_train, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Validação do modelo no conjunto de teste * utilize a função predict para calcular os valores preditos considerando o dataset x_test<jupyter_code>predicted = clf.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_test, predicted)
r2 = r2_score(y_test, predicted)
mae = mean_absolute_error(y_test, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_test, 'predicted': predicted, 'diff': (y_test - predicted)})
resultado = pd.concat([x_test, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Random Forest sem modificação adicional de atributos e com GridSearch<jupyter_code>from sklearn.model_selection import GridSearchCV
param_grid = { 
    'n_estimators': [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
    'max_features': ['sqrt', 'log2', 3, 4, 5],
    'max_depth' : [2, 10, 20, 100, None]
}
rfc=RandomForestRegressor(random_state=4)
CV_rfc = GridSearchCV(estimator=rfc, param_grid=param_grid, cv= 3, verbose=1, n_jobs=-1)
CV_rfc.fit(x_train, y_train)
CV_rfc.best_params_
clf2 = RandomForestRegressor(n_estimators=1000, max_features = 'sqrt', max_depth=10, random_state=4, oob_score=True)
clf2.fit(x_train, y_train)
print(clf2.oob_score_)
print(clf2.feature_importances_)
print(x_train.columns)<jupyter_output>0.9042640694388276
[0.33767208 0.21645386 0.02002816 0.08581751 0.34002839]
Index(['area', 'suites', 'dormitorios', 'banheiros', 'vagas'], dtype='object')<jupyter_text>Validação do modelo no conjunto de treinamento<jupyter_code>predicted = clf2.predict(x_train)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_train, predicted)
r2 = r2_score(y_train, predicted)
mae = mean_absolute_error(y_train, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_train, 'predicted': predicted, 'diff': (y_train - predicted)})
resultado = pd.concat([x_train, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Validação do modelo no conjunto de teste<jupyter_code>predicted = clf2.predict(x_test)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_test, predicted)
r2 = r2_score(y_test, predicted)
mae = mean_absolute_error(y_test, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_test, 'predicted': predicted, 'diff': (y_test - predicted)})
resultado = pd.concat([x_test, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Random Forest com transformacao polinomial<jupyter_code>from sklearn.preprocessing import PolynomialFeatures
transformer = PolynomialFeatures(degree=3, include_bias=False)
transformer.fit(x_train)
train_ = transformer.transform(x_train)
from sklearn.model_selection import GridSearchCV
param_grid = { 
    'n_estimators': [100, 200, 300, 400, 500, 600, 700, 800, 900, 1000],
    'max_features': ['sqrt', 'log2', 3, 4, 5, 6],
    'max_depth' : [2, 10, 20, 100, None]
}
rfc=RandomForestRegressor(random_state=4)
CV_rfc = GridSearchCV(estimator=rfc, param_grid=param_grid, cv= 3, verbose=1, n_jobs=-1)
CV_rfc.fit(train_, y_train)
CV_rfc.best_params_
clf3 = RandomForestRegressor(n_estimators=100, max_features = 'sqrt', max_depth=20, random_state=4, oob_score=True)
clf3.fit(train_, y_train)
print(clf3.oob_score_)<jupyter_output>0.895218562969256<jupyter_text>Validação do modelo no dataset de treinamento<jupyter_code>predicted = clf3.predict(train_)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_train, predicted)
r2 = r2_score(y_train, predicted)
mae = mean_absolute_error(y_train, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_train, 'predicted': predicted, 'diff': (y_train - predicted)})
resultado = pd.concat([x_train, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Validação do modelo no conjunto de teste<jupyter_code>transformer.fit(x_test)
test_ = transformer.transform(x_test)
predicted = clf3.predict(test_)
from sklearn.metrics import mean_squared_error, r2_score, mean_absolute_error
rmse = mean_squared_error(y_test, predicted)
r2 = r2_score(y_test, predicted)
mae = mean_absolute_error(y_test, predicted)
print('rmse = %', rmse)
print('r2 = %', r2)
print('mae = %', mae)
resultado = pd.DataFrame({'real': y_test, 'predicted': predicted, 'diff': (y_test - predicted)})
resultado = pd.concat([x_test, resultado], axis=1)
ax = resultado.plot(x='area', y='diff', kind='scatter')
ax.set_title('Análise dos erros')<jupyter_output><empty_output><jupyter_text>Analisando os dois imóveis com erros altos no conjunto de teste<jupyter_code>temp = resultado[resultado['diff'] < -1000000]
temp<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.1219408771504725, 'fraction_numerical': 0.0354373637024473, 'mean_word_length': 7.01018922852984, 'pattern_counts': {'":': 0, '<': 139, '<?xml version=': 0, '>': 136, 'https://': 1, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 2, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '34', 'dir': 'jupyter-structured-clean-dedup', 'id': '646423', 'license': 'MIT', 'n_tokens_mistral': 6568, 'n_tokens_neox': 6113, 'n_words': 1403, 'path': 'scripts/RegressaoImoveis.ipynb', 'repo_name': 'fbarth/ds-saint-paul', 'size': '16508'}