Anasayfa / Büyük Veri / Çoklu Doğrusallık Sorunu Çözümünde VIF

Çoklu Doğrusallık Sorunu Çözümünde VIF

Çoklu regresyon analizinde bağımsız niteliklerin bağımlı nitelik üzerindeki etkisi incelenir. Bazı bağımsız nitelikler birbirleriyle yüksek doğrusal korelasyona sahip olduğundan bağımlı değişken üzerindeki etkisi dağılır. Modelin sadeliği va anlaşılırlığı adına bağımlı değişkene en çok etki eden az sayıda değişken ile model oluşturmak arzu edilen bir durumdur. Küçük veri analizinde kullanılan SPSS gibi paket programlar çoklu bağlantı tesptini yapabilmektedir. Ancak büyük veri dünyasında bu işler henüz o kadar olgunlaşmadı ve kolay da değil. Geçen gün Spark Scala ile çalışma yaparken benim de işim düştü çoklu bağlantı tespitine. Spark ML kütüphanesinde bir şey bulamadım. Böyle olunca ekip olarak biz de bir VIF değeri hesaplayan fonksiyon yazdık.

Az önce de bahsettiğim gibi bu yazımızda nitelikler arası çoklu bağlantıyı tespit etme yöntemlerinden biri olan Variance Inflation Factor (VIF – Varyans Enflasyon Faktörü)’den bahsedeceğiz ve Spark Scala ile basit bir örnek yapacağız. VIF’de her bir nitelik diğer niteliklerle sıra ile regresyona sokulur. bunun sebebi R2 değerini hesaplamaktadır. Çünkü VIF değerini tespit etmek için R2‘nin bilinmesine ihtiyaç vardır. R2 ile ilgili bilgilerimizi kısaca bir tazeleyelim. Veri noktalarının regresyon eğrisine uzaklıklarının, ortalamaya olan uzaklıklarına oranının 1’den çıkarılması bize R2‘yi verir, daha detaylı bilgi için buraya bakınız. VIF ise 1’in  R2‘nin 1’den çıkarılmış haline bölümüdür.

İki bağımsız değişken arasındaki ilişki arttıkça VIF değeri artar, azaldıkça azalır. İlişkinin olmaması 1 alt sınır; tam ilişki ise ∞ ise üst sınırdır.

 VIF=\frac { 1 }{ 1-{ R }^{ 2 } }

Uygulama esnasında kullanılan yazılım geliştirme ortamı, programlama dili,  işletim sistemi ve sürüm bilgileri: Spark 2.1.1, YARN, Hadoop 2.6.2, Scala 2.11, Apache Zeppelin Notebook, Spark2 interpreter.

Veri Setini Yükleme

[erkan@node3 ~]$ hdfs dfs -put /home/erkan/veri_setlerim/iris.csv /user/erkan/veri_setlerim/
[erkan@node3 ~]$ hdfs dfs -ls /user/erkan/veri_setlerim

Çıktı:

-rw-r--r-- 2 erkan hadoop 4551 2018-01-09 19:12 /user/erkan/veri_setlerim/iris.csv

Iris veri setini HDFS’e aktardıktan sonra Zeppelin’e geçiyorum. Iris veri dosyasını incelediğimde başlıkların olmadığını gördüm. Bu yüzden veri yüklerken option("header","true") seçeneğini kullanmıyorum. Onun yerine load() fonksiyonu sonunda toDF() içine el ile hazırladığım nitelikler listesini parametre olarak veriyorum.

val nitelikler = Seq("sepal-length","sepal-with","pedal-length","pedal-width","label")
val irisDF = spark.read.format("csv").option("inferSchema","true").load("/user/erkan/veri_setlerim/iris.csv").toDF(nitelikler:_*)

Yüklediğimiz veriye bir göz atalım:

irisDF.show(5)

Çıktı:

+------------+----------+------------+-----------+-----------+
|sepal-length|sepal-with|pedal-length|pedal-width|      label|
+------------+----------+------------+-----------+-----------+
|         5.1|       3.5|         1.4|        0.2|Iris-setosa|
|         4.9|       3.0|         1.4|        0.2|Iris-setosa|
|         4.7|       3.2|         1.3|        0.2|Iris-setosa|
|         4.6|       3.1|         1.5|        0.2|Iris-setosa|
|         5.0|       3.6|         1.4|        0.2|Iris-setosa|
+------------+----------+------------+-----------+-----------+
only showing top 5 rows

