Что такое линейная регрессия?

Википедия утверждает: линейная регрессия в статистике — это линейный подход к моделированию связи между зависимой переменной и одной или несколькими независимыми переменными.

Линейная регрессия является основным и широко используемым типом прогнозного анализа.

Вернемся к школьной математике: каждую прямую можно представить уравнением: y = mx + b, где y — зависимая переменная, а X — независимая переменная, от которой зависит y.

Как мы можем использовать регрессию в реальной жизни?! Возьмем пример — что, если у меня есть данные за последние 5–10 лет о количестве производимой пшеницы ежегодно. С помощью линейной регрессии я смогу предсказать, каким будет производство пшеницы в этом году или через год.

Почему предсказание так важно? Это помогает нам планировать и быть готовыми. Это помогает нам справляться с непредвиденными ситуациями. В контексте приведенного выше примера страна будет знать количество пшеницы, которое она может экспортировать/импортировать за год. Это означает, что если глобальный спрос кажется намного ниже, чем количество, которое мы предполагаем производить, мы можем помочь фермерам выбрать какую-то другую культуру, поскольку меньший спрос означает минимальную цену продажи.

Некоторые дополнительные варианты использования:

  1. Постоянное повышение артериального давления и уровня сахара. Не приближается ли пациент к сердечному приступу?
  2. Характерная сейсмическая активность, нас ждет цунами/землетрясение?
  3. Внутренняя миграция птиц увеличивается с каждым годом. Определенные виды деревьев ответственны за приманку птиц?
  4. Будут ли акции определенных сталелитейных компаний двигаться вверх или вниз в этом году?

Это все некоторые основные варианты использования модели линейной регрессии. Мы называем это регрессией, потому что мы будем прогнозировать непрерывные значения (в отличие от результата «да» или «нет»). Графически линейное уравнение (с одной зависимой и одной независимой переменной) выглядит примерно так

Таким образом, для каждого X мы можем получить значение Y из уравнения.

Что произойдет, если Y зависит не только от одной независимой переменной (X), но и от нескольких других переменных. График выше будет иметь не только оси X, Y, но и ось Z для представления второй независимой переменной. Более двух независимых переменных трудно изобразить графически. Но можно довольно легко представить с помощью уравнения как

y= β + β1×1 + β2×2….

где β 1,β2…βn — коэффициенты при X1, X2, X3

β - y-пересечение

Что это означает для нашего примера производства пшеницы:

y(общее количество пшеницы, произведенной за год) = β + β1*Общая доступная земля в акрах + β2 * количество осадков, полученных за этот год + β3 * доступность удобрений на рынке….. Здесь количество полученных осадков, доступность удобрений являются дополнительными независимыми переменными. кроме размера земли в акрах.

Где машинное обучение входит в картину?

В приведенном выше уравнении — β1, β2, β3… все коэффициенты, значение которых нам нужно вычислить, чтобы составить линейное уравнение. Здесь происходит обучение. Основываясь на прошлых данных, ML изучает значения этих коэффициентов через ряд итераций.

Как?

Для начала мы загружаем данные за последние несколько лет в пакеты ML, это называется обучающими данными, поскольку они помогают обучать модель ML. Через большой блок данных и ряд итераций модель изучает значения каждого из коэффициентов.

Затем мы можем оценить модель, пакеты ML предлагают множество функций и связанных параметров, чтобы узнать, как работает модель. Основываясь на этих значениях, мы решаем, «достаточно ли» изучена модель, а затем используем это для данных, для которых нам нужно прогнозировать (тестовые данные).

О какой ошибке говорят в ML?

Если все точки данных (Y1, Y2, Y3….) образуют идеальную линейную линию, как показано выше, мы можем получить точный результат (прогноз), который мы ищем. Но в реальном мире это не так. Точки данных точно не образуют линию. Они немного разбросаны по графику. Так что же нам делать? Мы делаем линию таким образом, чтобы она находилась на минимально возможном расстоянии от точек, как показано ниже:

здесь используется среднеквадратическая ошибка или любой другой метод уменьшения ошибки. Итак, мы используем выбранный метод и получаем линию (которая лучше всего отображает заданные точки данных) в качестве вывода. На основе этой линии мы прогнозируем результат, отсюда берутся наши окончательные значения.

Давайте рассмотрим очень простой пример линейной регрессии в PySpark.

Я скачал набор данных с https://www.kaggle.com/leonbora/analytics-vidhya-loan-prediction.

from pyspark.sql import SparkSession spark = SparkSession.builder.appName('lr_example').getOrCreate()

2. Импорт пакетов линейной регрессии

from pyspark.ml.regression import LinearRegression

3. Прочитаем входные данные и посмотрим их структуру

data = spark.read.csv("train.csv",inferSchema=True,header=True) data.printSchema()
#output looks similar to this root |-- Loan_ID: string (nullable = true) |-- Gender: string (nullable = true) |-- Married: string (nullable = true) |-- Dependents: string (nullable = true) |-- Education: string (nullable = true) |-- Self_Employed: string (nullable = true) |-- ApplicantIncome: integer (nullable = true) |-- CoapplicantIncome: double (nullable = true) |-- LoanAmount: integer (nullable = true) |-- Loan_Amount_Term: integer (nullable = true) |-- Credit_History: integer (nullable = true) |-- Property_Area: string (nullable = true) |-- Loan_Status: string (nullable = true)

Пакеты машинного обучения ожидают только числовых входных данных и не могут принимать строки. Существует множество пакетов, которые помогут нам преобразовать наши данные в соответствии с требованиями ML. Этот аспект мы рассмотрим в другом посте. На данный момент мы просто рассмотрим два числовых поля из приведенной выше схемы данных («Доход заявителя», «Доход созаявителя») и попытаемся предсказать «Сумму займа» с помощью этих входных данных.

