やりたかったこと
文字列同士の類似性をサクッと算出したかった。Power Queryでは、FuzzyJoinができるのだから、テキストの類似度を算出する関数もあるかと思いきや、どうやらないようです。
試したこと
かなり力技くさいのですが、2つの文字列をそれぞれテーブルにして、しきい値を変えながらFuzzyJoinを試していき、結果を取る関数を作ってみました。
TextSimilarity
(s as text, t as text, step as number, optional joinOptions as nullable record) as number =>
let
// 各文字列ごとに1行1列のみのテーブルを生成
table_s = #table(type table [s = text], {{s}}),
table_t = #table(type table [t = text], {{t}}),
// 指定した閾値でFuzzyJoinできたかどうかを返す
isMatch = (threshold as number) as logical =>
not Table.IsEmpty(
Table.FuzzyJoin(
table_s, {"s"},
table_t, {"t"},
JoinKind.Inner,
[Threshold = threshold] & (if joinOptions = null then [] else joinOptions)
)
),
// 試行する閾値をリストアップ
li = List.Generate(
() => 0,
each _ < 100,
each _ + step,
each _ / 100
) & {1},
// 二分探索してマッチする最大の閾値を特定
fx = (left as number, right as number) =>
let
mid = Number.RoundDown((left + right) / 2),
result = [left = left, right = right, mid = mid, match = isMatch(li{mid})]
in
result,
results = List.Generate(
() => fx(1, List.Count(li)),
each [left] < [right],
each if [match] then
fx([mid] + 1, [right])
else
fx([left], [mid])
),
matchedResults = List.Select(results, each [match]),
values = List.Transform(matchedResults, each [mid]),
ans = li{List.Max(values, 0)}
in
ans
結果
のですが、テーブルから列の追加→カスタム関数の呼び出しだとエラーが出て駄目でした。
エラー詳細
予期しないエラー: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。
詳細:
Microsoft.Mashup.Evaluator.Interface.ErrorException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 ---> Microsoft.Mashup.Evaluator.Interface.ErrorException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 ---> Microsoft.Mashup.Evaluator.Interface.ErrorException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 ---> Microsoft.Mashup.Evaluator.Interface.ErrorException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 ---> Microsoft.Mashup.Evaluator.Interface.ErrorException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 ---> System.InvalidOperationException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。 ---> System.InvalidOperationException: オブジェクトの現在の状態に問題があるため、操作は有効ではありません。
場所 Microsoft.Mashup.Engine1.Language.Compiler.ToFunction(IFunctionExpression expression)
場所 Microsoft.Mashup.Engine1.Runtime.CollapseNestedFunctionsVisitor.VisitFunction(IFunctionExpression node)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitInvocation(IInvocationExpression invocation)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.LogicalAstVisitor2`1.VisitFunction(IFunctionExpression function, IList`1 bindings)
場所 Microsoft.Mashup.Engine1.Runtime.CollapseNestedFunctionsVisitor.VisitFunction(IFunctionExpression node)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitListElements(IExpression[] list)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitInvocation(IInvocationExpression invocation)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.LogicalAstVisitor2`1.VisitInitializer(VariableInitializer member)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitListElements(VariableInitializer[] list)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitListElements(IList`1 list)
場所 Microsoft.Mashup.Engine.Ast.LogicalAstVisitor2`1.VisitRecord(IRecordExpression record, TBinding binding, IList`1 bindings)
場所 Microsoft.Mashup.Engine1.Runtime.CollapseNestedFunctionsVisitor.VisitRecord(IRecordExpression node)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitFieldAccess(IFieldAccessExpression fieldAccess)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.LogicalAstVisitor2`1.VisitFunction(IFunctionExpression function, IList`1 bindings)
場所 Microsoft.Mashup.Engine1.Runtime.CollapseNestedFunctionsVisitor.VisitFunction(IFunctionExpression node)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitInvocation(IInvocationExpression invocation)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitListElements(IExpression[] list)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitInvocation(IInvocationExpression invocation)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine.Ast.LogicalAstVisitor2`1.VisitFunction(IFunctionExpression function, IList`1 bindings)
場所 Microsoft.Mashup.Engine1.Runtime.CollapseNestedFunctionsVisitor.VisitFunction(IFunctionExpression node)
場所 Microsoft.Mashup.Engine.Ast.AstVisitor2.VisitExpression(IExpression expression)
場所 Microsoft.Mashup.Engine1.Language.Query.NormalizationVisitor.Normalize(IExpression node, TypeValue[] parameterTypes, Boolean normalizeInvocation)
場所 Microsoft.Mashup.Engine1.Language.Query.QueryExpressionBuilder.TryToQueryExpression(TypeValue type, IFunctionExpression functionExpression, QueryExpression& queryExpression)
場所 Microsoft.Mashup.Engine1.Language.Query.AddColumnsQuery.CreateQueryExpressions(FunctionValue columnGeneratorFunction, RecordTypeValue rowType)
場所 Microsoft.Mashup.Engine1.Language.Query.ProjectColumnsQuery.TryAddColumns(ColumnsConstructor columnGenerator, Query& query, ColumnSelection& newColumnProjection)
場所 Microsoft.Mashup.Engine1.Language.Query.ProjectColumnsQuery.AddColumns(ColumnsConstructor columnGenerator)
場所 Microsoft.Mashup.Engine1.Language.Query.QueryTableValue.AddColumns(ColumnsConstructor columnGenerator)
場所 Microsoft.Mashup.Engine1.Runtime.RelatedTablesTableValue.AddColumns(ColumnsConstructor columnsConstructor)
場所 Microsoft.Mashup.Engine1.Runtime.TableValue.AddColumns(ListValue columnNames, FunctionValue columnGenerator, Value columnTypes)
場所 Microsoft.Mashup.Engine1.Runtime.NativeFunctionValue4`5.Invoke(Value arg0, Value arg1, Value arg2, Value arg3)
場所 Microsoft.Mashup.Engine1.Runtime.FunctionValue.Invoke(Value[] args)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue1.Invoke(Value arg0)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.Force(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.get_Item(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.RuntimeFunctionValueN.Invoke(Value[] args)
場所 Microsoft.Mashup.Engine1.Language.FunctionInvocationInstruction2.Execute(MembersFrameN& frame)
場所 Microsoft.Mashup.Engine1.Language.RuntimeFunctionValueN.Invoke(Value[] args)
場所 Microsoft.Mashup.Engine1.Language.DebugInstruction.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.FunctionInvocationInstruction2.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.DebugInstruction.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.InstructionInvocationInstruction2.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.DebugInstruction.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue1.Invoke(Value arg0)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.Force(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.get_Item(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue1.Invoke(Value arg0)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.Force(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.get_Item(Int32 index)
場所 Microsoft.Mashup.Engine1.Runtime.Library.Linker.BindFunctionValue.TypedInvoke(RecordValue environment, Value section, TextValue name)
場所 Microsoft.Mashup.Engine1.Runtime.NativeFunctionValue3`4.Invoke(Value arg0, Value arg1, Value arg2)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue0.Invoke()
場所 Microsoft.Mashup.Engine1.Language.ListInstruction.RuntimeListValue.Force(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.ListInstruction.RuntimeListValue.get_Item(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue1.Invoke(Value arg0)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.Force(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.get_Item(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.FunctionInvocationInstruction2.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.Instruction.ExecuteCondition(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.DebugInstruction.ExecuteCondition(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.IfInstruction.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.DebugInstruction.Execute(MembersFrame1& frame)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue1.Invoke(Value arg0)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.Force(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.RecordInstruction.RuntimeRecordValue.get_Item(Int32 index)
場所 Microsoft.Mashup.Engine1.Language.MembersFunctionValue0.Invoke()
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.BeginGetResult(DocumentEvaluationParameters parameters, Action`1 callback)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.BeginGetResult(DocumentEvaluationParameters parameters, Action`1 callback)
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.BeginGetResult(DocumentEvaluationParameters parameters, Action`1 callback)
場所 Microsoft.Mashup.Evaluator.FirewallPartition.BeginGetResult[T](Action`1 callback)
場所 Microsoft.Mashup.Evaluator.FirewallDocumentEvaluator.Evaluation`1.OnBufferComplete(Exception exception)
場所 Microsoft.Mashup.Evaluator.Firewall.BeginBufferPartitions(Action`1 callback)
場所 Microsoft.Mashup.Evaluator.FirewallDocumentEvaluator.BeginGetResultInternal[T](DocumentEvaluationParameters parameters, Action`1 callback)
場所 Microsoft.Mashup.Evaluator.Interface.IDocumentEvaluatorExtensions.GetResult[T](IDocumentEvaluator`1 evaluator, DocumentEvaluationParameters parameters)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.OnBeginGetResult[T](IMessageChannel channel, BeginGetResultMessage message, Action`1 action)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.OnBeginGetPreviewValueSource(IMessageChannel channel, BeginGetPreviewValueSourceMessage message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.OnMessageWithUnknownChannel(IMessageChannel baseChannel, MessageWithUnknownChannel messageWithUnknownChannel)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.EvaluationHost.Run()
場所 Microsoft.Mashup.Container.EvaluationContainerMain.Run(Object args)
場所 Microsoft.Mashup.Evaluator.SafeThread2.<>c__DisplayClass9_0.<CreateAction>b__0(Object o)
場所 Microsoft.Mashup.Container.EvaluationContainerMain.SafeRun(String[] args)
場所 Microsoft.Mashup.Container.EvaluationContainerMain.Main(String[] args)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.<>c__DisplayClass3_0.<BeginGetResult>b__0(EvaluationResult2`1 result)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.<>c__DisplayClass3_0.<BeginGetResult>b__0(EvaluationResult2`1 result)
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.BeginGetResult(DocumentEvaluationParameters parameters, Action`1 callback)
場所 Microsoft.Mashup.Evaluator.SimpleDocumentEvaluator.BeginGetResult(DocumentEvaluationParameters parameters, Action`1 callback)
場所 Microsoft.Mashup.Evaluator.FirewallPartition.BeginGetResult[T](Action`1 callback)
場所 Microsoft.Mashup.Evaluator.FirewallDocumentEvaluator.Evaluation`1.OnBufferComplete(Exception exception)
場所 Microsoft.Mashup.Evaluator.Firewall.BeginBufferPartitions(Action`1 callback)
場所 Microsoft.Mashup.Evaluator.FirewallDocumentEvaluator.BeginGetResultInternal[T](DocumentEvaluationParameters parameters, Action`1 callback)
場所 Microsoft.Mashup.Evaluator.Interface.IDocumentEvaluatorExtensions.GetResult[T](IDocumentEvaluator`1 evaluator, DocumentEvaluationParameters parameters)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.OnBeginGetResult[T](IMessageChannel channel, BeginGetResultMessage message, Action`1 action)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.OnBeginGetPreviewValueSource(IMessageChannel channel, BeginGetPreviewValueSourceMessage message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.OnMessageWithUnknownChannel(IMessageChannel baseChannel, MessageWithUnknownChannel messageWithUnknownChannel)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.EvaluationHost.Run()
場所 Microsoft.Mashup.Container.EvaluationContainerMain.Run(Object args)
場所 Microsoft.Mashup.Evaluator.SafeThread2.<>c__DisplayClass9_0.<CreateAction>b__0(Object o)
場所 Microsoft.Mashup.Container.EvaluationContainerMain.SafeRun(String[] args)
場所 Microsoft.Mashup.Container.EvaluationContainerMain.Main(String[] args)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.<>c__DisplayClass9_1.<OnBeginGetPreviewValueSource>b__1()
場所 Microsoft.Mashup.Evaluator.RemotePreviewValueSource.<>c__DisplayClass0_0.<RunStub>b__0()
場所 Microsoft.Mashup.Evaluator.EvaluationHost.ReportExceptions(IHostTrace trace, IEngineHost engineHost, IMessageChannel channel, Action action)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.Mashup.Evaluator.EvaluationHost.<>c__DisplayClass11_0.<TryReportException>b__1()
場所 Microsoft.Mashup.Common.SafeExceptions.IgnoreSafeExceptions(IEngineHost host, IHostTrace trace, Action action)
場所 Microsoft.Mashup.Evaluator.EvaluationHost.TryReportException(IHostTrace trace, IEngineHost engineHost, IMessageChannel channel, Exception exception)
場所 Microsoft.Mashup.Evaluator.EvaluationHost.ReportExceptions(IHostTrace trace, IEngineHost engineHost, IMessageChannel channel, Action action)
場所 Microsoft.Mashup.Evaluator.RemotePreviewValueSource.RunStub(IEngineHost engineHost, IMessageChannel channel, Func`1 getPreviewValueSource)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.<>c__DisplayClass12_1`1.<OnBeginGetResult>b__0()
場所 Microsoft.Mashup.Evaluator.EvaluationHost.ReportExceptions(IHostTrace trace, IEngineHost engineHost, IMessageChannel channel, Action action)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.OnBeginGetResult[T](IMessageChannel channel, BeginGetResultMessage message, Action`1 action)
場所 Microsoft.Mashup.Evaluator.RemoteDocumentEvaluator.Service.OnBeginGetPreviewValueSource(IMessageChannel channel, BeginGetPreviewValueSourceMessage message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.OnMessageWithUnknownChannel(IMessageChannel baseChannel, MessageWithUnknownChannel messageWithUnknownChannel)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.EvaluationHost.Run()
場所 Microsoft.Mashup.Container.EvaluationContainerMain.Run(Object args)
場所 Microsoft.Mashup.Evaluator.SafeThread2.<>c__DisplayClass9_0.<CreateAction>b__0(Object o)
場所 Microsoft.Mashup.Container.EvaluationContainerMain.SafeRun(String[] args)
場所 Microsoft.Mashup.Container.EvaluationContainerMain.Main(String[] args)
--- 内部例外スタック トレースの終わり ---
場所 Microsoft.Mashup.Evaluator.EvaluationHost.OnException(IEngineHost engineHost, IMessageChannel channel, ExceptionMessage message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.ChannelMessenger.ChannelMessageHandlers.TryDispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.MessageHandlers.Dispatch(IMessageChannel channel, Message message)
場所 Microsoft.Mashup.Evaluator.Interface.IMessageChannelExtensions.WaitFor[T](IMessageChannel channel)
場所 Microsoft.Mashup.Evaluator.RemotePreviewValueSource.PreviewValueSource.WaitFor(Func`1 condition, Boolean disposing)
場所 Microsoft.Mashup.Evaluator.RemotePreviewValueSource.PreviewValueSource.get_TableSource()
場所 Microsoft.Mashup.Evaluator.Interface.TracingPreviewValueSource.get_TableSource()
場所 Microsoft.Mashup.Host.Document.Analysis.PackageDocumentAnalysisInfo.PackagePartitionAnalysisInfo.SetPreviewValue(EvaluationResult2`1 result, Func`1 getStaleSince, Func`1 getSampled)