Son olarak VIF sonuçlarını hesaplayıp yazdıran fonksiyonumuzu paylaşıyorum. Gerekli açıklamaları kodların içinde yazdığım için burada fazla bir açıklamada bulunmuyorum.

// Nitelikler arası çoklu bağlantıyı tespitedip gereksiz niteliklerin budanması için
//Önce kütüphaneler
import org.apache.spark.ml.regression._
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.sql.DataFrame

// Dataframe alarak içindeki her bir nitelik için VIF hesaplayan ve sonuçları yazdıran fonksiyon
def printCloumnsVIF(data:DataFrame):Unit = {
	
// Tüm sütun isimlerini listele ve hesaplamak istemediğin sütun isimlerini listeden çıkar. 
// (Bunlar hedef nitelik veya kategorik nitelikler olabilir mesela)
val columns = data.columns.filter(_ != "label")

// Sütun isimleri listesini (columns) tek tek dolaş.
for (col<- columns) {
			
	// Döngüde sırası gelen nitelik haricindeki tüm nitelikler bağımsız nitelik olsun.
	val inputCols = columns.filter(_ != col)
			
	// Hedef değişken döngüde sırası gelen nitelik olsun
	val outputCol = col
			
	// Vector Assembler nesnesi oluştur 
	val assembler = new VectorAssembler().setInputCols(inputCols).setOutputCol("features")
			
	// VectorAssembler nesnesi ile döngü sırası haricindeki tüm nitelikleri tek sütunda birleştir 
	val assembled_df = assembler.transform(data)
		 
	// Lineer regresyon nesnesi oluştur girdi nitelikler ve hedef niteliği set et.
	val lr = new LinearRegression().setFeaturesCol("features").setLabelCol(col)
		 
	// Oluşturduğun lineer modeli eğit
	val model = lr.fit(assembled_df)
		 
	// Eğitilen model r2 hesaplamıştı. Bu modelden r2'yi kullanarak VIF'yi hesapla ve yazdır.
	println(col + " için VIF değeri: " + 1/(1-model.summary.r2))
		 
	}
}
        
// Yukarıda hazırladığımız fonksiyonu burada çağırıp içine iris datasını verelim.
printCloumnsVIF(irisDF)

Çıktılarımız:

import org.apache.spark.ml.regression._
import org.apache.spark.ml.feature.VectorAssembler
import org.apache.spark.sql.DataFrame
printCloumnsVIF: (data: org.apache.spark.sql.DataFrame)Unit
sepal-length için VIF değeri: 7.1031134428332985
sepal-with için VIF değeri: 2.09903862574209
pedal-length için VIF değeri: 31.39729165071975
pedal-width için VIF değeri: 16.141563956997715

Sonuçların yorumu:
sepal-length ve sepal-with değerleri fena durmuyor. Kalan iki nitelikte aşırı bir bağlantıya sahip değilse de ilk iki niteliğe göre epey fazla. Ben olsam ilk iki niteliği tutardım. Acaba doğru mu yapardım?
Hoşçakalın…

Kapak resmi kaynak: https://www.kiplinger.com/article/business/T019-C000-S010-inflation-rate-forecast.html

Hakkında Erkan ŞİRİN

2014'ten beri hem akademik alanda hem de sektörde pratik anlamda büyük veri ve veri bilimi ile ilgili çalışmalar yürütmektedir. Halihazırda İmpektra Bilişim A.Ş.'de büyük veri yöneticisi olarak çalışmakta olup aynı zamanda Gazi Üniversitesi Yönetim Bilişim Sistemleri doktora öğrencisidir. Büyük veri ve veri bilimi ile ilgili birçok kurum ve şirkete eğitimler vermekte ve projeler icra etmektedir. Çalışma alanları: büyük veri platformlarının kurulum ve yönetimi, büyük veri üzerinde makine öğrenmesi, olağan dışılık tespiti, sahtecilik tespiti, veri hazırlama sürecidir.

GÖZ ATMAK İSTEYEBİLİRSİNİZ

Pandas Dataframe’i MongoDB’ye Yazmak

Merhabalar bu yazımızda Python Pandas Dataframe verisini Python kullanarak MongoDB’ye yazacağız. MongoDB ile etkileşime geçmek …

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir