<jupyter_start><jupyter_text>Tytuł projektu Dane pobrałem stąd - https://www.kaggle.com/orgesleka/used-cars-database . Są to ogłoszenia o sprzedaży samochodów z niemieckiego serwisu Ebay, zebrane w roku 2016. Na ich podstawie postaram się wyestymować cenę samochodu w zależności od jego parametrów, takich jak moc oraz licznik kilometrów,<jupyter_code>import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
from sklearn.model_selection import train_test_split
from google.colab import drive
drive.mount('/content/drive')
#autos = pd.read_csv('autos.csv', encoding='cp1252')
autos = pd.read_csv('/content/drive/My Drive/Colab Notebooks/autos.csv', encoding='cp1252')
autos.info()
autos.head()<jupyter_output><empty_output><jupyter_text>Jak widać, mamy sporo kolumn, z czego nie wszystkie nas interesują, część ma też puste wartości.Zajmijmy się wstępną obróbką danych. Najpierw zdecydujemy, jakie kolumny mogą zawierać wartościowe informacje. Kolumna name nie jest interesująca - jest to po prostu tytuł ogłoszenia. Wszystkie potrzebne informacje o autach są zawarte w innych kolumnach. Kolumna seller zawiera informacje o tym, czy sprzedawcą jest osoba prywatna, czy dealer, też jest nieistotna. Usuniemy też kolumny z datą stworzenia ogłoszenia, liczbą zdjęć, kodem pocztowym, ostatnim momentem, kiedy ogłoszenie było widoczne, miesiącem rejestracji (zostawimy rok).<jupyter_code>autos = autos.drop(columns = ['dateCrawled', 'name', 'seller', 'monthOfRegistration', 'dateCreated', 'nrOfPictures', 'postalCode', 'lastSeen'])<jupyter_output><empty_output><jupyter_text>Kolumna offerType zawiera tylko dwie wartości, z czego druga występuje bardzo rzadko. Nie wniesie żadnych informacji, więc ją usuniemy.<jupyter_code>autos['offerType'].value_counts()
autos = autos.drop(columns = ['offerType'])<jupyter_output><empty_output><jupyter_text>Załóżmy, że powypadkowe samochody nas nie iteresują. W takim razie, usuńmy wszystkie auta, które mają jakieś nienaprawione uszkodzenia.<jupyter_code>autos = autos[autos['notRepairedDamage'] != 'ja']<jupyter_output><empty_output><jupyter_text>Odfiltrujmy wartości, które na pewno nie są poprawne, np. samochody zarejestrowane w 1200 roku.<jupyter_code>autos['yearOfRegistration'].unique()
autos = autos[autos['yearOfRegistration'].between(1950, 2016)]
autos = autos[autos['price'].between(200, 75000)]
autos = autos[autos['powerPS'].between(30, 800)]
autos = autos[autos['kilometer'].between(1000, 400000)]<jupyter_output><empty_output><jupyter_text>Teraz zobaczmy, czy mamy jakieś brakujące dane.<jupyter_code>autos.isnull().sum()<jupyter_output><empty_output><jupyter_text>Jak widać, 5 kolumn ma brakujące dane. Możemy albo usunąć te wiersze, albo uzupełnić je innymi danymi. Ewentualnie usunąć całą kolumnę, co zrobię z kolumną notRepairedDamage ( już i tak uzyskaliśmy potrzebne z niej informacje).<jupyter_code>autos = autos.drop(columns = ['notRepairedDamage'])<jupyter_output><empty_output><jupyter_text>W przypadku skrzyni biegów, możemy uzupełnić wartości skojarzone z marką auta ( to pole nie zawiera żadnych pustych wartości). To samo zrobimy z typem paliwa.<jupyter_code>def fill_values (column_in, column_out, fill_null):
    val_dict = { 'brand_name' : ('gear_type', 1)}

    for (brand_name, gear_type), gear_count in autos.groupby(column_in)[column_out].value_counts().items():
        if brand_name in val_dict :
            if gear_count > val_dict[brand_name][1] :
                val_dict[brand_name] = (gear_type, gear_count)
        else:
            val_dict[brand_name] = (gear_type, gear_count)

    for brand_name in val_dict:
        if fill_null:
            autos.loc[(autos[column_in] == brand_name) & (autos[column_out].isnull()), column_out] = val_dict[brand_name][0] 
        else:
            autos.loc[(autos[column_in] == brand_name) & (autos[column_out] == 0), column_out] = val_dict[brand_name][0] 

