Pandas ve Sci-Kit Learn İle Veri Önişleme Hakkında Bir Sorum Var

Merhaba arkadaşlar.

Şu sitedeki, şu csv dosyası yine aynı sitedeki şu Python kodu ile önişlenmiş. Ama bana fazla karmaşık geldi.
Bunun daha basit, daha okunaklı ve daha anlaşılır bir yöntemi var mıdır?

Şimdiden teşekkür ederim. :slight_smile:

1 Beğeni

merhaba, buna eşlik eden bir video var mı ki, sanki anlatarak yazılmış gibi. Ona erişiminiz var mı varsa?

Sitede Udemy eğitiminin linki var.

1 Beğeni

Videosu var ama, BTK Akademi’de. YouTube’da bir kopyasını bulmaya çalıştım ama bulamadım. :confused:

1 Beğeni
# -*- coding: utf-8 -*-

"""

Created on Mon Jul  6 18:50:13 2020

@author: sadievrenseker

"""

#kutuphaneler

import numpy as np

import matplotlib.pyplot as plt

import pandas as pd
veriler = pd.read_csv('eksikveriler.csv')
print(veriler)

Eğer bir CSV dosyası yüklenecekse, pandas.read_csv ilk adres eğer pandas kullanıyorsak. Verilere şöyle bir bakmak da hemen 2.aşama (print’in yaptığı). Hemen sonra birtakım grafikler çizmek iyi olabilir ama burada yok.

boy = veriler[['boy']]
print(boy)

boykilo = veriler[['boy','kilo']]
print(boykilo)

burada eldeki verilere şöyle bir bakılıyor. DataFrame indekslemenin yollarından biri görülüyor.

x = 10

class insan:
    boy = 180
    def kosmak(self,b):
        return b + 10

ali = insan()
print(ali.boy)
print(ali.kosmak(90))

bu neden var bilmiyorum. OOP ile ilgili bir konuya hatırlatma amaçlı temas ediliyor olabilir.

from sklearn.impute import SimpleImputer

imputer = SimpleImputer(missing_values=np.nan, strategy='mean')

Yas = veriler.iloc[:,1:4].values

print(Yas)

imputer = imputer.fit(Yas[:,1:4])

Yas[:,1:4] = imputer.transform(Yas[:,1:4])

print(Yas)

