Correlación con Python – Ejercicio Estación Meteorológica

Referencia: Ross 8.2 p334

De una estación meteorológica se obtiene un archivo.csv con los datos de los sensores disponibles.

2021_10_EstMeteorologica.csv

 

Nota: las instrucciones para la lectura del archivo se describen en:

Archivos.csv con Python – Ejercicio con gráfica de temperatura y Humedad

Para observar la correlación entre las medidas obtenidas de varios sensores, se considera usar las variables:

sensor_EM = ["TEMP","Humidity","Solar_rad","Bar_press."]

La correlación entre las variables se realiza seleccionando las columnas desde una lista, para luego realizar la operación desde una de las funciones de Pandas-Python

# Matriz de Correlación
mediciones = tablaEM[sensor_EM].copy()
correlacion_matriz = mediciones.corr()

obteniendo como resultados:

Matriz de correlación:
                TEMP  Humidity  Solar_rad  Bar_press.
TEMP        1.000000 -0.957730   0.743379   -0.387187
Humidity   -0.957730  1.000000  -0.765766    0.447845
Solar_rad   0.743379 -0.765766   1.000000   -0.093236
Bar_press. -0.387187  0.447845  -0.093236    1.000000

Del resultado se observa que el coeficiente de correlación entre las mediciones de «TEMP» y «Humidity» es alta. Para observar el caso se usa la gráfica entre las dos variables comparando los datos en el tiempo por fechas.
Cuando la temperatura aumenta la Humedad disminuye, lo opuesto tambien es observable.

Comparando solo entre las dos variables:

Para el caso de radiación solar y presión baromérica, el coeficiente de correlación es «bajo».

comparando entre las dos variables solamente:

Instrucciones en Python

# Archivos de estación meteorologica
# correlacion entre sensor_EM
import numpy as np
import pandas as pd
import datetime as dt
import os
import matplotlib.pyplot as plt
from matplotlib.dates import DateFormatter, DayLocator

# INGRESO
archivoEM = "2021_10_EstMeteorologica.csv"
sensor_EM = ["TEMP","Humidity","Solar_rad","Bar_press."]
sensor_EM_u = ["(°C)","(%)","(kW)","(hPa)"]

# PROCEDIMIENTO
# tabla estacion meteorologica
tablaEM = pd.read_csv(archivoEM, sep=';',decimal=',')
tablaEM = pd.DataFrame(tablaEM)
tablaEM_n = len(tablaEM)

# Matriz de Correlación
mediciones = tablaEM[sensor_EM].copy()
correlacion_matriz = mediciones.corr()

# SALIDA
print('Matriz de correlación:')
print(correlacion_matriz)

Para añadir las gráficas, se añaden instrucciones para seleccionar las variables en intervalos de fechas.

# tabla estacion meteorologica
fechaformatoEM = "%d/%m/%Y %H:%M:%S"
# fechas concatenando columnas de texto
tablaEM['fecha'] = tablaEM['Date']+' '+tablaEM['Time']
tablaEM['fecha'] = pd.to_datetime(tablaEM['fecha'],
                                  format=fechaformatoEM)
# grafica
sensorA = "TEMP"
sensorB = "Humidity"
fechaA = "2021/10/01"
fechaB = "2021/10/07"

ti = tablaEM["fecha"].loc[tablaEM["fecha"].between(fechaA,fechaB)]
xi = tablaEM[sensorA].loc[tablaEM["fecha"].between(fechaA,fechaB)]
yi = tablaEM[sensorB].loc[tablaEM["fecha"].between(fechaA,fechaB)]

# grafica compara sensores en tiempo
fig_Pt, graf1 = plt.subplots()
graf1.scatter(ti,xi, marker = '.',
              label=sensorA)

eje12 = graf1.twinx()  # segundo eje del grafico
eje12.scatter(ti,yi, marker = '.',
              color='orange',label=sensorB)
graf1.set_ylabel(sensorA, color='blue')
eje12.set_ylabel(sensorB, color='orange')
plt.show()

# grafica compara sensores
plt.scatter(xi,yi)
plt.xlabel(sensorA, color='blue')
plt.ylabel(sensorB, color='orange')
plt.show()

 

2.1 Valor Esperado E[x] a partir de pmf – Ejercicio