fill_values('brand', 'gearbox', True)

fill_values('brand', 'fuelType', True)<jupyter_output><empty_output><jupyter_text>Następnie usuniemy wszystkie modele, które nie istnieją, a potem uzupełnimy wartości kolumny vehicleType skojarzone z nazwą modelu.<jupyter_code>autos = autos[autos['model'].notnull()]
fill_values('model', 'vehicleType', True)<jupyter_output><empty_output><jupyter_text>Jak widać, nasze dane nie zawierają żadnych pustych pól. Warto też zobaczyć, w jakim stanie aktualnie jest nasz data frame.<jupyter_code>print(autos.isnull().sum())
autos.head()<jupyter_output>price                 0
abtest                0
vehicleType           0
yearOfRegistration    0
gearbox               0
powerPS               0
model                 0
kilometer             0
fuelType              0
brand                 0
dtype: int64<jupyter_text>Nie przejmujemy się też tym, czy oferta była wystawion jako abtest. Dodatkowo, uzupełnijmy też wartości kolumny powerPS w miejscach, gdzie jest równa 0 - cena będzie zależna od mocy.<jupyter_code>autos = autos.drop(columns = ['abtest'])
fill_values('model', 'powerPS', False)
autos.head()<jupyter_output><empty_output><jupyter_text>Ostatnią rzeczą jaką wykonamy, jest zamienieni wszystkich kolumn z liczbami na typ numeryczny ( ponieważ niektóre są typu object) oraz zamiana kolumn z dwoma wartościami na 0 oraz 1 (czyli gearbox).<jupyter_code>autos['powerPS'] = pd.to_numeric(autos['powerPS'])
autos.loc[autos['gearbox'] == 'manuell', 'gearbox'] = 0
autos.loc[autos['gearbox'] == 'automatik', 'gearbox'] = 1
autos['gearbox'] = pd.to_numeric(autos['gearbox'])<jupyter_output><empty_output><jupyter_text>Teraz możemy sobie zwizualizować różne zależności. Zobaczmy najpierw, czy są jakieś koleracje między danymi.<jupyter_code>sns.set(style="darkgrid")

corr = autos.corr()

# Generate a mask for the upper triangle
mask = np.zeros_like(corr, dtype=np.bool)
mask[np.triu_indices_from(mask)] = True

# Set up the matplotlib figure
f, ax = plt.subplots(figsize=(11, 9))

# Generate a custom diverging colormap
cmap = sns.diverging_palette(220, 10, as_cmap=True)

# Draw the heatmap with the mask and correct aspect ratio
sns.heatmap(corr, mask=mask, cmap=cmap, vmin=-1, vmax=1,
            square=True, xticklabels=corr.columns, yticklabels=corr.columns,
            linewidths=.5, cbar_kws={"shrink": .5}, ax=ax, annot=True)
plt.show()
corr<jupyter_output><empty_output><jupyter_text>Jak widać, jakieś są, szczególnie, po oczyszczeniu danych ( przed były bliskie zeru). Największa koleracja (pozytywna) występuje pomiędzy ceną, a mocą auta, a największa (negatywna) między ceną, a przebiegiem.<jupyter_code>autos.describe()<jupyter_output><empty_output><jupyter_text>Teraz, podzielimy dane na zestaw treningowy i testowy. Niestety, musiałem bardzo obciąć zbiór, bo nie starczało mi pamięci.<jupyter_code>temp, temp2 = train_test_split(autos, test_size=0.9)
temp = temp.drop(columns = ['vehicleType','gearbox', 'fuelType', 'brand', 'model'])
from sklearn.preprocessing import MinMaxScaler
scaler = MinMaxScaler()
temp[['price', 'yearOfRegistration', 'powerPS','kilometer']] = scaler.fit_transform(temp[['price', 'yearOfRegistration', 'powerPS','kilometer']])
autos_train, autos_test = train_test_split(temp, test_size=0.5)
temp
#https://stackoverflow.com/a/40005797
autos_train['single_input_vector'] = autos_train[['yearOfRegistration','powerPS', 'kilometer']].apply(tuple, axis=1).apply(list)
autos_train['single_input_vector'] = autos_train.single_input_vector.apply(lambda x: [list(x)])
autos_train['cumulative_input_vectors'] = autos_train.single_input_vector.cumsum()
autos_train['output_vector'] = autos_train[['price']].apply(tuple, axis=1).apply(list)
X_train_init = np.asarray(autos_train[['yearOfRegistration','powerPS', 'kilometer']])
X_train = np.hstack(X_train_init).reshape(len(autos_train),1, 3)
y_train = np.hstack(np.asarray(autos_train.output_vector)).reshape(len(autos_train),1)<jupyter_output>/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:2: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:3: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead

See the caveats in the documentation: https://pandas.pydata.org/pandas-docs/stable/user_guide/indexing.html#returning-a-view-versus-a-copy
  This is separate from the ipykernel package so we can avoid doing imports until
/usr/local/lib/python3.6/dist-packages/ipykernel_launcher.py:4: SettingWithCopyWarning: 
A value is trying to be set on a copy of a slice from a DataFrame.
Try using .loc[row_indexer,col_indexer] = value instead[...]<jupyter_text>Zróbmy sobie pierwszy model RNN<jupyter_code>from keras.models import Model, Sequential
from keras.layers import LSTM, Dense

# Build the model
model = Sequential()

input_length = X_train.shape[1]
input_dim = X_train.shape[2]
# Output dimensions is the shape of a single output vector
# In this case it's just 1, but it could be more
output_dim = len(y_train[0])

model.add(LSTM(4, input_dim = input_dim, input_length = input_length))
model.add(Dense(output_dim, activation='relu'))



model.compile(loss='mean_squared_error',
              optimizer='sgd',
              metrics=['accuracy'])
history = model.fit(X_train, y_train,
              batch_size=100, nb_epoch=200,
              verbose = 1)
autos_test['single_input_vector'] = autos_test[['yearOfRegistration','powerPS', 'kilometer']].apply(tuple, axis=1).apply(list)
autos_test['single_input_vector'] = autos_test.single_input_vector.apply(lambda x: [list(x)])
autos_test['cumulative_input_vectors'] = autos_test.single_input_vector.cumsum()
X_train_init1 = np.asarray(autos_test[['yearOfRegistration','powerPS', 'kilometer']])
X_test = np.hstack(X_train_init1).reshape(len(autos_train),1,3)
plt.plot(history.history['accuracy'])
plt.show()
plt.plot(history.history['loss'])
plt.show()

X_train = np.hstack(X_train_init).reshape(len(autos_train), 3)
X_test = np.hstack(X_train_init1).reshape(len(autos_train),3)
autos_test['output_vector'] = autos_test[['price']].apply(tuple, axis=1).apply(list)
y_test = np.hstack(np.asarray(autos_test.output_vector)).reshape(len(autos_test),1)

from keras.callbacks import History

history = History()
model = Sequential()
model.add(Dense(2704,activation="sigmoid",input_shape=(X_train.shape[1],)))
model.add(Dense(50,activation="sigmoid"))
model.add(Dense(10,activation="sigmoid"))
model.add(Dense(1,activation="sigmoid"))
model.summary()
model.compile(loss="binary_crossentropy",optimizer="Adam", metrics=["accuracy"])
history = model.fit(X_train, y_train, validation_data= (X_test, y_test), batch_size=32,epochs=100)
import pandas as pd

pd.DataFrame(history.history).plot(figsize=(8, 5))
plt.grid(True)
plt.gca().set_ylim(0, 1)
plt.show()
model.evaluate(X_test,y_test)
model.predict(X_test)<jupyter_output><empty_output>
{'fraction_non_alphanumeric': 0.11882702167851039, 'fraction_numerical': 0.013492848790141225, 'mean_word_length': 6.163659793814433, 'pattern_counts': {'":': 1, '<': 63, '<?xml version=': 0, '>': 64, 'https://': 4, 'lorem ipsum': 0, 'www.': 1, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'chain_length': '16', 'dir': 'jupyter-structured-clean-dedup', 'id': '308626', 'license': 'MIT', 'n_tokens_mistral': 4295, 'n_tokens_neox': 4232, 'n_words': 865, 'path': 'Projekt.ipynb', 'repo_name': 'thefil9/AIProject', 'size': '11117'}