yas sütununda eksik veriler var. (veriyi print ettiğinizde nan (not a number) diye gözüken şeyler. Burada bunların doldurulması amaçlanıyor. Gelin görün ki 1 satırlık işlem 8 satırda yapılıyor, ama amaç sklearn'ün Imputer’larını göstermek olsa gerek. Bir de, yas sütunu 3.sütun olmasına rağmen (0 indeksli), yazar [1:4] gibi bir seçim yapıyor. Sadece yası değil, boy ve kiloyu da alıyor. Buna gerek yoktur; ancak yineleyeyim: bazı şeyleri göstermek adına yapıyor olabilir, videoyu izlemek gerek.

Bu kod kütlesinin eşdeğeri

veriler.yas.fillna(veriler.yas.mean(), inplace=True)

veya

veriler.yas = veriler.yas.fillna(veriler.yas.mean())

(inplace'e dikkat birinde var birinde yok!)

Meali şudur: `verilerin “yaş” sütunundaki eksik elemanları (na) verilerin yaş sütununun ortalamasıyla (mean) doldur (fill). Birinde olduğu yerde değiştir (inplace), diğerinde döndür sen değeri ben eşitleyeyim. (hangisi daha iyi derseniz, ikincisinin tercih edilesi olduğunu söyleyebiliriz.

ulke = veriler.iloc[:,0:1].values
print(ulke)

from sklearn import preprocessing

le = preprocessing.LabelEncoder()

ulke[:,0] = le.fit_transform(veriler.iloc[:,0])

print(ulke)

Neden [0:1] denmiş de direkt [0] denmemiş: bir şey anlatmaya çalışıyor olabilir, videoya bakmak gerek… Onun dışında, LabelEncoder, "aralarında sıralı bir ilişki bulunduğu varsayılabilen ve modelin çıktılarından meydana gelen sütün"un kullanımına mahsustur. Burada hedef çıktı (yani tahmin edilmek istenen sütun) nedir tam bilemiyorum, ülke olabilir belki.

Eğer ülke değilse, LabelEncoderı burada kullanmamalıyız zira hedef çıktı değil (OrdinalEncoder'a yönelmeliyiz).

Eğer ülke hedef çıktı ise, yine kullanmamalıyız zira en son print edilen değerden de görebileceğiniz üzere, ülkeler arası bir sıralama meydana geliyor: tr: 1, us: 2, fr: 0. Böylesi bir sıralama olmadığı için (var mı yoksa :d), bu işlem yapılmamalıdır. Niye? Çünkü bu işlem yapılırsa, model amerikatürkiyenin iki katı gibi değerlendirecek, fransanın ise türkiyeye amerikadan daha yakın olduğunu varsayacaktır. Bunlar makul olmadığından böylesi bir encode’lamadan bu durumda kaçınırız.

Ne zaman kaçınmamalıyız mesela? Diyelim ki IMDB reytinglerini tahmin ediyorsunuz: kötü, orta, iyi , baya iyi gibi. O zaman sırasıyla 0, 1, 2, 3 değerleri atamak makuldur ve istenen bir durumdur. Yazar heralde “bunu kullanmayın” demek için bu kodları yazmıştır, zira bir sonrakinde daha iyi seçeneği görüyoruz.

ohe = preprocessing.OneHotEncoder()

ulke = ohe.fit_transform(ulke).toarray()

print(ulke)

“kategorik” denilen, nümerik olmayan (ülke, cinsiyet) gibi değişkenlerin bir şekilde sayıya çevrilmesi gerek. Bir önceki LabelEncoder bir çözüm sunuyordu, her zaman uygun olmayan. OneHotEncoding ise hemen hemen her zaman kategorik encode’lamada kullanılabilecek bir yöntem zira yaptığı şey, sütundaki eşsiz değerlerin sayısını bulmak (ülke için 3: tr, fr, us). Sonrasında bu uzunlukta 0’lardan oluşan vektörler oluşturmak ve hangi ülkedeyse sıra onun olduğu kısma 1 koymak. Yani; [1, 0, 0] tr için, [0, 1, 0] fr için ve [0, 0, 1] us için gibi. Bu, az önceki yapay olarak ortaya gelen “önem sıralamasının” önüne geçiyor. Kodda verilen print(ulke)den sonra daha anlaşılır olabilir.

Tabii, bu encode’lamalar için luraya bakabilirsiniz isterseniz: https://towardsdatascience.com/all-about-categorical-variable-encoding-305f3361fd02 Yazar .toarray kullanmış çünkü dönen şey sparse bir matris yani pek bir olayı yok onun. Onun önüne geçmek için OneHotEncoder constructor’ına sparse=False verebilirsiniz, toarray'e gerek kalmaz.

print(list(range(22)))

sonuc = pd.DataFrame(data=ulke, index = range(22), columns = ['fr','tr','us'])

print(sonuc)

sonuc2 = pd.DataFrame(data=Yas, index = range(22), columns = ['boy','kilo','yas'])

print(sonuc2)

cinsiyet = veriler.iloc[:,-1].values

print(cinsiyet)

sonuc3 = pd.DataFrame(data = cinsiyet, index = range(22), columns = ['cinsiyet'])

print(sonuc3)

s=pd.concat([sonuc,sonuc2], axis=1)

print(s)

s2=pd.concat([s,sonuc3], axis=1)

print(s2)

bu kısmın verileri değiştiren işleyen bir tarafı yok. Heralde DataFrame ve pd.concat anlatılmak istenmiş.

1 Beğeni

Evet tamda öyle, Allah’tan Python’u ve OOP’yi daha önceden öğrenmişim. :smile:


İşte benim devreler, tam da burda kopuyor. Yani: hoca önce DataFrame komple dağıtıyor, birkaç değişiklik yapıp geri topluyor; en azından benim anladığım(daha doğrusu anlayamadığım :slight_smile:) bu.


Evet, hoca burda kategorik verileri, sütunlara bölmenin daha faydalı olduğunu anlatmıştı.


Burası da, anladığım kadarıyla hocanın dağıttığı DataFrame’i geri topladığı kısım.


Ve şunu belirtmeliyim ki: yapay zeka ile uğraştığnızdan mıdır bilmem, kendi zekanızda epey gelişmiş, çoğu şeye sanki videoyu izlemiş gibi cevap verdiniz.

Son olarak, gerçekten çok teşekkür ederim :slight_smile:. Elinize emeğinize sağlık. Sayenizde üstüne devam edebileceğim düzgün bir taslağım oldu ve olayın temelini daha düzgün kavradım. Aslında hocanın anlatışı fena sayılmaz, ama Makine Öğrenmesi gibi önemli bir konuya hız limitini aşarak girdiği için pek birşey anlayamadım. :smile:

1 Beğeni

Bu anlatıklarınız üzerine dosyayı şu şekilde optimize ettim:

from sklearn import preprocessing
import pandas as pd
import numpy as np


veriler = pd.read_csv('eksikveriler.csv')
print(veriler)


veriler.yas = veriler.yas.fillna(veriler.yas.mean())


ohe = preprocessing.OneHotEncoder(sparse=False)
ulke = ohe.fit_transform(veriler.iloc[:,0:1].values)

ulke = pd.DataFrame(data=ulke, index=range(len(ulke)), columns = ['fr','tr','us'])
veriler = veriler.drop("ulke", axis=1)
veriler = pd.concat([ulke, veriler], axis=1)


print(veriler)

Neticede aynı sonuca daha kısa ve düzgün bir kodla ulaştım. Bu kodu, hem “belki birinin işine yarar” diye; hem de, bir yanlışlık varsa söyleyin diye bırakıyorum.

1 Beğeni