6.分析贵州茅台近20年的最高股价和最低股价:直接使用SQL查询获取贵州茅台最高股价和最低股价对应的日期和数值,并使用orderBy方法对结果进行排序。这里注意需要把close转换为数值以确保正确比较。代码如下:
7.计算上周的平均涨幅:使用SQL查询计算上周的平均涨幅,通过AVG函数实现,同时结合BETWEEN条件来筛选上周的日期范围。代码如下:
8.统计每年上涨和下跌天数使用groupBy方法按年份对DataFrame进行分组。使用agg方法计算每年上涨和下跌天数,通过sum和when函数实现,并添加列计算上涨和下跌天数占总天数的比值。代码如下:
本实验在本地构建了LLM与数据库的结合的pipeline,接下来是详细的介绍。首先我们读入HDFS的文件,对其进行数据格式的转换,并构建视图用于SQL查询,代码如下:
spark=SparkSession.builder.getOrCreate()df=spark.read.csv("stock_everyday_data.csv",header=True)#将a_stock_everyday_data中除了trade_date的字符串都转换为数值,以确保使用sql语句时能正常比较forcolindf.columns:ifcol!="trade_date":df=df.withColumn(col,df[col].cast("float"))df.createOrReplaceTempView("a_stock_everyday_data")接下来,我们需要在本地加载LLM,模型参数量为7B,大约占用17G显存,这里使用Transformers库进行便捷部署:
fromtransformersimportAutoTokenizer,AutoModelForCausalLMmodel_name="defog/sqlcoder-7b-2"tokenizer=AutoTokenizer.from_pretrained(model_name)model=AutoModelForCausalLM.from_pretrained(model_name,trust_remote_code=True,torch_dtype=torch.float16,#load_in_4bit=True,device_map="auto",use_cache=True,)在输入大语言模型时,需要一同给出我们的数据库结构,以便LLM能给出正确的SQL查询语句,因此我们需要构建Prompt模版,指明表格结构,在接收到用户的问题后,替换模版中的{question}内容,从而输入大语言模型,代码如下:
prompt="""<|begin_of_text|><|start_header_id|>user<|end_header_id|>GenerateaSQLquerytoanswerthisquestion:`{question}`DDLstatements:CREATETABLEa_stock_everyday_data(trade_dateDATE,--Tradingdate交易日期,以纯数字形式给出,例如20240515openDECIMAL(10,2),--Openingprice开盘价highDECIMAL(10,2),--Highestprice当日最高价lowDECIMAL(10,2),--Lowestprice当日最低价closeDECIMAL(10,2),--Closingprice收盘价pre_closeDECIMAL(10,2),--Previousclosingprice前一天的收盘价changeDECIMAL(10,2),--Pricechange股价变化pct_chgDECIMAL(10,2),--Pricechangepercentage股价变化率volBIGINT,--Tradingvolume成交额amountDECIMAL(15,2),--Tradingamount成交量);<|eot_id|><|start_header_id|>assistant<|end_header_id|>ThefollowingSQLquerybestanswersthequestion`{question}`:```sql"""构建完成模型输入后,我们需要调用LLM并生成对应结果,在LLM输出结果后,还需要进行解析和格式化处理,为了便于代码复用,我们将调用流程封装为以下函数:
defgenerate_query(question):updated_prompt=prompt.format(question=question)inputs=tokenizer(updated_prompt,return_tensors="pt").to("cuda")#生成SQL语句的参数,确保do_sample=False以保证生成的SQL语句是确定性的并且可复现generated_ids=model.generate(**inputs,num_return_sequences=1,eos_token_id=tokenizer.eos_token_id,pad_token_id=tokenizer.eos_token_id,max_new_tokens=400,do_sample=False,num_beams=1,)outputs=tokenizer.batch_decode(generated_ids,skip_special_tokens=True)torch.cuda.empty_cache()torch.cuda.synchronize()returnoutputs[0].split("```sql")[1].split(";")[0]最后,是接收用户输入并调用模型获取SQL查询语句,在通过spark进行SQL查询的代码:
为了使分析结果更加直观,本次实验还根据不同的分析项目设计了不同可视化结果。可视化主要通过matplotlib实现。
这里使用柱状图展示每年股票的平均交易量,可以直观体现出每一年的交易活跃度,其中2015年为整个市场的牛市,交易量显著高于其它年份。代码如下:
同样使用柱状图展示,代码如下:
为了直观展示各年之间上涨的下跌天数的对比,这里采用堆叠的柱状图进行可视化,并以绿色和红色直观的代表上涨和下跌。代码如下:
为了体现出不同环境下各个指标的区别,这里选择簇状柱状图进行可视化,同时,考虑到各个指标的数据量级不一样,还需要进行适当放缩,以便其在同一张图上显示。
当需要反映数据趋势时,通常选择折线图,股价的波动也适合用折线图来表示。