Referencia: LoRaWan – Descriptor estadístico de un punto en Girni,

El indicador de fuerza de la señal recibida (RSSI) para un dispositivo a una distancia desde el gateway es un valor entero que se encuentra alrededor el valor esperado o media. Las condiciones del ambiente generan un componente aleatorio que se muestra en la figura.

Las mediciones se pueden obtener para el enlace de subida (dispositivo a gateway) o enlace de bajada (gateway a dispositivo). A partir de los valores se pueden obtener la pmf del enlace de subida o de bajada

Ejercicio

A partir de los datos de los datos obtenidos para un punto con ubicación  etiquetada LOS04, calcular el valor esperado para los enlaces de subida (UP) y de bajada (Down) a partir de los siguientes datos, presentados en forma de un diccionario de Python:

{"pmf":
 {"pmf_down":
  {"intervalo":[-70,-69,-68,-67,-66,-65,-64],
   "freq_relativa":[0.036101083,0.1371841155,0.1732851986,0.1624548736,0.2707581227,0.202166065,0.0180505415]
   },
  "pmf_up":
  {"intervalo":[-83,-82,-81,-80,-79,-78,-77,-76,-75,-74,-73,-72,-71,-70,-69,-68,-67,-66,-65,-64,-63,-62,-61,-60,-59,-58,-57],
   "freq_relativa":[0.036101083,0.0,0.0252707581,0.0,0.0072202166,0.0,0.1010830325,0.0036101083,0.1083032491,0.0,0.1227436823,0.0,0.0433212996,0.0324909747,0.0180505415,0.0252707581,0.0685920578,0.1335740072,0.0288808664,0.0,0.1046931408,0.1046931408,0.0180505415,0.0072202166,0.0072202166,0.0,0.0036101083]
   }
  },
 "dispositivo":{"pmf_down":"cc24","pmf_up":"cc24"}
 }

Unidades

PAM a PSK – valor esperado

Y(t) = a \cos \big( 2\pi t + \frac{\pi}{2}X(t) \big)

La pmf de x(t) es 0.5 para cada valor de [-1,1]

c) Encuentre la media y autocorrelación de Y(t)

E[Y(t)] = E\big[ a \cos \big( 2\pi t + \frac{\pi}{2}X \big)\big]

Referencia:  León-García 3.3.1 p. 107. Valor esperado de funciones de variable aleatoria

Si z =g(x)

E[g(x)] = \sum_k g(x_k)p_x(X_k)

se tiene entonces que:

= \big[a \cos \big( 2\pi t + \frac{\pi}{2}(-1) \big)\big]\frac{1}{2} + \big[a \cos \big( 2\pi t + \frac{\pi}{2}(1) \big)\big] \frac{1}{2} = \frac{a}{2}\cos \big( 2\pi t - \frac{\pi}{2} \big) + \frac{a}{2}\cos \big( 2\pi t + \frac{\pi}{2} \big) = \frac{a}{2} \sin \big( 2\pi t \big) - \frac{a}{2} \sin \big( 2\pi t \big) = 0 E[Y(t)] = 0

Correlación bits con ruido

Dada una secuencia de bits, al transmitirlos se distorsionó con ruido aditivo. En el receptor será dificil discriminar los valores de los bits tomados de la señal recibida.

La correlación permite «limpiar» un poco la señal en el receptor y una mejor estimación de los bits recibidos.

Para el ejemplo se usa una secuencia de bits 01101001 como señal a transmitir, el ruido aditivo es de tipo normal con media m=0 y varianza σ2=1

Para referencia del proceso, se usa un punto rojo en el centro de la ventana de tiempo de cada bit.

La correlación se realiza con un bit y la señal con ruido.

Observe que luego de la correlación es más sencillo discriminar si lo recibido fué un bit 0 o un bit 1.

señal de bits sin ruido
[0 1 1 0 1 0 0 1]
estimado de bits en el receptor
[ 0.002  0.985  1.07   0.054  0.947 -0.079 -0.006  1.149]

Instrucciones en Python

# secuencia de bits con Ruido
# usar correlación para mejorar la senal
# estimar el bit recibido
# Tarea: convertir estimado en bits

import numpy as np
import matplotlib.pyplot as plt
import scipy.stats as st

# INGRESO