4. Все наши входные данные должны быть в виде векторов, входных данных для пакетов ML. Итак, давайте сначала разберемся с этим:

from pyspark.ml.feature import (VectorAssembler, VectorIndexer) #lets define what inputs will go into our vector and give a name for the output of it lassembler = VectorAssembler( inputCols=['ApplicantIncome','CoapplicantIncome'], outputCol='features')

5. Теперь мы преобразуем наши данные в стандартный ввод ML.

output = lassembler.transform(data)

Если вы загрузили тот же набор, выполнение приведенной выше команды выведет что-то похожее на:

Ошибка довольно ясна, при преобразовании данных ML обнаружил в данных нули и запрашивает разъяснение того, что нужно сделать. У нас есть два варианта: один, очистить данные от нулевых значений и передать их обратно или указать пакетам ML пропускать нулевые значения. Мы выберем второй маршрут, добавив дополнительную строку на шаге 5.

output = lassembler.setHandleInvalid("skip").transform(data)

Теперь код выполняется. Давайте посмотрим, что там в выводе «features»

output.select("features").show()
#output looks similar to below +-----------------+ | features| +-----------------+ | [4583.0,1508.0]| | [3000.0,0.0]| | [2583.0,2358.0]| | [6000.0,0.0]| | [5417.0,4196.0]| | [2333.0,1516.0]| | [3036.0,2504.0]| | [4006.0,1526.0]| |[12841.0,10968.0]| | [3200.0,700.0]| | [2500.0,1840.0]| | [3073.0,8106.0]| | [1853.0,2840.0]| | [1299.0,1086.0]| | [4950.0,0.0]| | [3596.0,0.0]| | [3510.0,0.0]| | [4887.0,0.0]| | [2600.0,3500.0]| | [7660.0,0.0]| +-----------------+ only showing top 20 rows

6. Давайте теперь подадим этот входной вектор и наше значение прогноза (Y), которое равно «LoanAmount».

loan_data = output.select('features','LoanAmount') loan_data.show()
#and Output is +-----------------+----------+ | features|LoanAmount| +-----------------+----------+ | [4583.0,1508.0]| 128| | [3000.0,0.0]| 66| | [2583.0,2358.0]| 120| | [6000.0,0.0]| 141| | [5417.0,4196.0]| 267| | [2333.0,1516.0]| 95| | [3036.0,2504.0]| 158| | [4006.0,1526.0]| 168| |[12841.0,10968.0]| 349| | [3200.0,700.0]| 70| | [2500.0,1840.0]| 109| | [3073.0,8106.0]| 200| | [1853.0,2840.0]| 114| | [1299.0,1086.0]| 17| | [4950.0,0.0]| 125| | [3596.0,0.0]| 100| | [3510.0,0.0]| 76| | [4887.0,0.0]| 133| | [2600.0,3500.0]| 115| | [7660.0,0.0]| 104| +-----------------+----------+ only showing top 20 rows

7. Стандартная практика состоит в том, чтобы разделить тестовые данные на 2 части: обучить модель машинного обучения первой и позволить ей предсказать значения второго набора, чтобы мы могли перепроверить производительность.

#splitting train and test data into 70% and 30% of total data available train_data,test_data = loan_data.randomSplit([0.7,0.3]) #finally, calling the linear regression package we imported lr = LinearRegression(labelCol='LoanAmount') #we are specifying our 'Y' by explicitly mentioned it with 'labelCol' #fitting the model to train data set lrModel = lr.fit(train_data)

Когда вы запустите вышеуказанное, вы должны получить результат, как показано ниже.

Ошибка говорит — «Параметры должны быть либо картой параметров…». Причина этой ошибки в том, что наша зависимая переменная (LoanAmount) имеет нулевые значения, а ML не может соответствовать модели, которая является нулевой в качестве выходных значений. Есть много способов очистить такие данные, мы не будем рассматривать нулевые значения в нашем примере. Давайте отфильтруем нулевые значения «LoanAmount», когда мы читаем данные из самого csv, например:

data = spark.read.csv("train.csv",inferSchema=True,header=True) #we will add a filter to remove the null values from our dependent variable data = data.filter("LoanAmount is not NULL") data.printSchema()

Повторите шаги, описанные выше, и ошибка исчезнет. Итак, наша модель линейной регрессии готова.

8. Давайте проверим остатки (остаток = наблюдаемое значение (значение на наших входных данных) — прогнозируемое значение (значение, предсказанное моделью) Y). Каждая точка данных будет иметь одну невязку. Таким образом, количество остатков будет равно количеству записей, которые мы подали в качестве входных данных.

test_results = lrModel.evaluate(test_data) test_results.residuals.show()
#output looks similar to below +--------------------+ | residuals| +--------------------+ |5.684341886080801...| |-1.42108547152020...| |-4.26325641456060...| |-1.42108547152020...| |-1.42108547152020...| |-2.84217094304040...| |-1.42108547152020...| |-1.42108547152020...| |-1.42108547152020...| |-1.42108547152020...| | 0.0| |-1.42108547152020...| |-2.13162820728030...| |-1.42108547152020...| |-2.84217094304040...| | 0.0| |2.842170943040400...| |-1.42108547152020...| |-1.42108547152020...| |-3.55271367880050...| +--------------------+ only showing top 20 rows

9. Вуаля, теперь мы можем использовать эту модель для прогнозирования вывода наших тестовых данных.

predictions_data = test_data.select('features') predictions = lrModel.transform(predictions_data) predictions.show()

Первоначально опубликовано на http://blog.wisdatum.com 7 апреля 2019 г.