Perhaps you need a context for that, some texts that use that sort of expressions? For example, a scientific text would not call "cloud" to be "flaffy", but a fairy tale would. Let's get Alice In Wonderland text.
alice = ToLowerCase[ExampleData[{"Text", "AliceInWonderland"}]];
Strangely it does not talk about clouds a single time:
StringCases[alice, "cloud"]
(*{}*)
But it does talk a lot about animals in a sort of metaphoric way, so I will try to build the metaphor
function for animals. This gets only sentences containing the word in question, say "cat":
Select[TextSentences[alice], StringContainsQ[#, "cat"] &]
Now, in all those sentences, you find only words that can be adjectives. Of course minus the stop words. When you get them, tally by frequency of appearance:
Sort[Tally[Select[DeleteStopwords[
Flatten[TextWords[Select[TextSentences[alice], StringContainsQ[#, "cat"] &]]]],
MemberQ[WordData[#, "PartsOfSpeech"], "Adjective"] &]], #1[[2]] > #2[[2]] &]

So say 3 top words will do:
metaphor[cont_String][s_String] :=
Sort[Tally[Select[DeleteCases[DeleteStopwords[
Flatten[TextWords[Select[TextSentences[cont], StringContainsQ[#, s] &]]]], "said"],
MemberQ[WordData[#, "PartsOfSpeech"], "Adjective"] &]], #1[[2]] > #2[[2]] &][[;; 3, 1]]
Now let's see:
Grid[{#, metaphor[alice][#]} & /@ {"cat", "rat"}]

But other context would give a different result:
beowulf = ToLowerCase[ExampleData[{"Text", "BeowulfModern"}]];
Grid[{#, metaphor[beowulf][#]} & /@ {"cat", "rat"}]

So if you get some large corpus of text reflecting on the context you target, then perhaps this would work.