senalbit = np.array([0, 1, 1, 0, 1, 0, 0, 1])

# PROCEDIMIENTO

# señal moduladora son escalones por cada bit
# o forma rectangular de duración anchobit
anchobit = 128
mitadbit = anchobit//2
senal = np.repeat(senalbit, anchobit)
muestras=len(senal)

# reloj para observar la mitad del bit
reloj = np.arange(mitadbit, muestras, anchobit)

# Ruido normal o Gausiano
media = 0
varianza = 1
ruido = st.norm.rvs(media,varianza,muestras)

# Añade el ruido a la señal
senalruido = senal + ruido

# Referencia de un bit para correlación
modelo = np.ones(anchobit)

# correlación modelo de bits
correlacion = np.correlate(senalruido, modelo, mode='same')
# normaliza el resultado [0,1]
correlacion = correlacion / anchobit

# estimado de bits en el receptor
estimado=correlacion[reloj]

# SALIDA
print('señal de bits sin ruido')
print(senalbit)
print('estimado de bits en el receptor')
np.set_printoptions(precision=3)
print(estimado)

#GRAFICA
plt.figure(1)       # define la grafica
plt.suptitle('señal binaria con ruido gaussiano')

plt.subplot(311)
plt.plot(senal)
plt.plot(reloj, senal[reloj], 'ro')
plt.ylabel('señal original')
plt.margins(0,0.05)

plt.subplot(312)
plt.plot(senalruido)
plt.plot(reloj, senalruido[reloj], 'ro')
plt.ylabel('senal con ruido')
plt.margins(0,0.05)

plt.subplot(313)
plt.plot(correlacion)
plt.ylabel('correlación')
plt.plot(reloj, correlacion[reloj], 'ro')
plt.margins(0,0.05)

plt.show()

pmf – Modulación QPSK

QPSK (Quadrature Phase-Shift Keying)

Este esquema de modulación es conocido también como Quaternary PSK (PSK Cuaternaria), Quadriphase PSK (PSK Cuadrafásica).

Esta modulación digital es representada en el diagrama de constelación por cuatro puntos equidistantes del origen de coordenadas.

Con cuatro fases, QPSK puede codificar dos bits por cada símbolo.

Respecto a un ancho de banda predeterminado, la ventaja de QPSK sobre BPSK está que con el primero se transmite el doble de la velocidad de datos en un ancho de banda determinado en comparación con BPSK, usando la misma tasa de error.

En el caso de la canción procesada en BPSK, se cargan una cantidad de datos que se pueden procesar con la mitad de símbolos, enviando la información por pares.

La pmf del proceso QPSK será:


Resultados del algoritmo:

datos cargados:  8595119
símbolos procesados:  4297559
[[ 539083       0 1580668]
 [      1       0       0]
 [1638724       0  539083]]
pmf[x,y]
[[  1.25439348e-01   0.00000000e+00   3.67806003e-01]
 [  2.32690232e-07   0.00000000e+00   0.00000000e+00]
 [  3.81315067e-01   0.00000000e+00   1.25439348e-01]]
>>> 

Instrucciones en Python

# Modulacion digital QPSK - pmf
# propuesta:edelros@espol.edu.ec
import numpy as np
import matplotlib.pyplot as plt

# INGRESO
# archivo = input('archivo de delta-sigma:' )
narchivo = 'elaguacate_deltasigma_datos.txt'
senal = np.loadtxt(narchivo,dtype=int)

# PROCEDIMIENTO
n = len(senal)

simbolos = [-1,0,1]
m = len(simbolos)

