import numpy as np
import pandas as pd
import datetime as dt
import seaborn as sns
import statsmodels.api as sm
import matplotlib.pyplot as plt
from matplotlib import font_manager, rc
from sklearn.linear_model import LinearRegression
from sklearn.preprocessing import MinMaxScaler
# 폰트 설정
font_path = "C:/Windows/Fonts/malgun.ttf" # 한글 폰트 경로
font_name = font_manager.FontProperties(fname=font_path).get_name()
rc('font', family=font_name)
root = 'C:/AI_Project/AI/12_smartfarm/data'
불러오고자 하는 csv file의 이름을 입력합니다.
충남 부여 연동 방울토마토 재배 비닐 하우스 농가 3곳 데이터(cny1, cny2, cny3)
cny1 = pd.read_csv(root+'/cny1.csv', encoding='cp949')
cny2 = pd.read_csv(root+'/cny2.csv', encoding='cp949')
cny3 = pd.read_csv(root+'/cny3.csv', encoding='cp949')
# .csv 파일이 존재하는 폴더
root = 'C:/AI_Project/AI/12_smartfarm/data'
cny1 = pd.read_csv(root+'/cny1.csv', encoding='cp949')
cny2 = pd.read_csv(root+'/cny2.csv', encoding='cp949')
cny3 = pd.read_csv(root+'/cny3.csv', encoding='cp949')
## 예시 사이즈 : 엽장이 20주차 31일 때
input_week = int(input("작물의 주차 : "))
input_size = float(input("분석하고자 하는 작물의 사이즈 : "))
작물의 주차 : 20 분석하고자 하는 작물의 사이즈 : 31
# 데이터 결측치 처리 및 주차 컬럼 형식 변경
def data_preprocess(dataframe, columns=[]):
if columns:
dataframe = dataframe[columns]
df_colDel = dataframe.dropna(axis=1, how='all')
df_rowDel = df_colDel.dropna(subset=['주차'])
df_rowDel['주차'] = df_rowDel['주차'].str.extract('(\d+)').astype(int)
df_unique_rows = df_rowDel.drop_duplicates()
df = df_unique_rows.reset_index(drop=True)
return df
# 신뢰 구간을 포함한 Linear Regression Model
def linear_regression_with_confidence_interval(df, xcol, ycol):
df_cleaned = df.dropna(subset=[xcol, ycol]) # NaN이 있는 행 제외
# 선형 회귀 모델 초기화 및 훈련
X = sm.add_constant(df_cleaned[[xcol]])
model = sm.OLS(df_cleaned[ycol], X).fit()
# 95% 신뢰 구간 계산
ci = model.get_prediction(X).conf_int(alpha=0.05)
# 예측값
predicted_values = model.predict(X)
# 결과를 데이터프레임으로 생성
result_df = pd.DataFrame({
xcol: df_cleaned[xcol],
'lowerbound': ci[:, 0],
'upperbound': ci[:, 1],
})
return predicted_values, result_df
# Visualization Linear Regression Model
def print_LR(df_list, xcol, ycol, input_week, input_size):
df_concat = pd.concat(df_list, axis=0)
df_concat = df_concat.reset_index(drop=True)
df = df_concat.dropna(subset=[xcol, ycol])
X = df[[xcol]]
y = df[ycol]
# 선형 회귀 모델 초기화 및 훈련
model = LinearRegression()
model.fit(X, y)
# 함수 호출
predicted_values, confidence_interval = linear_regression_with_confidence_interval(df_concat, xcol=xcol, ycol=ycol) # 예측값, 신뢰구간
# 회귀선 시각화
plt.figure(figsize=(8, 6))
sns.regplot(x=xcol, y=ycol, data=df)
plt.plot(df[xcol], model.predict(X), color='red', linewidth=2, label='Linear Regression')
plt.scatter(input_week, input_size, color='red', s=20, label='Input Value')
plt.title(f'Linear Regression: {ycol} - {xcol}')
plt.xlabel(xcol)
plt.ylabel(ycol)
plt.legend()
plt.grid(True, linestyle='--', alpha=0.7)
plt.show()
# 회귀 계수 및 절편 출력
print(f'Intercept (절편): {model.intercept_}')
print(f'Coefficient (기울기): {model.coef_[0]}')
return model.intercept_, model.coef_[0], predicted_values, confidence_interval
- xcol = '주차'
- ycol = '엽장'
processed_cny1 = data_preprocess(cny1, ['시설ID', '조사일', '주차', '생장길이', '화방높이', '줄기직경', '엽장', '엽폭', '엽수', '개화군', '착과군', '열매수', '최종화방차수'])
processed_cny2 = data_preprocess(cny2, ['시설ID', '조사일', '주차', '생장길이', '화방높이', '줄기직경', '엽장', '엽폭', '엽수', '개화군', '착과군', '열매수', '최종화방차수'])
processed_cny3 = data_preprocess(cny3, ['시설ID', '조사일', '주차', '생장길이', '화방높이', '줄기직경', '엽장', '엽폭', '엽수', '개화군', '착과군', '열매수', '최종화방차수'])
# x-axis = 주차 / y-axis = 엽장
xcol = '주차'
ycol = '엽장'
# print_LR 함수를 통해 그래프 도출
intercept, coef, predicted_values, confidence_interval = print_LR([processed_cny1, processed_cny2, processed_cny3], xcol, ycol, input_week, input_size)
C:\Users\정하영\AppData\Local\Temp/ipykernel_10560/1572217170.py:7: 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
df_rowDel['주차'] = df_rowDel['주차'].str.extract('(\d+)').astype(int)
C:\Anaconda3\lib\site-packages\statsmodels\tsa\tsatools.py:142: FutureWarning: In a future version of pandas all arguments of concat except for the argument 'objs' will be keyword-only
x = pd.concat(x[::order], 1)
Intercept (절편): 17.75582034520376 Coefficient (기울기): 1.0331842129743172
y_pred = coef*input_week+intercept
print('===========================================================================\n')
print(f'{input_week}{xcol} 일 때, 예상 {ycol} 사이즈는 {round(y_pred, 2)} 입니다.\n')
print(f'해당 작물은 예상 크기의 {round(input_size/y_pred*100,2)}% 사이즈 입니다.')
print('\n===========================================================================')
=========================================================================== 20주차 일 때, 예상 엽장 사이즈는 38.42 입니다. 해당 작물은 예상 크기의 80.69% 사이즈 입니다. ===========================================================================