# Codificar de 2 en dos
agrupar = 2
cuenta  = np.zeros(shape=(m,m), dtype=int)
nmax = (n//agrupar)*agrupar
for i in range(0,nmax,agrupar):
    a = senal[i]
    b = senal[i+1]
    f = simbolos.index(a)
    c = simbolos.index(b)
    cuenta[f,c] = cuenta[f,c]+1

k = np.sum(cuenta)
pxy = cuenta/k

# SALIDA
print('datos cargados: ', n)
print('símbolos procesados: ', k)
print(cuenta)
print('pmf[x,y]')
print(pxy)


# Gráfica:
from mpl_toolkits.mplot3d import Axes3D
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')

xpos, ypos = np.meshgrid(simbolos,simbolos)
xpos = xpos.flatten('F')

ypos = ypos.flatten('F')
zpos = np.zeros_like(xpos)
dx = 0.8 * np.ones_like(zpos)
dy = dx.copy()
dz = pxy.flatten()
ax.bar3d(xpos, ypos, zpos, dx, dy, dz, color='b', zsort='average')
plt.show()

Tarea: Obtener las pmf marginales del ejercicio.

pmf – Modulación BPSK

La modulación por desplazamiento de fase o PSK (Phase Shift Keying) es una forma de modulación angular en que se modifica la fase de la portadora acorde a valores discretos.

BPSK (PSK Binario)

La modulación consiste en el desplazamiento de fase para 2 símbolos.
También conocida como 2-PSK o PRK (Phase Reversal Keying).

Es la modulación más sencilla por  emplear solo 2 símbolos, con 1 bit de información cada uno.

Los símbolos suelen tener un valor de salto de fase de 0º para el 1 y 180º para el 0 (-1), como se muestra en un diagrama de constelación.

En cambio, su velocidad de transmisión es la más baja de las modulaciones de fase.

BPSK – pmf

La pmf de BPSK muestra el uso de cada símbolo durante una transmisión. Por ejemplo: de un ejercicio previo se codificó a Sigma-Delta una canción teniendo como resultado:

elaguacate_deltasigma_datos.txt

elaguacate_deltasigma_parametros.txt


resultado del algoritmo:

cantidad de símbolos:  8595119
cuenta de símbolos: [4297559       1 4297559]
pmf de símbolos:  [  4.99999942e-01   1.16345102e-07   4.99999942e-01]
>>> 

Instrucciones en Python

# PMF de una señal Sigma-Delta
# propuesta:edelros@espol.edu.ec
import numpy as np
import matplotlib.pyplot as plt

# INGRESO 
# archivo = input('archivo delta-sigma:' )
archivo = 'elaguacate_deltasigma_datos.txt'
senal = np.loadtxt(archivo, dtype=int)

# PROCEDIMIENTO
n = len(senal)
simbolos = [-1,0,1]
m = len(simbolos)
cuenta = np.zeros(m, dtype=int)
for i in range(0,n,1):
    bit = senal[i]
    cual = simbolos.index(bit)
    cuenta[cual] = cuenta[cual]+1
pmf = cuenta/n

# SALIDA
print('cantidad de símbolos: ', n)
print('cuenta de símbolos:', cuenta)
print('pmf de símbolos: ', pmf)

# Gráfica
plt.stem(simbolos,pmf)
plt.title('pmf sigma-delta')
plt.xlabel('símbolos')
plt.ylabel('frecuencia relativa')
plt.show()

Media, Varianza correlacion

Procesos aleatorios Discretos en tiempo

Media:
m_X(n) = E[X(n)]
Varianza:
VAR[X(n)] = E[(X(n) - m_X(n))^2]

Autocorrelación
R_X(n_1,n_2) = E[X(n_1,n_2)]

Autocovarianza:
C_X(n_1,n_2) = E[\{X(n_1) - m_X(n_1) \} \{ X(n_2) - m_X(n_2)\}
C_X(n_1,n_2) = R_X(n_1,n_2) - m_X(n_1) m_X(n_2)

Suma y Retraso de procesos estocásticos

Referencia: León García ejemplos 10.4 y 10.5 p58, Gubner Ejemplo 10.18 p396

Suma de dos procesos

Encuentre la densidad espectral de potencia de Z(t) = X(t) + Y(t), donde X(t) y Y(t) son procesos conjuntamente estacionarios en el sentido amplio WSS.

Solución

Autocorelación de Z(t) es

R_Z(\tau) = E[Z(t + \tau )Z(t)] = = E[(X(t+ \tau)+ Y(t + \tau ))(X(t) + Y(t))] R_Z(\tau) = R_X(\tau) + R_{XY}(\tau) +R_{YX}(\tau) + R_Y(\tau)

La densidad espectral de potencia se calcula como:

S_Z(f) = Fourier\{ R_X(\tau) + R_{XY}(\tau) +R_{YX}(\tau) + R_Y(\tau) \} S_Z(f) = S_X(f) + S_{XY}(f) +S_{YX}(f) + S_Y(f)

Referencia: León García Ejemplo 10.5 p.582, Gubner Ejemplo 10.18 p396

Retraso

Sea Y(t) = X(t- d), donde d es una constante de retraso y donde X(t) es estacionario en el sentido amplio WSS.
Encuentre RYX(τ), SYX(f), RY(τ) y SY(f)

Solución

Usando las definiciones se tiene que:

R_{YX}(\tau) = E[Y(t + \tau )X(t)] = = E[X(t + \tau - d)X(t)] = R_{YX}(\tau) = R_X (\tau - d)

que usando la propiedad de desplazamiento en tiempo de la transformada de Fourier:

S_{YX}(f) = Fourier\{ R_X(\tau - d) \} = = S_X(f) e^{-j2 \pi fd} = = S_X(f) \cos (2\pi fd) - jS_x(f) sin (2 \pi fd)

Finalmente.

R_Y(\tau) = E[Y(t + \tau)Y(t)] = = E[X(t + \tau - d)X(t - d)] = R_X(\tau) S_Y(f) = Fourier\{ R_Y(\tau) \} = Fourier\{ R_X(\tau) \} = S_Y(f) = S_X(f)

Note que la densidad espectral de potencia crusada es compleka, y que SX(f) = SY (f) sin importar el hecho que X(t) ≠ Y(t). Entonces SX(f) = SY(f) lo que no implica que X(t) = Y(t)

Densidad espectral de Potencia de PM

Referencia: León-García Ejemplo 10.2 p581, Gubner Ejemplo 10.21 p399

Ejercicio

Sea X(t) = a cos(ω t + Θ), donde Θ es uniforme en el intervalo (0,2π) Encontrar la autocovarianza de X(t).
Encuentre la densidad espectral de potencia de SX(f):

Solución

S_X(f) = Fourier\{ R_X (\tau) \}

Autocorrelación

R_X (t_1,t_2) = E[(a \cos(\omega t_1 + \Theta)) (a \cos(\omega t_2 +\Theta))]

Recordando que:

E[g(x)] = \int_{-\infty}^{\infty} g(x) f(x) dx cos(x) cos(y) = \frac{cos(x-y) + cos(x+y) }{2}

se tiene que:

= \int_{-\pi}^{\pi} [a\cos(\omega t_1 + \Theta) a\ cos(\omega t_2 +\Theta)] \frac{1}{2\pi} d\Theta = \int_{-\pi}^{\pi} a^2 \frac{\cos(\omega (t_1 - t_2))+\cos(\omega (t_1 + t_2)+ 2\Theta)}{2} \frac{1}{2\pi} d\Theta = a^2 \int_{-\pi}^{\pi} \frac{cos(\omega (t_1 - t_2))}{2} \frac{1}{2\pi} d\Theta + a^2\int_{-\pi}^{\pi} \frac{cos(\omega (t_1 + t_2 )+ 2\Theta)}{2} \frac{1}{2\pi} d\Theta

El primer integral, el coseno no depende de Θ, mientras que el segundo integral es semejante al intergral de la media y cuyo resultado es cero.

= a^2 \left. \frac{cos(\omega (t_1 - t_2))}{2} \frac{\Theta}{2\pi} \right|_{-\pi}^{\pi} + 0 R_X (t_1,t_2) = \frac{a^2}{2} cos(\omega (t_1 - t_2)) R_X (t_1,t_2) = \frac{a^2}{2} cos(\omega \tau)

La densidad espectral de potencia entonces es:

S_X(f) = Fourier\{ R_X (\tau) \} = Fourier\{ \frac{a^2}{2} cos(\omega \tau) \} = \frac{a^2}{2} Fourier\{ cos(\omega \tau) \} = \frac{a^2}{2} Fourier\{ cos(2\pi f_0 \tau) \}

usando las tablas de transformadas de Fourier:

= \frac{a^2}{2} (\frac{1}{2}\delta (f-f_0) + \frac{1}{2} \delta (f+f_0)) = \frac{a^2}{4} \delta (f-f_0) + \frac{a^2}{4} \delta (f+f_0))

El promedio de potencia de la señal es RX(0) = a2/2.
De toda esta potencia, se concentra en las frecuencias en f0 positiva y negativa, por lo que la densidad espectral de potencia en esta frecuencias es infinita.